diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-01-02 23:58:06 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-01-02 23:58:06 +0200 |
commit | 6db017a32e379bb2eb7878771dea969f77c3168c (patch) | |
tree | 0e1563b8239f7c681708c64c0d693f6541e4e155 /src/ctl.c | |
parent | 061afaf6385340f87bbeaa6d7e8ff6befa532551 (diff) | |
download | pies-6db017a32e379bb2eb7878771dea969f77c3168c.tar.gz pies-6db017a32e379bb2eb7878771dea969f77c3168c.tar.bz2 |
Switch to new control interface.
Old control options (--status, --restart-components) rewritten using
piesctl.
SIGUSR1 and SIGUSR2 no longer handled.
* lib/arraymember.c (array_index): New function.
* lib/libpies.h: Likewise.
* src/cmdline.opt: Fix copyright years.
* src/piesctl-cl.opt: Likewise.
* src/ctl.c (ctlio_do_command): Implement restart.
(pies_control_url): New function.
(eval_env): rename json to result.
New member cond.
Restore pcond_ functions.
(json_to_pcond): New function.
(res_programs): Conditional selection of programs to list.
Implement restart.
* src/pies.c (ctlfile, statfile): Remove.
(pies_keywords): Mark control-file and stat-file as inactive.
(default_sigv): Remove SIGUSR1 and SIGUSR2
(pies_check_status): Don't send SIGUSR2.
(stop_components): Remove.
(request_restart_components): Rewrite as a wrapper.
Call piesctl to do the job.
(list_components): New function.
* src/pies.h (ACTION_COMPRELOAD)
(ACTION_DUMPSTATS): Remove. All callers changed.
(progman_dump_stats): Remove.
* src/piesctl.c (shttp_request_send): Don't initialize conn->req; the
caller is responsible for that.
(parse_condition, json_to_string)
(parse_condition_to_uri): New functions.
(com_list): Read conditional expression from the command line.
(com_restart): Implement.
* src/progman.c (progman_dump_stats): Remove.
Diffstat (limited to 'src/ctl.c')
-rw-r--r-- | src/ctl.c | 442 |
1 files changed, 398 insertions, 44 deletions
@@ -1000,8 +1000,20 @@ ctlio_do_command (struct ctlio *io, struct wordsplit *uri) | |||
1000 | //FIXME: Reply json | 1000 | //FIXME: Reply json |
1001 | } | 1001 | } |
1002 | } | 1002 | } |
1003 | else if (method != METH_POST | ||
1004 | && uri->ws_wordc > 1 | ||
1005 | && strchr ("\"{[", uri->ws_wordv[uri->ws_wordc-1][0])) | ||
1006 | { | ||
1007 | json = json_parse_string (uri->ws_wordv[uri->ws_wordc-1], | ||
1008 | strlen (uri->ws_wordv[uri->ws_wordc-1])); | ||
1009 | if (!json) | ||
1010 | ctlio_reply (io, 400, NULL); | ||
1011 | free (uri->ws_wordv[uri->ws_wordc-1]); | ||
1012 | uri->ws_wordv[uri->ws_wordc-1] = NULL; | ||
1013 | uri->ws_wordc--; | ||
1014 | } | ||
1003 | else | 1015 | else |
1004 | json = json_value_create (json_null); | 1016 | json = json_new_bool (1); |
1005 | 1017 | ||
1006 | res->handler (io, method, uri->ws_wordc, uri->ws_wordv, json); | 1018 | res->handler (io, method, uri->ws_wordc, uri->ws_wordv, json); |
1007 | json_value_free (json); | 1019 | json_value_free (json); |
@@ -1138,11 +1150,9 @@ ctl_accept (int socket, void *data) | |||
1138 | return 0; | 1150 | return 0; |
1139 | } | 1151 | } |
1140 | 1152 | ||
1141 | void | 1153 | char const * |
1142 | ctl_open () | 1154 | pies_control_url (void) |
1143 | { | 1155 | { |
1144 | int fd; | ||
1145 | |||
1146 | if (!control.url) | 1156 | if (!control.url) |
1147 | { | 1157 | { |
1148 | char *str = xasprintf (DEFAULT_CONTROL_URL, instance); | 1158 | char *str = xasprintf (DEFAULT_CONTROL_URL, instance); |
@@ -1150,11 +1160,19 @@ ctl_open () | |||
1150 | { | 1160 | { |
1151 | logmsg (LOG_CRIT, _("%s: cannot create URL: %s"), | 1161 | logmsg (LOG_CRIT, _("%s: cannot create URL: %s"), |
1152 | str, strerror (errno)); | 1162 | str, strerror (errno)); |
1153 | return; | 1163 | exit (EX_OSERR); |
1154 | } | 1164 | } |
1155 | free (str); | 1165 | free (str); |
1156 | } | 1166 | } |
1157 | 1167 | return control.url->string; | |
1168 | } | ||
1169 | |||
1170 | void | ||
1171 | ctl_open () | ||
1172 | { | ||
1173 | int fd; | ||
1174 | |||
1175 | pies_control_url (); | ||
1158 | fd = create_socket (control.url, SOCK_STREAM, NULL, 077); | 1176 | fd = create_socket (control.url, SOCK_STREAM, NULL, 077); |
1159 | if (fd == -1) | 1177 | if (fd == -1) |
1160 | { | 1178 | { |
@@ -1271,7 +1289,8 @@ res_instance (struct ctlio *io, enum http_method meth, | |||
1271 | struct eval_env | 1289 | struct eval_env |
1272 | { | 1290 | { |
1273 | struct ctlio *io; | 1291 | struct ctlio *io; |
1274 | struct json_value *json; | 1292 | struct pcond_node *cond; |
1293 | struct json_value *result; | ||
1275 | }; | 1294 | }; |
1276 | 1295 | ||
1277 | static int | 1296 | static int |
@@ -1299,26 +1318,14 @@ auth_prog (struct prog *prog, struct ctlio *io) | |||
1299 | } | 1318 | } |
1300 | return 0; | 1319 | return 0; |
1301 | } | 1320 | } |
1302 | |||
1303 | static struct json_value *prog_serialize (struct prog *prog); | ||
1304 | |||
1305 | static int | ||
1306 | selector (struct prog *prog, void *data) | ||
1307 | { | ||
1308 | struct eval_env *env = data; | ||
1309 | |||
1310 | if (auth_prog (prog, env->io)) | ||
1311 | json_array_append (env->json, prog_serialize (prog)); | ||
1312 | return 0; | ||
1313 | } | ||
1314 | 1321 | ||
1315 | static char const *pies_type_str[] = { | 1322 | static char * const pies_type_str[] = { |
1316 | [TYPE_COMPONENT] = "component", | 1323 | [TYPE_COMPONENT] = "component", |
1317 | [TYPE_REDIRECTOR] = "redirector", | 1324 | [TYPE_REDIRECTOR] = "redirector", |
1318 | [TYPE_COMMAND] = "command" | 1325 | [TYPE_COMMAND] = "command" |
1319 | }; | 1326 | }; |
1320 | 1327 | ||
1321 | static char const *pies_comp_mode_str[] = { | 1328 | static char * const pies_comp_mode_str[] = { |
1322 | [pies_comp_exec] = "exec", | 1329 | [pies_comp_exec] = "exec", |
1323 | [pies_comp_accept] = "accept", | 1330 | [pies_comp_accept] = "accept", |
1324 | [pies_comp_inetd] = "inetd", | 1331 | [pies_comp_inetd] = "inetd", |
@@ -1337,7 +1344,7 @@ static char const *pies_comp_mode_str[] = { | |||
1337 | [pies_comp_kbrequest] = "kbrequest" | 1344 | [pies_comp_kbrequest] = "kbrequest" |
1338 | }; | 1345 | }; |
1339 | 1346 | ||
1340 | static char const *status_str[] = { | 1347 | static char * const pies_status_str[] = { |
1341 | [status_enabled] = "enabled", | 1348 | [status_enabled] = "enabled", |
1342 | [status_disabled] = "disabled", | 1349 | [status_disabled] = "disabled", |
1343 | [status_listener] = "listener", | 1350 | [status_listener] = "listener", |
@@ -1348,7 +1355,7 @@ static char const *status_str[] = { | |||
1348 | 1355 | ||
1349 | static void | 1356 | static void |
1350 | format_idx (struct json_value *obj, const char *name, unsigned i, | 1357 | format_idx (struct json_value *obj, const char *name, unsigned i, |
1351 | char const **a, size_t s) | 1358 | char * const *a, size_t s) |
1352 | { | 1359 | { |
1353 | if (i < s && a[i]) | 1360 | if (i < s && a[i]) |
1354 | json_object_set (obj, name, json_new_string (a[i])); | 1361 | json_object_set (obj, name, json_new_string (a[i])); |
@@ -1356,7 +1363,318 @@ format_idx (struct json_value *obj, const char *name, unsigned i, | |||
1356 | 1363 | ||
1357 | #define FORMAT_IDX(io,n,a,i) \ | 1364 | #define FORMAT_IDX(io,n,a,i) \ |
1358 | format_idx (io, n, i, a, sizeof(a)/sizeof(a[0])) | 1365 | format_idx (io, n, i, a, sizeof(a)/sizeof(a[0])) |
1366 | |||
1367 | enum pcond_type | ||
1368 | { | ||
1369 | pcond_true, | ||
1370 | pcond_component, | ||
1371 | pcond_type, | ||
1372 | pcond_mode, | ||
1373 | pcond_status, | ||
1374 | pcond_not, | ||
1375 | pcond_and, | ||
1376 | pcond_or | ||
1377 | }; | ||
1378 | |||
1379 | struct pcond_node | ||
1380 | { | ||
1381 | enum pcond_type type; | ||
1382 | union | ||
1383 | { | ||
1384 | char *tag; | ||
1385 | enum pies_comp_mode mode; | ||
1386 | enum prog_status status; | ||
1387 | enum prog_type type; | ||
1388 | struct pcond_node *unary; | ||
1389 | struct pcond_node *binary[2]; | ||
1390 | } v; | ||
1391 | }; | ||
1392 | |||
1393 | static struct pcond_node * | ||
1394 | pcond_node_alloc (enum pcond_type t) | ||
1395 | { | ||
1396 | struct pcond_node *pn; | ||
1397 | |||
1398 | pn = grecs_zalloc (sizeof (*pn)); | ||
1399 | pn->type = t; | ||
1400 | return pn; | ||
1401 | } | ||
1402 | |||
1403 | static void | ||
1404 | pcond_node_free (struct pcond_node *node) | ||
1405 | { | ||
1406 | if (!node) | ||
1407 | return; | ||
1408 | switch (node->type) | ||
1409 | { | ||
1410 | case pcond_not: | ||
1411 | pcond_node_free (node->v.unary); | ||
1412 | break; | ||
1413 | |||
1414 | case pcond_and: | ||
1415 | case pcond_or: | ||
1416 | pcond_node_free (node->v.binary[0]); | ||
1417 | pcond_node_free (node->v.binary[1]); | ||
1418 | break; | ||
1419 | |||
1420 | default: | ||
1421 | break; | ||
1422 | } | ||
1423 | grecs_free (node); | ||
1424 | } | ||
1425 | |||
1426 | static int | ||
1427 | pcond_eval (struct pcond_node *node, struct prog *p) | ||
1428 | { | ||
1429 | if (!node) | ||
1430 | return 0; | ||
1431 | switch (node->type) | ||
1432 | { | ||
1433 | case pcond_true: | ||
1434 | return 1; | ||
1435 | |||
1436 | case pcond_component: | ||
1437 | return strcmp (p->tag, node->v.tag) == 0; | ||
1438 | |||
1439 | case pcond_type: | ||
1440 | return p->type == node->v.type; | ||
1441 | |||
1442 | case pcond_mode: | ||
1443 | return IS_COMPONENT (p) && p->v.p.comp->mode == node->v.mode; | ||
1444 | |||
1445 | case pcond_status: | ||
1446 | return IS_COMPONENT (p) && p->v.p.status == node->v.status; | ||
1447 | |||
1448 | case pcond_not: | ||
1449 | return !pcond_eval (node->v.unary, p); | ||
1450 | |||
1451 | case pcond_and: | ||
1452 | if (!pcond_eval (node->v.binary[0], p)) | ||
1453 | return 0; | ||
1454 | return pcond_eval (node->v.binary[1], p); | ||
1455 | |||
1456 | case pcond_or: | ||
1457 | if (pcond_eval (node->v.binary[0], p)) | ||
1458 | return 1; | ||
1459 | return pcond_eval (node->v.binary[1], p); | ||
1460 | |||
1461 | default: | ||
1462 | abort (); | ||
1463 | } | ||
1464 | } | ||
1465 | |||
1466 | static int json_to_pcond (struct ctlio *io, struct json_value *val, | ||
1467 | struct pcond_node **pnode); | ||
1468 | |||
1469 | static int | ||