aboutsummaryrefslogtreecommitdiff
path: root/src/piesctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/piesctl.c')
-rw-r--r--src/piesctl.c244
1 files changed, 156 insertions, 88 deletions
diff --git a/src/piesctl.c b/src/piesctl.c
index 8c4e2e1..4b448ad 100644
--- a/src/piesctl.c
+++ b/src/piesctl.c
@@ -1230,11 +1230,2 @@ peek_token (struct pcond_parser_state *state)
static struct json_value *
-json_new_array2 (struct json_value *a, struct json_value *b)
-{
- struct json_value *ret = json_new_array ();
- json_array_append (ret, a);
- json_array_append (ret, b);
- return ret;
-}
-
-static struct json_value *
json_encode_op (char const *op, struct json_value *arg)
@@ -1302,2 +1293,39 @@ pcond_parse_unary (struct pcond_parser_state *state, struct json_value **ret)
+static int
+is_op (struct json_value *val, char const *opcode)
+{
+ struct json_value *op;
+
+ if (json_object_get (val, "op", &op) == 0)
+ {
+ if (op->type == json_string && strcmp (op->v.s, opcode) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+static void
+binop_append_optimized (struct json_value *ar, struct json_value *val,
+ char const *opcode)
+{
+ if (is_op (val, opcode))
+ {
+ size_t i, n;
+ struct json_value *arg;
+
+ json_object_get (val, "arg", &arg);
+ n = json_array_size (arg);
+ for (i = 0; i < n; i++)
+ {
+ struct json_value *elt;
+ json_array_get (arg, i, &elt);
+ json_array_set (arg, i, NULL);
+ json_array_append (ar, elt);
+ }
+ json_value_free (val);
+ }
+ else
+ json_array_append (ar, val);
+}
+
static void
@@ -1306,3 +1334,3 @@ pcond_parse_and (struct pcond_parser_state *state, struct json_value **ret)
char const *token;
- struct json_value *left, *right;
+ struct json_value *left, *right, *ar;
@@ -1317,3 +1345,6 @@ pcond_parse_and (struct pcond_parser_state *state, struct json_value **ret)
pcond_parse_and (state, &right);
- *ret = json_encode_op (token, json_new_array2 (left, right));
+ ar = json_new_array ();
+ json_array_append (ar, left);
+ binop_append_optimized (ar, right, token);
+ *ret = json_encode_op (token, ar);
}
@@ -1324,3 +1355,3 @@ pcond_parse_or (struct pcond_parser_state *state, struct json_value **ret)
char const *token;
- struct json_value *left, *right;
+ struct json_value *left, *right, *ar;
@@ -1335,3 +1366,6 @@ pcond_parse_or (struct pcond_parser_state *state, struct json_value **ret)
pcond_parse_or (state, &right);
- *ret = json_encode_op (token, json_new_array2 (left, right));
+ ar = json_new_array ();
+ json_array_append (ar, left);
+ binop_append_optimized (ar, right, token);
+ *ret = json_encode_op (token, ar);
}
@@ -1371,23 +1405,3 @@ acc_writer (void *closure, char const *text, size_t len)
static char *
-json_to_string (struct json_value *val)
-{
- struct grecs_txtacc *acc = grecs_txtacc_create ();
- struct json_format fmt = {
- .indent = 0,
- .precision = 0,
- .write = acc_writer,
- .data = acc
- };
- char *ret;
-
- json_format_value (val, &fmt);
- grecs_txtacc_grow_char (acc, 0);
- ret = grecs_txtacc_finish (acc, 1);
- grecs_txtacc_free (acc);
-
- return ret;
-}
-
-static char *
-parse_condition_to_uri (char const *base, int argc, char **argv)
+parse_condition_to_uri (char const *base, int argc, char **argv, int mandatory)
{
@@ -1397,4 +1411,11 @@ parse_condition_to_uri (char const *base, int argc, char **argv)
+ if (mandatory && argc == 1)
+ {
+ grecs_error (NULL, 0, _("condition must be specified"));
+ exit (EX_USAGE);
+ }
+
acc = grecs_txtacc_create ();
- grecs_txtacc_grow_string (acc, base);
+ if (base)
+ grecs_txtacc_grow_string (acc, base);
@@ -1409,3 +1430,4 @@ parse_condition_to_uri (char const *base, int argc, char **argv)
};
- grecs_txtacc_grow_char (acc, '/');
+ if (base)
+ grecs_txtacc_grow_char (acc, '/');
json_format_value (val, &fmt);
@@ -1417,3 +1439,2 @@ parse_condition_to_uri (char const *base, int argc, char **argv)
grecs_txtacc_free (acc);
-
return ret;
@@ -1424,3 +1445,3 @@ com_list (struct shttp_connection *conn, int argc, char **argv)
{
- char *uri = parse_condition_to_uri ("/programs", argc, argv);
+ char *uri = parse_condition_to_uri ("/programs/select", argc, argv, 0);
@@ -1445,19 +1466,70 @@ com_list (struct shttp_connection *conn, int argc, char **argv)
static int
-com_stop (struct shttp_connection *conn, int argc, char **argv)
+json_object_get_type (struct json_value *obj, char const *name,
+ enum json_value_type type, struct json_value **ret)
{
- char *buf = NULL;
- size_t len = 0;
- size_t i;
-
- for (i = 1; i < argc; i++)
+ struct json_value *v;
+ int rc = json_object_get (obj, name, &v);
+ if (rc)
+ return rc;
+ if (v->type != type)
{
- struct json_value *v;
- grecs_asprintf (&buf, &len, "/programs/%s", argv[i]);
- shttp_io_init (&conn->req);
- 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);
+ errno = EACCES;
+ return -1;
}
- free (buf);
+ *ret = v;
+ return 0;
+}
+
+static void
+shttp_print_response_status (struct shttp_connection *conn)
+{
+ 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 *elt, *v;
+
+ if (json_array_get (conn->result, i, &elt) == 0)
+ {
+ if (elt->type != json_object)
+ {
+ grecs_error (NULL, 0, _("%lu: unexpected value type"),
+ (unsigned long) i);
+ print_json (stderr, v);
+ continue;
+ }
+ if (json_object_get_type (elt, "tag", json_string, &v) == 0)
+ {
+ printf ("%s: ", v->v.s);
+ if (json_object_get_type (elt, "status", json_string, &v)
+ == 0)
+ {
+ if (strcmp (v->v.s, "OK") == 0)
+ fputs (v->v.s, stdout);
+ else if (json_object_get_type (elt, "error_message",
+ json_string, &v) == 0)
+ fputs (v->v.s, stdout);
+ else
+ printf ("unknown error");
+ }
+ else
+ printf ("unknown status");
+ fputc ('\n', stdout);
+ }
+ }
+ }
+ }
+}
+
+static int
+com_stop (struct shttp_connection *conn, int argc, char **argv)
+{
+ char *uri = parse_condition_to_uri ("/programs/select", argc, argv, 1);
+
+ shttp_io_init (&conn->req);
+ shttp_process (conn, METH_DELETE, uri);
+ grecs_free (uri);
+ shttp_print_response_status (conn);
return 0;
@@ -1468,17 +1540,8 @@ com_start (struct shttp_connection *conn, int argc, char **argv)
{
- 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_io_init (&conn->req);
- 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);
+ char *uri = parse_condition_to_uri ("/programs/select", argc, argv, 1);
+
+ shttp_io_init (&conn->req);
+ shttp_process (conn, METH_PUT, uri);
+ grecs_free (uri);
+ shttp_print_response_status (conn);
return 0;
@@ -1489,20 +1552,7 @@ com_restart (struct shttp_connection *conn, int argc, char **argv)
{
- struct json_value *val = json_new_array ();
- size_t i;
-
- if (argc == 1)
- {
- grecs_error (NULL, 0, _("missing component names"));
- exit (EX_USAGE);
- }
- for (i = 1; i < argc; i++)
- json_array_append (val, json_new_string (argv[i]));
-
shttp_io_init (&conn->req);
- conn->req.content = json_to_string (val);
+ conn->req.content = parse_condition_to_uri (NULL, argc, argv, 1);
conn->req.content_length = strlen (conn->req.content);
- json_value_free (val);
-
- shttp_process (conn, METH_POST, "/programs");
-
+ shttp_process (conn, METH_POST, "/programs/select");
+ shttp_print_response_status (conn);
return 0;
@@ -1587,6 +1637,6 @@ struct comtab
static struct comtab comtab[] = {
- { "list", N_("[EXPR]"), N_("list configured components"), com_list },
- { "stop", N_("TAG [TAG...]"), N_("stop components"), com_stop },
- { "start", N_("TAG [TAG...]"), N_("start components"), com_start },
- { "restart", N_("TAG [TAG...]"), N_("restart components"), com_restart },
+ { "list", N_("[CONDITION]"), N_("list configured components"), com_list },
+ { "stop", N_("CONDITION"), N_("stop components"), com_stop },
+ { "start", N_("CONDITION"), N_("start components"), com_start },
+ { "restart", N_("CONDITION"), N_("restart components"), com_restart },
{ "id", N_("[KEYWORDS...]"),
@@ -1641,3 +1691,3 @@ command_help (FILE *fp)
- fputs (_("Available commands are:"), fp);
+ fputs (_("Available commands with their arguments are:"), fp);
fputc ('\n', fp);
@@ -1657,2 +1707,20 @@ command_help (FILE *fp)
fputc ('\n', fp);
+ fputs (_("Condition is defined as:"), fp);
+ fputc ('\n', fp);
+ fputc ('\n', fp);
+ fputs ("\
+ <condition> ::= <disjunction>\n\
+ <disjunction> ::= <conjunction> | <conjunction> \"or\" <disjunction>\n\
+ <conjunction> ::= <unary> | <unary> \"and\" <conjunction>\n\
+ <unary> ::= <term> | \"not\" <condition> | \"(\" <condition> \")\"\n\
+ <term> ::= \"all\" | <keyword> <value>\n\
+ <keyword> ::= \"type\" | \"mode\" | \"status\" | \"component\"\n\
+ <value> ::= <word> | <quoted-string>\n\
+ <word> ::= <printable> | <word> <printable>\n\
+ <printable> ::= \"A\" - \"Z\" | \"a\" - \"z\" | \"0\" - \"9\" |\n\
+ \"_\" | \".\" | \"*\" | \":\" | \"@\" | \"[\" | \"]\" | \"-\" | \"/\"\n\
+ <quoted-string> ::= \"\"\" <string> \"\"\"\n\
+ <string> ::= <char> | <string> <char>\n\
+ <char> ::= <any character except \"\\\" and \"\"\"> | \"\\\\\" | \"\\\"\"\n\n", fp);
+
}

Return to:

Send suggestions and report system problems to the System administrator.