aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ctl.c4
-rw-r--r--src/piesctl-cl.opt8
-rw-r--r--src/piesctl.c338
3 files changed, 336 insertions, 14 deletions
diff --git a/src/ctl.c b/src/ctl.c
index ce13dab..cbc5fea 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -1,3 +1,3 @@
/* This file is part of GNU Pies.
- Copyright (C) 2007-2013 Sergey Poznyakoff
+ Copyright (C) 2007-2016 Sergey Poznyakoff
@@ -1448,3 +1448,3 @@ res_programs (struct ctlio *io, enum http_method meth,
{
- prog->v.p.comp->flags &= CF_DISABLED;
+ prog->v.p.comp->flags &= ~CF_DISABLED;
prog->v.p.status = status_enabled;
diff --git a/src/piesctl-cl.opt b/src/piesctl-cl.opt
index 04ff051..a83616e 100644
--- a/src/piesctl-cl.opt
+++ b/src/piesctl-cl.opt
@@ -1,3 +1,3 @@
/* This file is part of GNU Pies. -*- c -*-
- Copyright (C) 2008-2014 Sergey Poznyakoff
+ Copyright (C) 2008-2016 Sergey Poznyakoff
@@ -54,2 +54,8 @@ END
+OPTION(dump,d,,
+ [<dump obtained responsed verbatim>])
+BEGIN
+ ++dump;
+END
+
OPTION(url,u,URL,
diff --git a/src/piesctl.c b/src/piesctl.c
index 0618caa..9c5ef8b 100644
--- a/src/piesctl.c
+++ b/src/piesctl.c
@@ -1,3 +1,3 @@
/* This file is part of GNU Pies.
- Copyright (C) 2015 Sergey Poznyakoff
+ Copyright (C) 2015, 2016 Sergey Poznyakoff
@@ -37,2 +37,3 @@
#include "grecsasrt.h"
+#include "fprintftime.h"
@@ -45,2 +46,3 @@ int preprocess_only;
int verbose;
+int dump;
@@ -796,5 +798,5 @@ shttp_get_reply (struct shttp_connection *conn)
static void
-stderr_writer (void *closure, char const *text, size_t len)
+fp_writer (void *closure, char const *text, size_t len)
{
- fwrite (text, len, 1, stderr);
+ fwrite (text, len, 1, (FILE*) closure);
}
@@ -802,3 +804,3 @@ stderr_writer (void *closure, char const *text, size_t len)
static void
-shttp_format_result (struct shttp_connection *conn)
+print_json (FILE *fp, struct json_value *v)
{
@@ -807,6 +809,14 @@ shttp_format_result (struct shttp_connection *conn)
.precision = 0,
- .write = stderr_writer,
+ .write = fp_writer,
+ .data = fp
};
+ json_format_value (v, &fmt);
+ fputc ('\n', fp);
+}
+
+static void
+shttp_format_result (struct shttp_connection *conn, FILE *fp)
+{
fprintf (stderr, "%s: raw JSON reply follows:\n", program_name);
- json_format_value (conn->result, &fmt);
+ print_json (fp, conn->result);
}
@@ -823,3 +833,3 @@ shttp_fatal (struct shttp_connection *conn)
else
- shttp_format_result (conn);
+ shttp_format_result (conn, stderr);
}
@@ -929,2 +939,4 @@ shttp_process (struct shttp_connection *conn, int method, char const *uri)
shttp_get_reply (conn);
+ if (dump && conn->result)
+ shttp_format_result (conn, stdout);
if (conn->resp.code / 100 == 2)
@@ -938,2 +950,214 @@ shttp_process (struct shttp_connection *conn, int method, char const *uri)
+static struct json_value *
+shttp_getval (struct shttp_connection *conn, char const *name,
+ enum json_value_type type)
+{
+ struct json_value *p = NULL;
+
+ switch (json_object_get (conn->result, name, &p))
+ {
+ case 0:
+ if (p->type != type)
+ {
+ grecs_error (NULL, 0, _("\"%s\" has wrong type"), name);
+ p = NULL;
+ }
+ break;
+
+ case 1:
+ grecs_error (NULL, 0, _("no \"%s\" member"), name);
+ break;
+
+ default:
+ grecs_error (NULL, errno, _("can't get value of \"%s\""), name);
+ }
+ return p;
+}
+
+struct kwtrans
+{
+ char const *name;
+ int c;
+};
+
+struct kwtrans mode_trans[] = {
+ { "exec", 'C' },
+ { "accept", 'A' },
+ { "inetd", 'I' },
+ { "pass_fd", 'P' },
+ { "wait", 'W' },
+ { "once", 'c' },
+ { "boot", 'B' },
+ { "bootwait", 'w' },
+ { "powerfail", 'F' },
+ { "powerwait", 'f' },
+ { "powerokwait", 'o' },
+ { "ctrlaltdel", '3' },
+ { "ondemand", 'D' },
+ { "sysinit", 'i' },
+ { "powerfailnow", 'n' },
+ { "kbrequest", 'k' },
+ { NULL }
+};
+
+struct kwtrans status_trans[] = {
+ { "enabled", 'R' },
+ { "disabled", 'D' },
+ { "listener", 'L' },
+ { "sleeping", 's' },
+ { "stopping", 'S' },
+ { "finished", 'f' },
+ { NULL }
+};
+
+static int
+kwtoc (char const *s, struct kwtrans const *trans)
+{
+ for (; trans->name; trans++)
+ {
+ if (strcmp (trans->name, s) == 0)
+ return trans->c;
+ }
+ return '-';
+}
+
+static struct json_value *
+getval (struct json_value *v, char const *name, enum json_value_type type,
+ int optional)
+{
+ struct json_value *p = NULL;
+
+ switch (json_object_get (v, name, &p))
+ {
+ case 0:
+ if (p->type != type)
+ {
+ grecs_error (NULL, 0, _("\"%s\" has wrong type"), name);
+ p = NULL;
+ }
+ break;
+
+ case 1:
+ if (!optional)
+ grecs_error (NULL, 0, _("no \"%s\" member"), name);
+ break;
+
+ default:
+ grecs_error (NULL, errno, _("can't get value of \"%s\""), name);
+ }
+ return p;
+}
+
+static void
+print_comp (FILE *fp, struct json_value *v, size_t n)
+{
+ struct json_value *p;
+ char const *type;
+ char fbuf[5];
+ int fidx = 0;
+ int status = -1;
+
+ if (v->type != json_object)
+ {
+ grecs_error (NULL, 0, _("%lu: unexpected value type"),
+ (unsigned long) n);
+ print_json (fp, v);
+ return;
+ }
+
+ p = getval (v, "type", json_string, 0);
+ if (!p)
+ {
+ print_json (fp, v);
+ return;
+ }
+ type = p->v.s;
+
+ p = getval (v, "tag", json_string, 0);
+ if (!p)
+ {
+ print_json (fp, v);
+ return;
+ }
+
+ fprintf (fp, "%-16s ", p->v.s);
+
+ if (strcmp (type, "component") == 0)
+ {
+ p = getval (v, "mode", json_string, 0);
+ if (v)
+ fbuf[fidx++] = kwtoc (p->v.s, mode_trans);
+ else
+ fbuf[fidx++] = '-';
+ p = getval (v, "status", json_string, 0);
+ if (p)
+ fbuf[fidx++] = status = kwtoc (p->v.s, status_trans);
+ else
+ fbuf[fidx++] = '-';
+ }
+ else if (strcmp (type, "redirector") == 0)
+ {
+ fbuf[fidx++] = 'R';
+ }
+ else if (strcmp (type, "command") == 0)
+ {
+ fbuf[fidx++] = 'E';
+ }
+ else
+ {
+ fbuf[fidx++] = '-';
+ }
+
+ fbuf[fidx++] = 0;
+ fprintf (fp, "%-8.8s ", fbuf);
+
+ if (strcmp (type, "component") == 0)
+ {
+ p = getval (v, "PID", json_number, 1);
+ if (p)
+ fprintf (fp, "%10.0f ", p->v.n);
+ else if (status == 'L' /* listener */
+ && (p = getval (v, "URL", json_string, 1)))
+ fprintf (fp, "%-10s ", p->v.s);
+ else
+ fprintf (fp, "%-10s ", "N/A");
+
+ if (status == 's') /* sleeping */
+ {
+ p = getval (v, "wakeup-time", json_number, 0);
+ if (p)
+ {
+ time_t t = (time_t) p->v.n;
+ fprintftime (fp, "%H:%M:%S", localtime (&t), 0, 0);
+ }
+ }
+
+ p = getval (v, "argv", json_arr, 0);
+ if (p)
+ {
+ size_t i, n = json_array_size (p);
+
+ for (i = 0; i < n; i++)
+ {
+ struct json_value *elt;
+ if (json_array_get (p, i, &elt) == 0)
+ fprintf (fp, " %s", elt->v.s);
+ }
+ }
+ }
+ else if (strcmp (type, "redirector") == 0)
+ {
+ p = getval (v, "PID", json_number, 0);
+ if (p)
+ fprintf (fp, "%10.0f ", p->v.n);
+ }
+ else if (strcmp (type, "command") == 0)
+ {
+ p = getval (v, "command", json_string, 0);
+ if (p)
+ fprintf (fp, "%s", p->v.s);
+ }
+ fputc ('\n', fp);
+}
+
static int
@@ -942,2 +1166,14 @@ com_list (struct shttp_connection *conn, int argc, char **argv)
shttp_process (conn, METH_GET, "/programs");
+ if (!dump && conn->result && conn->result->type == json_arr)
+ {
+ size_t i, n = json_array_size (conn->result);
+
+ for (i = 0; i < n; i++)
+ {
+ struct json_value *v;
+
+ if (json_array_get (conn->result, i, &v) == 0)
+ print_comp (stdout, v, i);
+ }
+ }
return 0;
@@ -948,3 +1184,16 @@ com_stop (struct shttp_connection *conn, int argc, char **argv)
{
- abort ();
+ char *buf = NULL;
+ size_t len = 0;
+ size_t i;
+
+ for (i = 1; i < argc; i++)
+ {
+ struct json_value *v;
+ grecs_asprintf (&buf, &len, "/programs/%s", argv[i]);
+ shttp_process (conn, METH_DELETE, buf);
+ v = shttp_getval (conn, "error_message", json_string);
+ if (v)
+ printf ("%s: %s\n", argv[i], v->v.s);
+ }
+ free (buf);
return 0;
@@ -955,3 +1204,16 @@ com_start (struct shttp_connection *conn, int argc, char **argv)
{
- abort ();
+ char *buf = NULL;
+ size_t len = 0;
+ size_t i;
+
+ for (i = 1; i < argc; i++)
+ {
+ struct json_value *v;
+ grecs_asprintf (&buf, &len, "/programs/%s", argv[i]);
+ shttp_process (conn, METH_PUT, buf);
+ v = shttp_getval (conn, "error_message", json_string);
+ if (v)
+ printf ("%s: %s\n", argv[i], v->v.s);
+ }
+ free (buf);
return 0;
@@ -967,5 +1229,53 @@ com_restart (struct shttp_connection *conn, int argc, char **argv)
static int
+com_id (struct shttp_connection *conn, int argc, char **argv)
+{
+ struct json_value *v;
+
+ if (argc == 1)
+ {
+ size_t i;
+ static char *keywords[] = {
+ "package",
+ "version",
+ "instance",
+ "binary",
+ };
+
+ 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);
+ }
+ else
+ {
+ char *buf = NULL;
+ size_t size = 0;
+ size_t i;
+
+ for (i = 1; i < argc; i++)
+ {
+ grecs_asprintf (&buf, &size, "/instance/%s", argv[i]);
+ shttp_process (conn, METH_GET, buf);
+ if (json_object_get (conn->result, argv[i], &v) == 0)
+ {
+ printf ("%s: ", argv[i]);
+ print_json (stdout, v);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
com_shutdown (struct shttp_connection *conn, int argc, char **argv)
{
- abort ();
+ shttp_process (conn, METH_DELETE, "/instance/PID");
return 0;
@@ -976,3 +1286,3 @@ com_reboot (struct shttp_connection *conn, int argc, char **argv)
{
- abort ();
+ shttp_process (conn, METH_PUT, "/instance/PID");
return 0;
@@ -993,2 +1303,3 @@ static struct comtab comtab[] = {
{ "restart", com_restart },
+ { "id", com_id },
{ "shutdown", com_shutdown },
@@ -1054,2 +1365,7 @@ main (int argc, char **argv)
argv += i;
+ if (argc == 0)
+ {
+ grecs_error (NULL, 0, _("not enough arguments"));
+ exit (EX_USAGE);
+ }

Return to:

Send suggestions and report system problems to the System administrator.