diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-10-31 17:14:07 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-10-31 17:14:07 +0200 |
commit | c221897e72debfb161365c28f08d7f4bac5511e5 (patch) | |
tree | 9db9ef8e74d27cb32cb02c4eb45ce277b744a2a9 /src | |
parent | 9861a788306d5f742e633ff6a8a26a913f5e3fd1 (diff) | |
download | pies-c221897e72debfb161365c28f08d7f4bac5511e5.tar.gz pies-c221897e72debfb161365c28f08d7f4bac5511e5.tar.bz2 |
Implement list control command.
* src/ctl.c: Implement list.
* src/prog.h (IS_COMPONENT): New macro (from progman.c)
* src/progman.c: Move IS_COMPONENT to src/prog.h
* src/socket.c (create_socket): Clear uid, gid and umaskval for
inet sockets.
Diffstat (limited to 'src')
-rw-r--r-- | src/ctl.c | 468 | ||||
-rw-r--r-- | src/pies.h | 2 | ||||
-rw-r--r-- | src/prog.h | 2 | ||||
-rw-r--r-- | src/progman.c | 4 | ||||
-rw-r--r-- | src/socket.c | 4 |
5 files changed, 470 insertions, 10 deletions
@@ -110,6 +110,7 @@ static void cmd_quit (struct ctlio *, size_t, char **); | |||
110 | static void cmd_noop (struct ctlio *, size_t, char **); | 110 | static void cmd_noop (struct ctlio *, size_t, char **); |
111 | static void cmd_help (struct ctlio *, size_t, char **); | 111 | static void cmd_help (struct ctlio *, size_t, char **); |
112 | static void cmd_id (struct ctlio *, size_t, char **); | 112 | static void cmd_id (struct ctlio *, size_t, char **); |
113 | static void cmd_list (struct ctlio *, size_t, char **); | ||
113 | 114 | ||
114 | struct ctlio_command | 115 | struct ctlio_command |
115 | { | 116 | { |
@@ -130,6 +131,8 @@ static struct ctlio_command cmdtab[] = { | |||
130 | CTL_ALL_STATES, 1, 1, cmd_quit }, | 131 | CTL_ALL_STATES, 1, 1, cmd_quit }, |
131 | { "help", "display help", | 132 | { "help", "display help", |
132 | CTL_ALL_STATES, 1, 1, cmd_help }, | 133 | CTL_ALL_STATES, 1, 1, cmd_help }, |
134 | { "list", "list components", | ||
135 | CTL_AUTHENTICATED_STATE, 1, 0, cmd_list }, | ||
133 | { NULL } | 136 | { NULL } |
134 | }; | 137 | }; |
135 | 138 | ||
@@ -161,10 +164,14 @@ ctlio_create (void) | |||
161 | struct ctlio *io; | 164 | struct ctlio *io; |
162 | 165 | ||
163 | io = xmalloc (sizeof (*io)); | 166 | io = xmalloc (sizeof (*io)); |
164 | io->state = CTL_INITIAL_STATE; | 167 | io->state = CTL_AUTHENTICATED_STATE; //FIXME CTL_INITIAL_STATE; |
165 | ctlbuf_init (&io->ibuf); | 168 | ctlbuf_init (&io->ibuf); |
166 | ctlbuf_init (&io->obuf); | 169 | ctlbuf_init (&io->obuf); |
167 | io->wsflags = WRDSF_DEFFLAGS; | 170 | io->ws.ws_delim = " \t()"; |
171 | io->wsflags = WRDSF_DELIM | | ||
172 | WRDSF_NOVAR | WRDSF_NOCMD | | ||
173 | WRDSF_QUOTE | WRDSF_RETURN_DELIMS | | ||
174 | WRDSF_WS; | ||
168 | return io; | 175 | return io; |
169 | } | 176 | } |
170 | 177 | ||
@@ -305,12 +312,12 @@ static void | |||
305 | cmd_id (struct ctlio *io, size_t argc, char **argv) | 312 | cmd_id (struct ctlio *io, size_t argc, char **argv) |
306 | { | 313 | { |
307 | ctlio_reply (io, "110", "instance identification follows"); | 314 | ctlio_reply (io, "110", "instance identification follows"); |
308 | ctlio_printf (io, "Package:%s%s", PACKAGE_NAME, CRLF); | 315 | ctlio_printf (io, "Package: %s%s", PACKAGE_NAME, CRLF); |
309 | ctlio_printf (io, "Version:%s%s", PACKAGE_VERSION, CRLF); | 316 | ctlio_printf (io, "Version: %s%s", PACKAGE_VERSION, CRLF); |
310 | #if HAVE_DECL_PROGRAM_INVOCATION_NAME | 317 | #if HAVE_DECL_PROGRAM_INVOCATION_NAME |
311 | ctlio_printf (io, "Binary:%s%s", program_invocation_name, CRLF); | 318 | ctlio_printf (io, "Binary: %s%s", program_invocation_name, CRLF); |
312 | #endif | 319 | #endif |
313 | ctlio_printf (io, "Instance:%s%s", instance, CRLF); | 320 | ctlio_printf (io, "Instance: %s%s", instance, CRLF); |
314 | ctlio_eot (io); | 321 | ctlio_eot (io); |
315 | } | 322 | } |
316 | 323 | ||
@@ -327,7 +334,456 @@ cmd_help (struct ctlio *io, size_t argc, char **argv) | |||
327 | } | 334 | } |
328 | ctlio_eot (io); | 335 | ctlio_eot (io); |
329 | } | 336 | } |
337 | |||
338 | static char const *pies_comp_mode_str[] = { | ||
339 | [pies_comp_exec] = "exec", | ||
340 | [pies_comp_accept] = "accept", | ||
341 | [pies_comp_inetd] = "inetd", | ||
342 | [pies_comp_pass_fd] = "pass_fd", | ||
343 | [pies_comp_wait] = "wait", | ||
344 | [pies_comp_once] = "once", | ||
345 | [pies_comp_boot] = "boot", | ||
346 | [pies_comp_bootwait] = "bootwait", | ||
347 | [pies_comp_powerfail] = "powerfail", | ||
348 | [pies_comp_powerwait] = "powerwait", | ||
349 | [pies_comp_powerokwait] = "powerokwait", | ||
350 | [pies_comp_ctrlaltdel] = "ctrlaltdel", | ||
351 | [pies_comp_ondemand] = "ondemand", | ||
352 | [pies_comp_sysinit] = "sysinit", | ||
353 | [pies_comp_powerfailnow] = "powerfailnow", | ||
354 | [pies_comp_kbrequest] = "kbrequest" | ||
355 | }; | ||
356 | |||
357 | static char const *status_str[] = { | ||
358 | [status_enabled] = "enabled", | ||
359 | [status_disabled] = "disabled", | ||
360 | [status_listener] = "listener", | ||
361 | [status_sleeping] = "sleeping", | ||
362 | [status_stopping] = "stopping", | ||
363 | [status_finished] = "finished" | ||
364 | }; | ||
365 | |||
366 | static void | ||
367 | format_idx (struct ctlio *io, const char *header, unsigned i, | ||
368 | char const **a, size_t s) | ||
369 | { | ||
370 | if (i < s && a[i]) | ||
371 | ctlio_printf (io, "%s: %s%s", header, a[i], CRLF); | ||
372 | } | ||
373 | |||
374 | #define FORMAT_IDX(io,h,a,i) \ | ||
375 | format_idx (io, h, i, a, sizeof(a)/sizeof(a[0])) | ||
376 | |||
377 | static int | ||
378 | term_to_idx (char const *str, char const **a, size_t s) | ||
379 | { | ||
380 | size_t i; | ||
381 | |||
382 | for (i = 0; i < s; i++) | ||
383 | if (strcasecmp (a[i], str) == 0) | ||
384 | return i; | ||
385 | return -1; | ||
386 | } | ||
387 | |||
388 | #define TERM_TO_IDX(str,a) term_to_idx (str, a, sizeof (a) / sizeof ((a)[0])) | ||
389 | |||
390 | /* Prog conditionals */ | ||
391 | enum pcond_type | ||
392 | { | ||
393 | pcond_true, | ||
394 | pcond_component, | ||
395 | pcond_mode, | ||
396 | pcond_status, | ||
397 | pcond_not, | ||
398 | pcond_and, | ||
399 | pcond_or | ||
400 | }; | ||
401 | |||
402 | struct pcond_node | ||
403 | { | ||
404 | enum pcond_type type; | ||
405 | union | ||
406 | { | ||
407 | char *tag; | ||
408 | enum pies_comp_mode mode; | ||
409 | enum prog_status status; | ||
410 | struct pcond_node *unary; | ||
411 | struct pcond_node *binary[2]; | ||
412 | } v; | ||
413 | }; | ||
414 | |||
415 | static struct pcond_node * | ||
416 | pcond_node_alloc (enum pcond_type t) | ||
417 | { | ||
418 | struct pcond_node *pn; | ||
419 | |||
420 | pn = xmalloc (sizeof (*pn)); | ||
421 | pn->type = t; | ||
422 | return pn; | ||
423 | } | ||
424 | |||
425 | static int | ||
426 | pcond_eval (struct pcond_node *node, struct prog *p) | ||
427 | { | ||
428 | if (!node) | ||
429 | return 0; | ||
430 | if (!IS_COMPONENT (p)) | ||
431 | return 0; | ||
432 | switch (node->type) | ||
433 | { | ||
434 | case pcond_true: | ||
435 | return 1; | ||
436 | |||
437 | case pcond_component: | ||
438 | return strcmp (p->tag, node->v.tag) == 0; | ||
439 | |||
440 | case pcond_mode: | ||
441 | return p->v.p.comp->mode == node->v.mode; | ||
442 | |||
443 | case pcond_status: | ||
444 | return p->v.p.status == node->v.status; | ||
445 | |||
446 | case pcond_not: | ||
447 | return !pcond_eval (node->v.unary, p); | ||
448 | |||
449 | case pcond_and: | ||
450 | if (!pcond_eval (node->v.binary[0], p)) | ||
451 | return 0; | ||
452 | return pcond_eval (node->v.binary[1], p); | ||
453 | |||
454 | case pcond_or: | ||
455 | if (pcond_eval (node->v.binary[0], p)) | ||
456 | return 1; | ||
457 | return pcond_eval (node->v.binary[1], p); | ||
458 | |||
459 | default: | ||
460 | abort (); | ||
461 | } | ||
462 | } | ||
463 | |||
464 | static void | ||
465 | pcond_free (struct pcond_node *node) | ||
466 | { | ||
467 | if (!node) | ||
468 | return; | ||
469 | switch (node->type) | ||
470 | { | ||
471 | case pcond_true: | ||
472 | break; | ||
473 | |||
474 | case pcond_component: | ||
475 | free (node->v.tag); | ||
476 | |||
477 | case pcond_mode: | ||
478 | case pcond_status: | ||
479 | break; | ||
480 | |||
481 | case pcond_not: | ||
482 | pcond_free (node->v.unary); | ||
483 | break; | ||
484 | |||
485 | case pcond_and: | ||
486 | pcond_free (node->v.binary[0]); | ||
487 | pcond_free (node->v.binary[1]); | ||
488 | break; | ||
489 | |||
490 | case pcond_or: | ||
491 | pcond_free (node->v.binary[0]); | ||
492 | pcond_free (node->v.binary[1]); | ||
493 | break; | ||
494 | |||
495 | default: | ||
496 | abort (); | ||
497 | } | ||
498 | free (node); | ||
499 | } | ||
500 | |||
501 | struct pcond_parser_state | ||
502 | { | ||
503 | struct ctlio *io; | ||
504 | size_t argc; | ||
505 | char **argv; | ||
506 | }; | ||
507 | |||
508 | static int pcond_parse_binary (struct pcond_parser_state *state, | ||
509 | struct pcond_node **ret); | ||
510 | |||
511 | static int | ||
512 | pcond_parse_unary (struct pcond_parser_state *state, struct pcond_node **ret) | ||
513 | { | ||
514 | char *term; | ||
515 | struct pcond_node *pn; | ||
516 | int rc, n; | ||
517 | |||