aboutsummaryrefslogtreecommitdiff
path: root/src/pies.c
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 /src/pies.c
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.
Diffstat (limited to 'src/pies.c')
-rw-r--r--src/pies.c294
1 files changed, 198 insertions, 96 deletions
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;

Return to:

Send suggestions and report system problems to the System administrator.