svn commit: trunk/busybox: debianutils include

aldot at busybox.net aldot at busybox.net
Wed Mar 28 20:35:14 UTC 2007


Author: aldot
Date: 2007-03-28 13:35:13 -0700 (Wed, 28 Mar 2007)
New Revision: 18265

Log:
- rewrite run-parts
   text    data     bss     dec     hex filename
   1029       0       0    1029     405 debianutils/run_parts.o-old
    478       0       0     478     1de debianutils/run_parts.o-new-bare
    600       0       0     600     258 debianutils/run_parts.o-new-full

bare, i.e. without long opts and fancy stuff
./scripts/bloat-o-meter bb_old busybox_unstripped   function                                             old     new   delta
act                                                    -     215    +215
run_parts_main                                       216     201     -15
valid_name                                            50       -     -50
runparts_long_options                                 64       -     -64
.rodata                                           124323  124163    -160
run_parts                                            513       -    -513
------------------------------------------------------------------------------
(add/remove: 1/3 grow/shrink: 0/2 up/down: 215/-802)         Total: -587 bytes



Modified:
   trunk/busybox/debianutils/Config.in
   trunk/busybox/debianutils/run_parts.c
   trunk/busybox/include/usage.h


Changeset:
Modified: trunk/busybox/debianutils/Config.in
===================================================================
--- trunk/busybox/debianutils/Config.in	2007-03-28 19:13:06 UTC (rev 18264)
+++ trunk/busybox/debianutils/Config.in	2007-03-28 20:35:13 UTC (rev 18265)
@@ -53,6 +53,15 @@
 	help
 	  Support long options for the run-parts applet.
 
+config FEATURE_RUN_PARTS_FANCY
+	bool "Support additional arguments"
+	default n
+	depends on RUN_PARTS
+	help
+	  Support additional options:
+	  -l --list print the names of the all matching files (not
+	            limited to executables), but don't actually run them.
+
 config START_STOP_DAEMON
 	bool "start-stop-daemon"
 	default y

Modified: trunk/busybox/debianutils/run_parts.c
===================================================================
--- trunk/busybox/debianutils/run_parts.c	2007-03-28 19:13:06 UTC (rev 18264)
+++ trunk/busybox/debianutils/run_parts.c	2007-03-28 20:35:13 UTC (rev 18265)
@@ -2,8 +2,10 @@
 /*
  * Mini run-parts implementation for busybox
  *
+ * Copyright (C) 2007 Bernhard Fischer
  *
- * Copyright (C) 2001 by Emanuele Aina <emanuele.aina at tiscali.it>
+ * Based on a older version that was in busybox which was 1k big..
+ *   Copyright (C) 2001 by Emanuele Aina <emanuele.aina at tiscali.it>
  *
  * Based on the Debian run-parts program, version 1.15
  *   Copyright (C) 1996 Jeff Noxon <jeff at router.patch.net>,
@@ -25,168 +27,125 @@
  *				execute them.
  * -a ARG		argument. Pass ARG as an argument the program executed. It can
  *				be repeated to pass multiple arguments.
- * -u MASK		umask. Set the umask of the program executed to MASK. */
-
-/* TODO
- * done - convert calls to error in perror... and remove error()
- * done - convert malloc/realloc to their x... counterparts
- * done - remove catch_sigchld
- * done - use bb's concat_path_file()
- * done - declare run_parts_main() as extern and any other function as static?
+ * -u MASK		umask. Set the umask of the program executed to MASK.
  */
 
+
 #include "busybox.h"
 #include <getopt.h>
 
+#if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS
 static const struct option runparts_long_options[] = {
-	{ "test",       0,      NULL,   't' },
-	{ "umask",      1,      NULL,   'u' },
 	{ "arg",        1,      NULL,   'a' },
+	{ "umask",      1,      NULL,   'u' },
+	{ "test",       0,      NULL,   't' },
+#if ENABLE_FEATURE_RUN_PARTS_FANCY
+	{ "list",       0,      NULL,   'l' },
+//XXX:TODO:	{ "reverse",       0,      NULL,   'r' },
+//XXX:TODO:	{ "verbose",       0,      NULL,   'v' },
+#endif
 	{ 0,            0,      0,      0   }
 };
+#endif
 
+struct globals {
+	char *cmd[10]; /* merely arbitrary arg count */
+	smalluint mode;
+};
+#define G (*(struct globals*)&bb_common_bufsiz1)
+
 /* valid_name */
 /* True or false? Is this a valid filename (upper/lower alpha, digits,
  * underscores, and hyphens only?)
  */
-static int valid_name(const struct dirent *d)
+static bool invalid_name(const char *c)
 {
-	const char *c = d->d_name;
-
 	while (*c) {
-		if (!isalnum(*c) && (*c != '_') && (*c != '-')) {
-			return 0;
+		if (!isalnum(*c) && (*c != '_') && (*c != '-' && (*c != '/'))) {
+			return 1;
 		}
 		++c;
 	}
-	return 1;
+	return 0;
 }
+#define RUN_PARTS_OPT_a (1<<0)
+#define RUN_PARTS_OPT_u (1<<1)
+#define RUN_PARTS_OPT_t (1<<2)
+#if ENABLE_FEATURE_RUN_PARTS_FANCY
+#define RUN_PARTS_OPT_l (1<<3)
+#endif
 
-/* test mode = 1 is the same as official run_parts
- * test_mode = 2 means to fail silently on missing directories
- */
-static int run_parts(char **args, const unsigned char test_mode)
+#define test_mode (G.mode & RUN_PARTS_OPT_t)
+#if ENABLE_FEATURE_RUN_PARTS_FANCY
+#define list_mode (G.mode & RUN_PARTS_OPT_l)
+#else
+#define list_mode (0)
+#endif
+static int act(const char *file, struct stat *statbuf, void *args, int depth)
 {
-	struct dirent **namelist = 0;
-	struct stat st;
-	char *filename;
-	char *arg0 = args[0];
-	int entries;
-	int i;
-	int exitstatus = 0;
+	int ret;
 
-#if __GNUC__
-	/* Avoid longjmp clobbering */
-	(void) &i;
-	(void) &exitstatus;
-#endif
-	/* scandir() isn't POSIX, but it makes things easy. */
-	entries = scandir(arg0, &namelist, valid_name, alphasort);
+	if (depth == 1)
+		return TRUE;
 
-	if (entries == -1) {
-		if (test_mode & 2) {
-			return 2;
-		}
-		bb_perror_msg_and_die("cannot open '%s'", arg0);
-	}
+	if (depth == 2 &&
+		((!list_mode && access(file, X_OK)) ||
+		 invalid_name(file) ||
+		 !(statbuf->st_mode & (S_IFREG | S_IFLNK))) )
+		return SKIP;
 
-	for (i = 0; i < entries; i++) {
-		filename = concat_path_file(arg0, namelist[i]->d_name);
-
-		xstat(filename, &st);
-		if (S_ISREG(st.st_mode) && !access(filename, X_OK)) {
-			if (test_mode) {
-				puts(filename);
-			} else {
-				/* exec_errno is common vfork variable */
-				volatile int exec_errno = 0;
-				int result;
-				int pid;
-
-				if ((pid = vfork()) < 0) {
-					bb_perror_msg_and_die("failed to fork");
-				} else if (!pid) {
-					args[0] = filename;
-					execve(filename, args, environ);
-					exec_errno = errno;
-					_exit(1);
-				}
-
-				waitpid(pid, &result, 0);
-				if (exec_errno) {
-					errno = exec_errno;
-					bb_perror_msg("failed to exec %s", filename);
-					exitstatus = 1;
-				}
-				if (WIFEXITED(result) && WEXITSTATUS(result)) {
-					bb_perror_msg("%s exited with return code %d", filename, WEXITSTATUS(result));
-					exitstatus = 1;
-				} else if (WIFSIGNALED(result)) {
-					bb_perror_msg("%s exited because of uncaught signal %d", filename, WTERMSIG(result));
-					exitstatus = 1;
-				}
-			}
-		} else if (!S_ISDIR(st.st_mode)) {
-			bb_error_msg("component %s is not an executable plain file", filename);
-			exitstatus = 1;
-		}
-
-		free(namelist[i]);
-		free(filename);
+	if (test_mode || list_mode) {
+		puts(file);
+		return TRUE;
 	}
-	free(namelist);
-
-	return exitstatus;
+	G.cmd[0] = (char*)file;
+	ret = wait4pid(spawn(G.cmd));
+	if (ret < 0) {
+		bb_error_msg("failed to exec %s", *G.cmd);
+	} else if (ret > 0) {
+		bb_perror_msg("%s exited with return code %d", *G.cmd, ret);
+	}
+	return !ret;
 }
 
-
-/* run_parts_main */
-/* Process options */
 int run_parts_main(int argc, char **argv);
 int run_parts_main(int argc, char **argv)
 {
-	char **args = xmalloc(2 * sizeof(char *));
-	unsigned char test_mode = 0;
-	unsigned short argcount = 1;
-	int opt;
+	char *umask_p;
+	llist_t *arg_list = NULL;
+	unsigned tmp;
 
 	umask(022);
-
-	while ((opt = getopt_long(argc, argv, "tu:a:",
-					runparts_long_options, NULL)) > 0)
-	{
-		switch (opt) {
-		/* Enable test mode */
-		case 't':
-			test_mode++;
-			break;
-		/* Set the umask of the programs executed */
-		case 'u':
-			/* Check and set the umask of the program executed. As stated in the original
-			 * run-parts, the octal conversion in libc is not foolproof; it will take the
-			 * 8 and 9 digits under some circumstances. We'll just have to live with it.
-			 */
-			umask(xstrtoul_range(optarg, 8, 0, 07777));
-			break;
-		/* Pass an argument to the programs */
-		case 'a':
-			/* Add an argument to the commands that we will call.
-			 * Called once for every argument. */
-			args = xrealloc(args, (argcount + 2) * (sizeof(char *)));
-			args[argcount++] = optarg;
-			break;
-		default:
-			bb_show_usage();
-		}
-	}
-
 	/* We require exactly one argument: the directory name */
-	if (optind != (argc - 1)) {
-		bb_show_usage();
+	opt_complementary = "=1:a::";
+#if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS
+	applet_long_options = runparts_long_options;
+#endif
+	tmp = getopt32(argc, argv, "a:u:t"USE_FEATURE_RUN_PARTS_FANCY("l"), &arg_list, &umask_p);
+	G.mode = tmp &~ (RUN_PARTS_OPT_a|RUN_PARTS_OPT_u);
+	if (tmp & RUN_PARTS_OPT_u) {
+		/* Check and set the umask of the program executed.
+		 * As stated in the original run-parts, the octal conversion in
+		 * libc is not foolproof; it will take the 8 and 9 digits under
+		 * some circumstances. We'll just have to live with it.
+		 */
+			umask(xstrtoul_range(umask_p, 8, 0, 07777));
 	}
-
-	args[0] = argv[optind];
-	args[argcount] = 0;
-
-	return run_parts(args, test_mode);
+//XXX: FIXME: reverse the list before handing it over to the user.
+//XXX: FIXME: The common case seems to be to use the order given by the user
+	arg_list = llist_rev(arg_list); /* XXX: getopt32 appends them */
+	G.cmd[0] = (char*)"";
+	for (tmp = 1; arg_list; arg_list = arg_list->link, tmp++)
+		G.cmd[tmp] = arg_list->data;
+	if (!recursive_action(argv[argc - 1],
+			TRUE,		/* recurse */
+			TRUE,		/* follow links */
+			FALSE,		/* depth first */
+			act,		/* file action */
+			act,		/* dir action */
+			NULL,		/* user data */
+			1			/* depth */
+			))
+			return EXIT_FAILURE;
+	return EXIT_SUCCESS;
 }

Modified: trunk/busybox/include/usage.h
===================================================================
--- trunk/busybox/include/usage.h	2007-03-28 19:13:06 UTC (rev 18264)
+++ trunk/busybox/include/usage.h	2007-03-28 20:35:13 UTC (rev 18265)
@@ -2760,14 +2760,29 @@
        "	-l, --range=RNG	Levelrange" \
 
 #define run_parts_trivial_usage \
-       "[-t] [-a ARG] [-u MASK] DIRECTORY"
+       "[-t] "USE_FEATURE_RUN_PARTS_FANCY("[-l] ")"[-a ARG] [-u MASK] DIRECTORY"
 #define run_parts_full_usage \
        "Run a bunch of scripts in a directory" \
        "\n\nOptions:\n" \
        "	-t	Prints what would be run, but does not actually run anything\n" \
        "	-a ARG	Pass ARG as an argument for every program invoked\n" \
-       "	-u MASK	Set the umask to MASK before executing every program"
+       "	-u MASK	Set the umask to MASK before executing every program" \
+USE_FEATURE_RUN_PARTS_FANCY("\n	-l	Prints names of all matching files even when they are not executable")
 
+#define run_parts_example_usage \
+	"$ run-parts -a start /etc/init.d\n" \
+	"$ run-parts -a stop=now /etc/init.d\n\n" \
+	"Let's assume you have a script foo/dosomething:\n" \
+	"#!/bin/sh\n" \
+	"for i in $*; do eval $i; done ; unset i\n" \
+	"case \"$1\" in\n" \
+	"start*) echo starting something ;;\n" \
+	"stop*) set -x ; shutdown -h $stop ;;\n" \
+	"esac\n\n" \
+	"Running this yields:\n" \
+	"$run-parts -a stop=+4m foo/\n" \
+	"+ shutdown -h +4m"
+
 #define runlevel_trivial_usage \
        "[utmp]"
 #define runlevel_full_usage \




More information about the busybox-cvs mailing list