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;  		}  	}  | 
