Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/debianutils/run_parts.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/debianutils/run_parts.c
r1765 r2725 3 3 * Mini run-parts implementation for busybox 4 4 * 5 * Copyright (C) 2007 Bernhard Fischer5 * Copyright (C) 2007 Bernhard Reutner-Fischer 6 6 * 7 7 * Based on a older version that was in busybox which was 1k big.. … … 13 13 * 14 14 * 15 * Licensed under GPL v2 or later, see file LICENSE in this tarball for details.15 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 16 16 */ 17 17 … … 24 24 * broken compatibility because the BusyBox policy doesn't allow them. 25 25 * The supported options are: 26 * -t 27 * 28 * -a ARG 29 * 30 * -u MASK 26 * -t test. Print the name of the files to be executed, without 27 * execute them. 28 * -a ARG argument. Pass ARG as an argument the program executed. It can 29 * be repeated to pass multiple arguments. 30 * -u MASK umask. Set the umask of the program executed to MASK. 31 31 */ 32 33 #include <getopt.h>34 32 35 33 #include "libbb.h" 36 34 37 #if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS 38 static const char runparts_longopts[] ALIGN1 = 39 "arg\0" Required_argument "a" 40 "umask\0" Required_argument "u" 41 "test\0" No_argument "t" 35 struct globals { 36 char **names; 37 int cur; 38 char *cmd[1]; 39 } FIX_ALIASING; 40 #define G (*(struct globals*)&bb_common_bufsiz1) 41 #define names (G.names) 42 #define cur (G.cur ) 43 #define cmd (G.cmd ) 44 45 enum { NUM_CMD = (COMMON_BUFSIZE - sizeof(G)) / sizeof(cmd[0]) - 1 }; 46 47 enum { 48 OPT_r = (1 << 0), 49 OPT_a = (1 << 1), 50 OPT_u = (1 << 2), 51 OPT_t = (1 << 3), 52 OPT_l = (1 << 4) * ENABLE_FEATURE_RUN_PARTS_FANCY, 53 }; 54 42 55 #if ENABLE_FEATURE_RUN_PARTS_FANCY 43 "list\0" No_argument "l" 44 //TODO: "reverse\0" No_argument "r" 45 //TODO: "verbose\0" No_argument "v" 46 #endif 47 ; 56 #define list_mode (option_mask32 & OPT_l) 57 #else 58 #define list_mode 0 48 59 #endif 49 60 50 struct globals { 51 smalluint mode; 52 char *cmd[10]; /* merely arbitrary arg count */ 53 }; 54 #define G (*(struct globals*)&bb_common_bufsiz1) 55 56 /* valid_name */ 57 /* True or false? Is this a valid filename (upper/lower alpha, digits, 61 /* Is this a valid filename (upper/lower alpha, digits, 58 62 * underscores, and hyphens only?) 59 63 */ … … 68 72 } 69 73 70 #define RUN_PARTS_OPT_a (1<<0) 71 #define RUN_PARTS_OPT_u (1<<1) 72 #define RUN_PARTS_OPT_t (1<<2) 73 #if ENABLE_FEATURE_RUN_PARTS_FANCY 74 #define RUN_PARTS_OPT_l (1<<3) 75 #endif 74 static int bb_alphasort(const void *p1, const void *p2) 75 { 76 int r = strcmp(*(char **) p1, *(char **) p2); 77 return (option_mask32 & OPT_r) ? -r : r; 78 } 76 79 77 #define test_mode (G.mode & RUN_PARTS_OPT_t) 78 #if ENABLE_FEATURE_RUN_PARTS_FANCY 79 #define list_mode (G.mode & RUN_PARTS_OPT_l) 80 #else 81 #define list_mode (0) 82 #endif 83 84 static int act(const char *file, struct stat *statbuf, void *args, int depth) 80 static int FAST_FUNC act(const char *file, struct stat *statbuf, void *args UNUSED_PARAM, int depth) 85 81 { 86 int ret;87 88 82 if (depth == 1) 89 83 return TRUE; 90 84 91 if (depth == 2 && 92 ((!list_mode && access(file, X_OK)) || 93 invalid_name(file) || 94 !(statbuf->st_mode & (S_IFREG | S_IFLNK))) ) 85 if (depth == 2 86 && ( !(statbuf->st_mode & (S_IFREG | S_IFLNK)) 87 || invalid_name(file) 88 || (!list_mode && access(file, X_OK) != 0)) 89 ) { 95 90 return SKIP; 91 } 96 92 97 if (test_mode || list_mode) { 98 puts(file); 99 return TRUE; 100 } 101 G.cmd[0] = (char*)file; 102 ret = wait4pid(spawn(G.cmd)); 103 if (ret < 0) { 104 bb_perror_msg("failed to exec %s", file); 105 } else if (ret > 0) { 106 bb_error_msg("%s exited with return code %d", file, ret); 107 } 108 return !ret; 93 names = xrealloc_vector(names, 4, cur); 94 names[cur++] = xstrdup(file); 95 /*names[cur] = NULL; - xrealloc_vector did it */ 96 97 return TRUE; 109 98 } 110 99 111 int run_parts_main(int argc, char **argv); 112 int run_parts_main(int argc, char **argv) 100 #if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS 101 static const char runparts_longopts[] ALIGN1 = 102 "arg\0" Required_argument "a" 103 "umask\0" Required_argument "u" 104 "test\0" No_argument "t" 105 #if ENABLE_FEATURE_RUN_PARTS_FANCY 106 "list\0" No_argument "l" 107 "reverse\0" No_argument "r" 108 //TODO: "verbose\0" No_argument "v" 109 #endif 110 ; 111 #endif 112 113 int run_parts_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 114 int run_parts_main(int argc UNUSED_PARAM, char **argv) 113 115 { 114 c har *umask_p;116 const char *umask_p = "22"; 115 117 llist_t *arg_list = NULL; 116 unsigned tmp; 118 unsigned n; 119 int ret; 117 120 118 umask(022);119 /* We require exactly one argument: the directory name */120 opt_complementary = "=1:a::";121 121 #if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS 122 122 applet_long_options = runparts_longopts; 123 123 #endif 124 tmp = getopt32(argv, "a:u:t"USE_FEATURE_RUN_PARTS_FANCY("l"), &arg_list, &umask_p);125 G.mode = tmp &~ (RUN_PARTS_OPT_a|RUN_PARTS_OPT_u);126 if (tmp & RUN_PARTS_OPT_u) {127 /* Check and set the umask of the program executed. 128 * As stated in the original run-parts, the octal conversion in129 * libc is not foolproof; it will take the 8 and 9 digits under 130 * some circumstances. We'll just have to live with it.131 */132 umask(xstrtoul_range(umask_p, 8, 0, 07777));124 /* We require exactly one argument: the directory name */ 125 opt_complementary = "=1:a::"; 126 getopt32(argv, "ra:u:t"IF_FEATURE_RUN_PARTS_FANCY("l"), &arg_list, &umask_p); 127 128 umask(xstrtou_range(umask_p, 8, 0, 07777)); 129 130 n = 1; 131 while (arg_list && n < NUM_CMD) { 132 cmd[n++] = llist_pop(&arg_list); 133 133 } 134 for (tmp = 1; arg_list; arg_list = arg_list->link, tmp++) 135 G.cmd[tmp] = arg_list->data; 136 /* G.cmd[tmp] = NULL; - G is already zeroed out */ 137 if (!recursive_action(argv[argc - 1], 134 /* cmd[n] = NULL; - is already zeroed out */ 135 136 /* run-parts has to sort executables by name before running them */ 137 138 recursive_action(argv[optind], 138 139 ACTION_RECURSE|ACTION_FOLLOWLINKS, 139 act, /* file action */ 140 act, /* dir action */ 141 NULL, /* user data */ 142 1 /* depth */ 143 )) 144 return EXIT_FAILURE; 145 return EXIT_SUCCESS; 140 act, /* file action */ 141 act, /* dir action */ 142 NULL, /* user data */ 143 1 /* depth */ 144 ); 145 146 if (!names) 147 return 0; 148 149 qsort(names, cur, sizeof(char *), bb_alphasort); 150 151 n = 0; 152 while (1) { 153 char *name = *names++; 154 if (!name) 155 break; 156 if (option_mask32 & (OPT_t | OPT_l)) { 157 puts(name); 158 continue; 159 } 160 cmd[0] = name; 161 ret = spawn_and_wait(cmd); 162 if (ret == 0) 163 continue; 164 n = 1; 165 if (ret < 0) 166 bb_perror_msg("can't execute '%s'", name); 167 else /* ret > 0 */ 168 bb_error_msg("%s exited with code %d", name, ret & 0xff); 169 } 170 171 return n; 146 172 }
Note:
See TracChangeset
for help on using the changeset viewer.