diff --git a/conf.c b/conf.c index 8e20c686..a3219b66 100644 --- a/conf.c +++ b/conf.c @@ -86,141 +86,168 @@ int parse_runlevels(char *runlevels) return bitmask; } -void parse_finit_conf(char *file) +static int parse_conf(char *file) { FILE *fp; char line[LINE_SIZE]; char cmd[CMD_SIZE]; + char *x; + const char *err = NULL; + /* Assume absolute path is given ... */ + fp = fopen(file, "r"); + if (!fp) { + /* ... if it fails, try /etc/finit.d/ as prefix */ + snprintf(line, sizeof(line), "%s/%s", rcsd, file); + fp = fopen(file, "r"); + if (!fp) + return 1; + } + + _d("Parse %s ...", file); + while (!feof(fp)) { + if (!fgets(line, sizeof(line), fp)) + continue; + chomp(line); + _d("conf: %s", line); + + /* Skip comments. */ + if (MATCH_CMD(line, "#", x)) + continue; + + /* Do this before mounting / read-write + * XXX: Move to plugin which checks /etc/fstab instead */ + if (MATCH_CMD(line, "check ", x)) { + char *dev = strip_line(x); + + strcpy(cmd, "/sbin/fsck -C -a "); + strlcat(cmd, dev, sizeof(cmd)); + run_interactive(cmd, "Checking file system %s", dev); + + continue; + } + + if (MATCH_CMD(line, "user ", x)) { + if (username) free(username); + username = strdup(strip_line(x)); + continue; + } + if (MATCH_CMD(line, "host ", x)) { + if (hostname) free(hostname); + hostname = strdup(strip_line(x)); + continue; + } + + if (MATCH_CMD(line, "module ", x)) { + char *mod = strip_line(x); + + strcpy(cmd, "/sbin/modprobe "); + strlcat(cmd, mod, sizeof(cmd)); + run_interactive(cmd, "Loading kernel module %s", mod); + + continue; + } + if (MATCH_CMD(line, "mknod ", x)) { + char *dev = strip_line(x); + + strcpy(cmd, "/bin/mknod "); + strlcat(cmd, dev, sizeof(cmd)); + run_interactive(cmd, "Creating device node %s", dev); + + continue; + } + + if (MATCH_CMD(line, "network ", x)) { + if (network) free(network); + network = strdup(strip_line(x)); + continue; + } + /* This is the directory from which executable scripts and + * any finit include files are read, default /etc/finit.d/ */ + if (MATCH_CMD(line, "runparts ", x)) { + if (rcsd) free(rcsd); + rcsd = strdup(strip_line(x)); + continue; + } + /* Parse any include file, use rcsd if absolute path not given. */ + if (MATCH_CMD(line, "include ", x)) { + char *file = strip_line(x); + char buf[60]; + + snprintf(buf, sizeof(buf), "Loading include file %s", file); + print_desc("", buf); + print_result(parse_conf(file)); + continue; + } + if (MATCH_CMD(line, "startx ", x)) { + svc_register(SVC_CMD_SERVICE, strip_line(x), username); + continue; + } + if (MATCH_CMD(line, "shutdown ", x)) { + if (sdown) free(sdown); + sdown = strdup(strip_line(x)); + continue; + } + + /* The desired runlevel to start when leaving + * bootstrap (S). Finit supports 1-9, but most + * systems only use 1-6, where 6 is reserved for + * reboot */ + if (MATCH_CMD(line, "runlevel ", x)) { + char *token = strip_line(x); + + cfglevel = strtonum(token, 1, 9, &err); + if (err) + cfglevel = RUNLEVEL; + if (cfglevel < 1 || cfglevel > 9 || cfglevel == 6) + cfglevel = 2; /* Fallback */ + continue; + } + + /* Monitored daemon, will be respawned on exit, as + * long as the (optional) service callback returns + * non-zero */ + if (MATCH_CMD(line, "service ", x)) { + svc_register(SVC_CMD_SERVICE, x, NULL); + continue; + } + + /* One-shot task, will not be respawned. Only runs if + * the (optional) service callback returns true */ + if (MATCH_CMD(line, "task ", x)) { + svc_register(SVC_CMD_TASK, x, NULL); + continue; + } + + /* Like task but waits for completion, useful w/ [S] */ + if (MATCH_CMD(line, "run ", x)) { + svc_register(SVC_CMD_RUN, x, NULL); + continue; + } + + if (MATCH_CMD(line, "console ", x)) { + if (console) free(console); + console = strdup(strip_line(x)); + continue; + } + if (MATCH_CMD(line, "tty ", x)) { + tty_register(strip_line(x)); + continue; + } + } + + fclose(fp); + + return 0; +} + +int parse_finit_conf(char *file) +{ username = strdup(DEFUSER); hostname = strdup(DEFHOST); rcsd = strdup(FINIT_RCSD); - if ((fp = fopen(file, "r")) != NULL) { - char *x; - const char *err = NULL; - - _d("Parse %s ...", file); - while (!feof(fp)) { - if (!fgets(line, sizeof(line), fp)) - continue; - chomp(line); - _d("conf: %s", line); - - /* Skip comments. */ - if (MATCH_CMD(line, "#", x)) - continue; - - /* Do this before mounting / read-write - * XXX: Move to plugin which checks /etc/fstab instead */ - if (MATCH_CMD(line, "check ", x)) { - char *dev = strip_line(x); - - strcpy(cmd, "/sbin/fsck -C -a "); - strlcat(cmd, dev, sizeof(cmd)); - run_interactive(cmd, "Checking file system %s", dev); - - continue; - } - - if (MATCH_CMD(line, "user ", x)) { - if (username) free(username); - username = strdup(strip_line(x)); - continue; - } - if (MATCH_CMD(line, "host ", x)) { - if (hostname) free(hostname); - hostname = strdup(strip_line(x)); - continue; - } - - if (MATCH_CMD(line, "module ", x)) { - char *mod = strip_line(x); - - strcpy(cmd, "/sbin/modprobe "); - strlcat(cmd, mod, sizeof(cmd)); - run_interactive(cmd, "Loading kernel module %s", mod); - - continue; - } - if (MATCH_CMD(line, "mknod ", x)) { - char *dev = strip_line(x); - - strcpy(cmd, "/bin/mknod "); - strlcat(cmd, dev, sizeof(cmd)); - run_interactive(cmd, "Creating device node %s", dev); - - continue; - } - - if (MATCH_CMD(line, "network ", x)) { - if (network) free(network); - network = strdup(strip_line(x)); - continue; - } - if (MATCH_CMD(line, "runparts ", x)) { - if (rcsd) free(rcsd); - rcsd = strdup(strip_line(x)); - continue; - } - if (MATCH_CMD(line, "startx ", x)) { - svc_register(SVC_CMD_SERVICE, strip_line(x), username); - continue; - } - if (MATCH_CMD(line, "shutdown ", x)) { - if (sdown) free(sdown); - sdown = strdup(strip_line(x)); - continue; - } - - /* The desired runlevel to start when leaving - * bootstrap (S). Finit supports 1-9, but most - * systems only use 1-6, where 6 is reserved for - * reboot */ - if (MATCH_CMD(line, "runlevel ", x)) { - char *token = strip_line(x); - - cfglevel = strtonum(token, 1, 9, &err); - if (err) - cfglevel = RUNLEVEL; - if (cfglevel < 1 || cfglevel > 9 || cfglevel == 6) - cfglevel = 2; /* Fallback */ - continue; - } - - /* Monitored daemon, will be respawned on exit, as - * long as the (optional) service callback returns - * non-zero */ - if (MATCH_CMD(line, "service ", x)) { - svc_register(SVC_CMD_SERVICE, x, NULL); - continue; - } - - /* One-shot task, will not be respawned. Only runs if - * the (optional) service callback returns true */ - if (MATCH_CMD(line, "task ", x)) { - svc_register(SVC_CMD_TASK, x, NULL); - continue; - } - - /* Like task but waits for completion, useful w/ [S] */ - if (MATCH_CMD(line, "run ", x)) { - svc_register(SVC_CMD_RUN, x, NULL); - continue; - } - - if (MATCH_CMD(line, "console ", x)) { - if (console) free(console); - console = strdup(strip_line(x)); - continue; - } - if (MATCH_CMD(line, "tty ", x)) { - tty_register(strip_line(x)); - continue; - } - } - fclose(fp); - } + return parse_conf(file); } diff --git a/finit.c b/finit.c index 93485f42..c379fb77 100644 --- a/finit.c +++ b/finit.c @@ -160,6 +160,8 @@ static void banner(void) int main(int argc, char* argv[]) { + int result; + if (getpid() != 1) return client(argc, argv); @@ -200,14 +202,16 @@ int main(int argc, char* argv[]) /* * Parse configuration file */ - parse_finit_conf(FINIT_CONF); + result = parse_finit_conf(FINIT_CONF); + print_desc("Loading " FINIT_CONF, NULL); + print_result(result); /* * Load plugins. Must run after finit.conf has registered * all services, or service plugins won't have anything to * hook on to. */ - print_desc("", "Loading Finit plugins"); + print_desc("Loading Finit plugins", NULL); print_result(plugin_load_all(PLUGIN_PATH)); /* diff --git a/finit.h b/finit.h index b8981926..e2910dc9 100644 --- a/finit.h +++ b/finit.h @@ -91,8 +91,8 @@ extern char *console; extern char *__progname; /* conf.c */ -int parse_runlevels (char *runlevels); -void parse_finit_conf (char *file); +int parse_runlevels (char *runlevels); +int parse_finit_conf (char *file); #endif /* FINIT_H_ */