diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-06-24 12:56:24 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-06-24 12:56:24 +0300 |
commit | 006bfbc5235c181783445d321ce7a7e3c6d8bd8a (patch) | |
tree | f483e0d30c3e801add01b372b24a342281b70b86 /src | |
parent | cb90ca582a46ef9f0779837dc4c6fb00656e70c9 (diff) | |
download | pies-006bfbc5235c181783445d321ce7a7e3c6d8bd8a.tar.gz pies-006bfbc5235c181783445d321ce7a7e3c6d8bd8a.tar.bz2 |
Enable/disable SystemV init code at compile time
* configure.ac: New option --enable-sysvinit. Disable the init
code if RUN_LVL is not available.
(PIES_SYSVINIT_ENABLED): New configuration define.
(PIES_COND_SYSVINIT): New condition
Print configuration settings summary.
* src/pies.h (is_sysvinit): Check for PIES_SYSVINIT_ENABLED.
(SYSVINIT_ACTIVE): New macro.
* grecs: Upgrade.
* src/Makefile.am: Conditionally link sysvinit-related code.
* src/cmdline.opt: Disable the --telinit option if sysvinit support
is not available.
(parse_options): Use SYSVINIT_ACTIVE in the conditional.
* src/comp.c (component_verify): Check if component definition is
allowed by the current state of the sysvinit support.
* src/ctl.c: Disable the /runlevel entry point if sysvinit support
is not compiled.
* src/diag.c (stderr_open): Make sure sysvinit-related code is not
compiled if the sysvinit support is not available.
* src/pies.c (config_syntax_tab): Add entry for CONF_INITTAB only if
sysvinit support is available.
(_cb_initdefault,_cb_runlevels): Remove. Use cb_initdefault and cb_runlevels
instead.
(component_keywords): Disable runlevels without sysvinit support.
(pies_keywords): Same for initdefault.
Use SYSVINIT_ACTIVE to suppress compilation of sysvinit code without
sysvinit support.
* src/progman.c: Use SYSVINIT_ACTIVE to suppress compilation of
sysvinit code without sysvinit support.
* src/sysvinit.c (cb_initdefault,cb_runlevels): New functions.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 10 | ||||
-rw-r--r-- | src/cmdline.opt | 4 | ||||
-rw-r--r-- | src/comp.c | 3 | ||||
-rw-r--r-- | src/ctl.c | 176 | ||||
-rw-r--r-- | src/diag.c | 2 | ||||
-rw-r--r-- | src/pies.c | 91 | ||||
-rw-r--r-- | src/pies.h | 13 | ||||
-rw-r--r-- | src/progman.c | 15 | ||||
-rw-r--r-- | src/sysvinit.c | 64 |
9 files changed, 208 insertions, 170 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 16f8a75..925da88 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,17 +27,21 @@ pies_SOURCES = \ inetd-bi.c\ limits.c\ meta1parse.c\ pies.c\ progman.c\ socket.c\ - sysdep.c\ - sysvinit.c\ - utmp.c\ userprivs.c +if PIES_COND_SYSVINIT +pies_SOURCES += \ + sysvinit.c\ + sysdep.c\ + utmp.c +endif + noinst_HEADERS = \ acl.h\ cmdline.h\ meta1parse.h\ pies.h\ prog.h\ diff --git a/src/cmdline.opt b/src/cmdline.opt index d2aaf6d..d9d90e1 100644 --- a/src/cmdline.opt +++ b/src/cmdline.opt @@ -115,18 +115,20 @@ OPTION(lint,t,, [<parse configuration file and exit>]) BEGIN log_to_stderr_only = 1; lint_mode = 1; END +CPP(#if PIES_SYSVINIT_ENABLED) OPTION(telinit,T,, [<telinit command: run "pies -T --help" for help>]) BEGIN log_to_stderr_only = 1; exit (telinit (argc - (optind - 1), argv + (optind - 1))); END +CPP(#endif) GROUP(Preprocessor) OPTION(include-directory,I,DIR, [<add include directory>]) BEGIN @@ -217,13 +219,13 @@ void parse_options (int *pargc, char ***pargv) { int argc = *pargc; char **argv = *pargv; int index; - if (init_process) + if (SYSVINIT_ACTIVE) { sysvinit_parse_argv (argc, argv); index = argc; } else { @@ -671,12 +671,15 @@ component_verify (struct component *comp, grecs_locus_t *locus) { COMPERR (grecs_error, "%s", _("socket must be specified in this mode")); return 1; } default: + if (PIES_SYSVINIT_ENABLED && comp->mode >= pies_mark_sysvinit) + COMPERR (grecs_error, + "%s", _("SystemV init support is not compiled in")); /* FIXME: more checks perhaps */ break; } if (comp->mode == pies_comp_inetd) { @@ -915,20 +915,23 @@ method_decode (char const *method) } static void res_instance (struct ctlio *, enum http_method, char const *, struct json_value *); static void res_programs (struct ctlio *, enum http_method, char const *, struct json_value *); +static void res_conf (struct ctlio *, enum http_method, char const *, + struct json_value *); + +#if PIES_SYSVINIT_ENABLED static void res_runlevel (struct ctlio *, enum http_method, char const *, struct json_value *); static void res_environ (struct ctlio *, enum http_method, char const *, struct json_value *); -static void res_conf (struct ctlio *, enum http_method, char const *, - struct json_value *); - static int pred_sysvinit (void); +#endif + struct ctlio_resource { char const *uri; size_t uri_len; int states; @@ -940,14 +943,16 @@ struct ctlio_resource static struct ctlio_resource restab[] = { #define S(s) #s, (sizeof (#s)-1) { S(/instance), CTL_ADMIN_STATE, NULL, res_instance }, { S(/conf), CTL_ADMIN_STATE, NULL, res_conf }, { S(/programs), CTL_ADMIN_STATE|CTL_USER_STATE, NULL, res_programs }, +#if PIES_SYSVINIT_ENABLED { S(/runlevel), CTL_ADMIN_STATE, pred_sysvinit, res_runlevel }, { S(/environ), CTL_ADMIN_STATE, pred_sysvinit, res_environ }, +#endif { NULL } #undef S }; static struct ctlio_resource * find_resource (struct ctlio *io, const char *endpoint) @@ -2114,12 +2119,13 @@ res_programs (struct ctlio *io, enum http_method meth, if (uri) res_programs_component (io, meth, uri, json); else res_programs_select (io, meth, uri, json); } +#if PIES_SYSVINIT_ENABLED static int pred_sysvinit (void) { return init_process; } @@ -2160,12 +2166,95 @@ res_runlevel (struct ctlio *io, enum http_method meth, } } } else ctlio_reply (io, 405, NULL); } + +/* GET /environ - List entire environment + * ["RUNLEVEL=3", "CONSOLE=/dev/tty", ...] + * GET /environ/NAME - Get value of variable NAME + * { "status":"OK", "value":"..." } + * { "status":"ER", "error_message":"..." } + * DELETE /environ/NAME - Unset variable + * { "status":"OK" } + * { "status":"ER", "error_message":"..." } + * PUT /environ/NAME=VALUE - Set variable + * { "status":"OK" } + * { "status":"ER", "error_message":"..." } + */ +static void +env_reply (struct ctlio *io, int ok, int rc) +{ + switch (rc) + { + case 0: + io->code = ok; + io->output.reply = json_reply_create (); + json_object_set_string (io->output.reply, "status", "OK"); + break; + + case 1: + ctlio_reply (io, 403, NULL); + break; + + case -1: + ctlio_reply (io, 404, NULL); + } +} + +static void +res_environ (struct ctlio *io, enum http_method meth, + char const *uri, struct json_value *json) +{ + if (meth == METH_GET) + { + if (uri && uri[1]) + { + char *value; + + if (sysvinit_envlocate (uri + 1, &value) == -1) + ctlio_reply (io, 404, NULL); + else + { + env_reply (io, 200, 0); + json_object_set_string (io->output.reply, "value", "%s", value); + } + } + else + { + size_t i; + + io->output.reply = json_new_array (); + io->code = 200; + for (i = 0; sysvinit_environ_hint[i]; i++) + { + json_array_append (io->output.reply, + json_new_string (sysvinit_environ_hint[i])); + } + } + } + else if (meth == METH_DELETE) + { + if (!(uri && uri[0])) + ctlio_reply (io, 400, NULL); + else + env_reply (io, 200, sysvinit_envupdate (uri + 1)); + } + else if (meth == METH_PUT) + { + if (!(uri && uri[0])) + ctlio_reply (io, 400, NULL); + else + env_reply (io, 201, sysvinit_envupdate (uri + 1)); + } + else + ctlio_reply (io, 405, NULL); + +} +#endif /* GET /conf/runtime - List configuration * PUT /conf/runtime - Reload configuration * POST /conf/runtime - Post new configuration * * GET /conf/files - List configuration files @@ -2404,88 +2493,7 @@ res_conf (struct ctlio *io, enum http_method meth, ctlio_reply (io, 405, NULL); } } else ctlio_reply (io, 404, NULL); } - -/* GET /environ - List entire environment - * ["RUNLEVEL=3", "CONSOLE=/dev/tty", ...] - * GET /environ/NAME - Get value of variable NAME - * { "status":"OK", "value":"..." } - * { "status":"ER", "error_message":"..." } - * DELETE /environ/NAME - Unset variable - * { "status":"OK" } - * { "status":"ER", "error_message":"..." } - * PUT /environ/NAME=VALUE - Set variable - * { "status":"OK" } - * { "status":"ER", "error_message":"..." } - */ -static void -env_reply (struct ctlio *io, int ok, int rc) -{ - switch (rc) - { - case 0: - io->code = ok; - io->output.reply = json_reply_create (); - json_object_set_string (io->output.reply, "status", "OK"); - break; - case 1: - ctlio_reply (io, 403, NULL); - break; - - case -1: - ctlio_reply (io, 404, NULL); - } -} - -static void -res_environ (struct ctlio *io, enum http_method meth, - char const *uri, struct json_value *json) -{ - if (meth == METH_GET) - { - if (uri && uri[1]) - { - char *value; - - if (sysvinit_envlocate (uri + 1, &value) == -1) - ctlio_reply (io, 404, NULL); - else - { - env_reply (io, 200, 0); - json_object_set_string (io->output.reply, "value", "%s", value); - } - } - else - { - size_t i; - - io->output.reply = json_new_array (); - io->code = 200; - for (i = 0; sysvinit_environ_hint[i]; i++) - { - json_array_append (io->output.reply, - json_new_string (sysvinit_environ_hint[i])); - } - } - } - else if (meth == METH_DELETE) - { - if (!(uri && uri[0])) - ctlio_reply (io, 400, NULL); - else - env_reply (io, 200, sysvinit_envupdate (uri + 1)); - } - else if (meth == METH_PUT) - { - if (!(uri && uri[0])) - ctlio_reply (io, 400, NULL); - else - env_reply (io, 201, sysvinit_envupdate (uri + 1)); - } - else - ctlio_reply (io, 405, NULL); - -} @@ -70,13 +70,13 @@ stderr_printer (LOGSTREAM *str, int prio, const char *fmt, va_list ap) return 0; } static int stderr_open (int logf, LOGSTREAM *str) { - if (logf & DIAG_REOPEN_LOG) + if (PIES_SYSVINIT_ENABLED && (logf & DIAG_REOPEN_LOG)) { int fd = console_open (O_WRONLY|O_NOCTTY|O_NDELAY); if (fd == -1) return -1; str->file = fdopen (fd, "w"); if (!str->file) @@ -72,13 +72,15 @@ struct config_syntax static int pies_config_parse (char const *); static struct config_syntax config_syntax_tab[] = { [CONF_PIES] = { "pies" , pies_config_parse }, [CONF_META1] = { "meta1", meta1_config_parse }, [CONF_INETD] = { "inetd", inetd_config_parse }, +#if PIES_SYSVINIT_ENABLED [CONF_INITTAB] = { "inittab", inittab_parse }, +#endif }; struct config_file { struct config_syntax *syntax; char *name; @@ -1202,62 +1204,12 @@ _cb_flags (enum grecs_callback_command cmd, grecs_error (locus, 0, _("too many arguments")); return 1; } return 0; } -static int -_cb_initdefault (enum grecs_callback_command cmd, - grecs_node_t *node, - void *varptr, void *cb_data) -{ - grecs_locus_t *locus = &node->locus; - grecs_value_t *value = node->v.value; - int *val = varptr; - - if (grecs_assert_node_value_type (cmd, node, GRECS_TYPE_STRING)) - return 1; - if (strlen (value->v.string) != 1) - { - grecs_error (locus, 0, _("argument must be a single character")); - return 1; - } - if (!is_valid_runlevel (value->v.string[0])) - { - grecs_error (locus, 0, _("not a valid runlevel")); - return 1; - } - *val = toupper (value->v.string[0]); - return 0; -} - -static int -_cb_runlevels (enum grecs_callback_command cmd, - grecs_node_t *node, - void *varptr, void *cb_data) -{ - grecs_locus_t *locus = &node->locus; - grecs_value_t *value = node->v.value; - char **sptr = varptr, *p; - - if (grecs_assert_node_value_type (cmd, node, GRECS_TYPE_STRING)) - return 1; - for (p = value->v.string; *p; p++) - { - if (!is_valid_runlevel (*p)) - { - grecs_error (locus, 0, _("not a valid runlevel: %c"), *p); - return 1; - } - } - *sptr = grecs_strdup (value->v.string); - for (p = *sptr; *p; p++) - *p = toupper (*p); - return 0; -} - struct grecs_keyword component_keywords[] = { {"mode", N_("mode"), N_("Component execution mode."), grecs_type_string, GRECS_DFLT, NULL, offsetof (struct component, mode), @@ -1291,18 +1243,20 @@ struct grecs_keyword component_keywords[] = { }, {"flags", N_("list"), N_("List of flags."), grecs_type_string, GRECS_LIST, NULL, offsetof (struct component, flags), _cb_flags }, +#if PIES_SYSVINIT_ENABLED {"runlevels", N_("chars"), N_("Runlevels to start that component in."), grecs_type_string, GRECS_DFLT, NULL, offsetof (struct component, runlevels), - _cb_runlevels }, + cb_runlevels }, +#endif {"pass-fd-socket", N_("name"), N_("Pass fd through this socket."), grecs_type_string, GRECS_DFLT, NULL, offsetof (struct component, pass_fd_socket), NULL, @@ -1719,18 +1673,20 @@ struct grecs_keyword pies_keywords[] = { {"limits", NULL, N_("Set global system limits."), grecs_type_string, GRECS_DFLT, &pies_limits, 0, _cb_limits, }, +#if PIES_SYSVINIT_ENABLED {"initdefault", N_("arg: char"), N_("Default runlevel"), grecs_type_string, GRECS_DFLT, - &initdefault, 0, _cb_initdefault, + NULL, 0, cb_initdefault, }, +#endif {"shutdown-timeout", "n", N_("Wait <n> seconds for all components to shut down."), grecs_type_uint, GRECS_DFLT, &shutdown_timeout, 0, NULL, @@ -1856,13 +1812,13 @@ pies_read_config (void) { struct config_file *file = ep->data; if (file->syntax->parser (file->name)) ++err; } - if (init_process) + if (SYSVINIT_ACTIVE) err = 0; if (err) component_config_rollback (); return err; @@ -1895,13 +1851,13 @@ pies_schedule_children (int op) children_op |= op; } RETSIGTYPE sig_handler (int sig) { - if (init_process && sysvinit_sigtrans (sig, &action)) + if (SYSVINIT_ACTIVE && sysvinit_sigtrans (sig, &action)) return; switch (sig) { case SIGCHLD: pies_schedule_children (PIES_CHLD_CLEANUP); break; @@ -2275,13 +2231,13 @@ init_emu (void) return 0; } static void set_conf_file_names (const char *base) { - if (init_process) + if (SYSVINIT_ACTIVE) { config_file_add_type (CONF_INITTAB, "/etc/inittab"); config_file_add_type (CONF_PIES, "/etc/pies.init"); } else if (!config_list && !init_emu ()) { @@ -2335,13 +2291,13 @@ main (int argc, char **argv) init_process = 0; break; } } /* Set default logging */ - if (init_process) + if (SYSVINIT_ACTIVE) { 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); @@ -2370,13 +2326,13 @@ main (int argc, char **argv) } setenv ("PIES_INSTANCE", instance, 1); log_tag = grecs_strdup (instance); set_conf_file_names (instance); - if (init_process || !DEFAULT_PREPROCESSOR) + if (SYSVINIT_ACTIVE || !DEFAULT_PREPROCESSOR) grecs_preprocessor = NULL; else grecs_preprocessor = pp_command_line (); if (preprocess_only) { @@ -2448,13 +2404,13 @@ main (int argc, char **argv) default: pies_priv_setup (&pies_privs); if (pies_umask) umask (pies_umask); } - if (init_process) + if (SYSVINIT_ACTIVE) { foreground = 1; sysvinit_begin (); } else switch (pies_check_status (&pid)) @@ -2488,13 +2444,13 @@ main (int argc, char **argv) } diag_setup (DIAG_TO_SYSLOG); } logmsg (LOG_INFO, _("%s %s starting"), proginfo.package, proginfo.version); - if (!init_process) + if (!SYSVINIT_ACTIVE) { if (ctl_open ()) exit (EX_UNAVAILABLE); create_pidfile (pidfile); } @@ -2513,13 +2469,13 @@ main (int argc, char **argv) { if (children_op == PIES_CHLD_NONE) pies_pause (); switch (action) { case ACTION_RESTART: - if (pies_master_argv[0][0] != '/' || init_process) + if (pies_master_argv[0][0] != '/' || SYSVINIT_ACTIVE) { logmsg (LOG_INFO, _("restart command ignored")); action = ACTION_CONT; } break; @@ -2529,46 +2485,49 @@ main (int argc, char **argv) action = ACTION_CONT; break; } /* fall through */ case ACTION_COMMIT: component_config_commit (); - if (init_process) + if (SYSVINIT_ACTIVE) sysvinit_runlevel_setup (PIES_COMP_DEFAULT); progman_create_sockets (); progman_start (); pies_schedule_children (PIES_CHLD_WAKEUP); action = ACTION_CONT; break; case ACTION_STOP: - if (init_process) + if (SYSVINIT_ACTIVE) { debug (1, ("ignoring stop/restart")); action = ACTION_CONT; } break; case ACTION_CTRLALTDEL: debug (1, ("ctrl-alt-del")); - sysvinit_runlevel_setup (PIES_COMP_MASK (pies_comp_ctrlaltdel)); + if (SYSVINIT_ACTIVE) + sysvinit_runlevel_setup (PIES_COMP_MASK (pies_comp_ctrlaltdel)); pies_schedule_children (PIES_CHLD_WAKEUP); action = ACTION_CONT; break; case ACTION_KBREQUEST: debug (1, ("kbrequest")); - sysvinit_runlevel_setup (PIES_COMP_MASK (pies_comp_kbrequest)); + if (SYSVINIT_ACTIVE) + sysvinit_runlevel_setup (PIES_COMP_MASK (pies_comp_kbrequest)); pies_schedule_children (PIES_CHLD_WAKEUP); action = ACTION_CONT; break; case ACTION_POWER: debug (1, ("SIGPWR")); - sysvinit_power (); + if (SYSVINIT_ACTIVE) + sysvinit_power (); pies_schedule_children (PIES_CHLD_WAKEUP); action = ACTION_CONT; } if (action == ACTION_CONT) { if (children_op & PIES_CHLD_RESCHEDULE_ALARM) @@ -2579,13 +2538,13 @@ main (int argc, char **argv) progman_cleanup (0); if (children_op & PIES_CHLD_WAKEUP) progman_wake_sleeping (1); children_op = PIES_CHLD_NONE; } } - while (init_process || action == ACTION_CONT); + while (SYSVINIT_ACTIVE || action == ACTION_CONT); progman_stop (); remove_pidfile (pidfile); if (action == ACTION_RESTART) { @@ -273,13 +273,17 @@ struct component struct grecs_list *act_list; /* ACLs for control interface */ pies_acl_t list_acl; /* List access control list */ pies_acl_t adm_acl; /* Administrative ACL (stop, start, etc.) */ }; -#define is_sysvinit(cp) ((cp)->mode >= pies_mark_sysvinit || (cp)->runlevels) +#define is_sysvinit(cp) \ + (PIES_SYSVINIT_ENABLED \ + && ((cp)->mode >= pies_mark_sysvinit || (cp)->runlevels)) + +#define SYSVINIT_ACTIVE (PIES_SYSVINIT_ENABLED && init_process) enum pies_action { ACTION_CONT, ACTION_STOP, ACTION_RESTART, ACTION_RELOAD, @@ -562,12 +566,19 @@ int sysvinit_set_runlevel (int newlevel); void sysvinit_parse_argv (int argc, char **argv); int sysvinit_envlocate (char const *name, char **value); int sysvinit_envdelete (char const *name); int sysvinit_envupdate (char const *var); +int cb_initdefault (enum grecs_callback_command cmd, + grecs_node_t *node, + void *varptr, void *cb_data); +int cb_runlevels (enum grecs_callback_command cmd, + grecs_node_t *node, + void *varptr, void *cb_data); + extern char *sysvinit_environ_hint[]; extern char *init_fifo; #ifndef INIT_FIFO # define INIT_FIFO "/dev/initctl" #endif diff --git a/src/progman.c b/src/progman.c index 88f9afa..70ebf68 100644 --- a/src/progman.c +++ b/src/progman.c @@ -821,13 +821,13 @@ prog_start_prologue (struct prog *prog) { size_t i; for (i = 0; sockenv_var[i]; i++) environ_unset (prog->v.p.env, sockenv_var[i], NULL); } envop_exec (prog->v.p.comp->envop, prog->v.p.env); - if (init_process) + if (SYSVINIT_ACTIVE) { size_t i; for (i = 0; sysvinit_environ_hint[i]; i++) environ_add (prog->v.p.env, sysvinit_environ_hint[i]); } debug_environ (prog, 4); @@ -896,13 +896,13 @@ prog_start (struct prog *prog) if (prog->pid > 0 || !IS_COMPONENT (prog)) return; if (is_sysvinit (prog->v.p.comp)) { - if (!init_process) + if (!SYSVINIT_ACTIVE) { if (prog->active) { logmsg (LOG_NOTICE, "disabling sysvinit component %s", prog_tag (prog)); prog->v.p.status = status_stopped; @@ -992,13 +992,13 @@ prog_start (struct prog *prog) dup2 (prog->v.p.socket, 1); close (prog->v.p.socket); prog->v.p.socket = -1; break; default: - if (init_process) + if (SYSVINIT_ACTIVE) { int fd = console_open (O_RDWR|O_NOCTTY); if (fd < 0) { logmsg (LOG_CRIT, "open(%s): %s", console_device, strerror (errno)); @@ -1034,13 +1034,13 @@ prog_start (struct prog *prog) dup2 (redir[RETR_OUT], 1); } } break; } - if (!init_process) + if (!SYSVINIT_ACTIVE) { if (redir[RETR_ERR] == -1) { if (!DIAG_OUTPUT (DIAG_TO_STDERR)) { close (2); @@ -1597,13 +1597,13 @@ prog_stop (struct prog *prog, int sig) static void print_status (const char *tag, pid_t pid, int status, int expect_term) { int prio; - if (init_process) + if (SYSVINIT_ACTIVE) { if (debug_level <= 1) return; prio = LOG_DEBUG; } else @@ -2144,13 +2144,14 @@ progman_cleanup (int expect_term) enable_socket (listener->v.p.socket); } destroy_prog (&prog); } else { - if (prog->v.p.comp->mode >= pies_mark_sysvinit + if (PIES_SYSVINIT_ENABLED + && prog->v.p.comp->mode >= pies_mark_sysvinit && prog->v.p.comp->mode != pies_comp_ondemand) { sysvinit_acct (SYSV_ACCT_PROC_STOP, "", prog_tag (prog), pid, ""); prog->v.p.status = status_finished; @@ -2300,13 +2301,13 @@ prog_to_stop (struct prog *prog) if (IS_COMPONENT (prog) && prog->stop) break; return prog; } #define DIAG_CON \ - (init_process ? (DIAG_TO_STDERR|DIAG_REOPEN_LOG) : diag_output) + (SYSVINIT_ACTIVE ? (DIAG_TO_STDERR|DIAG_REOPEN_LOG) : diag_output) /* Stop all program components marked for termination. Wait at most 2*shutdown_timeout seconds. */ void progman_gc (void) { diff --git a/src/sysvinit.c b/src/sysvinit.c index 3ba986b..c5d25da 100644 --- a/src/sysvinit.c +++ b/src/sysvinit.c @@ -52,19 +52,19 @@ static int boot_trans_tab[max_boot_state][sizeof(valid_runlevels)-1] = { boot, boot, boot, boot, boot, single }, /* normal */ { normal, normal, normal, normal, normal, normal, normal, normal, normal, normal, normal }, }; enum boot_state boot_state; -int runlevel = 0; -int prevlevel = 'N'; +static int runlevel = 0; +static int prevlevel = 'N'; -int initdefault; /* Default runlevel */ -int dfl_level; -char *emergency_shell = EMERGENCY_SHELL; -int emergency; +int initdefault; +static int dfl_level; +static char *emergency_shell = EMERGENCY_SHELL; +static int emergency; static int inittrans (void); int console_open (int mode) { @@ -337,13 +337,13 @@ static const char valid_runlevel_arg[] = "0123456789SsQqAaBbCcUu"; int is_valid_runlevel (int c) { return !!strchr (valid_runlevel_arg, c); } - + #define ENVAR_CONSOLE "CONSOLE=" #define ENVTMPL_CONSOLE "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" static char env_prevlevel[] = "PREVLEVEL=x"; static char env_runlevel[] = "RUNLEVEL=x"; static char env_console[] = ENVAR_CONSOLE ENVTMPL_CONSOLE; @@ -1280,6 +1280,56 @@ sysvinit_parse_argv (int argc, char **argv) else if (!strcmp (arg, "-b") || !strcmp (arg, "emergency")) emergency = 1; else if (!arg[1] && strchr (valid_runlevels, (c = toupper (arg[0])))) dfl_level = c; } } + +int +cb_initdefault (enum grecs_callback_command cmd, + grecs_node_t *node, + void *varptr, void *cb_data) +{ + grecs_locus_t *locus = &node->locus; + grecs_value_t *value = node->v.value; + + if (grecs_assert_node_value_type (cmd, node, GRECS_TYPE_STRING)) + return 1; + if (strlen (value->v.string) != 1) + { + grecs_error (locus, 0, _("argument must be a single character")); + return 1; + } + if (!is_valid_runlevel (value->v.string[0])) + { + grecs_error (locus, 0, _("not a valid runlevel")); + return 1; + } + initdefault = toupper (value->v.string[0]); + return 0; +} + +int +cb_runlevels (enum grecs_callback_command cmd, + grecs_node_t *node, + void *varptr, void *cb_data) +{ + grecs_locus_t *locus = &node->locus; + grecs_value_t *value = node->v.value; + char **sptr = varptr, *p; + + if (grecs_assert_node_value_type (cmd, node, GRECS_TYPE_STRING)) + return 1; + for (p = value->v.string; *p; p++) + { + if (!is_valid_runlevel (*p)) + { + grecs_error (locus, 0, _("not a valid runlevel: %c"), *p); + return 1; + } + } + *sptr = grecs_strdup (value->v.string); + for (p = *sptr; *p; p++) + *p = toupper (*p); + return 0; +} + |