diff options
-rw-r--r-- | src/acl.c | 2 | ||||
-rw-r--r-- | src/pies.c | 28 | ||||
-rw-r--r-- | src/pies.h | 6 | ||||
-rw-r--r-- | src/prog.h | 1 | ||||
-rw-r--r-- | src/progman.c | 118 | ||||
-rw-r--r-- | src/socket.c | 2 | ||||
-rw-r--r-- | src/sysvinit.c | 296 |
7 files changed, 290 insertions, 163 deletions
@@ -642,4 +642,2 @@ acl_copy (void *a, void *b) { - const struct pies_acl *pb = b; - memcpy (a, b, sizeof (struct pies_acl)); @@ -997,3 +997,3 @@ _cb_runlevels (enum grecs_callback_command cmd, { - grecs_error (locus, 0, _("not a valid runlevel: %c")); + grecs_error (locus, 0, _("not a valid runlevel: %c"), *p); return 1; @@ -2117,27 +2117,2 @@ set_state_file_names (const char *base) -static char *try_console[] = { NULL, "/dev/console", "/dev/tty0" }; -char *console_device; - -static void -set_console_dev () -{ - int i; - for (i = 0; i < ARRAY_SIZE (try_console); i++) - { - if (try_console[i]) - { - int fd = open (try_console[i], O_RDONLY|O_NONBLOCK); - - if (fd >= 0) - { - close (fd); - console_device = try_console[i]; - return; - } - } - } - /* provide default */ - console_device = "/dev/null"; -} - int @@ -2308,3 +2283,2 @@ main (int argc, char **argv) foreground = 1; - set_console_dev (); sysvinit_begin (); @@ -305,4 +305,2 @@ void progman_iterate_comp (int (*fun) (struct component *, void *), void *data); -void progman_sysvinit_enable (int (*fun) (struct component *, int, void *), - void *data); @@ -464,2 +462,6 @@ int is_comp_wait (struct component *comp); int is_valid_runlevel (int c); +int console_open (int mode); +int telinit (const char *arg); + +extern char *sysvinit_environ_hint[]; @@ -85 +85,2 @@ struct prog void progman_foreach (int (*filter) (struct prog *, void *data), void *data); +void prog_stop (struct prog *prog, int sig); diff --git a/src/progman.c b/src/progman.c index 1895152..0463366 100644 --- a/src/progman.c +++ b/src/progman.c @@ -17,3 +17,2 @@ #include "pies.h" -#include <termios.h> #include "prog.h" @@ -29,11 +28,7 @@ static struct grecs_symtab *conn_tab; void -progman_iterate_comp (int (*fun) (struct component *, void *), void *data) +progman_foreach (int (*filter) (struct prog *, void *data), void *data) { struct prog *prog; - for (prog = proghead; prog; prog = prog->next) - if (IS_COMPONENT (prog) - && !(prog->v.p.comp->mode == pies_comp_inetd - && prog->v.p.listener) - && fun (prog->v.p.comp, data)) + if (IS_COMPONENT (prog) && filter (prog, data)) break; @@ -41,5 +36,5 @@ progman_iterate_comp (int (*fun) (struct component *, void *), void *data) +/* FIXME: Rewrite this using progman_foreach */ void -progman_sysvinit_enable (int (*fun) (struct component *, int, void *), - void *data) +progman_iterate_comp (int (*fun) (struct component *, void *), void *data) { @@ -48,18 +43,9 @@ progman_sysvinit_enable (int (*fun) (struct component *, int, void *), for (prog = proghead; prog; prog = prog->next) - if (IS_COMPONENT (prog) && is_sysvinit (prog->v.p.comp)) - { - int rc = fun (prog->v.p.comp, prog->v.p.status == status_finished, - data); - if (rc < 0) - continue; - if (rc) - prog->v.p.status = status_enabled; - else - prog->v.p.status = status_disabled; - debug (1, ("%s: %s", prog->tag, - prog->v.p.status == status_enabled ? - "enabled" : "disabled")); - } + if (IS_COMPONENT (prog) + && !(prog->v.p.comp->mode == pies_comp_inetd + && prog->v.p.listener) + && fun (prog->v.p.comp, data)) + break; } - + static struct prog * @@ -370,6 +356,3 @@ progman_running_p () prog->pid > 0) - { - debug (1, ("COMP %s still running", prog->tag)); - return 1; - } + return 1; } @@ -761,2 +744,3 @@ env_concat (const char *name, size_t namelen, const char *a, const char *b) b++; + len = strlen (b); res = xmalloc (namelen + 1 + len + 1); @@ -1017,2 +1001,4 @@ prog_start_prologue (struct prog *prog) ((prog->v.p.comp->flags & CF_SOCKENV) ? sockenv_hint : NULL)); + if (init_process) + environ_setup (sysvinit_environ_hint); DEBUG_ENVIRON (4); @@ -1074,64 +1060,2 @@ progman_run_comp (struct component *comp, int fd, -int -console_open (int mode) -{ - int i, fd; - - for (i = 0; i < 5; i++) - { - fd = open (console_device, mode | O_NONBLOCK); - if (fd >= 0) - { - fcntl (fd, F_SETFL, mode); - return fd; - } - } - return -1; -} - -static void -console_stty () -{ - struct termios tty; - int fd; - - if ((fd = console_open (O_RDWR|O_NOCTTY)) < 0) - { - logmsg (LOG_CRIT, "can't open %s", console_device); - return; - } - - tcgetattr (fd, &tty); - - tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD; - tty.c_cflag |= HUPCL|CLOCAL|CREAD; - - tty.c_cc[VINTR] = 3; /* ctrl('c') */ - tty.c_cc[VQUIT] = 28; /* ctrl('\\') */ - tty.c_cc[VERASE] = 127; - tty.c_cc[VKILL] = 24; /* ctrl('x') */ - tty.c_cc[VEOF] = 4; /* ctrl('d') */ - tty.c_cc[VTIME] = 0; - tty.c_cc[VMIN] = 1; - tty.c_cc[VSTART] = 17; /* ctrl('q') */ - tty.c_cc[VSTOP] = 19; /* ctrl('s') */ - tty.c_cc[VSUSP] = 26; /* ctrl('z') */ - - /* - * Set pre and post processing - */ - tty.c_iflag = IGNPAR|ICRNL|IXON|IXANY; - tty.c_oflag = OPOST|ONLCR; - tty.c_lflag = ISIG|ICANON|ECHO|ECHOCTL|ECHOPRT|ECHOKE; - - /* - * Now set the terminal line. - * We don't care about non-transmitted output data - * and non-read input data. - */ - tcsetattr (fd, TCSANOW, &tty); - tcflush(fd, TCIOFLUSH); - close (fd); -} - static void @@ -1202,2 +1126,5 @@ prog_start (struct prog *prog) return; + + default: + break; } @@ -1253,3 +1180,3 @@ prog_start (struct prog *prog) console_device, strerror (errno)); - fd = open("/dev/null", O_RDWR); + fd = open ("/dev/null", O_RDWR); } @@ -2474,11 +2401,2 @@ progman_cleanup (int expect_term) void -progman_foreach (int (*filter) (struct prog *, void *data), void *data) -{ - struct prog *prog; - for (prog = proghead; prog; prog = prog->next) - if (IS_COMPONENT (prog) && filter (prog, data)) - break; -} - -void progman_stop_component (const char *name) diff --git a/src/socket.c b/src/socket.c index c4edcc3..78f79f5 100644 --- a/src/socket.c +++ b/src/socket.c @@ -429,3 +429,3 @@ find_socket_handler (int (*handler) (int, void *)) -static int +static void calc_fd_max () diff --git a/src/sysvinit.c b/src/sysvinit.c index 940125f..23cad9a 100644 --- a/src/sysvinit.c +++ b/src/sysvinit.c @@ -18,2 +18,3 @@ #include "prog.h" +#include <termios.h> @@ -23,4 +24,3 @@ enum boot_state boot, - single0, - single1, + single, normal, @@ -32,4 +32,3 @@ static char *boot_state_name[] = { "boot", - "single0", - "single1", + "single", "normal" @@ -37,3 +36,3 @@ static char *boot_state_name[] = { -static char boot_state_str[] = "#*sS "; +static char boot_state_str[] = "#*s "; @@ -45,11 +44,9 @@ static int boot_trans_tab[max_boot_state][sizeof(valid_runlevels)-1] = { /* sysinit */ { boot, boot, boot, boot, boot, - boot, boot, boot, boot, boot, single0 }, + boot, boot, boot, boot, boot, single }, /* boot */ { normal, normal, normal, normal, normal, - normal, normal, normal, normal, normal, single1 }, - /* single0 */ { normal, normal, normal, normal, normal, - normal, normal, normal, normal, normal, single0 }, - /* single1 */ { normal, normal, normal, normal, normal, - normal, normal, normal, normal, normal, single1 }, + normal, normal, normal, normal, normal, normal }, + /* single */ { boot, boot, boot, boot, boot, + boot, boot, boot, boot, boot, single }, /* normal */ { normal, normal, normal, normal, normal, - normal, normal, normal, normal, normal, single1 }, + normal, normal, normal, normal, normal, normal }, }; @@ -58,2 +55,3 @@ enum boot_state boot_state; int runlevel = 0; +int prevlevel = 'N'; @@ -61,2 +59,135 @@ int initdefault; /* Default runlevel */ int dfl_level; + +int +console_open (int mode) +{ + int i, fd; + + for (i = 0; i < 5; i++) + { + fd = open (console_device, mode | O_NONBLOCK); + if (fd >= 0) + { + fcntl (fd, F_SETFL, mode); + return fd; + } + } + return -1; +} + +void +console_stty () +{ + struct termios tty; + int fd; + + if ((fd = console_open (O_RDWR|O_NOCTTY)) < 0) + { + logmsg (LOG_CRIT, "can't open %s", console_device); + return; + } + + tcgetattr (fd, &tty); + + tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD; + tty.c_cflag |= HUPCL|CLOCAL|CREAD; + + tty.c_cc[VINTR] = 3; /* ctrl('c') */ + tty.c_cc[VQUIT] = 28; /* ctrl('\\') */ + tty.c_cc[VERASE] = 127; + tty.c_cc[VKILL] = 24; /* ctrl('x') */ + tty.c_cc[VEOF] = 4; /* ctrl('d') */ + tty.c_cc[VTIME] = 0; + tty.c_cc[VMIN] = 1; + tty.c_cc[VSTART] = 17; /* ctrl('q') */ + tty.c_cc[VSTOP] = 19; /* ctrl('s') */ + tty.c_cc[VSUSP] = 26; /* ctrl('z') */ + + /* + * Set pre and post processing + */ + tty.c_iflag = IGNPAR|ICRNL|IXON|IXANY; + tty.c_oflag = OPOST|ONLCR; + tty.c_lflag = ISIG|ICANON|ECHO|ECHOCTL|ECHOPRT|ECHOKE; + + /* + * Now set the terminal line. + * We don't care about non-transmitted output data + * and non-read input data. + */ + tcsetattr (fd, TCSANOW, &tty); + tcflush(fd, TCIOFLUSH); + close (fd); +} + +int +askrunlevel () +{ + int fd; + char c, lvl = -1; + enum { srl_init, srl_char, srl_r, srl_n, srl_skip } srl = srl_init; + static const char prompt[] = "\nEnter runlevel: "; + + console_stty (); + fd = console_open (O_RDWR|O_NOCTTY); + if (fd == -1) + return 'S'; + + while (1) + { + if (srl == srl_init) + { + write (fd, prompt, sizeof (prompt) - 1); + if (read (fd, &lvl, 1) != 1) + return 'S'; + srl = srl_char; + } + else if (srl == srl_n) + { + if (is_valid_runlevel (lvl)) + break; + srl = srl_init; + } + else + { + if (read (fd, &c, 1) != 1) + { + if (!is_valid_runlevel (lvl)) + lvl = 'S'; + break; + } + + switch (srl) + { + case srl_char: + if (c == '\r') + srl = srl_r; + else if (c == '\n') + srl = srl_n; + else + srl = srl_skip; + break; + + case srl_r: + if (c == '\n') + srl = srl_n; + else + srl = srl_skip; + break; + + case srl_skip: + if (c == '\n') + srl = srl_init; + } + } + } + close (fd); + return toupper (lvl); +} + +static int +getinitdefault () +{ + return initdefault ? initdefault : askrunlevel (); +} @@ -77,3 +208,3 @@ runlevel_index (int n) static int -enablecomp (struct component *comp, int finished, void *data) +enablecomp (struct prog *prog, void *data) { @@ -81,2 +212,3 @@ enablecomp (struct component *comp, int finished, void *data) int rc; + struct component *comp = prog->v.p.comp; @@ -90,4 +222,3 @@ enablecomp (struct component *comp, int finished, void *data) - case single0: - case single1: + case single: case normal: @@ -113,3 +244,3 @@ enablecomp (struct component *comp, int finished, void *data) return rc; - if (finished) + if (prog->v.p.status == status_finished) return -1; @@ -127,2 +258,27 @@ enablecomp (struct component *comp, int finished, void *data) +static int +runlevel_setup_prog (struct prog *prog, void *data) +{ + if (is_sysvinit (prog->v.p.comp)) + { + int rc = enablecomp (prog, data); + if (rc < 0) + return 0; + if (rc) + prog->v.p.status = status_enabled; + else + prog->v.p.status = status_disabled; + debug (1, ("%s: %s", prog->tag, + prog->v.p.status == status_enabled ? + "enabled" : "disabled")); + } + return 0; +} + +static void +sysvinit_runlevel_setup (int *wait) +{ + progman_foreach (runlevel_setup_prog, wait); +} + static const char valid_runlevel_arg[] = "0123456789SsQqAaBbCcUu"; @@ -135,2 +291,53 @@ is_valid_runlevel (int 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; + +char *sysvinit_environ_hint[] = { + env_prevlevel, + env_runlevel, + env_console, + "INIT_VERSION=" PACKAGE_STRING, + "PATH=/bin:/usr/bin:/sbin:/usr/sbin", + NULL +}; + +#define ENVI_PREVLEVEL 0 +#define ENVI_RUNLEVEL 1 +#define ENVI_CONSOLE 2 +#define ENVI_VERSION 3 +#define ENVI_PATH 4 + +static void +envsetup () +{ + int i; + + for (i = 0; sysvinit_environ_hint[i]; i++) + { + char *str = sysvinit_environ_hint[i]; + switch (i) + { + case ENVI_PREVLEVEL: + str[strlen (str) - 1] = prevlevel; + break; + + case ENVI_RUNLEVEL: + str[strlen (str) - 1] = + boot_state_str[boot_state] == ' ' ? + (runlevel ? runlevel : '#') : boot_state_str[boot_state]; + break; + + case ENVI_CONSOLE: + if (strlen (console_device) >= sizeof (ENVTMPL_CONSOLE)) + logmsg (LOG_ERR, "console device name too long"); + else + strcpy (str + sizeof (ENVAR_CONSOLE) - 1, console_device); + } + } +} + static void create_fifo (void); @@ -267,2 +474,27 @@ create_fifo () +static char *try_console[] = { NULL, "/dev/console", "/dev/tty0" }; +char *console_device; + +static void +set_console_dev () +{ + int i; + for (i = 0; i < ARRAY_SIZE (try_console); i++) + { + if (try_console[i]) + { + int fd = open (try_console[i], O_RDONLY|O_NONBLOCK); + + if (fd >= 0) + { + close (fd); + console_device = try_console[i]; + return; + } + } + } + /* provide default */ + console_device = "/dev/null"; +} + void @@ -270,3 +502,10 @@ sysvinit_begin () { - progman_sysvinit_enable (enablecomp, NULL); + close (0); + close (1); + close (2); + set_console_dev (); + console_stty (); + setsid (); + envsetup (); + sysvinit_runlevel_setup (NULL); } @@ -283,10 +522,7 @@ inittrans () if (progman_running_p ()) - { - debug (1, ("%s exiting: some components still running",__FUNCTION__)); - /* Noting to do if there are processes left in the previous runlevel */ - return 0; - } + /* Noting to do if there are processes left in the previous runlevel */ + return 0; if (runlevel == 0) - n = runlevel_index (dfl_level ? dfl_level : initdefault); + n = runlevel_index (dfl_level ? dfl_level : getinitdefault ()); else @@ -297,5 +533,2 @@ inittrans () newstate = boot_trans_tab[boot_state][n]; - debug (1, ("STATE TRANS: %s(%c,%d) -> %s", boot_state_name[boot_state], - runlevel,n, - boot_state_name[newstate])); if (newstate != boot_state) @@ -316,9 +549,8 @@ inittrans () break; - case single0: + case single: newlevel = 'S'; break; - case single1: case normal: /* boot -> normal */ - newlevel = dfl_level ? dfl_level : initdefault; + newlevel = dfl_level ? dfl_level : getinitdefault (); create_fifo (); @@ -331,2 +563,3 @@ inittrans () mf_proctitle_format ("init [%c]", newlevel); + prevlevel = runlevel ? runlevel : 'N'; runlevel = newlevel; @@ -339,5 +572,6 @@ inittrans () { + envsetup (); if (wait == 0) { - progman_sysvinit_enable (enablecomp, &wait); + sysvinit_runlevel_setup (&wait); if (wait) @@ -345,3 +579,3 @@ inittrans () } - progman_sysvinit_enable (enablecomp, NULL); + sysvinit_runlevel_setup (NULL); wait = 0; |