aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-11-26 21:49:15 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2009-11-26 21:49:15 +0200
commit9de9182e3517c677e2309b0dd58ab4e3af1b3176 (patch)
treea8d2f33ee720591be9212b9cc6a33a5b018f60bd
parentc0802ebe4ebd7e7bb173c6efa2c6e59dd5440cc3 (diff)
downloadpies-9de9182e3517c677e2309b0dd58ab4e3af1b3176.tar.gz
pies-9de9182e3517c677e2309b0dd58ab4e3af1b3176.tar.bz2
Implement internal inetd services in the pies config.
* src/pies.h (CF_INTERNAL): New flag. (ISCF_TCPMUX): New macro. (struct component): Reorder fields. New field: tcpmux. (progman_lookup_service): Remove proto. (progman_lookup_tcpmux): New proto. (struct inetd_builtin.foo): Change signature. All uses updated. * src/progman.c (progman_lookup_service): Remove. (progman_lookup_tcpmux): New function. (progman_create_sockets): Skip tcpmux subservices. (progman_start): Skip disabled inetd components. * src/inetd-bi.c (tcpmux): Use progman_lookup_tcpmux. * src/inetd.c (tcpmux_service, mktag): New functions. (inetd_conf_file): Minor changes. * src/pies.c (_cb_bitmask, _cb_precious) (_cb_disabled, _cb_wait): Remove. (str_to_cf, _cb_flags): New functions. (component_keywords): Remove keywords: disable, precious, wait. Add keywords: flags, service, tcpmux-master. (component_verify): Improve. * src/url.c (pies_url_destroy): Fix coredump on NULL argument.
-rw-r--r--src/inetd-bi.c38
-rw-r--r--src/inetd.c66
-rw-r--r--src/pies.c294
-rw-r--r--src/pies.h28
-rw-r--r--src/progman.c33
-rw-r--r--src/url.c31
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)
diff --git a/src/pies.c b/src/pies.c
index 721c808..a09b984 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -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;
diff --git a/src/pies.h b/src/pies.h
index 9ec1410..4d2f774 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -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)
diff --git a/src/url.c b/src/url.c
index be74974..6bc28ad 100644
--- a/src/url.c
+++ b/src/url.c
@@ -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

Return to:

Send suggestions and report system problems to the System administrator.