Annotation of /trunk/mkinitrd-magellan/busybox/debianutils/run_parts.c
Parent Directory | Revision Log
Revision 984 -
(hide annotations)
(download)
Sun May 30 11:32:42 2010 UTC (14 years ago) by niro
File MIME type: text/plain
File size: 4488 byte(s)
Sun May 30 11:32:42 2010 UTC (14 years ago) by niro
File MIME type: text/plain
File size: 4488 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
1 | niro | 532 | /* vi: set sw=4 ts=4: */ |
2 | /* | ||
3 | * Mini run-parts implementation for busybox | ||
4 | * | ||
5 | niro | 816 | * Copyright (C) 2007 Bernhard Reutner-Fischer |
6 | niro | 532 | * |
7 | niro | 816 | * Based on a older version that was in busybox which was 1k big.. |
8 | * Copyright (C) 2001 by Emanuele Aina <emanuele.aina@tiscali.it> | ||
9 | niro | 532 | * |
10 | * Based on the Debian run-parts program, version 1.15 | ||
11 | * Copyright (C) 1996 Jeff Noxon <jeff@router.patch.net>, | ||
12 | * Copyright (C) 1996-1999 Guy Maor <maor@debian.org> | ||
13 | * | ||
14 | * | ||
15 | * Licensed under GPL v2 or later, see file LICENSE in this tarball for details. | ||
16 | */ | ||
17 | |||
18 | /* This is my first attempt to write a program in C (well, this is my first | ||
19 | * attempt to write a program! :-) . */ | ||
20 | |||
21 | /* This piece of code is heavily based on the original version of run-parts, | ||
22 | * taken from debian-utils. I've only removed the long options and a the | ||
23 | * report mode. As the original run-parts support only long options, I've | ||
24 | * broken compatibility because the BusyBox policy doesn't allow them. | ||
25 | * The supported options are: | ||
26 | niro | 816 | * -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 | niro | 532 | */ |
32 | |||
33 | niro | 816 | #include "libbb.h" |
34 | niro | 532 | |
35 | niro | 816 | struct globals { |
36 | char **names; | ||
37 | int cur; | ||
38 | char *cmd[1]; | ||
39 | niro | 532 | }; |
40 | niro | 816 | #define G (*(struct globals*)&bb_common_bufsiz1) |
41 | #define names (G.names) | ||
42 | #define cur (G.cur ) | ||
43 | #define cmd (G.cmd ) | ||
44 | niro | 532 | |
45 | niro | 816 | 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 | |||
55 | #if ENABLE_FEATURE_RUN_PARTS_FANCY | ||
56 | #define list_mode (option_mask32 & OPT_l) | ||
57 | #else | ||
58 | #define list_mode 0 | ||
59 | #endif | ||
60 | |||
61 | /* Is this a valid filename (upper/lower alpha, digits, | ||
62 | niro | 532 | * underscores, and hyphens only?) |
63 | */ | ||
64 | niro | 816 | static bool invalid_name(const char *c) |
65 | niro | 532 | { |
66 | niro | 816 | c = bb_basename(c); |
67 | niro | 532 | |
68 | niro | 816 | while (*c && (isalnum(*c) || *c == '_' || *c == '-')) |
69 | c++; | ||
70 | |||
71 | return *c; /* TRUE (!0) if terminating NUL is not reached */ | ||
72 | niro | 532 | } |
73 | |||
74 | niro | 816 | static int bb_alphasort(const void *p1, const void *p2) |
75 | niro | 532 | { |
76 | niro | 816 | int r = strcmp(*(char **) p1, *(char **) p2); |
77 | return (option_mask32 & OPT_r) ? -r : r; | ||
78 | } | ||
79 | niro | 532 | |
80 | niro | 816 | static int FAST_FUNC act(const char *file, struct stat *statbuf, void *args UNUSED_PARAM, int depth) |
81 | { | ||
82 | if (depth == 1) | ||
83 | return TRUE; | ||
84 | niro | 532 | |
85 | niro | 816 | if (depth == 2 |
86 | && ( !(statbuf->st_mode & (S_IFREG | S_IFLNK)) | ||
87 | || invalid_name(file) | ||
88 | || (!list_mode && access(file, X_OK) != 0)) | ||
89 | ) { | ||
90 | return SKIP; | ||
91 | niro | 532 | } |
92 | |||
93 | niro | 816 | names = xrealloc_vector(names, 4, cur); |
94 | names[cur++] = xstrdup(file); | ||
95 | /*names[cur] = NULL; - xrealloc_vector did it */ | ||
96 | niro | 532 | |
97 | niro | 816 | return TRUE; |
98 | } | ||
99 | niro | 532 | |
100 | niro | 816 | #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 | niro | 532 | |
113 | niro | 816 | int run_parts_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
114 | int run_parts_main(int argc UNUSED_PARAM, char **argv) | ||
115 | { | ||
116 | const char *umask_p = "22"; | ||
117 | llist_t *arg_list = NULL; | ||
118 | unsigned n; | ||
119 | int ret; | ||
120 | niro | 532 | |
121 | niro | 816 | #if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS |
122 | applet_long_options = runparts_longopts; | ||
123 | #endif | ||
124 | /* We require exactly one argument: the directory name */ | ||
125 | /* We require exactly one argument: the directory name */ | ||
126 | opt_complementary = "=1:a::"; | ||
127 | niro | 984 | getopt32(argv, "ra:u:t"IF_FEATURE_RUN_PARTS_FANCY("l"), &arg_list, &umask_p); |
128 | niro | 816 | |
129 | umask(xstrtou_range(umask_p, 8, 0, 07777)); | ||
130 | |||
131 | n = 1; | ||
132 | while (arg_list && n < NUM_CMD) { | ||
133 | cmd[n++] = llist_pop(&arg_list); | ||
134 | niro | 532 | } |
135 | niro | 816 | /* cmd[n] = NULL; - is already zeroed out */ |
136 | niro | 532 | |
137 | niro | 816 | /* run-parts has to sort executables by name before running them */ |
138 | niro | 532 | |
139 | niro | 816 | recursive_action(argv[optind], |
140 | ACTION_RECURSE|ACTION_FOLLOWLINKS, | ||
141 | act, /* file action */ | ||
142 | act, /* dir action */ | ||
143 | NULL, /* user data */ | ||
144 | 1 /* depth */ | ||
145 | ); | ||
146 | niro | 532 | |
147 | niro | 816 | if (!names) |
148 | return 0; | ||
149 | niro | 532 | |
150 | niro | 816 | qsort(names, cur, sizeof(char *), bb_alphasort); |
151 | niro | 532 | |
152 | niro | 816 | n = 0; |
153 | while (1) { | ||
154 | char *name = *names++; | ||
155 | if (!name) | ||
156 | niro | 532 | break; |
157 | niro | 816 | if (option_mask32 & (OPT_t | OPT_l)) { |
158 | puts(name); | ||
159 | continue; | ||
160 | niro | 532 | } |
161 | niro | 816 | cmd[0] = name; |
162 | ret = wait4pid(spawn(cmd)); | ||
163 | if (ret == 0) | ||
164 | continue; | ||
165 | n = 1; | ||
166 | if (ret < 0) | ||
167 | niro | 984 | bb_perror_msg("can't execute '%s'", name); |
168 | niro | 816 | else /* ret > 0 */ |
169 | bb_error_msg("%s exited with code %d", name, ret); | ||
170 | niro | 532 | } |
171 | |||
172 | niro | 816 | return n; |
173 | niro | 532 | } |