diff options
Diffstat (limited to 'src/progman.c')
-rw-r--r-- | src/progman.c | 291 |
1 files changed, 167 insertions, 124 deletions
diff --git a/src/progman.c b/src/progman.c index 1b09cd5..5bc4eb3 100644 --- a/src/progman.c +++ b/src/progman.c @@ -65,7 +65,7 @@ progman_lookup_component (const char *tag) if (IS_COMPONENT (prog) && strcmp (prog_tag (prog), tag) == 0) return prog->v.p.comp; return NULL; -} +} struct component * progman_lookup_tcpmux (const char *service, const char *master) @@ -122,7 +122,7 @@ link_prog (struct prog *prog, struct prog *ref) prog->prev = ref; prog->next = ref->next; - + if ((x = ref->next)) x->prev = prog; else @@ -151,21 +151,21 @@ void destroy_prog (struct prog **pp) { struct prog *p = *pp; - + unlink_prog (p); switch (p->type) { case TYPE_COMPONENT: component_ref_decr (p->v.p.comp); if (p->v.p.status == status_listener && p->v.p.socket != -1) - deregister_socket (p->v.p.socket); - /* FIXME: Remove also all dependent progs (esp. tcpmux) */ + deregister_socket (p->v.p.socket); + /* FIXME: Remove also all dependent progs (esp. tcpmux) */ if (p->v.p.redir[RETR_OUT]) p->v.p.redir[RETR_OUT]->v.r.master = NULL; if (p->v.p.redir[RETR_ERR]) p->v.p.redir[RETR_ERR]->v.r.master = NULL; break; - + case TYPE_REDIRECTOR: { struct prog *master = p->v.r.master; @@ -182,7 +182,7 @@ destroy_prog (struct prog **pp) free (p->v.r.tag); } break; - + case TYPE_COMMAND: free (p->v.c.tag); free (p->v.c.command); @@ -256,7 +256,7 @@ find_prog_ref (struct component *comp) if (!comp) return NULL; /* FIXME: Skip redirectors? */ } - + if (comp->prog) { for (prog = comp->prog; @@ -270,12 +270,12 @@ find_prog_ref (struct component *comp) prog = NULL; return prog; } - + static struct prog * register_prog0 (struct component *comp) { struct prog *newp; - + newp = grecs_zalloc (sizeof (*newp)); newp->type = TYPE_COMPONENT; newp->pid = 0; @@ -291,7 +291,7 @@ register_prog0 (struct component *comp) newp->active = 0; else newp->active = 1; - + if (comp->mode != pies_comp_exec) comp->redir[RETR_OUT].type = redir_null; @@ -317,14 +317,29 @@ register_command (char *tag, char *command, pid_t pid) link_prog (newp, progtail); } +static inline int +progman_startup_phase (void) +{ + struct prog *prog; + + for (prog = proghead; prog; prog = prog->next) + { + if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup) + return 1; + } + return 0; +} + int progman_waiting_p (void) { struct prog *prog; - + for (prog = proghead; prog; prog = prog->next) { - if (IS_COMPONENT (prog) && prog->wait && prog->pid > 0) + if (IS_COMPONENT (prog) + && prog->pid > 0 + && (prog->wait || prog->v.p.comp->mode == pies_comp_startup)) { debug (3, ("%s: waiting for %s (%lu)", __FUNCTION__, prog_tag (prog), @@ -406,17 +421,17 @@ open_redirector (struct prog *master, int stream) case redir_file: return redirect_to_file (master, stream); - + case redir_syslog: break; } - + if (pipe (p)) { logmsg (LOG_CRIT, "pipe: %s", strerror (errno)); return -1; } - + switch (pid = fork ()) { case 0: @@ -428,10 +443,10 @@ open_redirector (struct prog *master, int stream) FD_ZERO (&fdset); FD_SET (p[0], &fdset); close_fds (&fdset); - + diag_setup (0); signal_setup (redir_exit); - + close (p[1]); fp = fdopen (p[0], "r"); if (fp == NULL) @@ -441,7 +456,7 @@ open_redirector (struct prog *master, int stream) while (getline (&buf, &size, fp) > 0) syslog (prio, "%s", buf); _exit (0); - + case -1: logmsg (LOG_CRIT, _("cannot run redirector `%s': fork failed: %s"), @@ -466,7 +481,7 @@ conn_class_hasher (void *data, unsigned long n_buckets) size_t value = 0; unsigned char ch; size_t len; - + while ((ch = *tag++)) value = (value * 31 + ch) % n_buckets; @@ -530,7 +545,7 @@ conn_class_lookup (const char *tag, probe->sa_storage.s.sa_family); break; } - + probe->count = 0; if (!conn_tab) { @@ -725,7 +740,7 @@ env_concat (const char *name, size_t namelen, const char *a, const char *b) { char *res; size_t len; - + if (a && b) { res = grecs_malloc (namelen + 1 + strlen (a) + strlen (b) + 1); @@ -753,14 +768,14 @@ env_concat (const char *name, size_t namelen, const char *a, const char *b) res[namelen] = '='; return res; } - + static void environ_setup (char **hint) { char **old_env = environ; char **new_env; size_t count, i, j, n; - + if (!hint) return; @@ -769,22 +784,22 @@ environ_setup (char **hint) old_env = NULL; hint++; } - + /* Count new environment size */ count = 0; if (old_env) for (i = 0; old_env[i]; i++) count++; - + for (i = 0; hint[i]; i++) count++; /* Allocate new environment. */ new_env = grecs_calloc (count + 1, sizeof new_env[0]); - + /* Populate the environment. */ n = 0; - + if (old_env) for (i = 0; old_env[i]; i++) { @@ -795,7 +810,7 @@ environ_setup (char **hint) for (i = 0; hint[i]; i++) { char *p; - + if (hint[i][0] == '-') { /* Skip unset directives. */ @@ -806,12 +821,12 @@ environ_setup (char **hint) slot if there's no such variable in new_env */ if (find_env_pos (new_env, hint[i], &j, NULL)) j = n; - + if ((p = strchr (hint[i], '='))) { if (p == hint[i]) continue; /* Ignore erroneous entry */ - if (p[-1] == '+') + if (p[-1] == '+') new_env[j] = env_concat (hint[i], p - hint[i] - 1, find_env_ptr (environ, hint[i], 1), p + 1); @@ -835,7 +850,7 @@ environ_setup (char **hint) if (envsize) free (environ); - + environ = new_env; envsize = count + 1; } @@ -852,14 +867,14 @@ prog_sockenv (struct prog *prog) union pies_sockaddr_storage *sa_client = &prog->v.p.sa_storage; socklen_t cltlen = prog->v.p.sa_len; const char *proto = NULL; - + if (!(prog->v.p.comp->flags & CF_SOCKENV)) return; if (socket_type_to_str (prog->v.p.comp->socket_type, &proto)) proto = umaxtostr (prog->v.p.comp->socket_type, buf); add_env (ENV_SOCKTYPE, proto); - + if (prog->v.p.comp->socket_url) proto = prog->v.p.comp->socket_url->proto_s; else if (prog->v.p.listener) @@ -868,7 +883,7 @@ prog_sockenv (struct prog *prog) proto = "TCP"; add_env (ENV_PROTO, proto); - + if (getsockname (prog->v.p.socket, (struct sockaddr *) &sa_server, &len) < 0) logmsg (LOG_WARNING, "getsockname(): %s", strerror (errno)); @@ -920,7 +935,7 @@ static int check_rate (struct prog *prog, unsigned testtime, size_t max_count) { time_t now; - + time (&now); if (prog->v.p.timestamp + testtime > now) @@ -930,7 +945,7 @@ check_rate (struct prog *prog, unsigned testtime, size_t max_count) prog->v.p.failcount = 0; prog->v.p.timestamp = now; } - + if (prog->v.p.failcount > max_count) { prog->v.p.timestamp = now; @@ -938,7 +953,7 @@ check_rate (struct prog *prog, unsigned testtime, size_t max_count) pies_schedule_children (PIES_CHLD_RESCHEDULE_ALARM); return 1; } - + return 0; } @@ -961,7 +976,7 @@ static int check_connection_rate (struct prog *prog) { size_t max_rate = prog->v.p.comp->max_rate - ? prog->v.p.comp->max_rate : default_max_rate; + ? prog->v.p.comp->max_rate : default_max_rate; if (max_rate && check_rate (prog, 60, max_rate)) { logmsg (LOG_NOTICE, @@ -1009,7 +1024,7 @@ prog_start_prologue (struct prog *prog) logmsg (LOG_ERR, _("%s: cannot change to directory %s: %s"), prog_tag (prog), prog->v.p.comp->dir, strerror (errno)); } - + environ_setup (prog->v.p.comp->env ? prog->v.p.comp->env : ((prog->v.p.comp->flags & CF_SOCKENV) ? sockenv_hint : NULL)); @@ -1020,16 +1035,16 @@ prog_start_prologue (struct prog *prog) pies_priv_setup (&prog->v.p.comp->privs); if (prog->v.p.comp->umask) umask (prog->v.p.comp->umask); - + set_limits (prog_tag (prog), prog->v.p.comp->limits ? prog->v.p.comp->limits : pies_limits); - + if (debug_level >= 1) { int i; struct component *comp = prog->v.p.comp; - + logmsg_printf (LOG_DEBUG, "executing"); for (i = 0; i < comp->argc; i++) logmsg_printf (LOG_DEBUG, " %s", quotearg (comp->argv[i])); @@ -1047,7 +1062,7 @@ prog_execute (struct prog *prog) prog->v.p.comp->builtin->fun (0, prog->v.p.comp); _exit (0); } - + execvp (prog->v.p.comp->program ? prog->v.p.comp->program : prog->v.p.comp->argv[0], prog->v.p.comp->argv); @@ -1077,7 +1092,7 @@ prog_start (struct prog *prog) pid_t pid; int redir[2]; fd_set fdset; - + if (prog->pid > 0 || !IS_COMPONENT (prog)) return; @@ -1123,7 +1138,7 @@ prog_start (struct prog *prog) if (prog_open_socket (prog)) return; break; - + case pies_comp_accept: if (check_spawn_rate (prog)) return; @@ -1139,9 +1154,9 @@ prog_start (struct prog *prog) default: break; } - + debug (1, (_("starting %s"), prog_tag (prog))); - + if (prog->v.p.comp->rmfile) { debug (1, (_("unlinking %s"), prog->v.p.comp->rmfile)); @@ -1158,7 +1173,7 @@ prog_start (struct prog *prog) redir[RETR_OUT] = open_redirector (prog, RETR_OUT); redir[RETR_ERR] = open_redirector (prog, RETR_ERR); - + switch (pid = fork ()) { /* The child branch. */ @@ -1167,22 +1182,22 @@ prog_start (struct prog *prog) setsid (); prog_start_prologue (prog); switch (prog->v.p.comp->mode) - { - case pies_comp_accept: - case pies_comp_inetd: + { + case pies_comp_accept: + case pies_comp_inetd: prog_sockenv (prog); - dup2 (prog->v.p.socket, 0); - dup2 (prog->v.p.socket, 1); - close (prog->v.p.socket); + dup2 (prog->v.p.socket, 0); + dup2 (prog->v.p.socket, 1); + close (prog->v.p.socket); prog->v.p.socket = -1; - break; + break; default: if (init_process) { int fd = console_open (O_RDWR|O_NOCTTY); - if (fd < 0) + if (fd < 0) { logmsg (LOG_CRIT, "open(%s): %s", console_device, strerror (errno)); @@ -1218,8 +1233,8 @@ prog_start (struct prog *prog) dup2 (redir[RETR_OUT], 1); } } - break; - } + break; + } if (!init_process) { @@ -1236,7 +1251,7 @@ prog_start (struct prog *prog) dup2 (redir[RETR_ERR], 2); } } - + /* Close unneeded descripitors */ FD_ZERO (&fdset); FD_SET (0, &fdset); @@ -1247,8 +1262,8 @@ prog_start (struct prog *prog) close_fds (&fdset); prog_execute (prog); - - + + case -1: logmsg (LOG_CRIT, _("cannot run `%s': fork failed: %s"), @@ -1291,14 +1306,14 @@ check_acl (pies_acl_t acl, struct sockaddr *s, socklen_t salen, { struct acl_input input; int rc; - + if (!acl) return 0; input.addr = s; input.addrlen = salen; input.identity = identity; - + rc = pies_acl_check (acl, &input, 1); if (rc == 0) { @@ -1315,7 +1330,7 @@ void fd_report (int fd, const char *msg) { size_t len; - + if (!msg) return; @@ -1334,7 +1349,7 @@ fd_report (int fd, const char *msg) len -= rc; msg += rc; } -} +} static int _prog_accept (struct prog *p) @@ -1344,14 +1359,14 @@ _prog_accept (struct prog *p) union pies_sockaddr_storage addr; socklen_t addrlen = sizeof addr; struct conn_class *pcclass; - + fd = accept (p->v.p.socket, (struct sockaddr*) &addr, &addrlen); if (fd == -1) { logfuncall ("accept", NULL, errno); return 1; } - + if (debug_level >= 1) { char *s = sockaddr_to_astr ((struct sockaddr *)&addr, addrlen); @@ -1394,7 +1409,7 @@ _prog_accept (struct prog *p) close (fd); return 1; } - + if (check_connection_rate (p)) { disable_socket (p->v.p.socket); @@ -1447,7 +1462,7 @@ _prog_wait (struct prog *p) p->v.p.num_instances++; return 0; } - + int progman_accept (int socket, void *data) { @@ -1456,7 +1471,7 @@ progman_accept (int socket, void *data) if (p->v.p.comp->socket_type == SOCK_STREAM && !(p->v.p.comp->flags & CF_WAIT)) return _prog_accept (p); - + return _prog_wait (p); } @@ -1526,14 +1541,34 @@ progman_recompute_alarm (void) } void +program_init_startup (void) +{ + struct prog *prog; + + for (prog = proghead; prog; prog = prog->next) + if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup) + { + debug (1, ("running startup components")); + break; + } + + for (; prog; prog = prog->next) + if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup) + { + prog_start (prog); + } +} + +void progman_start (void) { struct prog *prog; if (progman_waiting_p ()) - /* Noting to do if there are processes left in the previous runlevel */ + /* Noting to do if there are processes left in the previous runlevel + (in sysv-init mode) or startup components running. */ return; - + debug (1, ("starting components")); for (prog = proghead; prog; prog = prog->next) if (IS_COMPONENT (prog)) @@ -1565,8 +1600,8 @@ check_stopping (struct prog *prog, time_t now) if (now - prog->v.p.timestamp >= shutdown_timeout) { if (prog->pid == 0) - logmsg (LOG_EMERG, - _("INTERNAL ERROR: attempting to kill unexisting process %s"), + logmsg (LOG_EMERG, + _("INTERNAL ERROR: attempting to kill unexisting process %s"), prog_tag (prog)); else if (prog->v.p.comp->flags & CF_SIGGROUP) kill (-prog->pid, SIGKILL); @@ -1625,7 +1660,7 @@ progman_wake_sleeping (int onalrm) pies_schedule_children (PIES_CHLD_RESCHEDULE_ALARM); } break; - + case status_stopping: check_stopping (prog, now); break; @@ -1634,7 +1669,7 @@ progman_wake_sleeping (int onalrm) if (IS_ACTIVE_COMPONENT (prog)) prog_start (prog); break; - + default: break; } @@ -1647,7 +1682,7 @@ prog_start_prerequisites (struct prog *prog) pies_depmap_pos_t pos; struct component *comp; int warned = 0; - + if (!prog->active) return 1; for (comp = component_depmap_first (depmap_col, prog->v.p.comp->arridx, &pos); @@ -1655,7 +1690,7 @@ prog_start_prerequisites (struct prog *prog) comp = component_depmap_next (pos)) { struct prog *p; - + if (!comp->prog || comp->flags & CF_PRECIOUS) continue; if (!warned) @@ -1669,16 +1704,16 @@ prog_start_prerequisites (struct prog *prog) prog->active = 0; return 1; } - + p = comp->prog; switch (p->v.p.status) { case status_running: continue; - + case status_stopped: break; - + case status_listener: continue; @@ -1700,7 +1735,7 @@ prog_start_prerequisites (struct prog *prog) ret = 1; } depmap_end (pos); - + return ret; } @@ -1757,7 +1792,7 @@ prog_stop (struct prog *prog, int sig) kill (-prog->pid, sig); else kill (prog->pid, sig); -} +} static int mark_for_stopping (struct prog *prog, void *data) @@ -1787,7 +1822,7 @@ print_status (const char *tag, pid_t pid, int status, int expect_term) } else prio = LOG_ERR; - + if (WIFEXITED (status)) { if (WEXITSTATUS (status) == 0) @@ -1801,7 +1836,7 @@ print_status (const char *tag, pid_t pid, int status, int expect_term) else if (WIFSIGNALED (status)) { char const *coremsg = ""; - + if (expect_term && WTERMSIG (status) == SIGTERM) prio = LOG_DEBUG; @@ -1823,7 +1858,7 @@ print_status (const char *tag, pid_t pid, int status, int expect_term) } static void propagate_child_exit (pid_t) ATTRIBUTE_NORETURN; - + static void propagate_child_exit (pid_t pid) { @@ -1855,7 +1890,7 @@ wordsplit_string (struct wordsplit const *ws) char **argv = grecs_calloc (count, sizeof (argv[0])); size_t i; size_t len = 0; - + for (i = 0; i < count; i++) { argv[i] = quotearg_n (i, ws->ws_wordv[i]); @@ -1883,7 +1918,7 @@ send_msg (char *rcpts, const char *msg_text) struct wordsplit ws; int p[2]; size_t size; - + ws.ws_offs = mailer_argc; ws.ws_delim = ","; if (wordsplit (rcpts, &ws, @@ -1896,7 +1931,7 @@ send_msg (char *rcpts, const char *msg_text) } debug (1, (_("sending notification to %s"), rcpts)); - + /* Copy mailer arguments */ for (i = 0; i < mailer_argc; i++) ws.ws_wordv[i] = mailer_argv[i]; @@ -1911,7 +1946,7 @@ send_msg (char *rcpts, const char *msg_text) { char *arg = ws.ws_wordv[i]; size_t len; - + while (*arg && c_isblank (*arg)) arg++; len = strlen (arg); @@ -1934,10 +1969,10 @@ send_msg (char *rcpts, const char *msg_text) k++; } ws.ws_wordv[k] = NULL; - + /* Fork a child: */ child_pid = fork (); - + if (child_pid < 0) { wordsplit_free (&ws); @@ -1955,7 +1990,7 @@ send_msg (char *rcpts, const char *msg_text) register_command (mailer_program, cmd, child_pid); return; } - + /* Child process */ /* ============= */ signal_setup (SIG_DFL); @@ -1967,7 +2002,7 @@ send_msg (char *rcpts, const char *msg_text) wordsplit_free (&ws); exit (EX_OSERR); } - + grand_child_pid = fork (); if (grand_child_pid < 0) { @@ -2030,7 +2065,7 @@ notify_get_tag (char **ret, void *data) if (!s) return WRDSE_NOSPACE; *ret = s; - return WRDSE_OK; + return WRDSE_OK; } static int @@ -2039,7 +2074,7 @@ notify_get_termination (char **ret, void *data) struct notify_closure const *clos = data; char const *msg; char *s; - + if (WIFEXITED (clos->status)) /* TRANSLATORS: The subject of this statement is 'component' */ msg = _("exited with code"); @@ -2053,16 +2088,16 @@ notify_get_termination (char **ret, void *data) if (!s) return WRDSE_NOSPACE; *ret = s; - return WRDSE_OK; + return WRDSE_OK; } - + static int notify_get_retcode (char **ret, void *data) { struct notify_closure const *clos = data; char *s = NULL; size_t l = 0; - + if (WIFEXITED (clos->status)) grecs_asprintf (&s, &l, "%d", WEXITSTATUS (clos->status)); else if (WIFSIGNALED (clos->status)) @@ -2072,9 +2107,9 @@ notify_get_retcode (char **ret, void *data) if (!s) return WRDSE_NOSPACE; *ret = s; - return WRDSE_OK; -} - + return WRDSE_OK; +} + struct notify_variable { char *name; @@ -2090,7 +2125,7 @@ static struct notify_variable notify_vartab[] = { #undef S { NULL } }; - + static int notify_getvar (char **ret, const char *vptr, size_t vlen, void *data) { @@ -2100,7 +2135,7 @@ notify_getvar (char **ret, const char *vptr, size_t vlen, void *data) return var->get (ret, data); return WRDSE_UNDEF; } - + static void notify (const char *tag, int status, struct action *act) { @@ -2120,7 +2155,7 @@ notify (const char *tag, int status, struct action *act) closure.tag = tag; closure.status = status; closure.act = act; - + env[PROGRAM_NAME_IDX] = program_name; env[INSTANCE_IDX] = instance; @@ -2144,7 +2179,7 @@ static int status_matches_p (struct action *act, unsigned status) { int i; - + if (act->nstat == 0) return 1; for (i = 0; i < act->nstat; i++) @@ -2184,7 +2219,7 @@ run_command (struct action *act, struct prog *prog, unsigned retcode, setenv ("PIES_STATUS", umaxtostr (STATUS_CODE (retcode), buf), 1); close_fds (NULL); - + argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = act->command; @@ -2208,7 +2243,7 @@ react (struct prog *prog, int status, pid_t pid) if (!list) list = default_component.act_list; - + if (WIFEXITED (status)) { retcode = WEXITSTATUS (status); @@ -2233,21 +2268,21 @@ react (struct prog *prog, int status, pid_t pid) for (ep = list->head; ep; ep = ep->next) { struct action *act = ep->data; - + if (status_matches_p (act, retcode)) { if (act->command) { run_command (act, prog, retcode, pid); } - + switch (act->act) { case action_restart: if (prog->v.p.comp->mode != pies_comp_inetd) prog_start (prog); break; - + case action_disable: logmsg (LOG_NOTICE, _("disabling component %s"), prog_tag (prog)); @@ -2263,7 +2298,7 @@ react (struct prog *prog, int status, pid_t pid) } } } - + if (!list && prog->v.p.comp->mode != pies_comp_inetd) /* Default action: */ prog_start (prog); @@ -2294,7 +2329,7 @@ progman_cleanup (int expect_term) if (prog->v.p.comp->mode == pies_comp_inetd) { struct prog *listener = prog->v.p.listener; - + listener->v.p.num_instances--; if (prog->v.p.cclass) { @@ -2307,7 +2342,7 @@ progman_cleanup (int expect_term) prog->v.p.cclass = NULL; } } - + prog_stop_redirectors (prog); if (listener->v.p.num_instances == 0 && !component_is_active (prog->v.p.comp)) @@ -2321,6 +2356,14 @@ progman_cleanup (int expect_term) } destroy_prog (&prog); } + else if (prog->v.p.comp->mode == pies_comp_startup) + { + debug (1, (_("removing startup component %s, pid=%lu"), + prog_tag (prog), (unsigned long)pid)); + destroy_prog (&prog); + if (!progman_startup_phase ()) + pies_schedule_children (PIES_CHLD_WAKEUP); + } else { if (prog->v.p.comp->mode >= pies_mark_sysvinit @@ -2329,7 +2372,7 @@ progman_cleanup (int expect_term) sysvinit_acct (SYSV_ACCT_PROC_STOP, "", prog_tag (prog), pid, ""); prog->v.p.status = status_finished; - + if (prog->wait) { pies_schedule_children (PIES_CHLD_WAKEUP); @@ -2351,7 +2394,7 @@ progman_cleanup (int expect_term) if (!component_is_active (prog->v.p.comp)) destroy_prog (&prog); } - + break; case TYPE_REDIRECTOR: @@ -2371,7 +2414,7 @@ progman_cleanup (int expect_term) break; } } - + if (!expect_term) /* This will also recompute alarm settings, if necessary */ progman_wake_sleeping (0); @@ -2389,7 +2432,7 @@ progman_stop_component (struct prog **progptr) logmsg (LOG_INFO, _("stopping component %s"), prog_tag (prog)); prog_stop (prog, SIGTERM); break; - + case status_listener: prog_deactivate_listener (prog); /* fall through */ @@ -2413,7 +2456,7 @@ progman_stop_component (struct prog **progptr) case status_stopping: break; - + case status_finished: prog->stop = 0; if (!component_is_active (prog->v.p.comp)) @@ -2441,7 +2484,7 @@ int prog_activate_listener (struct prog *prog) { struct component *comp = prog->v.p.comp; - + logmsg (LOG_INFO, _("activating listener %s"), prog_tag (prog)); if (comp->mode == pies_comp_inetd && !ISCF_TCPMUX (comp->flags) && prog->v.p.socket == -1) @@ -2535,9 +2578,9 @@ progman_gc (void) else break; } - + /* FIXME: Report remaining programs */ - + } - + /* EOF */ |