new implementation of applet option
This reworks the implementation of the --applet option so that it is processed in run_applets() and does not require two calls to the getopts_long() function. It is based on code by Robin Johnson and Chris Richards. X-Gentoo-Bug: 351712 X-Gentoo-Bug-URL: http://bugs.gentoo.org/show_bug.cgi?id=351712
This commit is contained in:
		@@ -429,6 +429,17 @@ run_applets(int argc, char **argv)
 | 
				
			|||||||
	char *p;
 | 
						char *p;
 | 
				
			||||||
	pid_t pid = 0;
 | 
						pid_t pid = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Bug 351712: We need an extra way to explicitly select an applet OTHER
 | 
				
			||||||
 | 
						 * than trusting argv[0], as argv[0] is not going to be the applet value if
 | 
				
			||||||
 | 
						 * we are doing SELinux context switching. For this, we allow calls such as
 | 
				
			||||||
 | 
						 * 'rc --applet APPLET', and shift ALL of argv down by two array items. */
 | 
				
			||||||
 | 
						if (strcmp(applet, "rc") == 0 && argc >= 3 &&
 | 
				
			||||||
 | 
							    (strcmp(argv[1],"--applet") == 0 || strcmp(argv[1], "-a") == 0)) {
 | 
				
			||||||
 | 
							applet = argv[2];
 | 
				
			||||||
 | 
							argv += 2;
 | 
				
			||||||
 | 
							argc -= 2;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* These are designed to be applications in their own right */
 | 
						/* These are designed to be applications in their own right */
 | 
				
			||||||
	if (strcmp(applet, "fstabinfo") == 0)
 | 
						if (strcmp(applet, "fstabinfo") == 0)
 | 
				
			||||||
		exit(fstabinfo(argc, argv));
 | 
							exit(fstabinfo(argc, argv));
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								src/rc/rc.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/rc/rc.c
									
									
									
									
									
								
							@@ -773,14 +773,16 @@ handle_bad_signal(int sig)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "_usage.h"
 | 
					#include "_usage.h"
 | 
				
			||||||
#define getoptstring "o:s:S" getoptstring_COMMON
 | 
					#define getoptstring "a:o:s:S" getoptstring_COMMON
 | 
				
			||||||
static const struct option longopts[] = {
 | 
					static const struct option longopts[] = {
 | 
				
			||||||
 | 
						{ "applet",   1, NULL, 'a' },
 | 
				
			||||||
	{ "override", 1, NULL, 'o' },
 | 
						{ "override", 1, NULL, 'o' },
 | 
				
			||||||
	{ "service",  1, NULL, 's' },
 | 
						{ "service",  1, NULL, 's' },
 | 
				
			||||||
	{ "sys",      0, NULL, 'S' },
 | 
						{ "sys",      0, NULL, 'S' },
 | 
				
			||||||
	longopts_COMMON
 | 
						longopts_COMMON
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
static const char * const longopts_help[] = {
 | 
					static const char * const longopts_help[] = {
 | 
				
			||||||
 | 
						"runs the applet specified by the next argument",
 | 
				
			||||||
	"override the next runlevel to change into\n"
 | 
						"override the next runlevel to change into\n"
 | 
				
			||||||
	"when leaving single user or boot runlevels",
 | 
						"when leaving single user or boot runlevels",
 | 
				
			||||||
	"runs the service specified with the rest\nof the arguments",
 | 
						"runs the service specified with the rest\nof the arguments",
 | 
				
			||||||
@@ -817,20 +819,6 @@ main(int argc, char **argv)
 | 
				
			|||||||
	signal_setup(SIGSEGV, handle_bad_signal);
 | 
						signal_setup(SIGSEGV, handle_bad_signal);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Bug 351712: We need an extra way to explicitly select an applet OTHER
 | 
					 | 
				
			||||||
	 * than trusting argv[0], as argv[0] is not going to be the applet value if
 | 
					 | 
				
			||||||
	 * we are doing SELinux context switching. For this, we allow calls such as
 | 
					 | 
				
			||||||
	 * 'rc --applet APPLET', and shift ALL of argv down by two array items. */
 | 
					 | 
				
			||||||
	if (strcmp(basename_c(argv[0]), "rc") == 0 && argc > 1 && strcmp(argv[1], "--applet") == 0) {
 | 
					 | 
				
			||||||
		if (argc == 2)
 | 
					 | 
				
			||||||
			eerrorx("applet argument required");
 | 
					 | 
				
			||||||
		for (i = 2; i < argc; i++)
 | 
					 | 
				
			||||||
			argv[i - 2] = argv[i];
 | 
					 | 
				
			||||||
		argv[argc - 2] = NULL;
 | 
					 | 
				
			||||||
		argv[argc - 1] = NULL;
 | 
					 | 
				
			||||||
		argc -= 2;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	/* Now we can trust our applet value in argv[0] */
 | 
					 | 
				
			||||||
	applet = basename_c(argv[0]);
 | 
						applet = basename_c(argv[0]);
 | 
				
			||||||
	LIST_INIT(&service_pids);
 | 
						LIST_INIT(&service_pids);
 | 
				
			||||||
	atexit(cleanup);
 | 
						atexit(cleanup);
 | 
				
			||||||
@@ -858,6 +846,10 @@ main(int argc, char **argv)
 | 
				
			|||||||
		    longopts, (int *) 0)) != -1)
 | 
							    longopts, (int *) 0)) != -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		switch (opt) {
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 'a':
 | 
				
			||||||
 | 
								/* Do nothing, actual logic in run_applets, this
 | 
				
			||||||
 | 
								 * is a placeholder */
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		case 'o':
 | 
							case 'o':
 | 
				
			||||||
			if (*optarg == '\0')
 | 
								if (*optarg == '\0')
 | 
				
			||||||
				optarg = NULL;
 | 
									optarg = NULL;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user