aboutsummaryrefslogtreecommitdiff
path: root/servicecmd
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@tele2.at>2018-04-12 05:30:12 +0200
committerDavid Oberhollenzer <david.oberhollenzer@tele2.at>2018-04-12 10:28:40 +0200
commit6cf0a254cd9e4892a941bb5ad6f8d9ed317b1617 (patch)
treead9f1b409c5a465986078ee16b102f6fa6cfbdb3 /servicecmd
parente148e873e05e4ebe4d7a90cdbe8cdd72618eb7ac (diff)
Build system and directory structure cleanup
Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
Diffstat (limited to 'servicecmd')
-rw-r--r--servicecmd/Makemodule.am13
-rw-r--r--servicecmd/disable.c89
-rw-r--r--servicecmd/dumpscript.c182
-rw-r--r--servicecmd/enable.c98
-rw-r--r--servicecmd/help.c129
-rw-r--r--servicecmd/list.c102
-rw-r--r--servicecmd/servicecmd.c90
-rw-r--r--servicecmd/servicecmd.h93
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 */
-