aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rc-update.c257
1 files changed, 142 insertions, 115 deletions
diff --git a/src/rc-update.c b/src/rc-update.c
index aa996c9d..b7c6e5fb 100644
--- a/src/rc-update.c
+++ b/src/rc-update.c
@@ -8,6 +8,7 @@
#define APPLET "rc-update"
#include <errno.h>
+#include <getopt.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
@@ -23,45 +24,17 @@
static char *applet = NULL;
-static void usage (void )
-{
- printf (
- "usage: %s -a|add script runlevel1 [runlevel2 ...]\n"
- " %s -d|del script [runlevel1 ...]\n"
- " %s -s|show [-v|--verbose] [runlevel1 ...]\n"
- " %s -h|help\n"
- "\n"
- "examples:\n"
- " # %s add net.eth0 default\n"
- " Adds the net.eth0 script (in /etc/init.d) to the `default' runlevel.\n"
- "\n"
- " # %s del sysklogd\n"
- " Deletes the sysklogd script from all runlevels. The original script\n"
- " is not deleted, just any symlinks to the script in /etc/runlevels/*.\n"
- "\n"
- " # %s del net.eth2 default wumpus\n"
- " Delete the net.eth2 script from the default and wumpus runlevels.\n"
- " All other runlevels are unaffected. Again, the net.eth2 script\n"
- " residing in /etc/init.d is not deleted, just any symlinks in\n"
- " /etc/runlevels/default and /etc/runlevels/wumpus.\n"
- "\n"
- " # %s show\n"
- " Show all enabled scripts and list at which runlevels they will\n"
- " execute. Run with --verbose to see all available scripts.\n",
- applet, applet, applet, applet, applet, applet, applet, applet);
-}
-
static bool add (const char *runlevel, const char *service)
{
bool retval = false;
if (! rc_service_exists (service))
- eerror ("service `%s' does not exist", service);
+ eerror ("%s: service `%s' does not exist", applet, service);
else if (! rc_runlevel_exists (runlevel))
- eerror ("runlevel `%s' does not exist", runlevel);
+ eerror ("%s: runlevel `%s' does not exist", applet, runlevel);
else if (rc_service_in_runlevel (service, runlevel)) {
- ewarn ("%s already installed in runlevel `%s'; skipping",
- service, runlevel);
+ ewarn ("%s: %s already installed in runlevel `%s'; skipping",
+ applet, service, runlevel);
retval = true;
} else if (rc_service_add (runlevel, service)) {
einfo ("%s added to runlevel %s", service, runlevel);
@@ -85,112 +58,166 @@ static bool delete (const char *runlevel, const char *service)
eerror ("%s: failed to remove service `%s' from runlevel `%s': %s",
applet, service, runlevel, strerror (errno));
} else if (! rc_service_exists (service))
- eerror ("service `%s' does not exist", service);
+ eerror ("%s: service `%s' does not exist", applet, service);
else if (! rc_runlevel_exists (runlevel))
- eerror ("runlevel `%s' does not exist", runlevel);
+ eerror ("%s: runlevel `%s' does not exist", applet, runlevel);
else
retval = true;
return (retval);
}
-int rc_update (int argc, char **argv)
+static void show (char **runlevels, bool verbose)
{
+ char *service;
+ char **services = rc_services_in_runlevel (NULL);
+ char *runlevel;
int i;
int j;
- char *service;
+
+ STRLIST_FOREACH (services, service, i) {
+ char **in = NULL;
+ bool inone = false;
+
+ STRLIST_FOREACH (runlevels, runlevel, j) {
+ if (rc_service_in_runlevel (service, runlevel)) {
+ in = rc_strlist_add (in, runlevel);
+ inone = true;
+ } else {
+ char buffer[PATH_MAX];
+ memset (buffer, ' ', strlen (runlevel));
+ buffer[strlen (runlevel)] = 0;
+ in = rc_strlist_add (in, buffer);
+ }
+ }
+
+ if (! inone && ! verbose)
+ continue;
+
+ printf (" %20s |", service);
+ STRLIST_FOREACH (in, runlevel, j)
+ printf (" %s", runlevel);
+ printf ("\n");
+ rc_strlist_free (in);
+ }
+
+ rc_strlist_free (services);
+}
+
+#include "_usage.h"
+#define getoptstring "adsv" getoptstring_COMMON
+static struct option longopts[] = {
+ { "add", 0, NULL, 'a'},
+ { "delete", 0, NULL, 'd'},
+ { "show", 0, NULL, 's'},
+ { "verbose", 0, NULL, 'v'},
+ longopts_COMMON
+ { NULL, 0, NULL, 0}
+};
+#include "_usage.c"
+
+#define DOADD (1 << 0)
+#define DODELETE (1 << 1)
+#define DOSHOW (1 << 2)
+
+int rc_update (int argc, char **argv)
+{
+ int i;
+ char *service = NULL;
char **runlevels = NULL;
char *runlevel;
- bool doadd;
- int retval;
+ int action = 0;
+ bool verbose = false;
+ int opt;
+ int retval = EXIT_FAILURE;
applet = argv[0];
- if (argc < 2 ||
- strcmp (argv[1], "show") == 0 ||
- strcmp (argv[1], "-s") == 0)
- {
- bool verbose = false;
- char **services = rc_services_in_runlevel (NULL);
- for (i = 2; i < argc; i++) {
- if (strcmp (argv[i], "--verbose") == 0 ||
- strcmp (argv[i], "-v") == 0)
+ while ((opt = getopt_long (argc, argv, getoptstring,
+ longopts, (int *) 0)) != -1)
+ {
+ switch (opt) {
+ case 'a':
+ action |= DOADD;
+ break;
+ case 'd':
+ action |= DODELETE;
+ break;
+ case 's':
+ action |= DOSHOW;
+ break;
+ case 'v':
verbose = true;
+ break;
+
+ case_RC_COMMON_GETOPT
+ }
+ }
+
+ if ((action & DOSHOW && action != DOSHOW) ||
+ (action & DOADD && action != DOADD) ||
+ (action & DODELETE && action != DODELETE))
+ eerrorx ("%s: cannot mix commands", applet);
+
+ /* We need to be backwards compatible */
+ if (! action) {
+ if (optind < argc) {
+ if (strcmp (argv[optind], "add") == 0)
+ action = DOADD;
+ else if (strcmp (argv[optind], "delete") == 0)
+ action = DODELETE;
+ else if (strcmp (argv[optind], "show") == 0)
+ action = DOSHOW;
+ if (action)
+ optind++;
else
- runlevels = rc_strlist_add (runlevels, argv[i]);
+ eerrorx ("%s: invalid command `%s'", applet, argv[optind]);
}
+ if (! action && opt)
+ action = DOSHOW;
+ }
+
+ if (optind >= argc) {
+ if (! action & DOSHOW)
+ eerrorx ("%s: no service specified", applet);
+ } else {
+ service = argv[optind];
+ optind++;
+
+ while (optind < argc)
+ if (rc_runlevel_exists (argv[optind]))
+ runlevels = rc_strlist_add (runlevels, argv[optind++]);
+ else {
+ rc_strlist_free (runlevels);
+ eerrorx ("%s: `%s' is not a valid runlevel", applet, argv[optind]);
+ }
+ }
+ if (action & DOSHOW) {
+ if (service)
+ runlevels = rc_strlist_add (runlevels, service);
if (! runlevels)
runlevels = rc_get_runlevels ();
- STRLIST_FOREACH (services, service, i) {
- char **in = NULL;
- bool inone = false;
-
- STRLIST_FOREACH (runlevels, runlevel, j) {
- if (rc_service_in_runlevel (service, runlevel)) {
- in = rc_strlist_add (in, runlevel);
- inone = true;
- } else {
- char buffer[PATH_MAX];
- memset (buffer, ' ', strlen (runlevel));
- buffer[strlen (runlevel)] = 0;
- in = rc_strlist_add (in, buffer);
+ show (runlevels, verbose);
+ retval = EXIT_SUCCESS;
+ } else {
+ if (! service)
+ eerror ("%s: no service specified", applet);
+ else if (! rc_service_exists (service))
+ eerror ("%s: service `%s' does not exist", applet, service);
+ else {
+ retval = EXIT_SUCCESS;
+ if (! runlevels)
+ runlevels = rc_strlist_add (runlevels, rc_get_runlevel ());
+ STRLIST_FOREACH (runlevels, runlevel, i) {
+ if (action & DOADD) {
+ if (! add (runlevel, service))
+ retval = EXIT_FAILURE;
+ } else if (action & DODELETE) {
+ if (! delete (runlevel, service))
+ retval = EXIT_FAILURE;
}
}
-
- if (! inone && ! verbose)
- continue;
-
- printf (" %20s |", service);
- STRLIST_FOREACH (in, runlevel, j)
- printf (" %s", runlevel);
- printf ("\n");
- rc_strlist_free (in);
- }
-
- rc_strlist_free (runlevels);
- rc_strlist_free (services);
- return (EXIT_SUCCESS);
- } else if (argc > 1 &&
- (strcmp (argv[1], "help") == 0 ||
- strcmp (argv[1], "--help") == 0 ||
- strcmp (argv[1], "-h") == 0))
- {
- usage ();
- return (EXIT_SUCCESS);
- }
-
- if (geteuid () != 0)
- eerrorx ("%s: must be root to add or delete services from runlevels",
- applet);
-
- if (! (service = argv[2]))
- eerrorx ("%s: no service specified", applet);
-
- if (strcmp (argv[1], "add") == 0 ||
- strcmp (argv[1], "-a") == 0)
- doadd = true;
- else if (strcmp (argv[1], "delete") == 0 ||
- strcmp (argv[1], "del") == 0 ||
- strcmp (argv[1], "-d") == 0)
- doadd = false;
- else
- eerrorx ("%s: unknown command `%s'", applet, argv[1]);
-
- for (i = 3; i < argc; i++)
- runlevels = rc_strlist_add (runlevels, argv[i]);
-
- if (! runlevels)
- runlevels = rc_strlist_add (runlevels, rc_get_runlevel ());
-
- retval = EXIT_SUCCESS;
- STRLIST_FOREACH (runlevels, runlevel, i) {
- if (doadd) {
- if (! add (runlevel, service))
- retval = EXIT_FAILURE;
- } else {
- if (! delete (runlevel, service))
- retval = EXIT_FAILURE;
}
}