diff options
Diffstat (limited to 'src/sysvinit.c')
-rw-r--r-- | src/sysvinit.c | 90 |
1 files changed, 69 insertions, 21 deletions
diff --git a/src/sysvinit.c b/src/sysvinit.c index be7aef8..337b922 100644 --- a/src/sysvinit.c +++ b/src/sysvinit.c @@ -235,17 +235,20 @@ enablecomp (struct prog *prog, void *data) switch (comp->mode) { case pies_comp_sysinit: case pies_comp_boot: case pies_comp_bootwait: return 0; + + case pies_comp_ondemand: + return prog->v.p.status == status_enabled; + case pies_comp_powerfail: case pies_comp_powerwait: case pies_comp_powerokwait: case pies_comp_ctrlaltdel: - case pies_comp_ondemand: case pies_comp_powerfailnow: case pies_comp_kbrequest: return s && (s->mask & PIES_COMP_MASK (comp->mode)); default: break; } @@ -297,13 +300,34 @@ sysvinit_runlevel_setup (int mask, int *wait) s.wait = *wait; } progman_foreach (runlevel_setup_prog, &s); if (wait) *wait = s.wait; } - + +static int +demand_prog (struct prog *prog, void *data) +{ + int *rl = data; + struct component *comp = prog->v.p.comp; + if (comp->mode == pies_comp_ondemand + && comp->runlevels + && strchr (comp->runlevels, *rl)) + { + prog->v.p.status = status_enabled; + debug (1, ("%s: %s", prog_tag (prog), "enabled")); + } + return 0; +} + +static void +sysvinit_demand (int rl) +{ + progman_foreach (demand_prog, &rl); +} + static const char valid_runlevel_arg[] = "0123456789SsQqAaBbCcUu"; int is_valid_runlevel (int c) { return !!strchr (valid_runlevel_arg, c); @@ -455,14 +479,27 @@ sysvinit_fifo_handler (int fd, void *data) case 'Q': break; default: if (buf.req.runlevel != runlevel) { - dfl_level = buf.req.runlevel; - inittrans (); + switch (buf.req.runlevel) + { + case 'A': + case 'B': + case 'C': + sysvinit_demand (buf.req.runlevel); + break; + + default: + if (runlevel_index (buf.req.runlevel) != -1) + { + dfl_level = buf.req.runlevel; + inittrans (); + } + } } } break; case INIT_CMD_SETENV: sysvinit_setenv (buf.req.data, sizeof (buf.req.data)); @@ -816,25 +853,25 @@ struct action_parser const char *action; enum pies_comp_mode mode; int (*parser) (struct component *comp, const char *file, unsigned line); }; static struct action_parser action_tab[] = { - { "wait", pies_comp_wait }, - { "once", pies_comp_once }, - { "boot", pies_comp_boot }, - { "bootwait", pies_comp_bootwait }, - { "powerfail", pies_comp_powerfail }, - { "powerwait", pies_comp_powerwait }, - { "powerokwait", pies_comp_powerokwait }, - { "ctrlaltdel", pies_comp_ctrlaltdel }, - { "ondemand", pies_comp_ondemand }, - { "sysinit", pies_comp_sysinit }, + { "wait", pies_comp_wait }, + { "once", pies_comp_once }, + { "boot", pies_comp_boot }, + { "bootwait", pies_comp_bootwait }, + { "powerfail", pies_comp_powerfail }, + { "powerwait", pies_comp_powerwait }, + { "powerokwait", pies_comp_powerokwait }, + { "ctrlaltdel", pies_comp_ctrlaltdel }, + { "ondemand", pies_comp_ondemand }, + { "sysinit", pies_comp_sysinit }, { "powerfailnow", pies_comp_powerfailnow }, - { "kbrequest", pies_comp_kbrequest }, - { "respawn", pies_comp_respawn }, + { "kbrequest", pies_comp_kbrequest }, + { "respawn", pies_comp_respawn }, { NULL } }; static struct action_parser * find_action_parser (const char *action) { @@ -843,12 +880,21 @@ find_action_parser (const char *action) for (ap = action_tab; ap->action; ap++) if (strcmp (ap->action, action) == 0) return ap; return NULL; } +static char * +strupr (char *s) +{ + char *p; + for (p = s; *p; p++) + *p = toupper (*p); + return s; +} + int inittab_parse (const char *file) { FILE *fp; size_t size = 0; char *buf = NULL; @@ -928,14 +974,13 @@ inittab_parse (const char *file) 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")); + logmsg (LOG_ERR, "%s:%u: %s", file, line_no, _("not enough fields")); err = 1; continue; } if (strcmp (action, "initdefault") == 0) { @@ -947,24 +992,27 @@ inittab_parse (const char *file) } else initdefault = toupper (runlevels[0]); continue; } + if (strcmp (action, "off") == 0) + /* Ignore the entry */ + continue; + ap = find_action_parser (action); if (!ap) { - logmsg (LOG_ERR, "%s:%u: %s", - file, line_no, _("unknown action")); + logmsg (LOG_ERR, "%s:%u: %s", file, line_no, _("unknown action")); err = 1; continue; } comp = component_create (id); comp->mode = ap->mode; - comp->runlevels = grecs_strdup (runlevels); + 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)); |