aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-05-24 12:45:25 +0300
committerSergey Poznyakoff <gray@gnu.org>2019-05-24 13:50:39 +0300
commit6dd0ec08db301984b8f8f9082f28006d5915c183 (patch)
treee916ad37fbd3cbcaf85103667f28e0d47f3c2e45
parent2a646ee7cbbcb6f4bbd8f38bb3c1e1418550f3fc (diff)
downloadpies-6dd0ec08db301984b8f8f9082f28006d5915c183.tar.gz
pies-6dd0ec08db301984b8f8f9082f28006d5915c183.tar.bz2
Initial implementation of "startup" components.
These are components that are run at program startup. Starting other components is delayed until all startup components terminate. This is similar to SysV "bootwait" components. Upon termination, startup components are removed from the configuration. They are not renewed upon configuratuion reload. * src/comp.c (comp_array_remove): Remove from the depmap as well. (component_ref_decr): Use comp_array_remove for active components and plain component_free for inactive ones. (component_build_depmap): Use comp_array_remove. (component_config_commit): Special handling for pies_comp_startup components. * src/pies.c (modetab): New component modes: "startup" and "shutdown". (main): Run program_init_startup. * src/pies.h (pies_comp_mode): New modes: pies_comp_startup and pies_comp_shutdown. (program_init_startup): New proto. * src/progman.c (progman_waiting_p): Return 1 if a startup component is still running. (program_init_startup): New function. (progman_cleanup): Handle pies_comp_startup termination. * src/socket.c (switch_eids): Avoid unnecessary calls to setegid and seteuid. * tests/atlocal.in (auxdir): New variable. * tests/mailer: Move to tests/aux/ * tests/respawn: Move to tests/aux/ * tests/retcode: Move to tests/aux/ * tests/aux/startup: New auxiliary program. * tests/redirect.at: Start components from $auxdir. * tests/respawn.at: Likewise. * tests/ret-exec.at: Likewise. * tests/ret-notify.at: Likewise. * tests/startup.at: New file. * tests/testsuite.at: Include startup.at * tests/Makefile.am: Add new tests.
-rw-r--r--src/comp.c87
-rw-r--r--src/pies.c115
-rw-r--r--src/pies.h38
-rw-r--r--src/progman.c291
-rw-r--r--src/socket.c54
-rw-r--r--tests/Makefile.am9
-rw-r--r--tests/atlocal.in2
-rwxr-xr-xtests/aux/mailer (renamed from tests/mailer)0
-rwxr-xr-xtests/aux/respawn (renamed from tests/respawn)0
-rwxr-xr-xtests/aux/retcode (renamed from tests/retcode)0
-rwxr-xr-xtests/aux/startup7
-rw-r--r--tests/redirect.at2
-rw-r--r--tests/respawn.at2
-rw-r--r--tests/ret-exec.at4
-rw-r--r--tests/ret-notify.at6
-rw-r--r--tests/startup.at84
-rw-r--r--tests/testsuite.at1
17 files changed, 442 insertions, 260 deletions
diff --git a/src/comp.c b/src/comp.c
index c3e998a..2346306 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -15,39 +15,44 @@
along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */
#include "pies.h"
#include "prog.h"
#include <assert.h>
struct complist
{
struct component *head;
struct component *tail;
};
+/* 0 on the first load, and 1 on all subsequent reloads. Tells the
+ component_config_commit whether we're starting from scratch or just
+ updating an already loaded configuration */
+static int loaded;
+
static struct complist comp_list[2];
static int cur;
static struct component **comp_array;
static size_t comp_count;
static pies_depmap_t depmap;
-static int
+static inline int
next_index (void)
{
return (cur + 1) % ARRAY_SIZE (comp_list);
}
-static int
+static inline int
prev_index (void)
{
return (cur + ARRAY_SIZE (comp_list) - 1) % ARRAY_SIZE (comp_list);
}
void
component_link (struct component *comp, struct component *ref)
{
if (!ref)
{
struct complist *list = &comp_list[comp->listidx];
@@ -76,24 +81,40 @@ component_link (struct component *comp, struct component *ref)
ref->next = comp;
}
}
void
component_append (struct component *comp)
{
component_link (comp, comp_list[comp->listidx].tail);
}
void
+comp_array_remove (size_t i)
+{
+ struct component *comp = comp_array[i];
+
+ depmap_remove (depmap, i);
+ while (i < comp_count -1)
+ {
+ comp_array[i] = comp_array[i+1];
+ comp_array[i]->arridx = i;
+ i++;
+ }
+ component_free (comp);
+ comp_count--;
+}
+
+void
component_unlink (struct component *comp)
{
struct complist *list = &comp_list[comp->listidx];
struct component *x;
if ((x = comp->prev))
x->next = comp->next;
else
list->head = comp->next;
if ((x = comp->next))
x->prev = comp->prev;
else
@@ -192,25 +213,30 @@ component_free (struct component *comp)
void
component_ref_incr (struct component *comp)
{
++comp->ref_count;
}
void
component_ref_decr (struct component *comp)
{
assert (comp->ref_count > 0);
if (--comp->ref_count == 0)
- component_free (comp);
+ {
+ if (component_is_active (comp))
+ comp_array_remove (comp->arridx);
+ else
+ component_free (comp);
+ }
}
static int
argvcmp (char **a, char **b)
{
size_t i;
if (!a != !b)
return 1;
for (i = 0; a[i]; i++)
if (!b[i] || strcmp (b[i], a[i]))
@@ -416,60 +442,48 @@ report_cyclic_dependency (pies_depmap_t dp, size_t idx)
}
depmap_end (pos);
if (n == (size_t)-1)
break;
i = n;
}
while (i != idx);
logmsg_printf (LOG_NOTICE, "%s\n", comp_array[idx]->tag);
}
void
-comp_array_remove (size_t i)
-{
- struct component *comp = comp_array[i];
- if (i < comp_count - 1)
- memmove (&comp_array[i], &comp_array[i+1],
- (comp_count - i - 1) * sizeof comp_array[0]);
- component_free (comp);
- comp_count--;
-}
-
-void
component_build_depmap (void)
{
size_t i;
pies_depmap_t dp;
free (depmap);
depmap = depmap_alloc (comp_count);
for (i = 0; i < comp_count; )
{
struct component *comp = comp_array[i];
struct grecs_list_entry *ep;
if (comp->prereq)
for (ep = comp->prereq->head; ep; ep = ep->next)
{
char const *tag = ep->data;
ssize_t tgt = component_lookup_index (tag);
if (tgt < 0)
{
logmsg (LOG_ERR,
_("component %s depends on %s, "
"which is not declared"),
comp->tag, tag);
comp_array_remove (i);
- depmap_remove (depmap, i);
continue;
}
depmap_set (depmap, i, tgt);
}
if (comp->depend)
for (ep = comp->depend->head; ep; ep = ep->next)
{
char const *tag = ep->data;
ssize_t tgt = component_lookup_index (tag);
if (tgt < 0)
{
@@ -488,28 +502,25 @@ component_build_depmap (void)
depmap_tc (dp);
for (i = 0; i < comp_count; i++)
if (!(comp_array[i]->flags & CF_REMOVE) && depmap_isset (dp, i, i))
{
logmsg (LOG_ERR, _("component %s depends on itself"),
comp_array[i]->tag);
report_cyclic_dependency (dp, i);
}
for (i = 0; i < comp_count;)
if (comp_array[i]->flags & CF_REMOVE)
- {
- comp_array_remove (i);
- depmap_remove (depmap, i);
- }
+ comp_array_remove (i);
else
i++;
free (dp);
}
void
component_config_commit (void)
{
struct complist *list = &comp_list[cur];
struct component *comp, *match;
int prev = prev_index ();
@@ -519,56 +530,72 @@ component_config_commit (void)
for (comp = list->head, i = 0; comp; comp = comp->next, i++)
/* nothing */;
if (i == 0)
{
free (comp_array);
comp_array = NULL;
}
else
comp_array = grecs_realloc (comp_array, i * sizeof (comp_array[0]));
comp_count = i;
- /* Rearrange components, registering prog entries for the new ones */
- for (comp = list->head, i = 0; comp; comp = comp->next, i++)
+ /* Rearrange components, registering entries for the new ones */
+ for (comp = list->head, i = 0; comp; )
{
- match = complist_find_match (prev, comp);
- if (match)
+ struct component *next = comp->next;
+ if (loaded && comp->mode == pies_comp_startup)
{
- component_merge (match, comp);
- component_unlink (match);
- match->listidx = cur;
- component_link (match, comp->prev);
+ /* Ignore startup components */
+ component_unlink (comp);
component_free (comp);
- comp = match;
}
- comp_array[i] = comp;
- comp->arridx = i;
+ else
+ {
+ match = complist_find_match (prev, comp);
+ if (match)
+ {
+ component_merge (match, comp);
+ component_unlink (match);
+ match->listidx = cur;
+ component_link (match, comp->prev);
+ component_free (comp);
+ comp = match;
+ }
+ comp_array[i] = comp;
+ comp->arridx = i;
+ i++;
+ }
+ comp = next;
}
+ /* Adjust comp_count */
+ comp_count = i;
/* Mark orphaned progs for termination */
list = &comp_list[prev];
if (list->head)
{
progman_foreach (mark_prog, NULL);
pies_schedule_children (PIES_CHLD_GC);
}
/* Build dependency map */
component_build_depmap ();
/* Register new progs */
for (comp = comp_list[cur].head; comp; comp = comp->next)
if (!comp->prog)
register_prog (comp);
+
+ loaded = 1;
}
static int
component_verify (struct component *comp, grecs_locus_t *locus)
{
int header = 0;
int i;
#define COMPERR(func, fmt, arg) \
do \
{ \
if (!header) \
{ \
diff --git a/src/pies.c b/src/pies.c
index 89c0b7e..98488a6 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -123,49 +123,49 @@ config_file_add (struct config_syntax *syntax, const char *name)
}
void
config_file_add_type (enum config_syntax_type syntax, const char *name)
{
config_file_add (&config_syntax_tab[syntax], name);
}
int
config_file_remove (const char *name)
{
struct grecs_list_entry *ep;
-
+
for (ep = config_list->head; ep; ep = ep->next)
{
struct config_file *file = ep->data;
if (strcmp (file->name, name) == 0)
{
grecs_list_remove_entry (config_list, ep);
config_file_free (file);
return 0;
}
}
return 1;
}
void
config_file_remove_all (void)
{
grecs_list_clear (config_list);
}
void
config_file_list_serialize (struct json_value *ar)
{
struct grecs_list_entry *ep;
-
+
for (ep = config_list->head; ep; ep = ep->next)
{
struct config_file *file = ep->data;
struct json_value *obj = json_new_object ();
json_object_set (obj, "syntax", json_new_string (file->syntax->name));
json_object_set (obj, "file", json_new_string (file->name));
json_array_append (ar, obj);
}
}
/* Logging */
static int
@@ -318,25 +318,25 @@ static struct tokendef sig_tokendef[] = {
#undef S
void
action_free (struct action *act)
{
if (!act)
return;
if (act->nstat > 0)
free (act->status);
free (act->addr);
free (act->message);
free (act->command);
-
+
free (act);
}
static void
free_entry_action (void *act)
{
action_free (act);
}
static struct action *
create_action (struct component *comp,
grecs_locus_t *locus,
@@ -350,25 +350,25 @@ create_action (struct component *comp,
struct action *act;
retv = grecs_calloc (argc, sizeof *retv);
if (argc == 0 || (argc == 1 && strcmp (getarg (val, 0, locus), "*") == 0))
allflag = 1;
else
{
for (i = 0; i < argc; i++)
{
unsigned n;
const char *arg = getarg (val, i, locus);
size_t len = strlen (arg);
-
+
if (isdigit (arg[0]))
{
char *p;
n = strtoul (arg, &p, 0);
if (*p)
{
grecs_error (locus, 0, _("%s: not a number"), p);
continue;
}
}
else if (len > 3 && memcmp (arg, "SIG", 3) == 0)
{
@@ -385,30 +385,30 @@ create_action (struct component *comp,
else if (strtotok_ci (sig_tokendef, arg, (int*) &n))
{
grecs_error (locus, 0, _("%s: not a signal code"), arg);
continue;
}
n |= STATUS_SIG_BIT;
}
else if (strtotok_ci (ex_tokendef, arg, (int *) &n))
{
grecs_error (locus, 0, _("%s: not a return code"), arg);
continue;
}
-
+
/* Alles in ordnung */
retv[retc++] = n;
}
}
-
+
if (retc == 0 && !allflag)
{
free (retv);
return NULL;
}
act = grecs_zalloc (sizeof *act);
if (!allflag)
{
act->nstat = retc;
act->status = retv;
}
@@ -463,45 +463,45 @@ return_code_section_parser (enum grecs_callback_command cmd,
struct component *comp = varptr;
size_t count;
struct action *act;
switch (cmd)
{
case grecs_callback_section_begin:
if (GRECS_VALUE_EMPTY_P (value))
{
grecs_error (locus, 0, _("missing tag"));
return 1;
}
-
+
switch (value->type)
{
case GRECS_TYPE_STRING:
act = create_action (comp, locus, value, 1, _get_string_arg);
break;
-
+
case GRECS_TYPE_ARRAY:
act = create_action (comp, locus, value,
value->v.arg.c, _get_array_arg);
break;
-
+
case GRECS_TYPE_LIST:
count = grecs_list_size (value->v.list);
act = create_action (comp, locus, value, count, _get_list_arg);
}
if (!act)
return 1;
*(struct action **) cb_data = act;
break;
-
+
case grecs_callback_section_end:
break;
case grecs_callback_set_value:
grecs_error (locus, 0, _("invalid use of block statement"));
}
return 0;
}
static char **
config_array_to_argv (grecs_value_t *val, grecs_locus_t *locus, size_t *pargc)
{
@@ -533,25 +533,25 @@ _cb_command (enum grecs_callback_command cmd,
switch (value->type)
{
case GRECS_TYPE_STRING:
if (wordsplit (value->v.string, &ws, WRDSF_DEFFLAGS))
{
grecs_error (locus, 0, "wordsplit: %s", strerror (errno));
return 1;
}
wordsplit_get_words (&ws, &comp->argc, &comp->argv);
wordsplit_free (&ws);
break;
-
+
case GRECS_TYPE_ARRAY:
comp->argv = config_array_to_argv (value, locus, &comp->argc);
break;
case GRECS_TYPE_LIST:
grecs_error (locus, 0, _("unexpected list"));
return 1;
}
return 0;
}
static int
@@ -693,97 +693,97 @@ static int
_cb_redir (enum grecs_callback_command cmd,
grecs_locus_t *locus,
void *varptr, grecs_value_t *value, void *cb_data)
{
struct redirector *rp = varptr;
static struct tokendef redirtab[] = {
{"null", redir_null},
{"syslog", redir_syslog},
{"file", redir_file},
{NULL}
};
int res;
-
+
switch (value->type)
{
case GRECS_TYPE_STRING:
if (strcmp (value->v.string, "null") == 0)
{
rp->type = redir_null;
break;
}
rp->type = redir_syslog;
if (string_to_syslog_priority (value->v.string, &rp->v.prio))
{
grecs_error (locus, 0, _("unknown syslog priority %s"),
value->v.string);
return 0;
}
break;
-
+
case GRECS_TYPE_ARRAY:
if (assert_grecs_value_type (locus, value->v.arg.v[0],
GRECS_TYPE_STRING))
return 0;
if (strtotok (redirtab, value->v.arg.v[0]->v.string, &res))
grecs_error (locus, 0, _("%s: unrecognised redirector type"),
value->v.arg.v[0]->v.string);
else
{
if (res != redir_null)
{
if (value->v.arg.c != 2)
{
grecs_error (locus, 0, _("wrong number of arguments"));
return 0;
}
if (assert_grecs_value_type (locus, value->v.arg.v[1],
GRECS_TYPE_STRING))
return 0;
-
+
switch (res)
{
case redir_null:
break;
-
+
case redir_syslog:
if (string_to_syslog_priority (value->v.arg.v[1]->v.string,
&rp->v.prio))
{
grecs_error (locus, 0,
_("unknown syslog priority %s"),
value->v.arg.v[1]->v.string);
return 0;
}
break;
-
+
case redir_file:
rp->v.file = grecs_strdup (value->v.arg.v[1]->v.string);
break;
}
}
rp->type = res;
}
break;
-
+
default:
grecs_error (locus, 0, _("unexpected list"));
}
-
+
return 0;
}
static struct tokendef socktype_xtab[] = {
- { "stream", SOCK_STREAM },
- { "dgram", SOCK_DGRAM },
+ { "stream", SOCK_STREAM },
+ { "dgram", SOCK_DGRAM },
{ "seqpacket", SOCK_SEQPACKET },
{ "raw", SOCK_RAW },
{ "rdm", SOCK_RDM },
#ifdef SOCK_PACKET
{ "packet", SOCK_PACKET },
#endif
{ NULL }
};
int
str_to_socket_type (const char *str, int *pres)
{
@@ -811,30 +811,32 @@ _cb_socket_type (enum grecs_callback_command cmd,
}
static struct tokendef modetab[] = {
{"exec", pies_comp_exec},
{"respawn", pies_comp_exec},
{"wait", pies_comp_wait},
{"once", pies_comp_once},
{"accept", pies_comp_accept},
{"inetd", pies_comp_inetd},
{"nostartaccept", pies_comp_inetd},
{"pass-fd", pies_comp_pass_fd},
{"pass", pies_comp_pass_fd},
+ {"startup", pies_comp_startup},
+ {"shutdown", pies_comp_shutdown},
{"boot", pies_comp_boot},
{"bootwait", pies_comp_boot},
{"powerfail", pies_comp_powerfail},
{"powerwait", pies_comp_powerwait},
{"powerokwait", pies_comp_powerokwait},
- {"ctrlaltdel", pies_comp_ctrlaltdel},
+ {"ctrlaltdel", pies_comp_ctrlaltdel},
{"ondemand", pies_comp_ondemand},
{"sysinit", pies_comp_sysinit},
{"powerfailnow", pies_comp_powerfailnow},
{"kbrequest", pies_comp_kbrequest},
{NULL}
};
static int
_cb_mode (enum grecs_callback_command cmd,
grecs_locus_t *locus,
void *varptr, grecs_value_t *value, void *cb_data)
@@ -911,44 +913,44 @@ _cb_flags (enum grecs_callback_command cmd,
{
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;
-
+
case GRECS_TYPE_LIST:
{
struct grecs_list_entry *ep;
-
+
for (ep = value->v.list->head; ep; ep = ep->next)
{
const grecs_value_t *vp = ep->data;
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;
-
+
case GRECS_TYPE_ARRAY:
grecs_error (locus, 0, _("too many arguments"));
return 1;
}
return 0;
}
static int
_cb_initdefault (enum grecs_callback_command cmd,
grecs_locus_t *locus,
void *varptr, grecs_value_t *value, void *cb_data)
{
@@ -1219,25 +1221,25 @@ struct grecs_keyword component_keywords[] = {
N_("tag"),
N_("Tag of master TCPMUX component."),
grecs_type_string, GRECS_DFLT,
NULL, offsetof (struct component, tcpmux),
NULL },
{NULL}
};
struct grecs_keyword *
find_component_keyword (const char *ident)
{
struct grecs_keyword *kwp;
-
+
for (kwp = component_keywords; kwp->ident; kwp++)
if (strcmp (kwp->ident, ident) == 0)
return kwp;
return NULL;
}
static int
component_section_parser (enum grecs_callback_command cmd,
grecs_locus_t *locus,
void *varptr, grecs_value_t *value, void *cb_data)
{
struct component *comp;
@@ -1247,25 +1249,25 @@ component_section_parser (enum grecs_callback_command cmd,
{
case grecs_callback_section_begin:
if (assert_grecs_value_type (locus, value, GRECS_TYPE_STRING))
return 1;
comp = component_create (value->v.string);
*section_data = comp;
break;
case grecs_callback_section_end:
comp = *(struct component **) section_data;
component_finish (comp, locus);
break;
-
+
case grecs_callback_set_value:
grecs_error (locus, 0, _("expected block statement"));
}
return 0;
}
struct grecs_keyword control_keywords[] = {
{"socket",
N_("url: string"),
N_("Listen on the given url."),
grecs_type_string, GRECS_DFLT,
&control.url, 0, conf_callback_url},
@@ -1525,77 +1527,77 @@ config_init (void)
pies_identity_mechanism_register (&pam_identity_mechanism);
#endif
}
int
pies_config_parse (char const *name)
{
struct grecs_node *node;
struct grecs_node *tree = grecs_parse (name);
if (!tree)
return 1;
-
+
for (node = tree; node; node = node->next)
{
node = grecs_find_node (node, "identity-provider");
if (!node)
break;
pies_config_provider (node);
}
if (grecs_tree_process (tree, pies_keywords))
return 1;
grecs_tree_free (tree);
if (grecs_error_count)
return 1;
-
+
return 0;
}
void
config_help (void)
{
static char docstring[] =
/* TRANSLATORS: do not translate words in quotes */
N_("Configuration file structure for pies.\n"
"For more information, use command \"info pies configuration\".");
grecs_print_docstring (docstring, 0, stdout);
grecs_print_statement_array (pies_keywords, 1, 0, stdout);
pies_config_identity_mechanisms_help ();
}
int
pies_read_config (void)
{
struct grecs_list_entry *ep;
int err = 0;
component_config_begin ();
-
+
for (ep = config_list->head; ep; ep = ep->next)
{
struct config_file *file = ep->data;
if (file->syntax->parser (file->name))
++err;
}
if (init_process)
err = 0;
-
+
if (err)
component_config_rollback ();
-
+
return err;
}
int
pies_reread_config (void)
{
logmsg (LOG_INFO, _("reading configuration"));
return pies_read_config ();
}
static struct config_syntax *current_syntax = &config_syntax_tab[CONF_PIES];
@@ -1647,25 +1649,25 @@ sig_handler (int sig)
case SIGALRM:
pies_schedule_children (PIES_CHLD_WAKEUP);
break;
}
}
void
setsigvhan (RETSIGTYPE (*handler) (int signo), int *sigv, int sigc)
{
int i;
struct sigaction act;
-
+
act.sa_flags = 0;
sigemptyset (&act.sa_mask);
for (i = 0; i < sigc; i++)
sigaddset (&act.sa_mask, sigv[i]);
act.sa_handler = handler;
for (i = 0; i < sigc; i++)
{
sigaction (sigv[i], &act, NULL);
}
}
@@ -1770,49 +1772,49 @@ pies_check_status (pid_t *ppid)
return pies_status_stale;
return pies_status_running;
}
#define pies_control_url() control.url->string
int
request_restart_components (size_t cc, char **cv)
{
char **argv;
size_t i, j;
-
+
argv = grecs_calloc (5 + 3 * cc - 1, sizeof (*argv));
argv[0] = "piesctl";
argv[1] = "--url";
argv[2] = (char*) pies_control_url ();
argv[3] = "restart";
j = 4;
for (i = 0; i < cc; i++)
{
if (i > 0)
argv[j++] = "or";
argv[j++] = "component";
argv[j++] = cv[i];
}
argv[j] = NULL;
execvp (argv[0], argv);
logmsg (LOG_ERR, "can't run piesctl: %s", strerror (errno));
return EX_OSFILE;
}
void
list_components (void)
{
char *argv[5];
-
+
argv[0] = "piesctl";
argv[1] = "--url";
argv[2] = (char*) pies_control_url ();
argv[3] = "list";
argv[4] = NULL;
execvp (argv[0], argv);
logmsg (LOG_ERR, "can't run piesctl: %s", strerror (errno));
exit (EX_OSFILE);
}
int
@@ -1933,25 +1935,25 @@ void
remove_pidfile (char *name)
{
if (unlink (name))
logfuncall ("unlink", name, errno);
}
static void
set_mailer_argcv (void)
{
int i;
struct wordsplit ws;
-
+
if (wordsplit (mailer_command_line, &ws, WRDSF_DEFFLAGS))
{
logmsg (LOG_CRIT, _("cannot parse mailer command line: %s"),
strerror (errno));
exit (EX_CONFIG);
}
mailer_argc = ws.ws_wordc;
mailer_argv = grecs_calloc (mailer_argc + 1, sizeof (mailer_argv[0]));
for (i = 0; i < mailer_argc; i++)
mailer_argv[i] = grecs_strdup (ws.ws_wordv[i]);
mailer_argv[i] = NULL;
wordsplit_free (&ws);
@@ -2024,73 +2026,73 @@ set_state_file_names (const char *base)
size_t pies_master_argc;
char **pies_master_argv;
int
main (int argc, char **argv)
{
pid_t pid;
extern char **environ;
struct grecs_list_entry *ep;
int diag_flags;
int i;
-
+
set_program_name (argv[0]);
#ifdef ENABLE_NLS
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
#endif
mf_proctitle_init (argc, argv, environ);
grecs_print_diag_fun = pies_diag_printer;
-
+
pies_master_argc = argc;
pies_master_argv = argv;
-
+
set_quoting_style (NULL, shell_quoting_style);
init_process = getpid () == 1;
for (i = 1; i < argc; i++)
{
if (strcmp (argv[i], "--no-init") == 0)
{
init_process = 0;
break;
}
}
-
+
/* Set default logging */
if (init_process)
{
log_facility = LOG_DAEMON;
diag_flags = DIAG_TO_STDERR | DIAG_REOPEN_LOG;
}
else
diag_flags = DIAG_TO_SYSLOG | (stderr_closed_p () ? 0 : DIAG_TO_STDERR);
-
+
diag_setup (diag_flags);
-
+
config_init ();
parse_options (&argc, &argv);
-
+
if (argc && !(command == COM_RESTART_COMPONENT
|| command == COM_TRACE_DEPEND
|| command == COM_TRACE_PREREQ))
{
logmsg (LOG_ERR, "extra command line arguments");
exit (EX_USAGE);
}
-
+
if (!instance)
{
instance = strrchr (program_name, '/');
if (!instance)
instance = (char*) program_name;
else
instance++;
}
setenv ("PIES_INSTANCE", instance, 1);
log_tag = grecs_strdup (instance);
set_conf_file_names (instance);
@@ -2110,72 +2112,72 @@ main (int argc, char **argv)
&& grecs_preproc_run (file->name, grecs_preprocessor))
exit (EX_CONFIG);
}
exit (0);
}
else if (pies_read_config ())
exit (EX_CONFIG);
component_config_commit ();
set_state_file_names (instance);
set_mailer_argcv ();
-
+
if (lint_mode)
exit (0);
/* Re-setup logging: it might have been reset in the config file */
diag_setup (log_to_stderr_only ? DIAG_TO_STDERR : 0);
-
+
if (!control.url)
{
char const *str = default_control_url[init_process];
if (pies_url_create (&control.url, str))
{
logmsg (LOG_CRIT, _("%s: cannot create control URL: %s"),
str, strerror (errno));
if (!init_process)
exit (EX_OSERR);
}
}
-
+
switch (command)
{
case COM_RESTART_COMPONENT:
pies_priv_setup (&pies_privs);
if (pies_umask)
umask (pies_umask);
exit (request_restart_components (argc, argv));
-
+
case COM_RELOAD:
exit (request_reload ());
case COM_STATUS:
exit (request_status ());
case COM_STOP:
exit (request_stop ());
case COM_DUMP_DEPMAP:
components_dump_depmap ();
exit (0);
case COM_TRACE_DEPEND:
components_trace (argv, depmap_row);
exit (0);
-
- case COM_TRACE_PREREQ:
+
+ case COM_TRACE_PREREQ:
components_trace (argv, depmap_col);
exit (0);
-
+
default:
pies_priv_setup (&pies_privs);
if (pies_umask)
umask (pies_umask);
}
if (init_process)
{
foreground = 1;
sysvinit_begin ();
}
else
@@ -2184,59 +2186,60 @@ main (int argc, char **argv)
case pies_status_ctr:
break;
case pies_status_stale:
case pies_status_noresp:
if (!force_option)
{
logmsg (LOG_ERR,
_("another pies instance may be running (pid %lu), "
"use --force to override"), (unsigned long) pid);
exit (EX_USAGE);
}
break;
-
+
case pies_status_running:
logmsg (LOG_ERR, _("another pies instance already running (pid %lu)"),
(unsigned long) pid);
exit (EX_USAGE);
}
-
+
if (!foreground)
{
check_pidfile (pidfile);
if (daemon (0, 0) == -1)
{
logfuncall ("daemon", NULL, errno);
exit (EX_SOFTWARE);
}
diag_setup (DIAG_TO_SYSLOG);
}