diff options
Diffstat (limited to 'src/progman.c')
-rw-r--r-- | src/progman.c | 166 |
1 files changed, 111 insertions, 55 deletions
diff --git a/src/progman.c b/src/progman.c index 35fc876..1235d81 100644 --- a/src/progman.c +++ b/src/progman.c @@ -78,6 +78,19 @@ static struct prog *proghead, *progtail; static pies_depmap_t depmap; static int recompute_alarm; +void +progman_iterate_comp (int (*fun) (struct component *, void *), 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)) + break; +} + static struct prog * prog_lookup_by_pid (pid_t pid) { @@ -110,6 +123,18 @@ prog_lookup_by_tag (const char *tag) return prog; } +struct prog * +prog_lookup_by_service (const char *service) +{ + struct prog *prog; + for (prog = proghead; prog; prog = prog->next) + if (IS_COMPONENT (prog) + && prog->v.p.comp->service + && strcmp (prog->v.p.comp->service, service) == 0) + break; + return prog; +} + struct component * progman_lookup_component (const char *tag) { @@ -120,6 +145,15 @@ progman_lookup_component (const char *tag) return NULL; } +struct component * +progman_lookup_service (const char *service) +{ + struct prog *prog = prog_lookup_by_service (service); + if (!prog) + return NULL; + return prog->v.p.comp; +} + struct prog * prog_lookup_by_idx (unsigned idx) { @@ -693,6 +727,77 @@ prog_open_socket (struct prog *prog) } static void +prog_start_prologue (struct prog *prog) +{ + if (prog->v.p.comp->dir) + { + debug (1, (_("chdir %s"), prog->v.p.comp->dir)); + if (chdir (prog->v.p.comp->dir)) + logmsg (LOG_ERR, _("%s: cannot change to directory %s: %s"), + prog->tag, prog->v.p.comp->dir, strerror (errno)); + } + + environ = env_setup (prog->v.p.comp->env); + if (debug_level >= 4) + { + int i; + logmsg_printf (LOG_DEBUG, "environment: "); + for (i = 0; environ[i]; i++) + logmsg_printf (LOG_DEBUG, "%s ", environ[i]); + logmsg_printf (LOG_DEBUG, "\n"); + } + + 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->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])); + logmsg_printf (LOG_DEBUG, "\n"); + } +} + +static void +prog_execute (struct prog *prog) +{ + if (prog->v.p.comp->builtin) + { + mf_proctitle_format ("inetd %s", + prog->v.p.comp->builtin->service); + prog->v.p.comp->builtin->fun (0); + _exit (0); + } + + execvp (prog->v.p.comp->program ? + prog->v.p.comp->program : prog->v.p.comp->argv[0], + prog->v.p.comp->argv); + openlog (log_tag, LOG_PID, prog->v.p.comp->facility); + syslog (LOG_CRIT, _("cannot start `%s': %s"), prog->tag, + strerror (errno)); + _exit (EX_SOFTWARE); +} + +void +progman_run_comp (struct component *comp, int fd) +{ + struct prog *prog = register_prog0 (comp, -1); + prog->v.p.socket = fd; + prog_start_prologue (prog); + prog_execute (prog); +} + +static void prog_start (struct prog *prog) { pid_t pid; @@ -769,52 +874,7 @@ prog_start (struct prog *prog) /* The child branch. */ case 0: signal_setup (SIG_DFL); - if (prog->v.p.comp->dir) - { - debug (1, (_("chdir %s"), prog->v.p.comp->dir)); - if (chdir (prog->v.p.comp->dir)) - logmsg (LOG_ERR, _("%s: cannot change to directory %s: %s"), - prog->tag, prog->v.p.comp->dir, strerror (errno)); - } - - environ = env_setup (prog->v.p.comp->env); - if (debug_level >= 4) - { - int i; - logmsg_printf (LOG_DEBUG, "environment: "); - for (i = 0; environ[i]; i++) - logmsg_printf (LOG_DEBUG, "%s ", environ[i]); - logmsg_printf (LOG_DEBUG, "\n"); - } - - 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->v.p.comp->limits ? - prog->v.p.comp->limits : pies_limits); - - if (prog->v.p.comp->builtin) - { - mf_proctitle_format ("inetd %s", - prog->v.p.comp->builtin->service); - prog->v.p.comp->builtin->fun (prog->v.p.socket); - _exit (0); - } - - 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])); - logmsg_printf (LOG_DEBUG, "\n"); - } - + prog_start_prologue (prog); switch (prog->v.p.comp->mode) { case pies_comp_pass_fd: @@ -858,14 +918,9 @@ prog_start (struct prog *prog) FD_SET (prog->v.p.socket, &fdset); close_fds (&fdset); - execvp (prog->v.p.comp->program ? - prog->v.p.comp->program : prog->v.p.comp->argv[0], - prog->v.p.comp->argv); - openlog (log_tag, LOG_PID, prog->v.p.comp->facility); - syslog (LOG_CRIT, _("cannot start `%s': %s"), prog->tag, - strerror (errno)); - _exit (EX_SOFTWARE); - + prog_execute (prog); + + case -1: logmsg (LOG_CRIT, _("cannot run `%s': fork failed: %s"), @@ -1199,7 +1254,8 @@ progman_create_sockets () if (IS_COMPONENT (prog)) { struct component *comp = prog->v.p.comp; - if (comp->mode == pies_comp_inetd) + if (comp->mode == pies_comp_inetd + && !(comp->flags & (CF_TCPMUXPLUS | CF_TCPMUX))) { int fd = create_socket (comp->socket_url, comp->socket_type, |