From 7dd7f4e2d7a5eaed676651caf456c1de0704b7cd Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Tue, 5 Jan 2016 17:42:13 +0200 Subject: Include argv in the output of ctl id command. * ctl.c (res_instance): Include "argv" in the return json. Use pies_master_argv[0] to report binary path. * pies.c (pies_master_argv,pies_master_argc): New globals. (main): Initialize them. Refuse to restart unless argv[0] begins with a slash. * pies.h (pies_master_argv,pies_master_argc): New globals. * piesctl.c (com_id): Rewrite output formatting. --- src/ctl.c | 22 ++++++++++-- src/pies.c | 17 +++++++-- src/pies.h | 3 ++ src/piesctl.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++----------- 4 files changed, 125 insertions(+), 25 deletions(-) diff --git a/src/ctl.c b/src/ctl.c index cdb9b6c..8845390 100644 --- a/src/ctl.c +++ b/src/ctl.c @@ -1298,6 +1298,23 @@ idfmt_pid (struct ctlio *io, char const *name, void *ptr) json_object_set_number (io->output.reply, name, getpid ()); } +static void +idfmt_argv (struct ctlio *io, char const *name, void *ptr) +{ + struct json_value *ar = json_new_array (); + size_t i; + + for (i = 0; i < pies_master_argc; i++) + json_array_append (ar, json_new_string (pies_master_argv[i])); + json_object_set (io->output.reply, name, ar); +} + +static void +idfmt_binary (struct ctlio *io, char const *name, void *ptr) +{ + json_object_set_string (io->output.reply, name, "%s", pies_master_argv[0]); +} + static void res_instance (struct ctlio *io, enum http_method meth, char const *uri, struct json_value *req) @@ -1309,11 +1326,10 @@ res_instance (struct ctlio *io, enum http_method meth, } idparam[] = { { "package", idfmt_string, PACKAGE_NAME }, { "version", idfmt_string, PACKAGE_VERSION }, -#if HAVE_DECL_PROGRAM_INVOCATION_NAME - { "binary", idfmt_string_ptr, &program_invocation_name }, -#endif + { "binary", idfmt_binary, NULL }, { "PID", idfmt_pid, NULL }, { "instance", idfmt_string_ptr, &instance }, + { "argv", idfmt_argv, NULL }, { NULL } }; struct idparam *p; diff --git a/src/pies.c b/src/pies.c index f069552..875684a 100644 --- a/src/pies.c +++ b/src/pies.c @@ -2130,6 +2130,9 @@ set_state_file_names (const char *base) qotdfile = mkfilename (statedir, base, ".qotd"); } +size_t pies_master_argc; +char **pies_master_argv; + int main (int argc, char **argv) { @@ -2146,6 +2149,9 @@ main (int argc, char **argv) textdomain (PACKAGE); #endif mf_proctitle_init (argc, argv, environ); + + pies_master_argc = argc; + pies_master_argv = argv; set_quoting_style (NULL, shell_quoting_style); @@ -2392,8 +2398,15 @@ main (int argc, char **argv) pies_pause (); switch (action) { - case ACTION_STOP: case ACTION_RESTART: + if (argv[0][0] != '/' || init_process) + { + logmsg (LOG_INFO, _("restart command ignored")); + action = ACTION_CONT; + } + break; + + case ACTION_STOP: if (init_process) { debug (1, ("ignoring stop/restart")); @@ -2436,7 +2449,7 @@ main (int argc, char **argv) progman_stop (); remove_pidfile (pidfile); - if (action == ACTION_RESTART && argv[0][0] == '/') + if (action == ACTION_RESTART) { int minfd = DIAG_OUTPUT (DIAG_TO_STDERR) ? 2 : 0; int i; diff --git a/src/pies.h b/src/pies.h index 7c5e6d7..f69c512 100644 --- a/src/pies.h +++ b/src/pies.h @@ -290,6 +290,9 @@ extern char *console_device; extern int initdefault; extern int dfl_level; +extern size_t pies_master_argc; +extern char **pies_master_argv; + enum config_syntax { CONF_PIES, diff --git a/src/piesctl.c b/src/piesctl.c index a9555a1..fcc346a 100644 --- a/src/piesctl.c +++ b/src/piesctl.c @@ -1558,33 +1558,87 @@ com_restart (struct shttp_connection *conn, int argc, char **argv) return 0; } +static void +id_fmt_string (struct json_value *val) +{ + fputs (val->v.s, stdout); +} + +static void +id_fmt_pid (struct json_value *val) +{ + printf ("%.0f", val->v.n); +} + +static void +id_fmt_argv (struct json_value *val) +{ + size_t i, n; + char const *delim = NULL; + + n = json_array_size (val); + for (i = 0; i < n; i++) + { + struct json_value *elt; + if (json_array_get (val, i, &elt) == 0 && elt->type == json_string) + { + if (delim) + fputs (delim, stdout); + fputs (elt->v.s, stdout); + delim = " "; + } + } +} + +struct id_fmt +{ + char *name; + enum json_value_type type; + void (*format) (struct json_value *); +}; + +static struct id_fmt id_fmt[] = { + { "package", json_string, id_fmt_string }, + { "version", json_string, id_fmt_string }, + { "instance", json_string, id_fmt_string }, + { "binary", json_string, id_fmt_string }, + { "argv", json_arr, id_fmt_argv }, + { "PID", json_number, id_fmt_pid }, + { NULL } +}; + +static struct id_fmt * +find_id_fmt (char const *name) +{ + struct id_fmt *p; + + for (p = id_fmt; p->name; p++) + if (strcmp (p->name, name) == 0) + return p; + return NULL; +} + static int com_id (struct shttp_connection *conn, int argc, char **argv) { struct json_value *v; - + struct id_fmt *fmt; + if (argc == 1) { - size_t i; - static char *keywords[] = { - "package", - "version", - "instance", - "binary", - }; - shttp_io_init (&conn->req); shttp_process (conn, METH_GET, "/instance"); - - for (i = 0; i < sizeof (keywords)/ sizeof (keywords[0]); i++) - { - v = shttp_getval (conn, keywords[i], json_string); - if (v) - printf ("%s: %s\n", keywords[i], v->v.s); - } - v = shttp_getval (conn, "PID", json_number); - if (v) - printf ("PID: %.0f\n", v->v.n); + if (!dump) + for (fmt = id_fmt; fmt->name; fmt++) + { + v = shttp_getval (conn, fmt->name, fmt->type); + if (v) + { + printf ("%s: ", fmt->name); + fmt->format (v); + putchar ('\n'); + } + } } else { @@ -1597,10 +1651,24 @@ com_id (struct shttp_connection *conn, int argc, char **argv) grecs_asprintf (&buf, &size, "/instance/%s", argv[i]); shttp_io_init (&conn->req); shttp_process (conn, METH_GET, buf); - if (json_object_get (conn->result, argv[i], &v) == 0) + if (dump) + continue; + fmt = find_id_fmt (argv[i]); + if (fmt) + { + v = shttp_getval (conn, fmt->name, fmt->type); + if (v) + { + printf ("%s: ", fmt->name); + fmt->format (v); + putchar ('\n'); + } + } + else if (json_object_get (conn->result, argv[i], &v) == 0) { printf ("%s: ", argv[i]); print_json (stdout, v); + putchar ('\n'); } } } -- cgit v1.2.1