diff options
author | Eric Andersen <andersen@codepoet.org> | 2003-07-26 09:16:00 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2003-07-26 09:16:00 +0000 |
commit | a1ed06b04739d85389fe23e78e97556864b77c64 (patch) | |
tree | 80ceac0ee76ad0bee1838252ced4f0cfd097659c | |
parent | aa820dbc00860a2ddcb7a0205345ffe39c7d18d7 (diff) | |
download | busybox-w32-a1ed06b04739d85389fe23e78e97556864b77c64.tar.gz busybox-w32-a1ed06b04739d85389fe23e78e97556864b77c64.tar.bz2 busybox-w32-a1ed06b04739d85389fe23e78e97556864b77c64.zip |
Move start_stop_daemon to debianutils.
Cleanup run_parts a bit and add long opts
-rw-r--r-- | debianutils/Config.in | 8 | ||||
-rw-r--r-- | debianutils/Makefile.in | 1 | ||||
-rw-r--r-- | debianutils/run_parts.c | 56 | ||||
-rw-r--r-- | init/Config.in | 9 | ||||
-rw-r--r-- | init/Makefile.in | 1 | ||||
-rw-r--r-- | init/start_stop_daemon.c | 253 |
6 files changed, 40 insertions, 288 deletions
diff --git a/debianutils/Config.in b/debianutils/Config.in index 108cc5388..8bdb91f26 100644 --- a/debianutils/Config.in +++ b/debianutils/Config.in | |||
@@ -33,6 +33,14 @@ config CONFIG_RUN_PARTS | |||
33 | Unless you know that run-parts is used in some of your scripts | 33 | Unless you know that run-parts is used in some of your scripts |
34 | you can safely say N here. | 34 | you can safely say N here. |
35 | 35 | ||
36 | config CONFIG_START_STOP_DAEMON | ||
37 | bool "start-stop-daemon" | ||
38 | default y | ||
39 | help | ||
40 | start-stop-daemon is used to control the creation and | ||
41 | termination of system-level processes, usually the ones | ||
42 | started during the startup of the system. | ||
43 | |||
36 | config CONFIG_WHICH | 44 | config CONFIG_WHICH |
37 | bool "which" | 45 | bool "which" |
38 | default n | 46 | default n |
diff --git a/debianutils/Makefile.in b/debianutils/Makefile.in index 313faa0de..8ca05c738 100644 --- a/debianutils/Makefile.in +++ b/debianutils/Makefile.in | |||
@@ -27,6 +27,7 @@ DEBIANUTILS-y:= | |||
27 | DEBIANUTILS-$(CONFIG_MKTEMP) += mktemp.o | 27 | DEBIANUTILS-$(CONFIG_MKTEMP) += mktemp.o |
28 | DEBIANUTILS-$(CONFIG_READLINK) += readlink.o | 28 | DEBIANUTILS-$(CONFIG_READLINK) += readlink.o |
29 | DEBIANUTILS-$(CONFIG_RUN_PARTS) += run_parts.o | 29 | DEBIANUTILS-$(CONFIG_RUN_PARTS) += run_parts.o |
30 | DEBIANUTILS-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o | ||
30 | DEBIANUTILS-$(CONFIG_WHICH) += which.o | 31 | DEBIANUTILS-$(CONFIG_WHICH) += which.o |
31 | 32 | ||
32 | libraries-y+=$(DEBIANUTILS_DIR)$(DEBIANUTILS_AR) | 33 | libraries-y+=$(DEBIANUTILS_DIR)$(DEBIANUTILS_AR) |
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index a941e1fc8..98fd58887 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c | |||
@@ -54,6 +54,13 @@ | |||
54 | 54 | ||
55 | #include "libbb.h" | 55 | #include "libbb.h" |
56 | 56 | ||
57 | static const struct option runparts_long_options[] = { | ||
58 | { "test", 0, NULL, 't' }, | ||
59 | { "umask", 1, NULL, 'u' }, | ||
60 | { "arg", 1, NULL, 'a' }, | ||
61 | { 0, 0, 0, 0 } | ||
62 | }; | ||
63 | |||
57 | /* run_parts_main */ | 64 | /* run_parts_main */ |
58 | /* Process options */ | 65 | /* Process options */ |
59 | int run_parts_main(int argc, char **argv) | 66 | int run_parts_main(int argc, char **argv) |
@@ -65,32 +72,31 @@ int run_parts_main(int argc, char **argv) | |||
65 | 72 | ||
66 | umask(022); | 73 | umask(022); |
67 | 74 | ||
68 | while ((opt = getopt(argc, argv, "tu:a:")) != -1) { | 75 | while ((opt = getopt_long (argc, argv, "tu:a:", |
76 | runparts_long_options, NULL)) > 0) | ||
77 | { | ||
69 | switch (opt) { | 78 | switch (opt) { |
70 | case 't': /* Enable test mode */ | 79 | /* Enable test mode */ |
71 | test_mode = 1; | 80 | case 't': |
72 | break; | 81 | test_mode++; |
73 | case 'u': /* Set the umask of the programs executed */ | 82 | break; |
74 | /* Check and set the umask of the program executed. As stated in the original | 83 | /* Set the umask of the programs executed */ |
75 | * run-parts, the octal conversion in libc is not foolproof; it will take the | 84 | case 'u': |
76 | * 8 and 9 digits under some circumstances. We'll just have to live with it. | 85 | /* Check and set the umask of the program executed. As stated in the original |
77 | */ | 86 | * run-parts, the octal conversion in libc is not foolproof; it will take the |
78 | { | 87 | * 8 and 9 digits under some circumstances. We'll just have to live with it. |
79 | const unsigned int mask = (unsigned int) strtol(optarg, NULL, 8); | 88 | */ |
80 | if (mask > 07777) { | 89 | umask(bb_xgetlarg(optarg, 8, 0, 07777)); |
81 | bb_perror_msg_and_die("bad umask value"); | 90 | break; |
82 | } | 91 | /* Pass an argument to the programs */ |
83 | umask(mask); | 92 | case 'a': |
84 | } | 93 | /* Add an argument to the commands that we will call. |
85 | break; | 94 | * Called once for every argument. */ |
86 | case 'a': /* Pass an argument to the programs */ | 95 | args = xrealloc(args, (argcount + 2) * (sizeof(char *))); |
87 | /* Add an argument to the commands that we will call. | 96 | args[argcount++] = optarg; |
88 | * Called once for every argument. */ | 97 | break; |
89 | args = xrealloc(args, (argcount + 2) * (sizeof(char *))); | 98 | default: |
90 | args[argcount++] = optarg; | 99 | bb_show_usage(); |
91 | break; | ||
92 | default: | ||
93 | bb_show_usage(); | ||
94 | } | 100 | } |
95 | } | 101 | } |
96 | 102 | ||
diff --git a/init/Config.in b/init/Config.in index af7aac833..eb4211386 100644 --- a/init/Config.in +++ b/init/Config.in | |||
@@ -85,15 +85,6 @@ config CONFIG_MSVC | |||
85 | help | 85 | help |
86 | msvc is used to start and stop processes controlled by minit | 86 | msvc is used to start and stop processes controlled by minit |
87 | 87 | ||
88 | # Should start-stop-daemon be moved under debianutils? | ||
89 | config CONFIG_START_STOP_DAEMON | ||
90 | bool "start-stop-daemon" | ||
91 | default y | ||
92 | help | ||
93 | start-stop-daemon is used to control the creation and | ||
94 | termination of system-level processes, usually the ones | ||
95 | started during the startup of the system. | ||
96 | |||
97 | config CONFIG_MESG | 88 | config CONFIG_MESG |
98 | bool "mesg" | 89 | bool "mesg" |
99 | default y | 90 | default y |
diff --git a/init/Makefile.in b/init/Makefile.in index b1f464d19..1b13f693b 100644 --- a/init/Makefile.in +++ b/init/Makefile.in | |||
@@ -31,7 +31,6 @@ INIT-$(CONFIG_MSVC) += msvc.o | |||
31 | INIT-$(CONFIG_PIDFILEHACK) += pidfilehack.o | 31 | INIT-$(CONFIG_PIDFILEHACK) += pidfilehack.o |
32 | INIT-$(CONFIG_POWEROFF) += poweroff.o | 32 | INIT-$(CONFIG_POWEROFF) += poweroff.o |
33 | INIT-$(CONFIG_REBOOT) += reboot.o | 33 | INIT-$(CONFIG_REBOOT) += reboot.o |
34 | INIT-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o | ||
35 | 34 | ||
36 | ifeq ($(CONFIG_HALT), y) | 35 | ifeq ($(CONFIG_HALT), y) |
37 | CONFIG_INIT_SHARED=y | 36 | CONFIG_INIT_SHARED=y |
diff --git a/init/start_stop_daemon.c b/init/start_stop_daemon.c deleted file mode 100644 index 482078e6e..000000000 --- a/init/start_stop_daemon.c +++ /dev/null | |||
@@ -1,253 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Mini start-stop-daemon implementation(s) for busybox | ||
4 | * | ||
5 | * Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>, | ||
6 | * public domain. | ||
7 | * Adapted for busybox David Kimdon <dwhedon@gordian.com> | ||
8 | */ | ||
9 | |||
10 | #include <stdio.h> | ||
11 | #include <stdlib.h> | ||
12 | #include <string.h> | ||
13 | #include <stdarg.h> | ||
14 | #include <signal.h> | ||
15 | #include <errno.h> | ||
16 | #include <sys/stat.h> | ||
17 | #include <dirent.h> | ||
18 | #include <unistd.h> | ||
19 | #include <getopt.h> | ||
20 | |||
21 | #include "busybox.h" | ||
22 | #include "pwd_.h" | ||
23 | |||
24 | static int start = 0; | ||
25 | static int stop = 0; | ||
26 | static int fork_before_exec = 0; | ||
27 | static int signal_nr = 15; | ||
28 | static int user_id = -1; | ||
29 | static char *userspec = NULL; | ||
30 | static char *cmdname = NULL; | ||
31 | static char *execname = NULL; | ||
32 | static char *startas = NULL; | ||
33 | |||
34 | typedef struct pid_list { | ||
35 | struct pid_list *next; | ||
36 | int pid; | ||
37 | } pid_list; | ||
38 | |||
39 | static pid_list *found = NULL; | ||
40 | |||
41 | static inline void | ||
42 | push(int pid) | ||
43 | { | ||
44 | pid_list *p; | ||
45 | |||
46 | p = xmalloc(sizeof(*p)); | ||
47 | p->next = found; | ||
48 | p->pid = pid; | ||
49 | found = p; | ||
50 | } | ||
51 | |||
52 | static int | ||
53 | pid_is_exec(int pid, const char *exec) | ||
54 | { | ||
55 | char buf[PATH_MAX]; | ||
56 | FILE *fp; | ||
57 | |||
58 | sprintf(buf, "/proc/%d/cmdline", pid); | ||
59 | fp = fopen(buf, "r"); | ||
60 | if (fp && fgets (buf, sizeof (buf), fp) ) { | ||
61 | fclose(fp); | ||
62 | if (strncmp (buf, exec, strlen(exec)) == 0) | ||
63 | return 1; | ||
64 | } | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | |||
69 | static int | ||
70 | pid_is_user(int pid, int uid) | ||
71 | { | ||
72 | struct stat sb; | ||
73 | char buf[32]; | ||
74 | |||
75 | sprintf(buf, "/proc/%d", pid); | ||
76 | if (stat(buf, &sb) != 0) | ||
77 | return 0; | ||
78 | return (sb.st_uid == uid); | ||
79 | } | ||
80 | |||
81 | |||
82 | static int | ||
83 | pid_is_cmd(int pid, const char *name) | ||
84 | { | ||
85 | char buf[32]; | ||
86 | FILE *f; | ||
87 | int c; | ||
88 | |||
89 | sprintf(buf, "/proc/%d/stat", pid); | ||
90 | f = fopen(buf, "r"); | ||
91 | if (!f) | ||
92 | return 0; | ||
93 | while ((c = getc(f)) != EOF && c != '(') | ||
94 | ; | ||
95 | if (c != '(') { | ||
96 | fclose(f); | ||
97 | return 0; | ||
98 | } | ||
99 | /* this hopefully handles command names containing ')' */ | ||
100 | while ((c = getc(f)) != EOF && c == *name) | ||
101 | name++; | ||
102 | fclose(f); | ||
103 | return (c == ')' && *name == '\0'); | ||
104 | } | ||
105 | |||
106 | |||
107 | static void | ||
108 | check(int pid) | ||
109 | { | ||
110 | if (execname && !pid_is_exec(pid, execname)) { | ||
111 | return; | ||
112 | } | ||
113 | if (userspec && !pid_is_user(pid, user_id)) { | ||
114 | return; | ||
115 | } | ||
116 | if (cmdname && !pid_is_cmd(pid, cmdname)) { | ||
117 | return; | ||
118 | } | ||
119 | push(pid); | ||
120 | } | ||
121 | |||
122 | |||
123 | |||
124 | static void | ||
125 | do_procfs(void) | ||
126 | { | ||
127 | DIR *procdir; | ||
128 | struct dirent *entry; | ||
129 | int foundany, pid; | ||
130 | |||
131 | procdir = opendir("/proc"); | ||
132 | if (!procdir) | ||
133 | bb_perror_msg_and_die ("opendir /proc"); | ||
134 | |||
135 | foundany = 0; | ||
136 | while ((entry = readdir(procdir)) != NULL) { | ||
137 | if (sscanf(entry->d_name, "%d", &pid) != 1) | ||
138 | continue; | ||
139 | foundany++; | ||
140 | check(pid); | ||
141 | } | ||
142 | closedir(procdir); | ||
143 | if (!foundany) | ||
144 | bb_error_msg_and_die ("nothing in /proc - not mounted?"); | ||
145 | } | ||
146 | |||
147 | |||
148 | static void | ||
149 | do_stop(void) | ||
150 | { | ||
151 | char what[1024]; | ||
152 | pid_list *p; | ||
153 | int killed = 0; | ||
154 | |||
155 | if (cmdname) | ||
156 | strcpy(what, cmdname); | ||
157 | else if (execname) | ||
158 | strcpy(what, execname); | ||
159 | else if (userspec) | ||
160 | sprintf(what, "process(es) owned by `%s'", userspec); | ||
161 | else | ||
162 | bb_error_msg_and_die ("internal error, please report"); | ||
163 | |||
164 | if (!found) { | ||
165 | printf("no %s found; none killed.\n", what); | ||
166 | return; | ||
167 | } | ||
168 | for (p = found; p; p = p->next) { | ||
169 | if (kill(p->pid, signal_nr) == 0) { | ||
170 | p->pid = -p->pid; | ||
171 | killed++; | ||
172 | } else { | ||
173 | bb_perror_msg("warning: failed to kill %d:", p->pid); | ||
174 | } | ||
175 | } | ||
176 | if (killed) { | ||
177 | printf("stopped %s (pid", what); | ||
178 | for (p = found; p; p = p->next) | ||
179 | if(p->pid < 0) | ||
180 | printf(" %d", -p->pid); | ||
181 | printf(").\n"); | ||
182 | } | ||
183 | } | ||
184 | |||
185 | |||
186 | static const struct option ssd_long_options[] = { | ||
187 | { "stop", 0, NULL, 'K' }, | ||
188 | { "start", 0, NULL, 'S' }, | ||
189 | { "background", 0, NULL, 'b' }, | ||
190 | { "startas", 1, NULL, 'a' }, | ||
191 | { "name", 1, NULL, 'n' }, | ||
192 | { "signal", 1, NULL, 's' }, | ||
193 | { "user", 1, NULL, 'u' }, | ||
194 | { "exec", 1, NULL, 'x' }, | ||
195 | { 0, 0, 0, 0 } | ||
196 | }; | ||
197 | |||
198 | int | ||
199 | start_stop_daemon_main(int argc, char **argv) | ||
200 | { | ||
201 | int flags; | ||
202 | char *signame; | ||
203 | bb_applet_long_options = ssd_long_options; | ||
204 | |||
205 | flags = bb_getopt_ulflags(argc, argv, "KSba:n:s:u:x:", | ||
206 | &startas, &cmdname, &signame, &userspec, &execname); | ||
207 | |||
208 | /* Be sneaky and avoid branching */ | ||
209 | stop = (flags & 1); | ||
210 | start = (flags & 2); | ||
211 | fork_before_exec = (flags & 4); | ||
212 | |||
213 | signal_nr = bb_xgetlarg(signame, 10, 0, NSIG); | ||
214 | |||
215 | if (start == stop) | ||
216 | bb_error_msg_and_die ("need exactly one of -S or -K"); | ||
217 | |||
218 | if (!execname && !userspec) | ||
219 | bb_error_msg_and_die ("need at least one of -x or -u"); | ||
220 | |||
221 | if (!startas) | ||
222 | startas = execname; | ||
223 | |||
224 | if (start && !startas) | ||
225 | bb_error_msg_and_die ("-S needs -x or -a"); | ||
226 | |||
227 | argc -= optind; | ||
228 | argv += optind; | ||
229 | |||
230 | if (userspec && sscanf(userspec, "%d", &user_id) != 1) | ||
231 | user_id = my_getpwnam(userspec); | ||
232 | |||
233 | do_procfs(); | ||
234 | |||
235 | if (stop) { | ||
236 | do_stop(); | ||
237 | return EXIT_SUCCESS; | ||
238 | } | ||
239 | |||
240 | if (found) { | ||
241 | printf("%s already running.\n%d\n", execname ,found->pid); | ||
242 | return EXIT_SUCCESS; | ||
243 | } | ||
244 | *--argv = startas; | ||
245 | if (fork_before_exec) { | ||
246 | if (daemon(0, 0) == -1) | ||
247 | bb_perror_msg_and_die ("unable to fork"); | ||
248 | } | ||
249 | setsid(); | ||
250 | execv(startas, argv); | ||
251 | bb_perror_msg_and_die ("unable to start %s", startas); | ||
252 | } | ||
253 | |||