diff options
-rw-r--r-- | src/inetd-bi.c | 38 | ||||
-rw-r--r-- | src/inetd.c | 66 | ||||
-rw-r--r-- | src/pies.c | 294 | ||||
-rw-r--r-- | src/pies.h | 28 | ||||
-rw-r--r-- | src/progman.c | 33 | ||||
-rw-r--r-- | src/url.c | 31 |
6 files changed, 318 insertions, 172 deletions
diff --git a/src/inetd-bi.c b/src/inetd-bi.c index 60e6fb5..30423de 100644 --- a/src/inetd-bi.c +++ b/src/inetd-bi.c @@ -21,7 +21,7 @@ /* Echo protocol, RFC 862 */ static void -echo_stream (int fd) +echo_stream (int fd, struct component const *comp) { int rc; char buffer[INTBUFSIZE]; @@ -32,7 +32,7 @@ echo_stream (int fd) } static void -echo_dg (int fd) +echo_dg (int fd, struct component const *comp) { int rc; char buffer[INTBUFSIZE]; @@ -47,7 +47,7 @@ echo_dg (int fd) /* Discard protocol, RFC 863 */ static void -discard_stream (int fd) +discard_stream (int fd, struct component const *comp) { int rc; char buffer[INTBUFSIZE]; @@ -62,7 +62,7 @@ discard_stream (int fd) } static void -discard_dg (int fd) +discard_dg (int fd, struct component const *comp) { char buffer[INTBUFSIZE]; read (fd, buffer, sizeof buffer); @@ -90,14 +90,14 @@ time_since_1900 (void) } static void -time_stream (int fd) +time_stream (int fd, struct component const *comp) { unsigned long result = time_since_1900 (); write (fd, (char *) &result, sizeof result); } static void -time_dg (int fd) +time_dg (int fd, struct component const *comp) { unsigned long result; struct sockaddr sa; @@ -111,7 +111,7 @@ time_dg (int fd) /* Daytime Protocol, RFC 867 */ static void -daytime_stream (int fd) +daytime_stream (int fd, struct component const *comp) { char buffer[27]; time_t now; @@ -122,7 +122,7 @@ daytime_stream (int fd) } static void -daytime_dg (int fd) +daytime_dg (int fd, struct component const *comp) { char buffer[27]; time_t now; @@ -160,7 +160,7 @@ chargen_next_line (char *text) } static void -chargen_stream (int fd) +chargen_stream (int fd, struct component const *comp) { char text[LINESIZ + 2]; @@ -176,7 +176,7 @@ chargen_stream (int fd) } static void -chargen_dg (int fd) +chargen_dg (int fd, struct component const *comp) { struct sockaddr sa; socklen_t size = sizeof sa; @@ -247,7 +247,7 @@ qotd_read (char *text) } static void -qotd_stream (int fd) +qotd_stream (int fd, struct component const *comp) { char text[QOTD_MAX]; size_t len = qotd_read (text); @@ -255,7 +255,7 @@ qotd_stream (int fd) } static void -qotd_dg (int fd) +qotd_dg (int fd, struct component const *comp) { char text[QOTD_MAX]; struct sockaddr sa; @@ -306,7 +306,7 @@ tcpmux_help (struct component *comp, void *data) { int *pfd = data; - if (comp->flags & (CF_TCPMUXPLUS | CF_TCPMUX)) + if (!(comp->flags & CF_DISABLED) && ISCF_TCPMUX (comp->flags)) { fd_write (*pfd, comp->service); fd_write (*pfd, "\r\n"); @@ -315,11 +315,11 @@ tcpmux_help (struct component *comp, void *data) } static void -tcpmux (int fd) +tcpmux (int fd, struct component const *comp) { char service[MAX_SERV_LEN + 1]; size_t len; - struct component *comp; + struct component *srv_comp; /* Read service name */ if ((len = fd_getline (fd, service, MAX_SERV_LEN)) < 0) @@ -337,17 +337,17 @@ tcpmux (int fd) return; } - comp = progman_lookup_service (service); - if (!comp) + srv_comp = progman_lookup_tcpmux (service, comp->tag); + if (!srv_comp) { fd_write (fd, "-Service not available\r\n"); return; } - if (comp->flags & CF_TCPMUXPLUS) + if (srv_comp->flags & CF_TCPMUXPLUS) fd_write (fd, "+Go\r\n"); - progman_run_comp (comp, fd); + progman_run_comp (srv_comp, fd); } diff --git a/src/inetd.c b/src/inetd.c index f356512..a43bdf2 100644 --- a/src/inetd.c +++ b/src/inetd.c @@ -39,6 +39,43 @@ listel_dispose(const void *el) #define TCPMUX_PREFIX_LEN (sizeof(TCPMUX_PREFIX_STR)-1) static int +tcpmux_service (const char *service, char **psrv, int *pflag) +{ + if (strncmp (service, TCPMUX_PREFIX_STR, TCPMUX_PREFIX_LEN) == 0) + { + service += TCPMUX_PREFIX_LEN; + if (*service == '+') + { + *pflag |= CF_TCPMUXPLUS; + service++; + } + else + *pflag |= CF_TCPMUX; + *psrv = (char *) service; + return 1; + } + return 0; +} + +static char * +mktag (const char *address, const char *service) +{ + char *str; + + if (address) + { + str = xmalloc (strlen (address) + 1 + strlen (service) + 1); + strcpy (str, address); + strcat (str, ":"); + strcat (str, service); + } + else + str = xstrdup (service); + return str; +} + + +static int inetd_conf_file (const char *file) { FILE *fp; @@ -141,17 +178,8 @@ inetd_conf_file (const char *file) tag = service; /* Handle eventual "tcpmux/" */ - if (strncmp (service, TCPMUX_PREFIX_STR, TCPMUX_PREFIX_LEN) == 0) + if (tcpmux_service (service, &service, &flags)) { - service += TCPMUX_PREFIX_LEN; - if (*service == '+') - { - flags |= CF_TCPMUXPLUS; - service++; - } - else - flags |= CF_TCPMUX; - if (strncmp (ws.ws_wordv[IFLD_PROTOCOL], "tcp", 3)) { logmsg (LOG_ERR, "%s:%lu: %s", @@ -224,7 +252,7 @@ inetd_conf_file (const char *file) if (!builtin) { logmsg (LOG_ERR, "%s:%lu: %s", - file, line_no, _("unknown built-in")); + file, line_no, _("unknown internal service")); continue; } } @@ -232,17 +260,9 @@ inetd_conf_file (const char *file) builtin = NULL; /* Create the component */ - if (address) - { - str = xmalloc (strlen (address) + 1 + strlen (tag) + 1); - strcpy (str, address); - strcat (str, ":"); - strcat (str, tag); - comp = component_create (str); - free (str); - } - else - comp = component_create (tag); + str = mktag (address, tag); + comp = component_create (str); + free (str); comp->mode = pies_comp_inetd; comp->socket_type = socket_type; @@ -255,6 +275,8 @@ inetd_conf_file (const char *file) } else comp->flags = flags; + if (ISCF_TCPMUX (comp->flags)) + comp->tcpmux = mktag (address, "tcpmux"); comp->service = xstrdup (service); comp->privs.user = xstrdup (user); /* FIXME: memory leak */ if (group) @@ -148,8 +148,8 @@ stderr_closed_p () (!(val) || ((val)->type == GRECS_TYPE_STRING && !(val)->v.string)) int -assert_grecs_value_type (grecs_locus_t * locus, - const grecs_value_t * value, int type) +assert_grecs_value_type (grecs_locus_t *locus, + const grecs_value_t *value, int type) { if (GRECS_VALUE_IS_EMPTY (value)) { @@ -168,7 +168,7 @@ assert_grecs_value_type (grecs_locus_t * locus, } int -assert_scalar_stmt (grecs_locus_t * locus, enum grecs_callback_command cmd) +assert_scalar_stmt (grecs_locus_t *locus, enum grecs_callback_command cmd) { if (cmd != grecs_callback_set_value) { @@ -181,8 +181,8 @@ assert_scalar_stmt (grecs_locus_t * locus, enum grecs_callback_command cmd) static int _cb_action (enum grecs_callback_command cmd, - grecs_locus_t * locus, - void *varptr, grecs_value_t * value, void *cb_data) + grecs_locus_t *locus, + void *varptr, grecs_value_t *value, void *cb_data) { enum return_action *pact = varptr; static struct tokendef actab[] = { @@ -317,8 +317,8 @@ static struct tokendef sig_tokendef[] = { static struct action * create_action (struct component *comp, - grecs_locus_t * locus, - grecs_value_t * val, int argc, + grecs_locus_t *locus, + grecs_value_t *val, int argc, const char *(*getarg) (grecs_value_t *, int, grecs_locus_t *)) { int i; @@ -399,7 +399,7 @@ create_action (struct component *comp, } const char * -_get_string_arg (grecs_value_t * val, int num, grecs_locus_t * locus) +_get_string_arg (grecs_value_t *val, int num, grecs_locus_t *locus) { if (num != 0) return NULL; @@ -407,7 +407,7 @@ _get_string_arg (grecs_value_t * val, int num, grecs_locus_t * locus) } const char * -_get_array_arg (grecs_value_t * val, int num, grecs_locus_t * locus) +_get_array_arg (grecs_value_t *val, int num, grecs_locus_t *locus) { if (num < val->v.arg.c) { @@ -419,7 +419,7 @@ _get_array_arg (grecs_value_t * val, int num, grecs_locus_t * locus) } const char * -_get_list_arg (grecs_value_t * val, int num, grecs_locus_t * locus) +_get_list_arg (grecs_value_t *val, int num, grecs_locus_t *locus) { grecs_value_t *elt = (grecs_value_t *) gl_list_get_at (val->v.list, num); if (!elt) @@ -433,9 +433,9 @@ _get_list_arg (grecs_value_t * val, int num, grecs_locus_t * locus) static int return_code_section_parser (enum grecs_callback_command cmd, - grecs_locus_t * locus, + grecs_locus_t *locus, void *varptr, - grecs_value_t * value, void *cb_data) + grecs_value_t *value, void *cb_data) { struct component *comp = varptr; size_t count; @@ -508,8 +508,8 @@ config_array_to_argv (grecs_value_t *val, grecs_locus_t *locus, size_t *pargc) static int _cb_command (enum grecs_callback_command cmd, - grecs_locus_t * locus, - void *varptr, grecs_value_t * value, void *cb_data) + grecs_locus_t *locus, + void *varptr, grecs_value_t *value, void *cb_data) { struct component *comp = varptr; struct wordsplit ws; @@ -539,8 +539,8 @@ _cb_command (enum grecs_callback_command cmd, static int _cb_umask (enum grecs_callback_command cmd, - grecs_locus_t * locus, - void *varptr, grecs_value_t * value, void *cb_data) + grecs_locus_t *locus, + void *varptr, grecs_value_t *value, void *cb_data) { mode_t *pmode = varptr; char *p; @@ -561,8 +561,8 @@ _cb_umask (enum grecs_callback_command cmd, static int _cb_env (enum grecs_callback_command cmd, - grecs_locus_t * locus, - void *varptr, grecs_value_t * value, void *cb_data) + grecs_locus_t *locus, + void *varptr, grecs_value_t *value, void *cb_data) { int argc; char **argv; @@ -646,8 +646,8 @@ string_to_syslog_facility (const char *key, int *pres) static int cb_syslog_facility (enum grecs_callback_command cmd, - grecs_locus_t * locus, - void *varptr, grecs_value_t * value, void *cb_data) + grecs_locus_t *locus, + void *varptr, grecs_value_t *value, void *cb_data) { const char *str; @@ -671,8 +671,8 @@ cb_syslog_facility (enum grecs_callback_command cmd, static int _cb_redir (enum grecs_callback_command cmd, - grecs_locus_t * locus, - void *varptr, grecs_value_t * value, void *cb_data) + grecs_locus_t *locus, + void *varptr, grecs_value_t *value, void *cb_data) { struct redirector *rp = varptr; static struct tokendef redirtab[] = { @@ -754,8 +754,8 @@ _cb_redir (enum grecs_callback_command cmd, static int _cb_url (enum grecs_callback_command cmd, - grecs_locus_t * locus, - void *varptr, grecs_value_t * value, void *cb_data) + grecs_locus_t *locus, + void *varptr, grecs_value_t *value, void *cb_data) { struct pies_url *url; @@ -817,8 +817,8 @@ static struct tokendef modetab[] = { static int _cb_mode (enum grecs_callback_command cmd, - grecs_locus_t * locus, - void *varptr, grecs_value_t * value, void *cb_data) + grecs_locus_t *locus, + void *varptr, grecs_value_t *value, void *cb_data) { int res; @@ -834,8 +834,8 @@ _cb_mode (enum grecs_callback_command cmd, static int _cb_limits (enum grecs_callback_command cmd, - grecs_locus_t * locus, - void *varptr, grecs_value_t * value, void *cb_data) + grecs_locus_t *locus, + void *varptr, grecs_value_t *value, void *cb_data) { limits_record_t *plrec = varptr; char *p; @@ -848,49 +848,86 @@ _cb_limits (enum grecs_callback_command cmd, return 0; } -static int -_cb_bitmask (enum grecs_callback_command cmd, - grecs_locus_t *locus, - int *fptr, grecs_value_t *value, int mask) +int +str_to_cf (const char *string, int *flags) { - int arg; + size_t len = strlen (string); + int neg = 0; + int mask; - if (assert_scalar_stmt (locus, cmd) - || assert_grecs_value_type (locus, value, GRECS_TYPE_STRING) - || grecs_string_convert (&arg, grecs_type_bool, value->v.string, - locus)) + if (len > 2 && memcmp (string, "no", 2) == 0) + { + neg++; + string += 2; + } + + if (strcmp (string, "disable") == 0) + mask = CF_DISABLED; + else if (strcmp (string, "precious") == 0) + mask = CF_PRECIOUS; + else if (strcmp (string, "wait") == 0) + mask = CF_WAIT; + else if (strcmp (string, "tcpmux") == 0) + mask = CF_TCPMUX; + else if (strcmp (string, "tcpmuxplus") == 0) + mask = CF_TCPMUXPLUS; + else if (strcmp (string, "internal") == 0) + mask = CF_INTERNAL; + else return 1; - if (arg) - *fptr |= mask; + + if (neg) + *flags &= ~mask; else - *fptr &= ~mask; + *flags |= mask; return 0; } static int -_cb_precious (enum grecs_callback_command cmd, - grecs_locus_t *locus, - void *varptr, grecs_value_t *value, void *cb_data) +_cb_flags (enum grecs_callback_command cmd, + grecs_locus_t *locus, + void *varptr, grecs_value_t *value, void *cb_data) { - return _cb_bitmask (cmd, locus, varptr, value, CF_PRECIOUS); -} + int *flags = varptr; + + switch (value->type) + { + case GRECS_TYPE_STRING: + if (str_to_cf (value->v.string, flags)) + { + grecs_error (locus, 0, _("%s: unrecognised flag"), value->v.string); + return 1; + } + break; -static int -_cb_disabled (enum grecs_callback_command cmd, - grecs_locus_t *locus, - void *varptr, grecs_value_t *value, void *cb_data) -{ - return _cb_bitmask (cmd, locus, varptr, value, CF_DISABLED); -} + case GRECS_TYPE_LIST: + { + const void *p; + gl_list_iterator_t itr = gl_list_iterator (value->v.list); + + while (gl_list_iterator_next (&itr, &p, NULL)) + { + const grecs_value_t *vp = p; + if (assert_grecs_value_type (locus, vp, GRECS_TYPE_STRING)) + return 1; + if (str_to_cf (vp->v.string, flags)) + { + grecs_error (locus, 0, _("%s: unrecognised flag"), + vp->v.string); + return 1; + } + } + } + break; -static int -_cb_wait (enum grecs_callback_command cmd, - grecs_locus_t *locus, - void *varptr, grecs_value_t *value, void *cb_data) -{ - return _cb_bitmask (cmd, locus, varptr, value, CF_WAIT); + case GRECS_TYPE_ARRAY: + grecs_error (locus, 0, _("too many arguments")); + return 1; + } + return 0; } + struct grecs_keyword component_keywords[] = { {"mode", /* TRANSLATORS: The words between '{' and '}' are keywords, do not @@ -926,6 +963,11 @@ struct grecs_keyword component_keywords[] = { grecs_type_string | GRECS_LIST, NULL, offsetof (struct component, depend), NULL, }, + {"flags", + N_("list"), + N_("List of flags."), + grecs_type_string | GRECS_LIST, NULL, offsetof (struct component, flags), + _cb_flags }, {"pass-fd-timeout", NULL, N_("Time to wait for pass-fd socket to become available."), @@ -933,26 +975,6 @@ struct grecs_keyword component_keywords[] = { offsetof (struct component, pass_fd_timeout), NULL, }, - {"disable", - NULL, - N_("Disable this entry."), - grecs_type_bool, NULL, offsetof (struct component, flags), - _cb_disabled, - }, - {"precious", - NULL, - N_("Mark this entry as precious."), - grecs_type_bool, NULL, - offsetof (struct component, flags), - _cb_precious, - }, - {"wait", - NULL, - N_("Wait for the server program to return."), - grecs_type_bool, NULL, - offsetof (struct component, flags), - _cb_wait, - }, {"max-instances", NULL, N_("Maximum number of running instances."), @@ -973,6 +995,7 @@ struct grecs_keyword component_keywords[] = { _cb_url, }, {"socket-type", + /* TRANSLATORS: words after `type:' are keywords. */ N_("type: stream | dgram | raw | rdm | seqpacket"), N_("Set socket type."), grecs_type_int, NULL, @@ -1067,6 +1090,16 @@ struct grecs_keyword component_keywords[] = { N_("Define what to do when the component finishes."), grecs_type_section, NULL, 0, return_code_section_parser, NULL, return_code_keywords}, + {"service", + N_("name"), + N_("Service name for inetd component."), + grecs_type_string, NULL, offsetof (struct component, service), + NULL }, + {"tcpmux-master", + N_("tag"), + N_("Tag of master TCPMUX component."), + grecs_type_string, NULL, offsetof (struct component, tcpmux), + NULL }, {NULL} }; @@ -1101,32 +1134,71 @@ component_verify (struct component *comp, grecs_locus_t *locus) { int header = 0; int i; -#define COMPERR(fmt, arg) \ +#define COMPERR(func, fmt, arg) \ do \ { \ if (!header) \ { \ - grecs_error (locus, 0, _("in component %s:"), comp->tag); \ + grecs_warning (locus, 0, _("in component %s:"), comp->tag); \ header = 1; \ } \ - grecs_error (locus, 0, fmt, arg); \ + func (locus, 0, fmt, arg); \ } \ while (0) - if (!comp->argv) - COMPERR ("%s", _("missing command line")); + if (comp->flags & CF_INTERNAL) + { + comp->mode = pies_comp_inetd; + if (!comp->service) + /* TRANSLATORS: do not translate quoted words, they are keywords. */ + COMPERR (grecs_error, + "%s", _("`internal' used without `service'")); + else + { + comp->builtin = inetd_builtin_lookup (comp->service, + comp->socket_type); + if (!comp->builtin) + COMPERR (grecs_error, + "%s", _("unknown internal service")); + if (comp->argv) + /* TRANSLATORS: do not translate quoted words, they are + keywords. */ + COMPERR (grecs_error, + "%s", _("`internal' used with `command'")); + } + } + else if (!comp->argv) + COMPERR (grecs_error, + "%s", _("missing command line")); + + if (ISCF_TCPMUX (comp->flags)) + { + comp->mode = pies_comp_inetd; + if ((comp->flags & (CF_TCPMUX | CF_TCPMUXPLUS)) + == (CF_TCPMUX | CF_TCPMUXPLUS)) + COMPERR (grecs_error, + "%s", _("both `tcpmux' and `tcpmuxplus' used")); + else if (!comp->service) + /* TRANSLATORS: do not translate quoted words, they are keywords. */ + COMPERR (grecs_error, + "%s", _("`internal' used without `service'")); + } + if (comp->pass_fd_socket && comp->mode != pies_comp_pass_fd) - COMPERR ("%s", _("pass-fd-socket ignored: wrong mode")); + COMPERR (grecs_error, + "%s", _("pass-fd-socket ignored: wrong mode")); switch (comp->mode) { case pies_comp_exec: if (comp->socket_url) - COMPERR ("%s", _("socket ignored: wrong mode")); + COMPERR (grecs_error, + "%s", _("socket ignored: wrong mode")); break; case pies_comp_pass_fd: if (!comp->pass_fd_socket) - COMPERR ("%s", _("must supply pass-fd-socket in this mode")); + COMPERR (grecs_error, + "%s", _("must supply pass-fd-socket in this mode")); else if (comp->pass_fd_socket[0] != '/') { if (comp->dir) @@ -1136,16 +1208,43 @@ component_verify (struct component *comp, grecs_locus_t *locus) comp->pass_fd_socket = p; } else - COMPERR ("%s", _("pass-fd-socket must be an absolute " + COMPERR (grecs_error, + "%s", _("pass-fd-socket must be an absolute " "file name or chdir must be specified")); } /* Fall through */ case pies_comp_accept: - case pies_comp_inetd: if (!comp->socket_url) { - COMPERR ("%s", _("socket must be specified in this mode")); + COMPERR (grecs_error, + "%s", _("socket must be specified in this mode")); + /* FIXME: Memory leak */ + return 1; + } + break; + + case pies_comp_inetd: + if (ISCF_TCPMUX (comp->flags)) + { + pies_url_destroy (&comp->socket_url); + if (!comp->tcpmux) + { + COMPERR (grecs_warning, + "%s", + _("TCPMUX master not specified, assuming \"tcpmux\"")); + comp->tcpmux = xstrdup ("tcpmux"); + } + } + else if (comp->tcpmux) + { + comp->flags |= CF_TCPMUX; + pies_url_destroy (&comp->socket_url); + } + else if (!comp->socket_url) + { + COMPERR (grecs_error, + "%s", _("socket must be specified in this mode")); /* FIXME: Memory leak */ return 1; } @@ -1156,21 +1255,23 @@ component_verify (struct component *comp, grecs_locus_t *locus) if ((comp->flags & CF_WAIT) && comp->socket_type == SOCK_STREAM) { if (comp->max_instances) - COMPERR ("%s", _("max-instances ignored")); + COMPERR (grecs_error, "%s", _("max-instances ignored")); else comp->max_instances = 1; } } else if (comp->flags & CF_WAIT) { - COMPERR ("%s", _("wait is useless in this mode")); + /* TRANSLATORS: `wait' is a keywords, do not translate. */ + COMPERR (grecs_error, "%s", _("wait is useless in this mode")); comp->flags &= ~CF_WAIT; } if (comp->mode != pies_comp_exec && comp->redir[RETR_OUT].type != redir_null) { - COMPERR ("%s", _("stdout translation invalid in this mode")); + COMPERR (grecs_error, + "%s", _("stdout translation invalid in this mode")); comp->redir[RETR_OUT].type = redir_null; } @@ -1186,7 +1287,8 @@ component_verify (struct component *comp, grecs_locus_t *locus) comp->redir[i].v.file = p; } else - COMPERR (_("%s: must be an absolute " + COMPERR (grecs_error, + _("%s: must be an absolute " "file name or chdir must be specified"), comp->redir[i].v.file); } @@ -1225,8 +1327,8 @@ component_finish (struct component *comp, grecs_locus_t *locus) static int component_section_parser (enum grecs_callback_command cmd, - grecs_locus_t * locus, - void *varptr, grecs_value_t * value, void *cb_data) + grecs_locus_t *locus, + void *varptr, grecs_value_t *value, void *cb_data) { struct component *comp; void **section_data = cb_data; @@ -1758,7 +1860,7 @@ enum pies_status }; enum pies_status -pies_check_status (pid_t * ppid) +pies_check_status (pid_t *ppid) { pid_t pid = pidfile_read (0); int i; @@ -142,6 +142,9 @@ enum pies_comp_mode #define CF_WAIT 0x04 #define CF_TCPMUX 0x08 #define CF_TCPMUXPLUS 0x10 +#define CF_INTERNAL 0x20 + +#define ISCF_TCPMUX(f) ((f) & (CF_TCPMUX | CF_TCPMUXPLUS)) struct component { @@ -156,23 +159,26 @@ struct component gl_list_t depend; /* Dependency targets */ int flags; /* CF_ bitmask */ size_t max_instances; /* Maximum number of simultaneously running - instances (inetd) */ - size_t max_rate; /* Maximum number of invocations per minute - (inetd) */ - int socket_type; /* Socket type */ - struct inetd_builtin *builtin; /* Builtin function (inetd) */ - char *service; + instances */ char *rmfile; /* Try to remove this file before starting */ struct pies_privs privs; /* UID/GIDS+groups to run under */ mode_t umask; /* Umask to install before starting */ limits_record_t limits; /* System limits */ + + /* For inetd components */ + size_t max_rate; /* Maximum number of invocations per minute */ + int socket_type; /* Socket type */ + struct inetd_builtin *builtin; /* Builtin function */ + char *service; + struct pies_url *socket_url; /* Socket to listen on (if mode != pies_comp_exec) */ - char *pass_fd_socket; /* Socket to pass fd on - (if mode == pies_comp_pass_fd) */ + char *pass_fd_socket; /* Socket to pass fd on + (if mode == pies_comp_pass_fd) */ unsigned pass_fd_timeout; /* Maximum time to wait for pass_fd socket to become available. */ pies_acl_t acl; + char *tcpmux; /* Master service for TCPMUX */ /* Redirectors: */ int facility; /* Syslog facility. */ struct redirector redir[2]; /* Repeaters for stdout and stderr */ @@ -208,7 +214,9 @@ int progman_accept (int socket); int progman_build_depmap (void); void progman_create_sockets (void); struct component *progman_lookup_component (const char *tag); -struct component *progman_lookup_service (const char *service); +struct component *progman_lookup_tcpmux (const char *service, + const char *master); + void progman_run_comp (struct component *comp, int fd); void progman_iterate_comp (int (*fun) (struct component *, void *), @@ -353,7 +361,7 @@ struct inetd_builtin int socktype; int single_process; int flags; - void (*fun) (int); + void (*fun) (int, struct component const *); }; struct inetd_builtin *inetd_builtin_lookup (const char *service, int socktype); diff --git a/src/progman.c b/src/progman.c index 89be1f5..4743507 100644 --- a/src/progman.c +++ b/src/progman.c @@ -146,12 +146,19 @@ progman_lookup_component (const char *tag) } struct component * -progman_lookup_service (const char *service) +progman_lookup_tcpmux (const char *service, const char *master) { - struct prog *prog = prog_lookup_by_service (service); - if (!prog) - return NULL; - return prog->v.p.comp; + struct prog *prog; + for (prog = proghead; prog; prog = prog->next) + if (IS_COMPONENT (prog) + && ISCF_TCPMUX (prog->v.p.comp->flags) + && !(prog->v.p.comp->flags & CF_DISABLED) + && prog->v.p.comp->service + && strcmp (prog->v.p.comp->service, service) == 0 + && prog->v.p.comp->tcpmux + && strcmp (prog->v.p.comp->tcpmux, master) == 0) + return prog->v.p.comp; + return NULL; } struct prog * @@ -775,7 +782,7 @@ prog_execute (struct prog *prog) { mf_proctitle_format ("inetd %s", prog->v.p.comp->builtin->service); - prog->v.p.comp->builtin->fun (0); + prog->v.p.comp->builtin->fun (0, prog->v.p.comp); _exit (0); } @@ -862,7 +869,7 @@ prog_start (struct prog *prog) if (prog->v.p.comp->builtin && prog->v.p.comp->builtin->single_process) { - prog->v.p.comp->builtin->fun (prog->v.p.socket); + prog->v.p.comp->builtin->fun (prog->v.p.socket, prog->v.p.comp); return; } @@ -1254,8 +1261,7 @@ progman_create_sockets () if (IS_COMPONENT (prog)) { struct component *comp = prog->v.p.comp; - if (comp->mode == pies_comp_inetd - && !(comp->flags & (CF_TCPMUXPLUS | CF_TCPMUX))) + if (comp->mode == pies_comp_inetd && !ISCF_TCPMUX (comp->flags)) { int fd = create_socket (comp->socket_url, comp->socket_type, @@ -1324,8 +1330,13 @@ progman_start () { if (prog->v.p.comp->mode == pies_comp_inetd) { - prog->v.p.status = status_listener; - enable_socket (prog->v.p.socket); + if (prog->v.p.comp->flags & CF_DISABLED) + disable_socket (prog->v.p.socket); + else + { + prog->v.p.status = status_listener; + enable_socket (prog->v.p.socket); + } } else if ((prog->v.p.status == status_enabled && prog->pid == 0) || prog->v.p.status == status_sleeping) @@ -205,21 +205,24 @@ void pies_url_destroy (struct pies_url **purl) { int i; - struct pies_url *url = *purl; + if (purl && *purl) + { + struct pies_url *url = *purl; - free (url->string); - free (url->scheme); - free (url->host); - free (url->port_s); - free (url->proto_s); - free (url->path); - free (url->user); - free (url->passwd); - for (i = 0; i < url->argc; i++) - free (url->argv[i]); - free (url->argv); - free (url); - *purl = NULL; + free (url->string); + free (url->scheme); + free (url->host); + free (url->port_s); + free (url->proto_s); + free (url->path); + free (url->user); + free (url->passwd); + for (i = 0; i < url->argc; i++) + free (url->argv[i]); + free (url->argv); + free (url); + *purl = NULL; + } } int |