diff --git a/src/confparser.c b/src/confparser.c index ba850be..132a814 100644 --- a/src/confparser.c +++ b/src/confparser.c @@ -25,12 +25,13 @@ #include #include #include +#include #include "log.h" #include "confparser.h" #include "enum_functions.h" -static int test_conf_perms(void); -static int test_conf_syntax(void); +static int test_conf_perms(char *config); +static int test_conf_syntax(char *config); struct conf_table conf = { 0, /* isvalid initial state */ @@ -155,11 +156,44 @@ static int fopen_and_mkdir(const char *dir) } -static int test_conf_perms(void) +static int test_conf_perms(char *config) { struct stat s; char confresult[128]; - int err = stat("/etc/rmps", &s); + char *config_copy = strdup(config); + int err = stat(config, &s); + + if (err == -1) { + if (errno == ENOENT) { + enumtostr(confresult, CONF_MISSING); + log(ERROR, confresult); + return 1; + } + } else { + if (!S_ISREG(s.st_mode)) { + enumtostr(confresult, CONF_NOTFILE); + log(ERROR, confresult); + return 1; + } + if (!(0400 & s.st_mode)) { + enumtostr(confresult, CONF_PERM); + log(ERROR, confresult); + return 1; + } + if (s.st_uid != 0) { + enumtostr(confresult, CONF_FILE_UID_INSECURE); + log(WARNING, confresult); + } else if (s.st_gid != 0) { + enumtostr(confresult, CONF_FILE_GID_INSECURE); + log(WARNING, confresult); + } else if ((0004 & s.st_mode) || + (0002 & s.st_mode)) { + enumtostr(confresult, CONF_FILE_PERM_INSECURE); + log(WARNING, confresult); + } + } + + err = stat(dirname(config_copy), &s); if (err == -1) { if (errno == ENOENT) { @@ -192,48 +226,17 @@ static int test_conf_perms(void) } } - err = stat("/etc/rmps/rmps.conf", &s); - - if (err == -1) { - if (errno == ENOENT) { - enumtostr(confresult, CONF_MISSING); - log(ERROR, confresult); - return 1; - } - } else { - if (!S_ISREG(s.st_mode)) { - enumtostr(confresult, CONF_NOTFILE); - log(ERROR, confresult); - return 1; - } - if (!(0400 & s.st_mode)) { - enumtostr(confresult, CONF_PERM); - log(ERROR, confresult); - return 1; - } - if (s.st_uid != 0) { - enumtostr(confresult, CONF_FILE_UID_INSECURE); - log(WARNING, confresult); - } else if (s.st_gid != 0) { - enumtostr(confresult, CONF_FILE_GID_INSECURE); - log(WARNING, confresult); - } else if ((0004 & s.st_mode) || - (0002 & s.st_mode)) { - enumtostr(confresult, CONF_FILE_PERM_INSECURE); - log(WARNING, confresult); - } - } return 0; /* conf is readable */ } -static int test_conf_syntax(void) +static int test_conf_syntax(char *config) { int i, j = 0, ok = 1, failed = 0; char buf[CFGLINESIZE], *tmp; - FILE *fp = fopen("/etc/rmps/rmps.conf", "r"); + FILE *fp = fopen(config, "r"); if (fp == NULL) { - log(ERROR, "Failed to read /etc/rmps/rmps.conf"); + log(ERROR, "Failed to read %s", config); return 1; } @@ -252,8 +255,7 @@ static int test_conf_syntax(void) *tmp = '\0'; else { log(ERROR, - "Bad entry in /etc/rmps/rmps.conf, line %d: %s", - j, buf); + "Bad entry in %s, line %d: %s", config, j, buf); ok = 0; failed = 1; continue; @@ -438,15 +440,15 @@ static int test_conf_syntax(void) return 0; } -int confparse(void) +int confparse(char *config) { int result; - result = test_conf_perms(); + result = test_conf_perms(config); if (result) return 1; /* Bad conf perms */ - result = test_conf_syntax(); + result = test_conf_syntax(config); if (result != 0) return 1; /* Bad conf syntax */ return 0; /* seems legit */ diff --git a/src/confparser.h b/src/confparser.h index a0826f2..e169bdd 100644 --- a/src/confparser.h +++ b/src/confparser.h @@ -66,10 +66,9 @@ struct conf_table { }; extern struct conf_table conf; -extern int confparse(void); +extern int confparse(char *); extern void confexport(void); extern const char *conf_db_pass(void); extern const char *conf_db_hostname(void); #endif /* CONFPARSER_H */ - diff --git a/src/main.c b/src/main.c index c460f78..a59fd41 100644 --- a/src/main.c +++ b/src/main.c @@ -25,61 +25,101 @@ #include #include #include +#include #include "confparser.h" #include "log.h" #include "rmps.h" static void usage(char *argv) { - log(ERROR, - "Usage:\n%s start|stop|restart [--daemonize=yes|no]", argv); + fprintf(stderr, "Usage:\n%s TASK [-c CONFIG] [-d]\n\n" + "Tasks:\n" + "\t--start\t\tStart the RMPS server.\n" + "\t--stop\t\tStop the RMPS server.\n" + "\t--restart\tRestart the RMPS server.\n\n" + "Options:\n" + "\t-c, --config\n" + "\t\tSpecify the configuration file path. Default is set " + "to /etc/rmps/rmps.conf\n" + "\t-d, --daemonize\n" + "\t\tSetting this will make the parent fork in the " + "backgroud. Default is not to fork.\n" + "\t-h, --help\n" + "\t\tShow this message.\n", argv); } int main(int argc, char *argv[]) { - int fork_flag = 1, task; + enum tasks { + START = 1, + STOP, + RESTART + }; + static int task; + const char opts_short[] = "dc:h"; + static struct option opts_long[] = + { + {"start", no_argument, &task, START}, + {"stop", no_argument, &task, STOP}, + {"restart", no_argument, &task, RESTART}, + {"daemonize", no_argument, 0, 'd'}, + {"config", required_argument, 0, 'c'}, + {"help", no_argument, 0, 'h'}, + {NULL, 0, NULL, 0} + }; + int opt = 0, opt_index = 0, fork_flag = 0; + char *config = NULL; - if (argc < 2 || argc > 3) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - if (!strcmp(argv[1], "start")) - task = 1; - else if (!strcmp(argv[1], "stop")) - task = 2; - else if (!strcmp(argv[1], "restart")) - task = 3; - else { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - if (argc == 3) { - if (!strcmp("--daemonize=yes", argv[2])) - fork_flag = 1; - else if (!strcmp("--daemonize=no", argv[2])) - fork_flag = 0; - else { - usage(argv[0]); - exit(EXIT_FAILURE); + while ((opt = getopt_long(argc, argv, opts_short, opts_long, &opt_index)) != -1) { + switch (opt) { + case 0: + if (opts_long[opt_index].flag != 0) + break; + log(INFO, "option %s", opts_long[opt_index].name); + if (optarg) + log(INFO, "with arg %s\n", optarg); + break; + case 'd': + fork_flag = 1; + break; + case 'c': + config = optarg; + break; + case 'h': + usage(argv[0]); + exit(EXIT_SUCCESS); + default: + usage(argv[0]); + exit(EXIT_FAILURE); } } - if (confparse() != 0) { + + if (!config) { + char path[] = "/etc/rmps/rmps.conf"; + int path_size = strlen(path) + 1; + config = calloc(sizeof(char), path_size); + if (config == NULL) { + log(ERROR, "malloc() failed for config"); + exit(EXIT_FAILURE); + } + memcpy(config, path, path_size); + } + + if (confparse(config) != 0) { log(ERROR, "Failed to parse the conf!"); exit(EXIT_FAILURE); } log(VERBOSE, "Conf parser finished successfully"); //confexport(); - if (task == 2 || task == 3) { + if (task == STOP|| task == RESTART) { char buf[10]; int pid; FILE *fp; - if (task == 2) + if (task == STOP) log(VERBOSE, "We got a stop signal!"); - else if (task == 3) + else if (task == RESTART) log(VERBOSE, "We got a restart signal!"); fp = fopen(conf.rmps.pidfile, "r"); @@ -99,7 +139,7 @@ int main(int argc, char *argv[]) log(ERROR, "Permission denied to read PID. Exiting!"); exit(EXIT_FAILURE); case ENOENT: - if (task == 2) + if (task == STOP) exit(EXIT_FAILURE); break; default: @@ -109,7 +149,7 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } } - if (task == 1 || task == 3) + if (task == START || task == RESTART) launch_rmps(&conf, fork_flag); return 0;