aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2003-07-26 09:16:00 +0000
committerEric Andersen <andersen@codepoet.org>2003-07-26 09:16:00 +0000
commita1ed06b04739d85389fe23e78e97556864b77c64 (patch)
tree80ceac0ee76ad0bee1838252ced4f0cfd097659c
parentaa820dbc00860a2ddcb7a0205345ffe39c7d18d7 (diff)
downloadbusybox-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.in8
-rw-r--r--debianutils/Makefile.in1
-rw-r--r--debianutils/run_parts.c56
-rw-r--r--init/Config.in9
-rw-r--r--init/Makefile.in1
-rw-r--r--init/start_stop_daemon.c253
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
36config 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
36config CONFIG_WHICH 44config 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:=
27DEBIANUTILS-$(CONFIG_MKTEMP) += mktemp.o 27DEBIANUTILS-$(CONFIG_MKTEMP) += mktemp.o
28DEBIANUTILS-$(CONFIG_READLINK) += readlink.o 28DEBIANUTILS-$(CONFIG_READLINK) += readlink.o
29DEBIANUTILS-$(CONFIG_RUN_PARTS) += run_parts.o 29DEBIANUTILS-$(CONFIG_RUN_PARTS) += run_parts.o
30DEBIANUTILS-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o
30DEBIANUTILS-$(CONFIG_WHICH) += which.o 31DEBIANUTILS-$(CONFIG_WHICH) += which.o
31 32
32libraries-y+=$(DEBIANUTILS_DIR)$(DEBIANUTILS_AR) 33libraries-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
57static 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 */
59int run_parts_main(int argc, char **argv) 66int 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?
89config 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
97config CONFIG_MESG 88config 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
31INIT-$(CONFIG_PIDFILEHACK) += pidfilehack.o 31INIT-$(CONFIG_PIDFILEHACK) += pidfilehack.o
32INIT-$(CONFIG_POWEROFF) += poweroff.o 32INIT-$(CONFIG_POWEROFF) += poweroff.o
33INIT-$(CONFIG_REBOOT) += reboot.o 33INIT-$(CONFIG_REBOOT) += reboot.o
34INIT-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o
35 34
36ifeq ($(CONFIG_HALT), y) 35ifeq ($(CONFIG_HALT), y)
37CONFIG_INIT_SHARED=y 36CONFIG_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
24static int start = 0;
25static int stop = 0;
26static int fork_before_exec = 0;
27static int signal_nr = 15;
28static int user_id = -1;
29static char *userspec = NULL;
30static char *cmdname = NULL;
31static char *execname = NULL;
32static char *startas = NULL;
33
34typedef struct pid_list {
35 struct pid_list *next;
36 int pid;
37} pid_list;
38
39static pid_list *found = NULL;
40
41static inline void
42push(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
52static int
53pid_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
69static int
70pid_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
82static int
83pid_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
107static void
108check(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
124static void
125do_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
148static void
149do_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
186static 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
198int
199start_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