Skip to content
Snippets Groups Projects
mwserv.c 3.59 KiB
Newer Older
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <getopt.h>
#include <errno.h>
#include <sys/types.h>
#include <pwd.h>
#include <string.h>

#include <util.h>
#include <mwcfg.h>
#include "servsock.h"

#define MWSERVCONF "mwserv.conf"
time_t uptime = 0;
static void usage(char *name)
	printf("Usage:\n  %s "
	       "[--config|-c <file>]"
	       "[--help|-h]"
	       "[--foreground|-f]"
	       "[--port|-p <port>]"
	       "[--print-config|-P]"
	       "\n", name);
/**
 * Config options must be set here so that the config system will recognise
 * them. It also uses them to validate the types of the overrides specified in
 * config files. Any options found in config files that are not listed here
 * will be ignored (non-fatally).
 **/
static const struct cfg_default_opt defcfgs[] = {
	CFG_OPT(BOOL, "foreground", 0),
	CFG_OPT(INT, "port", 9999),
	CFG_OPT(STR, "user", MWUSER),
	CFG_END
};

static int config_init(void)
{
	_autofree char *homeconf = NULL;
	const char *homedir;
	int ret;

	ret = cfg_init_defaults(defcfgs);
	if (ret)
		return ret;

	homedir = getenv("HOME");
	if (homedir) {
		ret = asprintf(&homeconf, "%s/."MWSERVCONF, homedir);
		if (ret > 0) {
			ret = cfg_load(homeconf);
			if (ret <= 0)
				return ret;
		}
	}
	ret = cfg_load("/etc/"MWSERVCONF);
	if (ret <= 0)
		return ret;
	return 0;
}

static int getconfig(int argc, char **argv)
	int printcfg = 0;
		{"config",       required_argument, 0, 'c'},
		{"foreground",   no_argument,       0, 'f'},
		{"help",         no_argument,       0, 'h'},
		{"print-config", no_argument,       0, 'P'},
		{"port",         required_argument, 0, 'p'},
	ret = config_init();
	if (ret != 0)
		c = getopt_long(argc, argv, "c:fhPp:", loptspec, &optidx);
			case 'c':
				ret = cfg_load(optarg);
				if (ret != 0)
					return ret;
				break;
			case 'P':
				/* Do this once all the config sources have been merged */
				printcfg = 1;
				break;
			case 'p':
				errno = 0;
				num = strtol(optarg, NULL, 0);
				if (errno != 0 || num < 1 || num > UINT16_MAX) {
					fprintf(stderr, "Bad port number\n");
					return 1;
				}
				cfg_set_int("port", num);
				cfg_set_bool("foreground", 1);
				usage(argv[0]);
				exit(0);
				usage(argv[0]);
				return 1;
		}
	}

	if (optind < argc) {
		fprintf(stderr, "Unrecognised arguments: ");
		while (optind < argc)
			fprintf(stderr, "%s ", argv[optind++]);
		fprintf(stderr, "\n");
		return 1;
	}

	if (printcfg) {
		cfg_dump(stdout);
		exit(0);
	}
int main(int argc, char **argv)
{
	int mainsock = -1;
	err = getconfig(argc, argv);
	if (err)
	mainsock = open_mainsock(cfg_get_int("port"));

	if (mainsock < 0) {
		fprintf(stderr, "Failed.\n");
		return 1;
	}

		const char *user = cfg_get_string("user");
		struct passwd *pwbuff = getpwnam(user);
			fprintf(stderr, "Username %s does not exist.\n", user);
			return 1;
		}
		if (setgid(pwbuff->pw_gid)) {
			fprintf(stderr, "Failed to setgid. %s\n", strerror(errno));
			return 1;
		}
		if (setuid(pwbuff->pw_uid)) {
			fprintf(stderr, "Failed to setuid. %s\n", strerror(errno));
			return 1;
		}
	}

	migrate_old_folders();
	if (cfg_get_bool("foreground"))
		setlinebuf(stdout);
	else
		daemon(0, 0);
	uptime = time(0);
	watch_mainsock(mainsock);
	printf("Done.\n");
}