aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2016-02-25 16:17:36 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2016-02-25 16:17:36 +0200
commitc9abb69acae95a0136ee1b03dec8b08d9639005e (patch)
treefa5849647e6d9430289a71035630475a82f4cf54 /src
parent1ec50721c1aa5959009f0c74afc8b7796f4ffd20 (diff)
downloadpies-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.c2
-rw-r--r--src/ctl.c86
-rw-r--r--src/pies.h4
-rw-r--r--src/piesctl.c143
-rw-r--r--src/sysvinit.c90
5 files changed, 293 insertions, 32 deletions
diff --git a/src/acl.c b/src/acl.c
index 7b834c9..7d7b110 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -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;
diff --git a/src/ctl.c b/src/ctl.c
index 61ed55e..731b31b 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -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 *);
921static void res_runlevel (struct ctlio *, enum http_method, char const *, 922static void res_runlevel (struct ctlio *, enum http_method, char const *,
922 struct json_value *); 923 struct json_value *);
924static void res_environ (struct ctlio *, enum http_method, char const *,
925 struct json_value *);
923static void res_conf (struct ctlio *, enum http_method, char const *, 926static 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 */
2423static void
2424env_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
2443static void
2444res_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}
diff --git a/src/pies.h b/src/pies.h
index c858932..6fce820 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -546,6 +546,10 @@ void sysvinit_report (struct json_value *obj);
546int sysvinit_set_runlevel (int newlevel); 546int sysvinit_set_runlevel (int newlevel);
547void sysvinit_parse_argv (int argc, char **argv); 547void sysvinit_parse_argv (int argc, char **argv);
548 548
549int sysvinit_envlocate (char const *name, char **value);
550int sysvinit_envdelete (char const *name);
551int sysvinit_envupdate (char const *var);
552
549extern char *sysvinit_environ_hint[]; 553extern char *sysvinit_environ_hint[];
550extern char *init_fifo; 554extern 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
894static void 894static void
895echo_off (struct termios *stored_settings) 895echo_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 */
1773struct telinit_parser 1775struct 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
1829static void
1830telinit_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",