aboutsummaryrefslogtreecommitdiff
path: root/debianutils
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2002-11-11 06:21:00 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2002-11-11 06:21:00 +0000
commit545106f8db3e9e40d454a8713e713b0741739b23 (patch)
treec5a1aa31cac00d7bd5bcfa466374ff746764f3f2 /debianutils
parent8f0722a53b9a88c0b4e60b79e4362d0f31c32c54 (diff)
downloadbusybox-w32-545106f8db3e9e40d454a8713e713b0741739b23.tar.gz
busybox-w32-545106f8db3e9e40d454a8713e713b0741739b23.tar.bz2
busybox-w32-545106f8db3e9e40d454a8713e713b0741739b23.zip
Move awk from textutils to editors. Cleanup run-parts, saves 200 bytes, moves the guts of run_parts to libbb to be used by ifupdown.
Diffstat (limited to 'debianutils')
-rw-r--r--debianutils/run_parts.c234
1 files changed, 44 insertions, 190 deletions
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c
index 3ec4b9d10..34e702ef8 100644
--- a/debianutils/run_parts.c
+++ b/debianutils/run_parts.c
@@ -49,203 +49,57 @@
49 * done - declare run_parts_main() as extern and any other function as static? 49 * done - declare run_parts_main() as extern and any other function as static?
50 */ 50 */
51 51
52#include <stdio.h>
53#include <stdarg.h>
54#include <stdlib.h>
55/* #include <sys/types.h> */
56#include <sys/wait.h>
57#include <dirent.h>
58#include <sys/stat.h>
59#include <unistd.h>
60#include <getopt.h> 52#include <getopt.h>
61#include <string.h> 53#include <stdlib.h>
62#include <errno.h>
63#include <ctype.h>
64
65#include "busybox.h"
66
67static int test_mode = 0;
68static int exitstatus = 0;
69
70static int argcount = 0, argsize = 0;
71static char **args = 0;
72
73
74/* set_umask */
75/* Check and set the umask of the program executed. As stated in the original
76 * run-parts, the octal conversion in libc is not foolproof; it will take the
77 * 8 and 9 digits under some circumstances. We'll just have to live with it.
78 */
79
80static void set_umask (void)
81{
82 int mask, result;
83
84 /*TODO
85 * We must substitute sscanf, according to bb's style guide? */
86 result = sscanf (optarg, "%o", &mask);
87 if ((result != 1) || (mask > 07777) || (mask < 0)) {
88 perror_msg_and_die ("bad umask value");
89 }
90
91 umask (mask);
92}
93
94/* add_argument */
95/* Add an argument to the commands that we will call. Called once for
96 every argument. */
97static void add_argument (char *newarg)
98{
99 if (argcount+1 >= argsize) {
100 argsize = argsize ? argsize*2 : 4;
101 /*TODO if we convert to xrealloc we lose the verbose error message */
102 args = realloc(args, argsize * (sizeof(char*)));
103 if (!args) {
104 perror_msg_and_die ("failed to reallocate memory for arguments");
105 }
106 }
107 args[argcount++] = newarg;
108 args[argcount] = 0;
109}
110
111/* valid_name */
112/* True or false? Is this a valid filename (upper/lower alpha, digits,
113 * underscores, and hyphens only?)
114 */
115
116static int valid_name (const struct dirent *d)
117{
118 char *c = d->d_name;
119 while (*c) {
120 if (!isalnum(*c) && *c!='_' && *c!='-') {
121 return 0;
122 }
123 ++c;
124 }
125 return 1;
126}
127
128
129/* run_part */
130/* Execute a file */
131
132static void run_part (char *progname)
133{
134 int result;
135 int pid;
136
137
138 if ((pid=fork()) < 0) {
139 perror_msg_and_die ("failed to fork");
140 }
141 else if (!pid) {
142 args[0] = progname;
143 execv (progname, args);
144 perror_msg_and_die ("failed to exec %s", progname);
145 }
146
147 if (0) {
148
149 } else {
150
151 waitpid(pid, &result, 0);
152 }
153
154 if (WIFEXITED (result) && WEXITSTATUS(result)) {
155 perror_msg ("%s exited with return code %d", progname, WEXITSTATUS(result));
156 exitstatus = 1;
157 }
158 else if (WIFSIGNALED (result)) {
159 perror_msg ("%s exited because of uncaught signal %d", progname,
160 WTERMSIG(result));
161 exitstatus = 1;
162 }
163}
164
165/* run_parts */
166/* Find the parts to run & call run_part() */
167
168static void run_parts (char *dir_name)
169{
170 struct dirent **namelist = 0;
171 char *filename;
172 int entries, i;
173 struct stat st;
174
175 /* -- */
176
177 /* scandir() isn't POSIX, but it makes things easy. */
178 entries = scandir (dir_name, &namelist, valid_name, alphasort);
179
180 if (entries < 0) {
181 perror_msg_and_die ("failed to open directory %s", dir_name);
182 }
183
184 for (i = 0; i < entries; i++) {
185
186 /* -- */
187 54
188 filename = concat_path_file (dir_name, namelist[i]->d_name); 55#include "libbb.h"
189
190 if (stat (filename, &st) < 0) {
191 perror_msg_and_die ("failed to stat component %s", filename);
192 }
193 if (S_ISREG(st.st_mode) && !access (filename, X_OK)) {
194 if (test_mode)
195 printf ("run-parts would run %s\n", filename);
196 else {
197 run_part (filename);
198 }
199 }
200
201 else if (!S_ISDIR(st.st_mode)) {
202 error_msg ("component %s is not an executable plain file",
203 filename);
204 exitstatus = 1;
205 }
206
207 free (namelist[i]);
208 free (filename);
209 }
210 free (namelist);
211}
212 56
213/* run_parts_main */ 57/* run_parts_main */
214/* Process options */ 58/* Process options */
215int run_parts_main (int argc, char *argv[]) 59int run_parts_main(int argc, char **argv)
216{ 60{
217 umask (022); 61 char **args = xmalloc(2 * sizeof(char *));
218 add_argument(0); 62 unsigned char test_mode = 0;
219 63 unsigned short argcount = 1;
220 for (;;) { 64 int opt;
221 int c; 65
66 umask(022);
67
68 while ((opt = getopt(argc, argv, "tu:a:")) != -1) {
69 switch (opt) {
70 case 't': /* Enable test mode */
71 test_mode = 1;
72 break;
73 case 'u': /* Set the umask of the programs executed */
74 /* Check and set the umask of the program executed. As stated in the original
75 * run-parts, the octal conversion in libc is not foolproof; it will take the
76 * 8 and 9 digits under some circumstances. We'll just have to live with it.
77 */
78 {
79 const unsigned int mask = (unsigned int) strtol(optarg, NULL, 8);
80 if (mask > 07777) {
81 perror_msg_and_die("bad umask value");
82 }
83 umask(mask);
84 }
85 break;
86 case 'a': /* Pass an argument to the programs */
87 /* Add an argument to the commands that we will call.
88 * Called once for every argument. */
89 args = xrealloc(args, (argcount + 2) * (sizeof(char *)));
90 args[argcount++] = optarg;
91 args[argcount] = 0;
92 break;
93 default:
94 show_usage();
95 }
96 }
222 97
223 opterr = 0; 98 /* We require exactly one argument: the directory name */
224 c = getopt(argc, argv, "tu:a:"); 99 if (optind != (argc - 1)) {
225
226 if (c == EOF)
227 break;
228 switch (c) {
229 case 't': /* Enable test mode */
230 test_mode = 1;
231 break;
232 case 'u': /* Set the umask of the programs executed */
233 set_umask ();
234 break;
235 case 'a': /* Pass an argument to the programs */
236 add_argument (optarg);
237 break;
238 default:
239 show_usage(); 100 show_usage();
240 } 101 }
241 }
242
243 /* We require exactly one argument: the directory name */
244 if (optind != (argc - 1)) {
245 show_usage();
246 }
247
248 run_parts (argv[optind]);
249 102
250 return exitstatus; 103 args[0] = argv[optind];
104 return(run_parts(args, test_mode));
251} 105}