diff options
Diffstat (limited to 'src/ctl.c')
-rw-r--r-- | src/ctl.c | 64 |
1 files changed, 58 insertions, 6 deletions
@@ -18,7 +18,6 @@ #include "prog.h" #include "identity.h" #include "base64.h" -#include "json.h" struct control control; @@ -443,7 +442,7 @@ json_reply_create (void) return json_new_object (); } -static void +void json_object_set_string (struct json_value *obj, char const *name, char const *fmt, ...) { @@ -458,7 +457,7 @@ json_object_set_string (struct json_value *obj, grecs_free (s); } -static void +void json_object_set_number (struct json_value *obj, char const *name, double val) { json_object_set (obj, name, json_new_number (val)); @@ -904,21 +903,27 @@ static void res_instance (struct ctlio *, enum http_method, char const *, struct json_value *); static void res_programs (struct ctlio *, enum http_method, char const *, struct json_value *); +static void res_runlevel (struct ctlio *, enum http_method, char const *, + struct json_value *); + +static int pred_sysvinit (void); struct ctlio_resource { char const *uri; size_t uri_len; int states; + int (*predicate) (void); void (*handler) (struct ctlio *, enum http_method, char const *uri, struct json_value *); }; static struct ctlio_resource restab[] = { #define S(s) #s, (sizeof (#s)-1) - { S(/instance), CTL_ADMIN_STATE, res_instance }, - { S(/programs), CTL_ADMIN_STATE|CTL_USER_STATE, + { S(/instance), CTL_ADMIN_STATE, NULL, res_instance }, + { S(/programs), CTL_ADMIN_STATE|CTL_USER_STATE, NULL, res_programs }, + { S(/runlevel), CTL_ADMIN_STATE, pred_sysvinit, res_runlevel }, { NULL } #undef S }; @@ -939,7 +944,8 @@ find_resource (struct ctlio *io, const char *endpoint) if (len >= p->uri_len && memcmp (p->uri, endpoint, p->uri_len) == 0 && (endpoint[p->uri_len] == 0 || endpoint[p->uri_len] == '/' - || endpoint[p->uri_len] == '?')) + || endpoint[p->uri_len] == '?') + && (!p->predicate || p->predicate())) return p; return NULL; } @@ -2010,3 +2016,49 @@ res_programs (struct ctlio *io, enum http_method meth, else res_programs_select (io, meth, uri, json); } + +static int +pred_sysvinit (void) +{ + return init_process; +} + +static void +res_runlevel (struct ctlio *io, enum http_method meth, + char const *uri, struct json_value *json) +{ + if (uri) + ctlio_reply (io, 404, NULL); + else if (meth == METH_GET) + { + io->output.reply = json_reply_create (); + io->code = 200; + sysvinit_report (io->output.reply); + } + else if (meth == METH_PUT) + { + struct json_value *val; + // { "runlevel": "3" } + if (json_object_get (json, "runlevel", &val)) + ctlio_reply (io, 400, "missing runlevel request"); + else if (val->type != json_string) + ctlio_reply (io, 400, "bad runlevel type"); + else + { + io->output.reply = json_reply_create (); + io->code = 200; + if (strlen (val->v.s) == 1 + && sysvinit_set_runlevel (val->v.s[0]) == 0) + json_object_set_string (io->output.reply, "status", "OK"); + else + { + json_object_set_string (io->output.reply, "status", "ER"); + json_object_set_string (io->output.reply, "error_message", + "invalid runlevel value"); + } + } + } + else + ctlio_reply (io, 405, NULL); +} + |