aboutsummaryrefslogtreecommitdiff
path: root/init
diff options
context:
space:
mode:
Diffstat (limited to 'init')
-rw-r--r--init/Config.in9
-rw-r--r--init/Makefile.in1
-rw-r--r--init/start_stop_daemon.c253
3 files changed, 0 insertions, 263 deletions
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