diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-02-25 16:17:36 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-02-25 16:17:36 +0200 |
commit | c9abb69acae95a0136ee1b03dec8b08d9639005e (patch) | |
tree | fa5849647e6d9430289a71035630475a82f4cf54 /src | |
parent | 1ec50721c1aa5959009f0c74afc8b7796f4ffd20 (diff) | |
download | pies-c9abb69acae95a0136ee1b03dec8b08d9639005e.tar.gz pies-c9abb69acae95a0136ee1b03dec8b08d9639005e.tar.bz2 |
Implement "telinit environ" ctl command
* src/ctl.c: New endpoint "environ"
* src/pies.h (sysvinit_envlocate)
(sysvinit_envdelete)
(sysvinit_envupdate): New protos.
* src/piesctl.c: New subcommand "telinit environ".
* src/sysvinit.c (sysvinit_envlocate)
(sysvinit_envdelete)
(sysvinit_envupdate): New functions.
(sysvinit_begin): Create allocated copies of
instance and pies_master_argv to avoid them being
rewritten by calls to mf_proctitle_format
Diffstat (limited to 'src')
-rw-r--r-- | src/acl.c | 2 | ||||
-rw-r--r-- | src/ctl.c | 86 | ||||
-rw-r--r-- | src/pies.h | 4 | ||||
-rw-r--r-- | src/piesctl.c | 143 | ||||
-rw-r--r-- | src/sysvinit.c | 90 |
5 files changed, 293 insertions, 32 deletions
@@ -148,7 +148,7 @@ _parse_token (struct acl_entry *entry, const grecs_value_t *value) | |||
148 | { | 148 | { |
149 | if (strcmp (value->v.string, "all") == 0 | 149 | if (strcmp (value->v.string, "all") == 0 |
150 | || strcmp (value->v.string, "any") == 0) | 150 | || strcmp (value->v.string, "any") == 0) |
151 | /* FIXME: Nothing? */ ; | 151 | /* nothing */ ; |
152 | else if (strcmp (value->v.string, "auth") == 0 | 152 | else if (strcmp (value->v.string, "auth") == 0 |
153 | || strcmp (value->v.string, "authenticated") == 0) | 153 | || strcmp (value->v.string, "authenticated") == 0) |
154 | entry->authenticated = 1; | 154 | entry->authenticated = 1; |
@@ -485,6 +485,7 @@ json_error_reply_create (const char *msg) | |||
485 | struct json_value *val; | 485 | struct json_value *val; |
486 | 486 | ||
487 | val = json_reply_create (); | 487 | val = json_reply_create (); |
488 | json_object_set_string (val, "status", "ER"); | ||
488 | json_object_set_string (val, "error_message", "%s", msg); | 489 | json_object_set_string (val, "error_message", "%s", msg); |
489 | return val; | 490 | return val; |
490 | } | 491 | } |
@@ -920,6 +921,8 @@ static void res_programs (struct ctlio *, enum http_method, char const *, | |||
920 | struct json_value *); | 921 | struct json_value *); |
921 | static void res_runlevel (struct ctlio *, enum http_method, char const *, | 922 | static void res_runlevel (struct ctlio *, enum http_method, char const *, |
922 | struct json_value *); | 923 | struct json_value *); |
924 | static void res_environ (struct ctlio *, enum http_method, char const *, | ||
925 | struct json_value *); | ||
923 | static void res_conf (struct ctlio *, enum http_method, char const *, | 926 | static void res_conf (struct ctlio *, enum http_method, char const *, |
924 | struct json_value *); | 927 | struct json_value *); |
925 | 928 | ||
@@ -942,6 +945,7 @@ static struct ctlio_resource restab[] = { | |||
942 | { S(/programs), CTL_ADMIN_STATE|CTL_USER_STATE, NULL, | 945 | { S(/programs), CTL_ADMIN_STATE|CTL_USER_STATE, NULL, |
943 | res_programs }, | 946 | res_programs }, |
944 | { S(/runlevel), CTL_ADMIN_STATE, pred_sysvinit, res_runlevel }, | 947 | { S(/runlevel), CTL_ADMIN_STATE, pred_sysvinit, res_runlevel }, |
948 | { S(/environ), CTL_ADMIN_STATE, pred_sysvinit, res_environ }, | ||
945 | { NULL } | 949 | { NULL } |
946 | #undef S | 950 | #undef S |
947 | }; | 951 | }; |
@@ -2403,3 +2407,85 @@ res_conf (struct ctlio *io, enum http_method meth, | |||
2403 | else | 2407 | else |
2404 | ctlio_reply (io, 404, NULL); | 2408 | ctlio_reply (io, 404, NULL); |
2405 | } | 2409 | } |
2410 | |||
2411 | /* GET /environ - List entire environment | ||
2412 | * ["RUNLEVEL=3", "CONSOLE=/dev/tty", ...] | ||
2413 | * GET /environ/NAME - Get value of variable NAME | ||
2414 | * { "status":"OK", "value":"..." } | ||
2415 | * { "status":"ER", "error_message":"..." } | ||
2416 | * DELETE /environ/NAME - Unset variable | ||
2417 | * { "status":"OK" } | ||
2418 | * { "status":"ER", "error_message":"..." } | ||
2419 | * PUT /environ/NAME=VALUE - Set variable | ||
2420 | * { "status":"OK" } | ||
2421 | * { "status":"ER", "error_message":"..." } | ||
2422 | */ | ||
2423 | static void | ||
2424 | env_reply (struct ctlio *io, int ok, int rc) | ||
2425 | { | ||
2426 | switch (rc) | ||
2427 | { | ||
2428 | case 0: | ||
2429 | io->code = ok; | ||
2430 | io->output.reply = json_reply_create (); | ||
2431 | json_object_set_string (io->output.reply, "status", "OK"); | ||
2432 | break; | ||
2433 | |||
2434 | case 1: | ||
2435 | ctlio_reply (io, 403, NULL); | ||
2436 | break; | ||
2437 | |||
2438 | case -1: | ||
2439 | ctlio_reply (io, 404, NULL); | ||
2440 | } | ||
2441 | } | ||
2442 | |||
2443 | static void | ||
2444 | res_environ (struct ctlio *io, enum http_method meth, | ||
2445 | char const *uri, struct json_value *json) | ||
2446 | { | ||
2447 | if (meth == METH_GET) | ||
2448 | { | ||
2449 | if (uri && uri[1]) | ||
2450 | { | ||
2451 | char *value; | ||
2452 | |||
2453 | if (sysvinit_envlocate (uri + 1, &value) == -1) | ||
2454 | ctlio_reply (io, 404, NULL); | ||
2455 | else | ||
2456 | { | ||
2457 | env_reply (io, 200, 0); | ||
2458 | json_object_set_string (io->output.reply, "value", "%s", value); | ||
2459 | } | ||
2460 | } | ||
2461 | else | ||
2462 | { | ||
2463 | size_t i; | ||
2464 | |||
2465 | io->output.reply = json_new_array (); | ||
2466 | io->code = 200; | ||
2467 | for (i = 0; sysvinit_environ_hint[i]; i++) | ||
2468 | { | ||
2469 | json_array_append (io->output.reply, | ||
2470 | json_new_string (sysvinit_environ_hint[i])); | ||
2471 | } | ||
2472 | } | ||
2473 | } | ||
2474 | else if (meth == METH_DELETE) | ||
2475 | { | ||
2476 | if (!(uri && uri[0])) | ||
2477 | ctlio_reply (io, 400, NULL); | ||
2478 | else | ||
2479 | env_reply (io, 200, sysvinit_envupdate (uri + 1)); | ||
2480 | } | ||
2481 | else if (meth == METH_PUT) | ||
2482 | { | ||
2483 | if (!(uri && uri[0])) | ||
2484 | ctlio_reply (io, 400, NULL); | ||
2485 | else | ||
2486 | env_reply (io, 201, sysvinit_envupdate (uri + 1)); | ||
2487 | } | ||
2488 | else | ||
2489 | ctlio_reply (io, 405, NULL); | ||
2490 | |||
2491 | } | ||
@@ -546,6 +546,10 @@ void sysvinit_report (struct json_value *obj); | |||
546 | int sysvinit_set_runlevel (int newlevel); | 546 | int sysvinit_set_runlevel (int newlevel); |
547 | void sysvinit_parse_argv (int argc, char **argv); | 547 | void sysvinit_parse_argv (int argc, char **argv); |
548 | 548 | ||
549 | int sysvinit_envlocate (char const *name, char **value); | ||
550 | int sysvinit_envdelete (char const *name); | ||
551 | int sysvinit_envupdate (char const *var); | ||
552 | |||
549 | extern char *sysvinit_environ_hint[]; | 553 | extern char *sysvinit_environ_hint[]; |
550 | extern char *init_fifo; | 554 | extern char *init_fifo; |
551 | 555 | ||
diff --git a/src/piesctl.c b/src/piesctl.c index ad0981b..eecb6f6 100644 --- a/src/piesctl.c +++ b/src/piesctl.c | |||
@@ -890,7 +890,7 @@ shttp_fatal (struct shttp_connection *conn) | |||
890 | 890 | ||
891 | exit (status); | 891 | exit (status); |
892 | } | 892 | } |
893 | 893 | ||
894 | static void | 894 | static void |
895 | echo_off (struct termios *stored_settings) | 895 | echo_off (struct termios *stored_settings) |
896 | { | 896 | { |
@@ -1037,7 +1037,7 @@ shttp_getval (struct shttp_connection *conn, char const *name, | |||
1037 | break; | 1037 | break; |
1038 | 1038 | ||
1039 | default: | 1039 | default: |
1040 | grecs_error (NULL, errno, _("can't get value of \"%s\""), name); | 1040 | grecs_error (NULL, errno, _("can't get value of \"%s\""), name); |
1041 | } | 1041 | } |
1042 | return p; | 1042 | return p; |
1043 | } | 1043 | } |
@@ -1768,7 +1768,9 @@ com_reboot (struct cmdline_parser_state *state) | |||
1768 | 1768 | ||
1769 | /* | 1769 | /* |
1770 | <telinit> ::= "telinit" <initcmd> | 1770 | <telinit> ::= "telinit" <initcmd> |
1771 | <initcmd> ::= "runlevel" | "runlevel" <level> | 1771 | <initcmd> ::= <runlevel> | <environ> |
1772 | <runlevel> ::= "runlevel" | "runlevel" <level> | ||
1773 | <environ> ::= "environ" "list" [<NAME>] | "environ" "set" <NAME>"="<VALUE> | ||
1772 | */ | 1774 | */ |
1773 | struct telinit_parser | 1775 | struct telinit_parser |
1774 | { | 1776 | { |
@@ -1809,6 +1811,7 @@ telinit_parse_runlevel (struct telinit_parser *p) | |||
1809 | { | 1811 | { |
1810 | char const *tok = next_token (p->state); | 1812 | char const *tok = next_token (p->state); |
1811 | 1813 | ||
1814 | p->uri = "/runlevel"; | ||
1812 | if (!tok) | 1815 | if (!tok) |
1813 | { | 1816 | { |
1814 | p->method = METH_GET; | 1817 | p->method = METH_GET; |
@@ -1822,7 +1825,119 @@ telinit_parse_runlevel (struct telinit_parser *p) | |||
1822 | p->format = NULL; | 1825 | p->format = NULL; |
1823 | } | 1826 | } |
1824 | } | 1827 | } |
1825 | 1828 | ||
1829 | static void | ||
1830 | telinit_format_environ (struct shttp_connection *conn) | ||
1831 | { | ||
1832 | int err = 0; | ||
1833 | |||
1834 | switch (conn->result->type) | ||
1835 | { | ||
1836 | case json_arr: | ||
1837 | { | ||
1838 | size_t i, n; | ||
1839 | |||
1840 | n = json_array_size (conn->result); | ||
1841 | for (i = 0; i < n; i++) | ||
1842 | { | ||
1843 | struct json_value *v; | ||
1844 | json_array_get (conn->result, i, &v); | ||
1845 | printf ("%s\n", v->v.s); | ||
1846 | } | ||
1847 | } | ||
1848 | break; | ||
1849 | |||
1850 | case json_object: | ||
1851 | { | ||
1852 | struct json_value *val; | ||
1853 | |||
1854 | val = json_object_require_type (conn->result, "status", json_string); | ||
1855 | if (strcmp (val->v.s, "OK") == 0) | ||
1856 | { | ||
1857 | if (json_object_get_type (conn->result, "value", | ||
1858 | json_string, &val) == 0) | ||
1859 | printf ("%s\n", val->v.s); | ||
1860 | } | ||
1861 | else if (strcmp (val->v.s, "ER") == 0) | ||
1862 | { | ||
1863 | if (json_object_get_type (conn->result, "error_message", | ||