PATCH: removing hardcoded paths from init

Gabriel L. Somlo somlo at cmu.edu
Mon Jan 15 23:02:45 UTC 2007


I noticed there are a bunch of places in init/init.c where hard-coded
commands are passed to new_init_action(). Things such as "/sbin/reboot",
"/bin/umount", "/sbin/swapon", etc.

The following patch allows the use of path-less commands by making
new_init_action() call a new function, resolve_command(), which adds
the appropriate prefix to a command, based on where it is found in
$PATH.

Thanks,
Gabriel


diff -NarU5 busybox-svn-17314.orig/init/init.c busybox-svn-17314/init/init.c
--- busybox-svn-17314.orig/init/init.c	2007-01-15 15:18:06.000000000 -0500
+++ busybox-svn-17314/init/init.c	2007-01-15 17:42:25.000000000 -0500
@@ -775,40 +775,78 @@
 	got_cont = 1;
 }
 
 #endif							/* ! ENABLE_DEBUG_INIT */
 
-static void new_init_action(int action, const char *command, const char *cons)
+/* resolve 'cmd args' into either '/path/cmd args' or '/bin/busybox cmd args';
+ * returns allocated string, caller must handle de-allocation;
+ */
+static char *resolve_command(const char *command)
+{
+	char *cmd, *args, *slash, *pathcmd, *ret;
+
+	cmd = xstrdup(command);
+
+	args = strchrnul(cmd, ' ');
+	slash = strchrnul(cmd, '/');
+	if (args > slash)
+		/* command part contains a path, so leave it alone */
+		return cmd;
+
+	if (*args == ' ')
+		*args++ = '\0';
+
+	pathcmd = find_execable(cmd);
+	if (!pathcmd)
+		pathcmd = xasprintf("/bin/busybox %s", cmd);
+
+	if (*args == '\0') {
+		free(cmd);
+		return pathcmd;
+	}
+
+	ret = xasprintf("%s %s", pathcmd, args);
+	free(cmd);
+	free(pathcmd);
+	return ret;
+}
+
+static void new_init_action(int action, const char *cmd, const char *cons)
 {
 	struct init_action *new_action, *a, *last;
+	char *command;
 
 	if (*cons == '\0')
 		cons = console;
 
 	if (strcmp(cons, bb_dev_null) == 0 && (action & ASKFIRST))
 		return;
 
 	new_action = xzalloc(sizeof(struct init_action));
 
+	command = resolve_command(cmd);
+
 	/* Append to the end of the list */
 	for (a = last = init_action_list; a; a = a->next) {
 		/* don't enter action if it's already in the list,
 		 * but do overwrite existing actions */
 		if ((strcmp(a->command, command) == 0) &&
 		    (strcmp(a->terminal, cons) ==0)) {
 			a->action = action;
 			free(new_action);
+			free(command);
 			return;
 		}
 		last = a;
 	}
 	if (last) {
 		last->next = new_action;
 	} else {
 		init_action_list = new_action;
 	}
 	strcpy(new_action->command, command);
+	free(command);
 	new_action->action = action;
 	strcpy(new_action->terminal, cons);
 	messageD(LOG|CONSOLE, "command='%s' action='%d' terminal='%s'\n",
 		new_action->command, new_action->action, new_action->terminal);
 }
@@ -850,17 +888,17 @@
 	file = fopen(INITTAB, "r");
 	if (file == NULL) {
 		/* No inittab file -- set up some default behavior */
 #endif
 		/* Reboot on Ctrl-Alt-Del */
-		new_init_action(CTRLALTDEL, "/sbin/reboot", "");
+		new_init_action(CTRLALTDEL, "reboot", "");
 		/* Umount all filesystems on halt/reboot */
-		new_init_action(SHUTDOWN, "/bin/umount -a -r", "");
+		new_init_action(SHUTDOWN, "umount -a -r", "");
 		/* Swapoff on halt/reboot */
-		if(ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "/sbin/swapoff -a", "");
+		if(ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
 		/* Prepare to restart init when a HUP is received */
-		new_init_action(RESTART, "/sbin/init", "");
+		new_init_action(RESTART, "init", "");
 		/* Askfirst shell on tty1-4 */
 		new_init_action(ASKFIRST, bb_default_login_shell, "");
 		new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
 		new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
 		new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
@@ -1037,13 +1075,13 @@
 		if (!sysinfo(&info) &&
 			(info.mem_unit ? : 1) * (long long)info.totalram < 1024*1024)
 		{
 			message(CONSOLE,"Low memory: forcing swapon.");
 			/* swapon -a requires /proc typically */
-			new_init_action(SYSINIT, "/bin/mount -t proc proc /proc", "");
+			new_init_action(SYSINIT, "mount -t proc proc /proc", "");
 			/* Try to turn on swap */
-			new_init_action(SYSINIT, "/sbin/swapon -a", "");
+			new_init_action(SYSINIT, "swapon -a", "");
 			run_actions(SYSINIT);   /* wait and removing */
 		}
 	}
 
 	/* Check if we are supposed to be in single user mode */



More information about the busybox mailing list