diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-02-21 12:40:53 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-02-21 12:40:53 +0200 |
commit | 6aac230ce3d21f1e71333ec3863c7ea1afd051c3 (patch) | |
tree | bddb95396d1eb12401db23946119fdac79becf43 | |
parent | da6e295140fc1a1ef56db1c6f792e86793f7f2b1 (diff) | |
download | pies-6aac230ce3d21f1e71333ec3863c7ea1afd051c3.tar.gz pies-6aac230ce3d21f1e71333ec3863c7ea1afd051c3.tar.bz2 |
Provide fall-back entry in init mode
* src/sysvinit.c (inittab_parse): Provide default entry if
inittab cannot be read or if it defined no components.
* src/comp.c (component_list_is_empty): New function.
* src/pies.c (pies_read_config): Always return 0 in init mode.
(main): Use LOG_DAEMON in init mode.
* src/pies.h (component_list_is_empty): New proto.
-rw-r--r-- | src/comp.c | 6 | ||||
-rw-r--r-- | src/pies.c | 9 | ||||
-rw-r--r-- | src/pies.h | 2 | ||||
-rw-r--r-- | src/sysvinit.c | 283 |
4 files changed, 177 insertions, 123 deletions
@@ -97,12 +97,18 @@ component_unlink (struct component *comp) if ((x = comp->next)) x->prev = comp->prev; else list->tail = comp->prev; } +int +component_list_is_empty (void) +{ + return !comp_list[cur].head; +} + struct component * component_lookup_tag (int idx, const char *tag) { struct complist *list = &comp_list[idx]; struct component *comp; @@ -1566,21 +1566,25 @@ config_help () int pies_read_config (void) { struct grecs_list_entry *ep; int err = 0; + logmsg (LOG_INFO, _("reading configuration")); component_config_begin (); for (ep = config_list->head; ep; ep = ep->next) { struct config_file *file = ep->data; if (file->syntax->parser (file->name)) ++err; } + if (init_process) + err = 0; + if (err) component_config_rollback (); return err; } @@ -2005,13 +2009,16 @@ main (int argc, char **argv) } } #endif /* Set default logging */ if (init_process) - diag_flags = DIAG_TO_STDERR | DIAG_REOPEN_LOG; + { + log_facility = LOG_DAEMON; + diag_flags = DIAG_TO_STDERR | DIAG_REOPEN_LOG; + } else diag_flags = DIAG_TO_SYSLOG | (stderr_closed_p () ? 0 : DIAG_TO_STDERR); diag_setup (diag_flags); config_init (); @@ -393,12 +393,14 @@ int socket_type_to_str (int socket_type, const char **pres); struct component *component_create (const char *name); void component_free (struct component *comp); void component_ref_incr (struct component *comp); void component_ref_decr (struct component *comp); +int component_list_is_empty (void); + void component_config_begin (void); void component_config_rollback (void); void component_config_commit (void); int component_is_active (struct component *comp); diff --git a/src/sysvinit.c b/src/sysvinit.c index 41d5b9d..695a22a 100644 --- a/src/sysvinit.c +++ b/src/sysvinit.c @@ -57,13 +57,14 @@ static int boot_trans_tab[max_boot_state][sizeof(valid_runlevels)-1] = { enum boot_state boot_state; int runlevel = 0; int prevlevel = 'N'; int initdefault; /* Default runlevel */ int dfl_level; -int emergency_shell; +char *emergency_shell = "/sbin/sulogin"; +int emergency; int console_open (int mode) { int i, fd; @@ -439,14 +440,13 @@ sysvinit_set_runlevel (int newlevel) "Activating on-demand level '%c'", newlevel); sysvinit_demand (newlevel); break; default: if (newlevel == runlevel) - { - } + break; else if (runlevel_index (newlevel) == -1) return -1; else { diagmsg (DIAG_ALL, LOG_INFO, "Switching to runlevel: %c", newlevel); dfl_level = newlevel; @@ -754,14 +754,14 @@ sysvinit_begin () console_stty (); setsid (); envsetup (); sysvinit_runlevel_setup (PIES_COMP_DEFAULT); add_extra_sigv (sigv, ARRAY_SIZE (sigv)); sysvinit_sysdep_begin (); - if (emergency_shell) - start_shell ("/sbin/sulogin"); + if (emergency) + start_shell (emergency_shell); } #define IS_RUNNING_DISABLED_PROG(prog) \ (IS_COMPONENT (prog) \ && prog->v.p.status == status_running \ && !prog->v.p.active) @@ -951,155 +951,194 @@ strupr (char *s) char *p; for (p = s; *p; p++) *p = toupper (*p); return s; } -int -inittab_parse (const char *file) +struct inittab_ctx { - FILE *fp; - size_t size = 0; - char *buf = NULL; - unsigned line_no = 0; - int err = 0; - - fp = fopen (file, "r"); - if (!fp) - { - logmsg (LOG_ERR, - _("cannot open configuration file %s: %s"), - file, strerror (errno)); - return 1; - } + char *buf; + size_t size; + char const *file; + unsigned line_no; +}; - while (getline (&buf, &size, fp) >= 0) - { - char *id, *runlevels, *action, *process, *p; - struct action_parser *ap; - struct component *comp; - struct wordsplit ws; - - line_no++; - for (p = buf; *p && c_isblank (*p); p++) - ; +enum inittab_status + { + inittab_ok, + inittab_err, + inittab_stop + }; - if (!p || *p == '\n') - continue; +static enum inittab_status +inittab_parse_line (struct inittab_ctx *ctx) +{ + char *id, *runlevels, *action, *process, *p; + struct action_parser *ap; + struct component *comp; + struct wordsplit ws; + + ctx->line_no++; + for (p = ctx->buf; *p && c_isblank (*p); p++) + ; - if (*p == '#') + if (!p || *p == '\n') + return inittab_ok; + + if (*p == '#') + { + if (wordsplit (p+1, &ws, WRDSF_DEFFLAGS)) { - if (wordsplit (p+1, &ws, WRDSF_DEFFLAGS)) + logmsg (LOG_ERR, "%s:%u: wordsplit: %s", ctx->file, ctx->line_no, + strerror (errno)); + return inittab_err; + } + /* pies pragma debug N */ + /* pies pragma next FORMAT FILE */ + /* pies pragma stop */ + if (ws.ws_wordc > 2 && strcmp (ws.ws_wordv[0], "pies") == 0 && + strcmp (ws.ws_wordv[1], "pragma") == 0) + { + if (strcmp (ws.ws_wordv[2], "debug") == 0) { - logmsg (LOG_ERR, "%s:%u: wordsplit: %s", file, line_no, - strerror (errno)); - err = 1; + if (ws.ws_wordc == 4) + debug_level = atoi (ws.ws_wordv[3]); } - /* pies pragma debug N */ - /* pies pragma next FORMAT FILE */ - /* pies pragma stop */ - if (ws.ws_wordc > 2 && strcmp (ws.ws_wordv[0], "pies") == 0 && - strcmp (ws.ws_wordv[1], "pragma") == 0) + else if (strcmp (ws.ws_wordv[2], "next") == 0) { - if (strcmp (ws.ws_wordv[2], "debug") == 0) - { - if (ws.ws_wordc == 4) - debug_level = atoi (ws.ws_wordv[3]); - } - else if (strcmp (ws.ws_wordv[2], "next") == 0) + if (ws.ws_wordc >= 5) { - if (ws.ws_wordc >= 5) - { - struct config_syntax *synt = - str_to_config_syntax (ws.ws_wordv[3]); + struct config_syntax *synt = + str_to_config_syntax (ws.ws_wordv[3]); - if (!synt) - logmsg (LOG_ERR, "%s:%u: %s", - file, line_no, _("unknown syntax type")); - else - config_file_add (synt, ws.ws_wordv[4]); - } - else if (ws.ws_wordc == 4) - config_file_add_type (CONF_PIES, ws.ws_wordv[3]); - } - else if (strcmp (ws.ws_wordv[2], "stop") == 0) - { - wordsplit_free (&ws); - break; + if (!synt) + logmsg (LOG_ERR, "%s:%u: %s", + ctx->file, ctx->line_no, _("unknown syntax type")); + else + config_file_add (synt, ws.ws_wordv[4]); } + else if (ws.ws_wordc == 4) + config_file_add_type (CONF_PIES, ws.ws_wordv[3]); } - - wordsplit_free (&ws); - continue; - } - - id = getfld (p, &p); - runlevels = getfld (p, &p); - action = getfld (p, &p); - process = p; - - if (!id || !runlevels || !action || !process) - { - logmsg (LOG_ERR, "%s:%u: %s", file, line_no, _("not enough fields")); - err = 1; - continue; - } - - if (strcmp (action, "initdefault") == 0) - { - if (!runlevels[0] || !is_valid_runlevel (runlevels[0])) + else if (strcmp (ws.ws_wordv[2], "stop") == 0) { - logmsg (LOG_ERR, "%s:%u: %s", - file, line_no, _("invalid runlevel")); - err = 1; + wordsplit_free (&ws); + return inittab_stop; } - else - initdefault = toupper (runlevels[0]); - continue; } + + wordsplit_free (&ws); + return inittab_ok; + } + + id = getfld (p, &p); + runlevels = getfld (p, &p); + action = getfld (p, &p); + process = p; - if (strcmp (action, "off") == 0) - /* Ignore the entry */ - continue; + if (!id || !runlevels || !action || !process) + { + logmsg (LOG_ERR, "%s:%u: %s", + ctx->file, ctx->line_no, _("not enough fields")); + return inittab_err; + } - ap = find_action_parser (action); - if (!ap) + if (strcmp (action, "initdefault") == 0) + { + if (!runlevels[0] || !is_valid_runlevel (runlevels[0])) { - logmsg (LOG_ERR, "%s:%u: %s", file, line_no, _("unknown action")); - err = 1; - continue; + logmsg (LOG_ERR, "%s:%u: %s", + ctx->file, ctx->line_no, _("invalid runlevel")); + return inittab_err; } + else + initdefault = toupper (runlevels[0]); + return inittab_ok; + } + + if (strcmp (action, "off") == 0) + /* Ignore the entry */ + return inittab_ok; + + ap = find_action_parser (action); + if (!ap) + { + logmsg (LOG_ERR, "%s:%u: %s", ctx->file, ctx->line_no, + _("unknown action")); + return inittab_err; + } - comp = component_create (id); - comp->mode = ap->mode; - comp->runlevels = grecs_strdup (strupr (runlevels)); + comp = component_create (id); + comp->mode = ap->mode; + comp->runlevels = grecs_strdup (strupr (runlevels)); - if (wordsplit (process, &ws, WRDSF_DEFFLAGS)) - { - component_free (comp); - logmsg (LOG_ERR, "%s:%u: wordsplit: %s", file, line_no, - strerror (errno)); - err = 1; - continue; - } - wordsplit_getwords (&ws, &comp->argc, &comp->argv); - comp->program = grecs_strdup (comp->argv[0]); - wordsplit_free (&ws); + if (wordsplit (process, &ws, WRDSF_DEFFLAGS)) + { + component_free (comp); + logmsg (LOG_ERR, "%s:%u: wordsplit: %s", ctx->file, ctx->line_no, + strerror (errno)); + return inittab_err; + } + wordsplit_getwords (&ws, &comp->argc, &comp->argv); + comp->program = grecs_strdup (comp->argv[0]); + wordsplit_free (&ws); - comp->flags |= CF_SIGGROUP; + comp->flags |= CF_SIGGROUP; - if (ap->parser && ap->parser (comp, file, line_no)) + if (ap->parser && ap->parser (comp, ctx->file, ctx->line_no)) + { + component_free (comp); + return inittab_err; + } + return inittab_ok; +} + +int +inittab_parse (const char *file) +{ + FILE *fp; + struct inittab_ctx ctx; + int err; + + ctx.size = 0; + ctx.buf = NULL; + ctx.file = file; + ctx.line_no = 0; + + fp = fopen (file, "r"); + if (fp) + { + while (getline (&ctx.buf, &ctx.size, fp) >= 0) { - component_free (comp); - err = 1; - continue; + enum inittab_status st = inittab_parse_line (&ctx); + if (st == inittab_err) + err = 1; + else if (st == inittab_stop) + break; } + fclose (fp); + } + else + { + logmsg (LOG_ERR, + _("cannot open configuration file %s: %s"), + file, strerror (errno)); + err = 1; } - free (buf); - fclose (fp); + if (component_list_is_empty ()) + { + /* Provide default inittab entry */ + ctx.file = __FILE__; + ctx.line_no = __LINE__; + grecs_asprintf (&ctx.buf, &ctx.size, "~~:%s:wait:%s\n", + valid_runlevels, emergency_shell); + inittab_parse_line (&ctx); + } + + free (ctx.buf); return err; } char *power_stat_file = POWER_STAT_FILE; void @@ -1179,11 +1218,11 @@ sysvinit_parse_argv (int argc, char **argv) { int c; char *arg = *++argv; if (!strcmp (arg, "single") || !strcmp (arg, "-s")) dfl_level = 'S'; else if (!strcmp (arg, "-b") || !strcmp (arg, "emergency")) - emergency_shell = 1; + emergency = 1; else if (!arg[1] && strchr (valid_runlevels, (c = toupper (arg[0])))) dfl_level = c; } } |