diff options
Diffstat (limited to 'servicecmd')
-rw-r--r-- | servicecmd/Makemodule.am | 13 | ||||
-rw-r--r-- | servicecmd/disable.c | 89 | ||||
-rw-r--r-- | servicecmd/dumpscript.c | 182 | ||||
-rw-r--r-- | servicecmd/enable.c | 98 | ||||
-rw-r--r-- | servicecmd/help.c | 129 | ||||
-rw-r--r-- | servicecmd/list.c | 102 | ||||
-rw-r--r-- | servicecmd/servicecmd.c | 90 | ||||
-rw-r--r-- | servicecmd/servicecmd.h | 93 |
8 files changed, 0 insertions, 796 deletions
diff --git a/servicecmd/Makemodule.am b/servicecmd/Makemodule.am deleted file mode 100644 index 7b85e3f..0000000 --- a/servicecmd/Makemodule.am +++ /dev/null @@ -1,13 +0,0 @@ -SRVHEADERS = servicecmd/servicecmd.h - -service_SOURCES = servicecmd/servicecmd.c servicecmd/help.c servicecmd/list.c -service_SOURCES += servicecmd/enable.c servicecmd/disable.c -service_SOURCES += servicecmd/dumpscript.c $(SRVHEADERS) -service_CPPFLAGS = $(AM_CPPFLAGS) -service_CFLAGS = $(AM_CFLAGS) -service_LDFLAGS = $(AM_LDFLAGS) -service_LDADD = libinit.a - -EXTRA_DIST += $(SRVHEADERS) - -sbin_PROGRAMS += service diff --git a/servicecmd/disable.c b/servicecmd/disable.c deleted file mode 100644 index 8a6f9f3..0000000 --- a/servicecmd/disable.c +++ /dev/null @@ -1,89 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * Copyright (C) 2018 - David Oberhollenzer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <errno.h> - -#include "servicecmd.h" - -static int cmd_disable(int argc, char **argv) -{ - int ret = EXIT_FAILURE; - char *linkname, *ptr; - struct stat sb; - - if (check_arguments(argv[0], argc, 2, 3)) - return EXIT_FAILURE; - - for (ptr = argv[1]; isalnum(*ptr) || *ptr == '_'; ++ptr) - ; - - if (*ptr != '\0') { - fprintf(stderr, "Invalid service name '%s'\n", argv[1]); - tell_read_help(argv[0]); - return EXIT_FAILURE; - } - - if (argc == 3) { - ret = asprintf(&linkname, "%s/%s@%s", - SVCDIR, argv[1], argv[2]); - } else { - ret = asprintf(&linkname, "%s/%s", SVCDIR, argv[1]); - } - - if (ret < 0) { - perror("asprintf"); - return EXIT_FAILURE; - } - - if (lstat(linkname, &sb)) { - fprintf(stderr, "lstat %s: %s\n", linkname, strerror(errno)); - goto out; - } - - if ((sb.st_mode & S_IFMT) != S_IFLNK) { - fprintf(stderr, "error: '%s' is not a symlink!", linkname); - goto out; - } - - if (unlink(linkname)) { - fprintf(stderr, "removing %s: %s\n", - linkname, strerror(errno)); - goto out; - } - - ret = EXIT_SUCCESS; -out: - free(linkname); - return ret; -} - -static command_t disable = { - .cmd = "disable", - .usage = "<name> [argument]", - .s_desc = "disable a service", - .l_desc = "This disables a service by removing the coresponding " - "symlink in " SVCDIR ".", - .run_cmd = cmd_disable, -}; - -REGISTER_COMMAND(disable) diff --git a/servicecmd/dumpscript.c b/servicecmd/dumpscript.c deleted file mode 100644 index 880631f..0000000 --- a/servicecmd/dumpscript.c +++ /dev/null @@ -1,182 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * Copyright (C) 2018 - David Oberhollenzer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> - -#include "servicecmd.h" -#include "service.h" - -static service_t *try_load(const char *directory, const char *filename) -{ - int dirfd, type; - struct stat sb; - service_t *svc; - - dirfd = open(directory, O_RDONLY | O_DIRECTORY); - - if (dirfd < 0) { - perror(directory); - return NULL; - } - - if (fstatat(dirfd, filename, &sb, AT_SYMLINK_NOFOLLOW)) { - fprintf(stderr, "stat %s/%s: %s\n", - directory, filename, strerror(errno)); - close(dirfd); - return NULL; - } - - type = (sb.st_mode & S_IFMT); - - if (type != S_IFREG && type != S_IFLNK) - return NULL; - - svc = rdsvc(dirfd, filename); - close(dirfd); - return svc; -} - -enum { - NEED_QUOTES = 0x01, - NEED_ESCAPE = 0x02, -}; - -static int check_str(const char *str) -{ - int ret = 0; - - while (*str != '\0') { - if (isspace(*str)) - ret |= NEED_QUOTES; - - if (!isascii(*str) || !isprint(*str)) - ret |= NEED_ESCAPE | NEED_QUOTES; - - if (*str == '\\' || *str == '"' || *str == '\n') - ret |= NEED_ESCAPE | NEED_QUOTES; - - ++str; - } - - return ret; -} - -static void print_str(const char *str) -{ - int flags = check_str(str); - - if (flags & NEED_QUOTES) - fputc('"', stdout); - - if (flags & NEED_ESCAPE) { - while (*str != '\0') { - switch (*str) { - case '\a': fputs("\\a", stdout); break; - case '\b': fputs("\\b", stdout); break; - case '\f': fputs("\\f", stdout); break; - case '\r': fputs("\\r", stdout); break; - case '\t': fputs("\\t", stdout); break; - case '\n': fputs("\\n", stdout); break; - case '\\': - case '"': - fprintf(stdout, "\\%c", *str); - break; - default: - if (!isascii(*str) || !isprint(*str)) { - fprintf(stdout, "\\x%02X", *str); - } else { - fputc(*str, stdout); - } - break; - } - ++str; - } - } else { - fputs(str, stdout); - } - - if (flags & NEED_QUOTES) - fputc('"', stdout); -} - -static int cmd_dumpscript(int argc, char **argv) -{ - char *filename, *ptr; - service_t *svc; - size_t len; - exec_t *e; - int i; - - if (check_arguments(argv[0], argc, 2, 3)) - return EXIT_FAILURE; - - for (len = 1, i = 1; i < argc; ++i) - len += strlen(argv[i]) + 1; - - filename = alloca(len); - filename[0] = '\0'; - - for (i = 1; i < argc; ++i) { - if (i > 1) - strcat(filename, "@"); - strcat(filename, argv[i]); - } - - svc = try_load(SVCDIR, filename); - - if (svc == NULL) { - fprintf(stderr, "Could not load service '%s'\n", filename); - return EXIT_FAILURE; - } - - fprintf(stdout, "#\n# commands executed for serice '%s'\n#\n", - filename); - - for (e = svc->exec; e != NULL; e = e->next) { - ptr = e->args; - - for (i = 0; i < e->argc; ++i) { - if (i) - fputc(' ', stdout); - - print_str(ptr); - ptr += strlen(ptr) + 1; - } - - putchar('\n'); - } - - delsvc(svc); - return EXIT_SUCCESS; -} - -static command_t dumpscript = { - .cmd = "dumpscript", - .usage = "<name> [arguments]", - .s_desc = "print commands executed for a service", - .l_desc = "This parses a service file from " SVCDIR " and " - "produces a pseudo-shell-script containing the " - "exact commands after argument expansion that init " - "runs when starting the service.", - .run_cmd = cmd_dumpscript, -}; - -REGISTER_COMMAND(dumpscript) diff --git a/servicecmd/enable.c b/servicecmd/enable.c deleted file mode 100644 index 5d4195e..0000000 --- a/servicecmd/enable.c +++ /dev/null @@ -1,98 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * Copyright (C) 2018 - David Oberhollenzer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <errno.h> - -#include "servicecmd.h" - -static int cmd_enable(int argc, char **argv) -{ - char *target, *linkname, *ptr; - int ret = EXIT_FAILURE; - struct stat sb; - - if (check_arguments(argv[0], argc, 2, 3)) - return EXIT_FAILURE; - - for (ptr = argv[1]; isalnum(*ptr) || *ptr == '_'; ++ptr) - ; - - if (*ptr != '\0') { - fprintf(stderr, "Invalid service name '%s'\n", argv[1]); - tell_read_help(argv[0]); - return EXIT_FAILURE; - } - - if (asprintf(&target, "%s/%s", TEMPLATEDIR, argv[1]) < 0) { - perror("asprintf"); - return EXIT_FAILURE; - } - - if (stat(target, &sb)) { - fprintf(stderr, "%s: %s\n", target, strerror(errno)); - goto out_tgt; - } - - if ((sb.st_mode & S_IFMT) != S_IFREG) { - fprintf(stderr, "%s: must be a regular file\n", target); - goto out_tgt; - } - - if (argc == 3) { - ret = asprintf(&linkname, "%s/%s@%s", - SVCDIR, argv[1], argv[2]); - } else { - ret = asprintf(&linkname, "%s/%s", SVCDIR, argv[1]); - } - - if (ret < 0) { - perror("asprintf"); - goto out_tgt; - } - - if (symlink(target, linkname)) { - fprintf(stderr, "creating symlink '%s' -> '%s: %s\n", - linkname, target, strerror(errno)); - goto out; - } - - ret = EXIT_SUCCESS; -out: - free(linkname); -out_tgt: - free(target); - return ret; -} - -static command_t enable = { - .cmd = "enable", - .usage = "<name> [argument]", - .s_desc = "enable a service", - .l_desc = "This marks a service as enabled by creating a symlink in " - SVCDIR " pointing to the template file in " TEMPLATEDIR ". " - "An optional argument can be supplied to parameterize the " - "template.", - .run_cmd = cmd_enable, -}; - -REGISTER_COMMAND(enable) diff --git a/servicecmd/help.c b/servicecmd/help.c deleted file mode 100644 index 4fa9951..0000000 --- a/servicecmd/help.c +++ /dev/null @@ -1,129 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * Copyright (C) 2018 - David Oberhollenzer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ -#include "servicecmd.h" - -extern char *__progname; - -static void pretty_print(const char *str, int padd, int len) -{ - int i, brk; -next: - while (isspace(*str) && *str != '\n') - ++str; - - if (!(*str)) - return; - - if (*str == '\n') { - fputc('\n', stdout); - ++str; - len = padd; - goto next; - } - - for (i = 0, brk = 0; str[i]; ++i) { - if (str[i] == '<' || str[i] == '[') - ++brk; - if (str[i] == '>' || str[i] == ']') - --brk; - if (!brk && isspace(str[i])) - break; - } - - if ((len + i) < 80) { - fwrite(str, 1, i, stdout); - str += i; - len += i; - - if ((len + 1) < 80) { - fputc(' ', stdout); - ++len; - goto next; - } - } - - printf("\n%*s", padd, ""); - len = padd; - goto next; -} - -static void print_cmd_usage(const char *cmd, const char *usage) -{ - int padd; - - padd = printf("Usage: %s %s ", __progname, cmd); - - if ((strlen(usage) + padd) < 80) { - fputs(usage, stdout); - return; - } - - pretty_print(usage, padd, padd); -} - -static int cmd_help(int argc, char **argv) -{ - const char *help; - command_t *cmd; - - if (argc < 2) - usage(EXIT_SUCCESS); - - if (argc > 2) { - fprintf(stderr, "Too many arguments\n\n" - "Usage: %s help <command>", __progname); - return EXIT_FAILURE; - } - - for (cmd = commands; cmd != NULL; cmd = cmd->next) { - if (strcmp(cmd->cmd, argv[1]) != 0) - continue; - - print_cmd_usage(cmd->cmd, cmd->usage); - fputs("\n\n", stdout); - - help = cmd->l_desc ? cmd->l_desc : cmd->s_desc; - - if (islower(*help)) { - fputc(toupper(*(help++)), stdout); - pretty_print(help, 0, 1); - } else { - pretty_print(help, 0, 0); - } - - fputc('\n', stdout); - return EXIT_SUCCESS; - } - - fprintf(stderr, "Unknown command '%s'\n\n" - "Try `%s help' for a list of available commands\n", - argv[1], __progname); - return EXIT_FAILURE; -} - -static command_t help = { - .cmd = "help", - .usage = "<command>", - .s_desc = "print a help text for a command", - .l_desc = "Print a help text for a specified command. If no command " - "is specified, print a generic help text and a list of " - "available commands.", - .run_cmd = cmd_help, -}; - -REGISTER_COMMAND(help) diff --git a/servicecmd/list.c b/servicecmd/list.c deleted file mode 100644 index b9e342a..0000000 --- a/servicecmd/list.c +++ /dev/null @@ -1,102 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * Copyright (C) 2018 - David Oberhollenzer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ -#include "servicecmd.h" -#include "service.h" -#include "config.h" - -static void print_services(service_t *svc) -{ - const char *ptr; - int i; - - for (; svc != NULL; svc = svc->next) { - printf("Name: %s\n", svc->name); - printf("\tDescrption: %s\n", svc->desc); - printf("\tType: %s\n", svc_type_to_string(svc->type)); - printf("\tTarget: %s\n", svc_target_to_string(svc->target)); - - if (svc->type == SVC_RESPAWN && svc->rspwn_limit > 0) - printf("\tRespawn limit: %d\n", svc->rspwn_limit); - - ptr = svc->before; - if (ptr != NULL && svc->num_before > 0) { - fputs("\tMust be run before:\n", stdout); - - for (i = 0; i < svc->num_before; ++i) { - printf("\t\t%s\n", ptr); - ptr += strlen(ptr) + 1; - } - } - - ptr = svc->after; - if (ptr != NULL && svc->num_after > 0) { - fputs("\tMust be run after:\n", stdout); - - for (i = 0; i < svc->num_after; ++i) { - printf("\t\t%s\n", ptr); - ptr += strlen(ptr) + 1; - } - } - } -} - -static int cmd_list(int argc, char **argv) -{ - int i, ret = EXIT_SUCCESS; - service_list_t list; - - if (check_arguments(argv[0], argc, 1, 2)) - return EXIT_FAILURE; - - if (svcscan(SVCDIR, &list)) { - fprintf(stderr, "Error while reading services from %s\n", - SVCDIR); - ret = EXIT_FAILURE; - } - - if (argc == 2) { - i = svc_target_from_string(argv[1]); - - if (i == -1) { - fprintf(stderr, "Unknown target `%s'\n", argv[1]); - tell_read_help(argv[0]); - ret = EXIT_FAILURE; - goto out; - } - - print_services(list.targets[i]); - } else { - for (i = 0; i < TGT_MAX; ++i) - print_services(list.targets[i]); - } -out: - del_svc_list(&list); - return ret; -} - -static command_t list = { - .cmd = "list", - .usage = "[target]", - .s_desc = "print a list of currently enabled services", - .l_desc = "Print a list of currently enabled services. If an " - "optional target is specified, print services for this " - "target.", - .run_cmd = cmd_list, -}; - -REGISTER_COMMAND(list) diff --git a/servicecmd/servicecmd.c b/servicecmd/servicecmd.c deleted file mode 100644 index 84e6a32..0000000 --- a/servicecmd/servicecmd.c +++ /dev/null @@ -1,90 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * Copyright (C) 2018 - David Oberhollenzer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ -#include <stdlib.h> -#include <stdio.h> - -#include "servicecmd.h" -#include "service.h" -#include "config.h" -#include "util.h" - - -command_t *commands; - -extern char *__progname; - - -void usage(int status) -{ - FILE *stream = (status == EXIT_SUCCESS ? stdout : stderr); - int padd = 0, len; - command_t *cmd; - - fprintf(stream, "usage: %s <command> [args...]\n\n" - "Available commands:\n\n", __progname); - - for (cmd = commands; cmd != NULL; cmd = cmd->next) { - len = strlen(cmd->cmd); - - padd = len > padd ? len : padd; - } - - for (cmd = commands; cmd != NULL; cmd = cmd->next) { - fprintf(stream, "%*s - %s\n", - (int)padd + 1, cmd->cmd, cmd->s_desc); - } - - fprintf(stream, "\nTry `%s help <command>' for more information " - "on a specific command\n", __progname); - - exit(status); -} - -void tell_read_help(const char *cmd) -{ - fprintf(stderr, "Try `%s help %s' for more information.\n", - __progname, cmd); -} - -int check_arguments(const char *cmd, int argc, int minc, int maxc) -{ - if (argc >= minc && argc <= maxc) - return 0; - - fprintf(stderr, "Too %s arguments for `%s'\n", - argc > maxc ? "many" : "few", cmd); - tell_read_help(cmd); - return -1; -} - -int main(int argc, char **argv) -{ - command_t *cmd; - - if (argc < 2) - usage(EXIT_SUCCESS); - - for (cmd = commands; cmd != NULL; cmd = cmd->next) { - if (!strcmp(cmd->cmd, argv[1])) { - return cmd->run_cmd(argc - 1, argv + 1); - } - } - - fprintf(stderr, "Unknown command '%s'\n\n", argv[1]); - usage(EXIT_FAILURE); -} diff --git a/servicecmd/servicecmd.h b/servicecmd/servicecmd.h deleted file mode 100644 index b839799..0000000 --- a/servicecmd/servicecmd.h +++ /dev/null @@ -1,93 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * Copyright (C) 2018 - David Oberhollenzer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ -#ifndef SERVICECMD_H -#define SERVICECMD_H - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <ctype.h> - -#include "util.h" - -/* - Describes a command that can be launched by passing its name as - second command line argument to the main() function (i.e. immediately - after the actual program name). - - Short and long descriptions can be provided to print out help text. - - The main() function calls into a callback in this structure to execute - the command. -*/ -typedef struct command_t { - struct command_t *next; - - const char *cmd; /* command name */ - const char *usage; /* list of possible arguments */ - const char *s_desc; /* short description used by help */ - const char *l_desc; /* long description used by help */ - - /* - Semantics are the same as for main(). Called from main() - function with first argument (i.e. top level program name) - removed. - */ - int (*run_cmd)(int argc, char **argv); -} command_t; - -/* Global list of available commands */ -extern command_t *commands; - -/* - Implemented in servicecmd.c. Prints program usage message and - terminates with the given exit status. -*/ -void usage(int status) NORETURN; - -/* - Write a message to stderr that advises the user how to consult the - help text for a specific command. -*/ -void tell_read_help(const char *cmd); - -/* - Check if the argument count is within specified bounds (minc and maxc - inclusive). If it is, return 0. - - If it isn't, complain about a wrong number of arguments for a - command (cmd), tell the user to consult the help text and return -1. -*/ -int check_arguments(const char *cmd, int argc, int minc, int maxc); - -/* - To implement a new command, add a global, static instance of a - command_t (or derived) structure to a C file and pass it to this - macro to have it automatically registered on program startup. -*/ -#define REGISTER_COMMAND(cmd) \ - static void __attribute__((constructor)) register_##cmd(void) \ - { \ - command_t *c = (command_t *)&cmd; \ - \ - c->next = commands; \ - commands = c; \ - } - -#endif /* SERVICECMD_H */ - |