diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rc-update.c | 257 |
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; } } |