aboutsummaryrefslogtreecommitdiff
path: root/init
diff options
context:
space:
mode:
authorandersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277>2004-05-26 10:28:32 +0000
committerandersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277>2004-05-26 10:28:32 +0000
commit42ea8612178195991445856579d8a917c180378d (patch)
treefab9d8c78a24c8b10f6763cb79fb70a57d150f87 /init
parent855bcf4451ce90fad56ec0819af0916d850ba76f (diff)
downloadbusybox-w32-42ea8612178195991445856579d8a917c180378d.tar.gz
busybox-w32-42ea8612178195991445856579d8a917c180378d.tar.bz2
busybox-w32-42ea8612178195991445856579d8a917c180378d.zip
As discussed, drop minit, which was not being supported in busybox.
People wishing to use minit can obtain it and obtain support from http://www.fefe.de/minit/ git-svn-id: svn://busybox.net/trunk/busybox@8872 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'init')
-rw-r--r--init/Config.in24
-rw-r--r--init/Makefile.in3
-rw-r--r--init/minit.c612
-rw-r--r--init/msvc.c300
-rw-r--r--init/pidfilehack.c78
5 files changed, 0 insertions, 1017 deletions
diff --git a/init/Config.in b/init/Config.in
index 22c6c5518..4465e75a1 100644
--- a/init/Config.in
+++ b/init/Config.in
@@ -61,30 +61,6 @@ config CONFIG_REBOOT
61 help 61 help
62 Stop all processes and reboot the system. 62 Stop all processes and reboot the system.
63 63
64config CONFIG_MINIT
65 bool "minit"
66 default n
67 depends on ! CONFIG_INIT
68 help
69 Minimal init, based on minit v0.9.1. This is a simple
70 init replacement that handles starting/stopping services,
71 and service dependencies. See http://www.fefe.de/minit/
72 for additional information.
73
74config CONFIG_PIDFILEHACK
75 bool "pidfilehack"
76 default y
77 depends on CONFIG_MINIT
78 help
79 pidfilehack is used by minit to run servers.
80
81config CONFIG_MSVC
82 bool "msvc"
83 default y
84 depends on CONFIG_MINIT
85 help
86 msvc is used to start and stop processes controlled by minit
87
88config CONFIG_MESG 64config CONFIG_MESG
89 bool "mesg" 65 bool "mesg"
90 default y 66 default y
diff --git a/init/Makefile.in b/init/Makefile.in
index 039921435..6264710db 100644
--- a/init/Makefile.in
+++ b/init/Makefile.in
@@ -26,9 +26,6 @@ INIT-y:=
26INIT-$(CONFIG_HALT) += halt.o 26INIT-$(CONFIG_HALT) += halt.o
27INIT-$(CONFIG_INIT) += init.o 27INIT-$(CONFIG_INIT) += init.o
28INIT-$(CONFIG_MESG) += mesg.o 28INIT-$(CONFIG_MESG) += mesg.o
29INIT-$(CONFIG_MINIT) += minit.o
30INIT-$(CONFIG_MSVC) += msvc.o
31INIT-$(CONFIG_PIDFILEHACK) += pidfilehack.o
32INIT-$(CONFIG_POWEROFF) += poweroff.o 29INIT-$(CONFIG_POWEROFF) += poweroff.o
33INIT-$(CONFIG_REBOOT) += reboot.o 30INIT-$(CONFIG_REBOOT) += reboot.o
34 31
diff --git a/init/minit.c b/init/minit.c
deleted file mode 100644
index 8269ac112..000000000
--- a/init/minit.c
+++ /dev/null
@@ -1,612 +0,0 @@
1/*
2 * minit version 0.9.1 by Felix von Leitner
3 * ported to busybox by Glenn McGrath <bug1@iinet.net.au>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include <time.h>
21#include <signal.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26#include <limits.h>
27#include <errno.h>
28#include <sys/fcntl.h>
29#include <sys/ioctl.h>
30#include <sys/poll.h>
31#include <sys/reboot.h>
32#include <sys/socket.h>
33#include <sys/types.h>
34#include <sys/un.h>
35#include <sys/wait.h>
36#include <linux/kd.h>
37
38#include "busybox.h"
39
40#define MINITROOT "/etc/minit"
41
42static int i_am_init;
43static int infd, outfd;
44
45extern char **environ;
46
47static struct process {
48 char *name;
49 pid_t pid;
50 char respawn;
51 char circular;
52 time_t startedat;
53 int __stdin, __stdout;
54 int logservice;
55} *root;
56
57static int maxprocess = -1;
58
59static int processalloc = 0;
60
61static unsigned int fmt_ulong(char *dest, unsigned long i)
62{
63 register unsigned long len, tmp, len2;
64
65 /* first count the number of bytes needed */
66 for (len = 1, tmp = i; tmp > 9; ++len)
67 tmp /= 10;
68 if (dest)
69 for (tmp = i, dest += len, len2 = len + 1; --len2; tmp /= 10)
70 *--dest = (tmp % 10) + '0';
71 return len;
72}
73
74/* split buf into n strings that are separated by c. return n as *len.
75 * Allocate plus more slots and leave the first ofs of them alone. */
76static char **split(char *buf, int c, int *len, int plus, int ofs)
77{
78 int n = 1;
79 char **v = 0;
80 char **w;
81
82 /* step 1: count tokens */
83 char *s;
84
85 for (s = buf; *s; s++)
86 if (*s == c)
87 n++;
88 /* step 2: allocate space for pointers */
89 v = (char **) malloc((n + plus) * sizeof(char *));
90 if (!v)
91 return 0;
92 w = v + ofs;
93 *w++ = buf;
94 for (s = buf;; s++) {
95 while (*s && *s != c)
96 s++;
97 if (*s == 0)
98 break;
99 if (*s == c) {
100 *s = 0;
101 *w++ = s + 1;
102 }
103 }
104 *len = w - v;
105 return v;
106}
107
108static int openreadclose(char *fn, char **buf, unsigned long *len)
109{
110 int fd = open(fn, O_RDONLY);
111
112 if (fd < 0)
113 return -1;
114 if (!*buf) {
115 *len = lseek(fd, 0, SEEK_END);
116 lseek(fd, 0, SEEK_SET);
117 *buf = (char *) malloc(*len + 1);
118 if (!*buf) {
119 close(fd);
120 return -1;
121 }
122 }
123 *len = read(fd, *buf, *len);
124 if (*len != (unsigned long) -1)
125 (*buf)[*len] = 0;
126 return close(fd);
127}
128
129/* return index of service in process data structure or -1 if not found */
130static int findservice(char *service)
131{
132 int i;
133
134 for (i = 0; i <= maxprocess; i++) {
135 if (!strcmp(root[i].name, service))
136 return i;
137 }
138 return -1;
139}
140
141/* look up process index in data structure by PID */
142static int findbypid(pid_t pid)
143{
144 int i;
145
146 for (i = 0; i <= maxprocess; i++) {
147 if (root[i].pid == pid)
148 return i;
149 }
150 return -1;
151}
152
153/* clear circular dependency detection flags */
154static void circsweep(void)
155{
156 int i;
157
158 for (i = 0; i <= maxprocess; i++)
159 root[i].circular = 0;
160}
161
162/* add process to data structure, return index or -1 */
163static int addprocess(struct process *p)
164{
165 if (maxprocess + 1 >= processalloc) {
166 struct process *fump;
167
168 processalloc += 8;
169 if ((fump =
170 (struct process *) xrealloc(root,
171 processalloc *
172 sizeof(struct process))) == 0)
173 return -1;
174 root = fump;
175 }
176 memmove(&root[++maxprocess], p, sizeof(struct process));
177 return maxprocess;
178}
179
180/* load a service into the process data structure and return index or -1
181 * if failed */
182static int loadservice(char *service)
183{
184 struct process tmp;
185 int fd;
186
187 if (*service == 0)
188 return -1;
189 fd = findservice(service);
190 if (fd >= 0)
191 return fd;
192 if (chdir(MINITROOT) || chdir(service))
193 return -1;
194 if (!(tmp.name = strdup(service)))
195 return -1;
196 tmp.pid = 0;
197 fd = open("respawn", O_RDONLY);
198 if (fd >= 0) {
199 tmp.respawn = 1;
200 close(fd);
201 } else
202 tmp.respawn = 0;
203 tmp.startedat = 0;
204 tmp.circular = 0;
205 tmp.__stdin = 0;
206 tmp.__stdout = 1;
207 {
208 char *logservice = alloca(strlen(service) + 5);
209
210 strcpy(logservice, service);
211 strcat(logservice, "/log");
212 tmp.logservice = loadservice(logservice);
213 if (tmp.logservice >= 0) {
214 int pipefd[2];
215
216 if (pipe(pipefd))
217 return -1;
218 root[tmp.logservice].__stdin = pipefd[0];
219 tmp.__stdout = pipefd[1];
220 }
221 }
222 return (addprocess(&tmp));
223}
224
225/* usage: isup(findservice("sshd")).
226 * returns nonzero if process is up */
227static int isup(int service)
228{
229 if (service < 0)
230 return 0;
231 return (root[service].pid != 0);
232}
233
234static void opendevconsole(void)
235{
236 int fd;
237
238 if ((fd = open("/dev/console", O_RDWR | O_NOCTTY)) >= 0) {
239 dup2(fd, 0);
240 dup2(fd, 1);
241 dup2(fd, 2);
242 if (fd > 2)
243 close(fd);
244 }
245}
246
247/* called from inside the service directory, return the PID or 0 on error */
248static pid_t forkandexec(int pause_flag, int service)
249{
250 char **argv = 0;
251 int count = 0;
252 pid_t p;
253 int fd;
254 unsigned long len;
255 char *s = 0;
256 int argc;
257 char *argv0 = 0;
258
259 again:
260 switch (p = fork()) {
261 case (pid_t) - 1:
262 if (count > 3)
263 return 0;
264 sleep(++count * 2);
265 goto again;
266 case 0:
267 /* child */
268
269 if (i_am_init) {
270 ioctl(0, TIOCNOTTY, 0);
271 setsid();
272 opendevconsole();
273 tcsetpgrp(0, getpgrp());
274 }
275 close(infd);
276 close(outfd);
277 if (pause_flag) {
278 struct timespec req;
279
280 req.tv_sec = 0;
281 req.tv_nsec = 500000000;
282 nanosleep(&req, 0);
283 }
284 if (!openreadclose("params", &s, &len)) {
285 argv = split(s, '\n', &argc, 2, 1);
286 if (argv[argc - 1])
287 argv[argc - 1] = 0;
288 else
289 argv[argc] = 0;
290 } else {
291 argv = (char **) xmalloc(2 * sizeof(char *));
292 argv[1] = 0;
293 }
294 argv0 = (char *) xmalloc(PATH_MAX + 1);
295 if (!argv || !argv0)
296 goto abort;
297 if (readlink("run", argv0, PATH_MAX) < 0) {
298 if (errno != EINVAL)
299 goto abort; /* not a symbolic link */
300 argv0 = strdup("./run");
301 }
302 argv[0] = strrchr(argv0, '/');
303 if (argv[0])
304 argv[0]++;
305 else
306 argv[0] = argv0;
307 if (root[service].__stdin != 0)
308 dup2(root[service].__stdin, 0);
309 if (root[service].__stdout != 1) {
310 dup2(root[service].__stdout, 1);
311 dup2(root[service].__stdout, 2);
312 }
313 {
314 int i;
315
316 for (i = 3; i < 1024; ++i)
317 close(i);
318 }
319 execve(argv0, argv, environ);
320 _exit(0);
321 abort:
322 free(argv0);
323 free(argv);
324 _exit(0);
325 default:
326 fd = open("sync", O_RDONLY);
327 if (fd >= 0) {
328 pid_t p2;
329
330 close(fd);
331 p2 = waitpid(p, 0, 0);
332 return 1;
333 }
334 return p;
335 }
336}
337
338/* start a service, return nonzero on error */
339static int startnodep(int service, int pause_flag)
340{
341 /* step 1: see if the process is already up */
342 if (isup(service))
343 return 0;
344
345 /* step 2: fork and exec service, put PID in data structure */
346 if (chdir(MINITROOT) || chdir(root[service].name))
347 return -1;
348 root[service].startedat = time(0);
349 root[service].pid = forkandexec(pause_flag, service);
350 return root[service].pid;
351}
352
353static int startservice(int service, int pause_flag)
354{
355 int dir = -1;
356 unsigned long len;
357 char *s = 0;
358 pid_t pid;
359
360 if (service < 0)
361 return 0;
362 if (root[service].circular)
363 return 0;
364 root[service].circular = 1;
365 if (root[service].logservice >= 0)
366 startservice(root[service].logservice, pause_flag);
367 if (chdir(MINITROOT) || chdir(root[service].name))
368 return -1;
369 if ((dir = open(".", O_RDONLY)) >= 0) {
370 if (!openreadclose("depends", &s, &len)) {
371 char **deps;
372 int depc, i;
373
374 deps = split(s, '\n', &depc, 0, 0);
375 for (i = 0; i < depc; i++) {
376 int service_index;
377
378 if (deps[i][0] == '#')
379 continue;
380 service_index = loadservice(deps[i]);
381 if (service_index >= 0 && root[service_index].pid != 1)
382 startservice(service_index, 0);
383 }
384 fchdir(dir);
385 }
386 pid = startnodep(service, pause_flag);
387 close(dir);
388 dir = -1;
389 return pid;
390 }
391 return 0;
392}
393
394static void sulogin(void)
395{
396 /* exiting on an initialization failure is not a good idea for init */
397 char *argv[] = { "sulogin", 0 };
398 execve("/sbin/sulogin", argv, environ);
399 exit(1);
400}
401
402static void handlekilled(pid_t killed)
403{
404 int i;
405
406 if (killed == (pid_t) - 1) {
407 write(2, "all services exited.\n", 21);
408 exit(0);
409 }
410 if (killed == 0)
411 return;
412 i = findbypid(killed);
413 if (i >= 0) {
414 root[i].pid = 0;
415 if (root[i].respawn) {
416 circsweep();
417 startservice(i, time(0) - root[i].startedat < 1);
418 } else {
419 root[i].startedat = time(0);
420 root[i].pid = 1;
421 }
422 }
423}
424
425static void childhandler(void)
426{
427 int status;
428 pid_t killed;
429
430 do {
431 killed = waitpid(-1, &status, WNOHANG);
432 handlekilled(killed);
433 } while (killed && killed != (pid_t) - 1);
434}
435
436static volatile int dowinch = 0;
437static volatile int doint = 0;
438
439static void sigchild(int whatever)
440{
441}
442static void sigwinch(int sig)
443{
444 dowinch = 1;
445}
446static void sigint(int sig)
447{
448 doint = 1;
449}
450
451extern int minit_main(int argc, char *argv[])
452{
453 /* Schritt 1: argv[1] als Service nehmen und starten */
454 struct pollfd pfd;
455 time_t last = time(0);
456 int nfds = 1;
457 int count = 0;
458 int i;
459
460 infd = open("/etc/minit/in", O_RDWR);
461 outfd = open("/etc/minit/out", O_RDWR | O_NONBLOCK);
462 if (getpid() == 1) {
463 int fd;
464
465 i_am_init = 1;
466 reboot(0);
467 if ((fd = open("/dev/console", O_RDWR | O_NOCTTY))) {
468 ioctl(fd, KDSIGACCEPT, SIGWINCH);
469 close(fd);
470 } else
471 ioctl(0, KDSIGACCEPT, SIGWINCH);
472 }
473/* signal(SIGPWR,sighandler); don't know what to do about it */
474/* signal(SIGHUP,sighandler); ??? */
475 {
476 struct sigaction sa;
477
478 sigemptyset(&sa.sa_mask);
479 sa.sa_sigaction = 0;
480 sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
481 sa.sa_handler = sigchild;
482 sigaction(SIGCHLD, &sa, 0);
483 sa.sa_handler = sigint;
484 sigaction(SIGINT, &sa, 0); /* ctrl-alt-del */
485 sa.sa_handler = sigwinch;
486 sigaction(SIGWINCH, &sa, 0); /* keyboard request */
487 }
488 if (infd < 0 || outfd < 0) {
489 puts("minit: could not open /etc/minit/in or /etc/minit/out\n");
490 sulogin();
491 nfds = 0;
492 } else
493 pfd.fd = infd;
494 pfd.events = POLLIN;
495
496 for (i = 1; i < argc; i++) {
497 circsweep();
498 if (startservice(loadservice(argv[i]), 0))
499 count++;
500 }
501 circsweep();
502 if (!count)
503 startservice(loadservice("default"), 0);
504 for (;;) {
505 char buf[1501];
506 time_t now;
507
508 if (doint) {
509 doint = 0;
510 startservice(loadservice("ctrlaltdel"), 0);
511 }
512 if (dowinch) {
513 dowinch = 0;
514 startservice(loadservice("kbreq"), 0);
515 }
516 childhandler();
517 now = time(0);
518 if (now < last || now - last > 30) {
519 /* The system clock was reset. Compensate. */
520 long diff = last - now;
521 int j;
522
523 for (j = 0; j <= maxprocess; ++j) {
524 root[j].startedat -= diff;
525 }
526 }
527 last = now;
528 switch (poll(&pfd, nfds, 5000)) {
529 case -1:
530 if (errno == EINTR) {
531 childhandler();
532 break;
533 }
534 opendevconsole();
535 puts("poll failed!\n");
536 sulogin();
537 /* what should we do if poll fails?! */
538 break;
539 case 1:
540 i = read(infd, buf, 1500);
541 if (i > 1) {
542 pid_t pid;
543 int idx = 0;
544 int tmp;
545
546 buf[i] = 0;
547
548 if (buf[0] != 's' && ((idx = findservice(buf + 1)) < 0))
549 error:
550 write(outfd, "0", 1);
551 else {
552 switch (buf[0]) {
553 case 'p':
554 write(outfd, buf, fmt_ulong(buf, root[idx].pid));
555 break;
556 case 'r':
557 root[idx].respawn = 0;
558 goto ok;
559 case 'R':
560 root[idx].respawn = 1;
561 goto ok;
562 case 'C':
563 if (kill(root[idx].pid, 0)) { /* check if still active */
564 handlekilled(root[idx].pid); /* no!?! remove form active list */
565 goto error;
566 }
567 goto ok;
568 break;
569 case 'P':
570 {
571 unsigned char *x = buf + strlen(buf) + 1;
572 unsigned char c;
573
574 tmp = 0;
575 while ((c = *x++ - '0') < 10)
576 tmp = tmp * 10 + c;
577 }
578 if (tmp > 0) {
579 if (kill(tmp, 0))
580 goto error;
581 pid = tmp;
582 }
583 root[idx].pid = tmp;
584 goto ok;
585 case 's':
586 idx = loadservice(buf + 1);
587 if (idx < 0)
588 goto error;
589 if (root[idx].pid < 2) {
590 root[idx].pid = 0;
591 circsweep();
592 idx = startservice(idx, 0);
593 if (idx == 0) {
594 write(outfd, "0", 1);
595 break;
596 }
597 }
598 ok:
599 write(outfd, "1", 1);
600 break;
601 case 'u':
602 write(outfd, buf,
603 fmt_ulong(buf, time(0) - root[idx].startedat));
604 }
605 }
606 }
607 break;
608 default:
609 break;
610 }
611 }
612}
diff --git a/init/msvc.c b/init/msvc.c
deleted file mode 100644
index 8a091b346..000000000
--- a/init/msvc.c
+++ /dev/null
@@ -1,300 +0,0 @@
1/*
2 * minit version 0.9.1 by Felix von Leitner
3 * ported to busybox by Glenn McGrath <bug1@iinet.net.au>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include <sys/fcntl.h>
21#include <sys/file.h>
22#include <signal.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <unistd.h>
27
28#include "busybox.h"
29
30static int infd, outfd;
31
32static char buf[1500];
33
34static unsigned int fmt_ulong(char *dest, unsigned long i)
35{
36 register unsigned long len, tmp, len2;
37
38 /* first count the number of bytes needed */
39 for (len = 1, tmp = i; tmp > 9; ++len)
40 tmp /= 10;
41 if (dest)
42 for (tmp = i, dest += len, len2 = len + 1; --len2; tmp /= 10)
43 *--dest = (tmp % 10) + '0';
44 return len;
45}
46
47static void addservice(char *service)
48{
49 char *service_ptr;
50
51 if (strncmp(service, "/etc/minit/", 11) == 0) {
52 service += 11;
53 }
54
55 while ((service_ptr = last_char_is(service, '/')) != NULL) {
56 *service_ptr = 0;
57 }
58 strncpy(buf + 1, service, 1400);
59 buf[1400] = 0;
60}
61
62static int addreadwrite(char *service)
63{
64 addservice(service);
65 write(infd, buf, strlen(buf));
66 return read(outfd, buf, 1500);
67}
68
69/* return PID, 0 if error */
70static pid_t __readpid(char *service)
71{
72 int len;
73
74 buf[0] = 'p';
75 len = addreadwrite(service);
76 if (len < 0)
77 return 0;
78 buf[len] = 0;
79 return atoi(buf);
80}
81
82/* return nonzero if error */
83static int respawn(char *service, int yesno)
84{
85 int len;
86
87 buf[0] = yesno ? 'R' : 'r';
88 len = addreadwrite(service);
89 return (len != 1 || buf[0] == '0');
90}
91
92/* return nonzero if error */
93static int startservice(char *service)
94{
95 int len;
96
97 buf[0] = 's';
98 len = addreadwrite(service);
99 return (len != 1 || buf[0] == '0');
100}
101
102extern int msvc_main(int argc, char **argv)
103{
104 if (argc < 2) {
105 bb_show_usage();
106 }
107 infd = bb_xopen("/etc/minit/in", O_WRONLY);
108 outfd = bb_xopen("/etc/minit/out", O_RDONLY);
109
110 while (lockf(infd, F_LOCK, 1)) {
111 bb_perror_msg("could not aquire lock!\n");
112 sleep(1);
113 }
114
115 if (argc == 2) {
116 pid_t pid = __readpid(argv[1]);
117
118 if (buf[0] != '0') {
119 int len;
120 int up_time;
121
122 printf("%s: ", argv[1]);
123 if (pid == 0)
124 printf("down ");
125 else if (pid == 1)
126 printf("finished ");
127 else {
128 printf("up (pid %d) ", pid);
129 }
130
131 buf[0] = 'u';
132 len = addreadwrite(argv[1]);
133 if (len < 0) {
134 up_time = 0;
135 } else {
136 buf[len] = 0;
137 up_time = atoi(buf);
138 }
139 printf("%d seconds\n", up_time);
140
141 if (pid == 0)
142 return 2;
143 else if (pid == 1)
144 return 3;
145 else
146 return 0;
147 } else {
148 bb_error_msg_and_die("no such service");
149 }
150 } else {
151 int i;
152 int ret = 0;
153 int sig = 0;
154 pid_t pid;
155
156 if (argv[1][0] == '-') {
157 switch (argv[1][1]) {
158 case 'g':
159 for (i = 2; i < argc; ++i) {
160 pid = __readpid(argv[i]);
161 if (pid < 2) {
162 if (pid == 1) {
163 bb_error_msg("%s, service termination", argv[i]);
164 } else {
165 bb_error_msg("%s, no such service", argv[i]);
166 }
167 ret = 1;
168 }
169 printf("%d\n", pid);
170 }
171 break;
172 case 'p':
173 sig = SIGSTOP;
174 goto dokill;
175 break;
176 case 'c':
177 sig = SIGCONT;
178 goto dokill;
179 break;
180 case 'h':
181 sig = SIGHUP;
182 goto dokill;
183 break;
184 case 'a':
185 sig = SIGALRM;
186 goto dokill;
187 break;
188 case 'i':
189 sig = SIGINT;
190 goto dokill;
191 break;
192 case 't':
193 sig = SIGTERM;
194 goto dokill;
195 break;
196 case 'k':
197 sig = SIGKILL;
198 goto dokill;
199 break;
200 case 'o':
201 for (i = 2; i < argc; ++i)
202 if (startservice(argv[i]) || respawn(argv[i], 0)) {
203 bb_error_msg("Couldnt not start %s\n", argv[i]);
204 ret = 1;
205 }
206 break;
207 case 'd':
208 for (i = 2; i < argc; ++i) {
209 pid = __readpid(argv[i]);
210 if (pid == 0) {
211 bb_error_msg("%s, no such service\n", argv[i]);
212 ret = 1;
213 } else if (pid == 1)
214 continue;
215 if (respawn(argv[i], 0) || kill(pid, SIGTERM)
216 || kill(pid, SIGCONT));
217 }
218 break;
219 case 'u':
220 for (i = 2; i < argc; ++i) {
221 if (startservice(argv[i]) || respawn(argv[i], 1)) {
222 bb_error_msg("Couldnt not start %s\n", argv[i]);
223 ret = 1;
224 }
225 break;
226 }
227 case 'C':
228 for (i = 2; i < argc; ++i) {
229 int len;
230
231 buf[0] = 'C';
232 len = addreadwrite(argv[i]);
233 if (len != 1 || buf[0] == '0') {
234 bb_error_msg("%s has terminated or was killed\n",
235 argv[i]);
236 ret = 1;
237 }
238 }
239 break;
240 case 'P':
241 pid = atoi(argv[1] + 2);
242 if (pid > 1) {
243 char *tmp;
244 int len;
245
246 buf[0] = 'P';
247 addservice(argv[2]);
248 tmp = buf + strlen(buf) + 1;
249 tmp[fmt_ulong(tmp, pid)] = 0;
250 write(infd, buf, strlen(buf) + strlen(tmp) + 2);
251 len = read(outfd, buf, 1500);
252 if (len != 1 || buf[0] == '0') {
253 bb_error_msg_and_die("Couldnt not set pid of service %s\n", argv[2]);
254 }
255 }
256 break;
257 default:
258 bb_show_usage();
259 }
260 } else {
261 bb_show_usage();
262 }
263 return ret;
264dokill:
265 for (i = 2; i < argc; i++) {
266 pid = __readpid(argv[i]);
267 if (!pid) {
268 bb_error_msg("%s no such service\n", argv[i]);
269 ret = 1;
270 }
271 if (kill(pid, sig)) {
272 bb_error_msg("%s, could not send signal %d to PID %d\n",
273 argv[i], sig, pid);
274 ret = 1;
275 }
276 }
277 return ret;
278 }
279}
280
281/*
282 -u Up. If the service is not running, start it. If the service stops,
283 restart it.
284 -d Down. If the service is running, send it a TERM signal and then a CONT
285 signal. After it stops, do not restart it.
286 -o Once. If the service is not running, start it. Do not restart it if it
287 stops.
288 -r Tell supervise that the service is normally running; this affects status
289 messages.
290 -s Tell supervise that the service is normally stopped; this affects status
291 messages.
292 -p Pause. Send the service a STOP signal.
293 -c Continue. Send the service a CONT signal.
294 -h Hangup. Send the service a HUP signal.
295 -a Alarm. Send the service an ALRM signal.
296 -i Interrupt. Send the service an INT signal.
297 -t Terminate. Send the service a TERM signal.
298 -k Kill. Send the service a KILL signal.
299 -x Exit. supervise will quit as soon as the service is down.
300*/
diff --git a/init/pidfilehack.c b/init/pidfilehack.c
deleted file mode 100644
index aa2fc0ac5..000000000
--- a/init/pidfilehack.c
+++ /dev/null
@@ -1,78 +0,0 @@
1/*
2 * minit version 0.9.1 by Felix von Leitner
3 * ported to busybox by Glenn McGrath <bug1@iinet.net.au>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include <unistd.h>
21#include <errno.h>
22#include <stdlib.h>
23#include <sys/fcntl.h>
24
25#include "busybox.h"
26/* purpose: argv[1] is the full path to a PID file,
27 * argv+2 is the daemon to run.
28 * the daemon is expected to fork in the background and write its PID in
29 * the pid file.
30 */
31
32extern int pidfilehack_main(int argc, char **argv)
33{
34 int count = 0;
35
36 if (argc < 3) {
37 bb_show_usage();
38
39 }
40 if (unlink(argv[2]) && (errno != ENOENT)) {
41 bb_perror_msg("could not remove pid file");
42 }
43 switch (fork()) {
44 case -1:
45 bb_perror_msg("could not fork");
46 return 2;
47 case 0: /* child */
48 execv(argv[3], argv + 3);
49 bb_perror_msg("execvp failed");
50 return 3;
51 }
52 do {
53 int fd = open(argv[2], O_RDONLY);
54
55 if (fd >= 0) {
56 static char buf[100] = "-P";
57 int len = read(fd, buf + 2, 100);
58
59 close(fd);
60 if (len > 0) {
61 char *_argv[] = { "msvc", 0, 0, 0 };
62 if (buf[len + 1] == '\n') {
63 buf[len + 1] = 0;
64 } else {
65 buf[len + 2] = 0;
66 }
67 _argv[1] = buf;
68 _argv[2] = argv[1];
69 execvp(_argv[0], _argv);
70 bb_perror_msg("execvp failed");
71 return 0;
72 }
73 }
74 sleep(1);
75 } while (++count < 30);
76
77 return(0);
78}