aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/acl.c2
-rw-r--r--src/pies.c28
-rw-r--r--src/pies.h6
-rw-r--r--src/prog.h1
-rw-r--r--src/progman.c118
-rw-r--r--src/socket.c2
-rw-r--r--src/sysvinit.c296
7 files changed, 290 insertions, 163 deletions
diff --git a/src/acl.c b/src/acl.c
index df53165..301f56f 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -642,4 +642,2 @@ acl_copy (void *a, void *b)
{
- const struct pies_acl *pb = b;
-
memcpy (a, b, sizeof (struct pies_acl));
diff --git a/src/pies.c b/src/pies.c
index 36bd220..beab6fa 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -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 ();
diff --git a/src/pies.h b/src/pies.h
index 0da13e3..ca50a26 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -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[];
diff --git a/src/prog.h b/src/prog.h
index 5a5ad13..8fddf97 100644
--- a/src/prog.h
+++ b/src/prog.h
@@ -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;

Return to:

Send suggestions and report system problems to the System administrator.