diff --git a/Makefile b/Makefile index 99ec2966..9f858caa 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -# Finit - Extremely fast /sbin/init replacement w/ I/O, hook & service plugins +# Finit - Fast /sbin/init replacement w/ I/O, hook & service plugins # # Copyright (c) 2008-2010 Claudio Matsuoka -# Copyright (c) 2008-2014 Joachim Nilsson +# Copyright (c) 2008-2015 Joachim Nilsson # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -36,7 +36,8 @@ ARCHIVEZ = ../$(ARCHIVE).xz EXEC = finit reboot HEADERS = plugin.h svc.h helpers.h queue.h DISTFILES = LICENSE README CHANGELOG finit.conf services -OBJS = finit.o conf.o helpers.o sig.o svc.o service.o plugin.o tty.o inetd.o +OBJS = finit.o client.o conf.o helpers.o sig.o svc.o service.o \ + plugin.o tty.o inetd.o TOPDIR = $(shell pwd) -include config.mk diff --git a/client.c b/client.c new file mode 100644 index 00000000..edb4d5dc --- /dev/null +++ b/client.c @@ -0,0 +1,162 @@ +/* Finit client for querying status and control services + * + * Copyright (c) 2008-2010 Claudio Matsuoka + * Copyright (c) 2008-2015 Joachim Nilsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "finit.h" +#include "helpers.h" +#include "service.h" + +#include "libite/lite.h" + + +static char *runlevel_string(svc_t *svc) +{ + int i, pos = 1;; + static char lvl[10] = "[]"; + + for (i = 0; i < 10; i++) { + if (ISSET(svc->runlevels, i)) { + if (i == 0) + lvl[pos++] = 'S'; + else + lvl[pos++] = '0' + i; + } + } + lvl[pos++] = ']'; + lvl[pos] = 0; + + return lvl; +} + +static int status(void) +{ + svc_t *svc; + + printf("Status PID Runlevels Service Description\n"); + printf("==============================================================================\n"); + for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) { + printf("%7s %-6d %-9s %-20s %s\n", + svc->pid ? "running" : "waiting", svc->pid, + runlevel_string(svc), svc->cmd, svc->desc); + } + + return 0; +} + +static int usage(int rc) +{ + fprintf(stderr, "Usage: %s [OPTIONS] [status | <1-6>]\n\n" + "Options:\n" + " -d, --debug Enable/Disable debug\n" + " -h, --help This help text\n\n" + "Commands:\n" + " status Show status of services\n\n", __progname); + + return rc; +} + +int client(int argc, char *argv[]) +{ + int fd; + int c; + int result = -1; + ssize_t len; + struct { + char *cmd; + int (*cb)(void); + } command[] = { + { "status", status }, + { NULL, NULL } + }; + struct option long_options[] = { + {"debug", 0, NULL, 'd'}, + {"help", 0, NULL, 'h'}, + {NULL, 0, NULL, 0} + }; + struct init_request rq = { + .magic = INIT_MAGIC, + .cmd = 0 + }; + + while ((c = getopt_long(argc, argv, "h?d", long_options, NULL)) != EOF) { + switch(c) { + case 'd': + rq.cmd = INIT_CMD_DEBUG; + break; + + case 'h': + case '?': + return usage(0); + default: + return usage(1); + } + } + + if (!rq.cmd) { + if (argc < 2) { + fprintf(stderr, "Missing argument.\n"); + return usage(1); + } + + for (c = 0; command[c].cmd; c++) { + if (!strcmp(command[c].cmd, argv[1])) + return command[c].cb(); + } + + rq.cmd = INIT_CMD_RUNLVL; + rq.runlevel = (int)argv[1][0]; + } + + if (!fexist(FINIT_FIFO)) { + fprintf(stderr, "/sbin/init does not support %s!\n", FINIT_FIFO); + return 1; + } + + fd = open(FINIT_FIFO, O_RDWR); + if (-1 == fd) { + perror("Failed opening " FINIT_FIFO); + return 1; + } + + len = write(fd, &rq, sizeof(rq)); + if (len == sizeof(rq)) { + len = read(fd, &rq, sizeof(rq)); + if (len == sizeof(rq) && rq.cmd == INIT_CMD_ACK) + result = 0; + } + + close(fd); + + return result; +} + +/** + * Local Variables: + * version-control: t + * indent-tabs-mode: t + * c-file-style: "linux" + * End: + */ diff --git a/finit.c b/finit.c index e6c14580..d270752c 100644 --- a/finit.c +++ b/finit.c @@ -1,7 +1,7 @@ -/* Finit - Extremely fast /sbin/init replacement w/ I/O, hook & service plugins +/* Finit - Fast /sbin/init replacement w/ I/O, hook & service plugins * * Copyright (c) 2008-2010 Claudio Matsuoka - * Copyright (c) 2008-2014 Joachim Nilsson + * Copyright (c) 2008-2015 Joachim Nilsson * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,7 +26,6 @@ #include #include #include /* umask(), mkdir() */ -#include #include "finit.h" #include "helpers.h" @@ -72,78 +71,6 @@ static void parse_kernel_cmdline(void) } } -static int usage(int rc) -{ - fprintf(stderr, "Usage: %s [OPTIONS] [RUNLEVEL]\n\n" - " -d, --debug Enable/Disable debug\n" - " -h, --help This help text\n\n", __progname); - - return rc; -} - -static int client(int argc, char *argv[]) -{ - int fd; - int c; - int result = -1; - ssize_t len; - struct option long_options[] = { - {"debug", 0, NULL, 'd'}, - {"help", 0, NULL, 'h'}, - {NULL, 0, NULL, 0} - }; - struct init_request rq = { - .magic = INIT_MAGIC, - .cmd = 0 - }; - - while ((c = getopt_long(argc, argv, "h?d", long_options, NULL)) != EOF) { - switch(c) { - case 'd': - rq.cmd = INIT_CMD_DEBUG; - break; - - case 'h': - case '?': - return usage(0); - default: - return usage(1); - } - } - - if (!rq.cmd) { - if (argc < 2) { - fprintf(stderr, "Missing runlevel.\n"); - return 1; - } - - rq.cmd = INIT_CMD_RUNLVL; - rq.runlevel = (int)argv[1][0]; - } - - if (!fexist(FINIT_FIFO)) { - fprintf(stderr, "/sbin/init does not support %s!\n", FINIT_FIFO); - return 1; - } - - fd = open(FINIT_FIFO, O_RDWR); - if (-1 == fd) { - perror("Failed opening " FINIT_FIFO); - return 1; - } - - len = write(fd, &rq, sizeof(rq)); - if (len == sizeof(rq)) { - len = read(fd, &rq, sizeof(rq)); - if (len == sizeof(rq) && rq.cmd == INIT_CMD_ACK) - result = 0; - } - - close(fd); - - return result; -} - static void banner(void) { delline(); diff --git a/finit.h b/finit.h index edf24825..51e66405 100644 --- a/finit.h +++ b/finit.h @@ -1,7 +1,7 @@ -/* Finit - Extremely fast /sbin/init replacement w/ I/O, hook & service plugins +/* Finit - Fast /sbin/init replacement w/ I/O, hook & service plugins * * Copyright (c) 2008-2010 Claudio Matsuoka - * Copyright (c) 2008-2013 Joachim Nilsson + * Copyright (c) 2008-2015 Joachim Nilsson * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/private.h b/private.h index c8260f99..5df2b861 100644 --- a/private.h +++ b/private.h @@ -30,6 +30,8 @@ uev_ctx_t *ctx; /* Main loop context */ +int client (int argc, char *argv[]); + void service_bootstrap(void); void service_monitor (pid_t lost);