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/
No binary (build failed)
—
(log yok)
| @@ -367,9 +367,6 @@ | |
| #ifdef CONFIG_MESG | |
| APPLET(mesg, mesg_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) | |
| #endif | |
| - | #ifdef CONFIG_MINIT |
| - | APPLET(minit, minit_main, _BB_DIR_SBIN, _BB_SUID_NEVER) |
| - | #endif |
| #ifdef CONFIG_MKDIR | |
| APPLET(mkdir, mkdir_main, _BB_DIR_BIN, _BB_SUID_NEVER) | |
| #endif | |
| @@ -400,9 +397,6 @@ | |
| #ifdef CONFIG_MSH | |
| APPLET_NOUSAGE("msh", msh_main, _BB_DIR_BIN, _BB_SUID_NEVER) | |
| #endif | |
| - | #ifdef CONFIG_MSVC |
| - | APPLET(msvc, msvc_main, _BB_DIR_BIN, _BB_SUID_NEVER) |
| - | #endif |
| #ifdef CONFIG_MT | |
| APPLET(mt, mt_main, _BB_DIR_BIN, _BB_SUID_NEVER) | |
| #endif | |
| @@ -433,9 +427,6 @@ | |
| #ifdef CONFIG_PATCH | |
| APPLET(patch, patch_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) | |
| #endif | |
| - | #ifdef CONFIG_PIDFILEHACK |
| - | APPLET(pidfilehack, pidfilehack_main, _BB_DIR_BIN, _BB_SUID_NEVER) |
| - | #endif |
| #ifdef CONFIG_PIDOF | |
| APPLET(pidof, pidof_main, _BB_DIR_BIN, _BB_SUID_NEVER) | |
| #endif | |
| @@ -1591,11 +1591,6 @@ | |
| "\ty\tAllow write access to your terminal.\n" \ | |
| "\tn\tDisallow write access to your terminal.\n" | |
| - | #define minit_trivial_usage \ |
| - | "[-spPrRC]" |
| - | #define minit_full_usage \ |
| - | "A small replacement for SysV init" |
| - | |
| #define mkdir_trivial_usage \ | |
| "[OPTION] DIRECTORY..." | |
| #define mkdir_full_usage \ | |
| @@ -1726,25 +1721,6 @@ | |
| "$ mount /dev/fd0 /mnt -t msdos -o ro\n" \ | |
| "$ mount /tmp/diskimage /opt -t ext2 -o loop\n" | |
| - | #define msvc_trivial_usage \ |
| - | "-[udorspchaitkx] service" |
| - | #define msvc_full_usage \ |
| - | "[option] service\n" \ |
| - | "Where option is one of\n" \ |
| - | "\t-u\tUp. If the service is not running, start it. If the service stops, restart it.\n" \ |
| - | "\t-d\tDown. If the service is running, stop it, do not restart it.\n" \ |
| - | "\t-o\tOnce. If the service is not running, start it. Do not restart it if it stops.\n" \ |
| - | "\t-r\tTell supervise that the service is normally running; this affects status messages.\n" \ |
| - | "\t-s\tTell supervise that the service is normally stopped; this affects status messages.\n" \ |
| - | "\t-p\tPause. Send the service a STOP signal.\n" \ |
| - | "\t-c\tContinue. Send the service a CONT signal.\n" \ |
| - | "\t-h\tHangup. Send the service a HUP signal.\n" \ |
| - | "\t-a\tAlarm. Send the service an ALRM signal.\n" \ |
| - | "\t-i\tInterrupt. Send the service an INT signal.\n" \ |
| - | "\t-t\tTerminate. Send the service a TERM signal.\n" \ |
| - | "\t-k\tKill. Send the service a KILL signal.\n" \ |
| - | "\t-x\tExit. supervise will quit as soon as the service is down." |
| - | |
| #define mt_trivial_usage \ | |
| "[-f device] opcode value" | |
| #define mt_full_usage \ | |
| @@ -1861,11 +1837,6 @@ | |
| #define patch_example_usage \ | |
| "$ patch -p1 <example.diff" | |
| - | #define pidfilehack_trivial_usage \ |
| - | "[daemon.pid] [daemon]" |
| - | #define pidfilehack_full_usage \ |
| - | "service /var/run/daemon.pid /usr/sbin/daemon args...\n" |
| - | |
| #define pidof_trivial_usage \ | |
| "process-name [process-name ...]" | |
| #define pidof_full_usage \ | |
| @@ -61,30 +61,6 @@ config CONFIG_REBOOT | |
| help | |
| Stop all processes and reboot the system. | |
| - | config CONFIG_MINIT |
| - | bool "minit" |
| - | default n |
| - | depends on ! CONFIG_INIT |
| - | help |
| - | Minimal init, based on minit v0.9.1. This is a simple |
| - | init replacement that handles starting/stopping services, |
| - | and service dependencies. See http://www.fefe.de/minit/ |
| - | for additional information. |
| - | |
| - | config CONFIG_PIDFILEHACK |
| - | bool "pidfilehack" |
| - | default y |
| - | depends on CONFIG_MINIT |
| - | help |
| - | pidfilehack is used by minit to run servers. |
| - | |
| - | config CONFIG_MSVC |
| - | bool "msvc" |
| - | default y |
| - | depends on CONFIG_MINIT |
| - | help |
| - | msvc is used to start and stop processes controlled by minit |
| - | |
| config CONFIG_MESG | |
| bool "mesg" | |
| default y | |
| @@ -26,9 +26,6 @@ INIT-y:= | |
| INIT-$(CONFIG_HALT) += halt.o | |
| INIT-$(CONFIG_INIT) += init.o | |
| INIT-$(CONFIG_MESG) += mesg.o | |
| - | INIT-$(CONFIG_MINIT) += minit.o |
| - | INIT-$(CONFIG_MSVC) += msvc.o |
| - | INIT-$(CONFIG_PIDFILEHACK) += pidfilehack.o |
| INIT-$(CONFIG_POWEROFF) += poweroff.o | |
| INIT-$(CONFIG_REBOOT) += reboot.o | |
| @@ -1,612 +0,0 @@ | |
| - | /* |
| - | * minit version 0.9.1 by Felix von Leitner |
| - | * ported to busybox by Glenn McGrath <[email protected]> |
| - | * |
| - | * This program is free software; you can redistribute it and/or modify |
| - | * it under the terms of the GNU General Public License as published by |
| - | * the Free Software Foundation; either version 2 of the License, or |
| - | * (at your option) any later version. |
| - | * |
| - | * This program is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| - | * GNU General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU General Public License |
| - | * along with this program; if not, write to the Free Software |
| - | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| - | */ |
| - | |
| - | #include <time.h> |
| - | #include <signal.h> |
| - | #include <stdio.h> |
| - | #include <stdlib.h> |
| - | #include <string.h> |
| - | #include <unistd.h> |
| - | #include <limits.h> |
| - | #include <errno.h> |
| - | #include <sys/fcntl.h> |
| - | #include <sys/ioctl.h> |
| - | #include <sys/poll.h> |
| - | #include <sys/reboot.h> |
| - | #include <sys/socket.h> |
| - | #include <sys/types.h> |
| - | #include <sys/un.h> |
| - | #include <sys/wait.h> |
| - | #include <linux/kd.h> |
| - | |
| - | #include "busybox.h" |
| - | |
| - | #define MINITROOT "/etc/minit" |
| - | |
| - | static int i_am_init; |
| - | static int infd, outfd; |
| - | |
| - | extern char **environ; |
| - | |
| - | static struct process { |
| - | char *name; |
| - | pid_t pid; |
| - | char respawn; |
| - | char circular; |
| - | time_t startedat; |
| - | int __stdin, __stdout; |
| - | int logservice; |
| - | } *root; |
| - | |
| - | static int maxprocess = -1; |
| - | |
| - | static int processalloc = 0; |
| - | |
| - | static unsigned int fmt_ulong(char *dest, unsigned long i) |
| - | { |
| - | register unsigned long len, tmp, len2; |
| - | |
| - | /* first count the number of bytes needed */ |
| - | for (len = 1, tmp = i; tmp > 9; ++len) |
| - | tmp /= 10; |
| - | if (dest) |
| - | for (tmp = i, dest += len, len2 = len + 1; --len2; tmp /= 10) |
| - | *--dest = (tmp % 10) + '0'; |
| - | return len; |
| - | } |
| - | |
| - | /* split buf into n strings that are separated by c. return n as *len. |
| - | * Allocate plus more slots and leave the first ofs of them alone. */ |
| - | static char **split(char *buf, int c, int *len, int plus, int ofs) |
| - | { |
| - | int n = 1; |
| - | char **v = 0; |
| - | char **w; |
| - | |
| - | /* step 1: count tokens */ |
| - | char *s; |
| - | |
| - | for (s = buf; *s; s++) |
| - | if (*s == c) |
| - | n++; |
| - | /* step 2: allocate space for pointers */ |
| - | v = (char **) malloc((n + plus) * sizeof(char *)); |
| - | if (!v) |
| - | return 0; |
| - | w = v + ofs; |
| - | *w++ = buf; |
| - | for (s = buf;; s++) { |
| - | while (*s && *s != c) |
| - | s++; |
| - | if (*s == 0) |
| - | break; |
| - | if (*s == c) { |
| - | *s = 0; |
| - | *w++ = s + 1; |
| - | } |
| - | } |
| - | *len = w - v; |
| - | return v; |
| - | } |
| - | |
| - | static int openreadclose(char *fn, char **buf, unsigned long *len) |
| - | { |
| - | int fd = open(fn, O_RDONLY); |
| - | |
| - | if (fd < 0) |
| - | return -1; |
| - | if (!*buf) { |
| - | *len = lseek(fd, 0, SEEK_END); |
| - | lseek(fd, 0, SEEK_SET); |
| - | *buf = (char *) malloc(*len + 1); |
| - | if (!*buf) { |
| - | close(fd); |
| - | return -1; |
| - | } |
| - | } |
| - | *len = read(fd, *buf, *len); |
| - | if (*len != (unsigned long) -1) |
| - | (*buf)[*len] = 0; |
| - | return close(fd); |
| - | } |
| - | |
| - | /* return index of service in process data structure or -1 if not found */ |
| - | static int findservice(char *service) |
| - | { |
| - | int i; |
| - | |
| - | for (i = 0; i <= maxprocess; i++) { |
| - | if (!strcmp(root[i].name, service)) |
| - | return i; |
| - | } |
| - | return -1; |
| - | } |
| - | |
| - | /* look up process index in data structure by PID */ |
| - | static int findbypid(pid_t pid) |
| - | { |
| - | int i; |
| - | |
| - | for (i = 0; i <= maxprocess; i++) { |
| - | if (root[i].pid == pid) |
| - | return i; |
| - | } |
| - | return -1; |
| - | } |
| - | |
| - | /* clear circular dependency detection flags */ |
| - | static void circsweep(void) |
| - | { |
| - | int i; |
| - | |
| - | for (i = 0; i <= maxprocess; i++) |
| - | root[i].circular = 0; |
| - | } |
| - | |
| - | /* add process to data structure, return index or -1 */ |
| - | static int addprocess(struct process *p) |
| - | { |
| - | if (maxprocess + 1 >= processalloc) { |
| - | struct process *fump; |
| - | |
| - | processalloc += 8; |
| - | if ((fump = |
| - | (struct process *) xrealloc(root, |
| - | processalloc * |
| - | sizeof(struct process))) == 0) |
| - | return -1; |
| - | root = fump; |
| - | } |
| - | memmove(&root[++maxprocess], p, sizeof(struct process)); |
| - | return maxprocess; |
| - | } |
| - | |
| - | /* load a service into the process data structure and return index or -1 |
| - | * if failed */ |
| - | static int loadservice(char *service) |
| - | { |
| - | struct process tmp; |
| - | int fd; |
| - | |
| - | if (*service == 0) |
| - | return -1; |
| - | fd = findservice(service); |
| - | if (fd >= 0) |
| - | return fd; |
| - | if (chdir(MINITROOT) || chdir(service)) |
| - | return -1; |
| - | if (!(tmp.name = strdup(service))) |
| - | return -1; |
| - | tmp.pid = 0; |
| - | fd = open("respawn", O_RDONLY); |
| - | if (fd >= 0) { |
| - | tmp.respawn = 1; |
| - | close(fd); |
| - | } else |
| - | tmp.respawn = 0; |
| - | tmp.startedat = 0; |
| - | tmp.circular = 0; |
| - | tmp.__stdin = 0; |
| - | tmp.__stdout = 1; |
| - | { |
| - | char *logservice = alloca(strlen(service) + 5); |
| - | |
| - | strcpy(logservice, service); |
| - | strcat(logservice, "/log"); |
| - | tmp.logservice = loadservice(logservice); |
| - | if (tmp.logservice >= 0) { |
| - | int pipefd[2]; |
| - | |
| - | if (pipe(pipefd)) |
| - | return -1; |
| - | root[tmp.logservice].__stdin = pipefd[0]; |
| - | tmp.__stdout = pipefd[1]; |
| - | } |
| - | } |
| - | return (addprocess(&tmp)); |
| - | } |
| - | |
| - | /* usage: isup(findservice("sshd")). |
| - | * returns nonzero if process is up */ |
| - | static int isup(int service) |
| - | { |
| - | if (service < 0) |
| - | return 0; |
| - | return (root[service].pid != 0); |
| - | } |
| - | |
| - | static void opendevconsole(void) |
| - | { |
| - | int fd; |
| - | |
| - | if ((fd = open("/dev/console", O_RDWR | O_NOCTTY)) >= 0) { |
| - | dup2(fd, 0); |
| - | dup2(fd, 1); |
| - | dup2(fd, 2); |
| - | if (fd > 2) |
| - | close(fd); |
| - | } |
| - | } |
| - | |
| - | /* called from inside the service directory, return the PID or 0 on error */ |
| - | static pid_t forkandexec(int pause_flag, int service) |
| - | { |
| - | char **argv = 0; |
| - | int count = 0; |
| - | pid_t p; |
| - | int fd; |
| - | unsigned long len; |
| - | char *s = 0; |
| - | int argc; |
| - | char *argv0 = 0; |
| - | |
| - | again: |
| - | switch (p = fork()) { |
| - | case (pid_t) - 1: |
| - | if (count > 3) |
| - | return 0; |
| - | sleep(++count * 2); |
| - | goto again; |
| - | case 0: |
| - | /* child */ |
| - | |
| - | if (i_am_init) { |
| - | ioctl(0, TIOCNOTTY, 0); |
| - | setsid(); |
| - | opendevconsole(); |
| - | tcsetpgrp(0, getpgrp()); |
| - | } |
| - | close(infd); |
| - | close(outfd); |
| - | if (pause_flag) { |
| - | struct timespec req; |
| - | |
| - | req.tv_sec = 0; |
| - | req.tv_nsec = 500000000; |
| - | nanosleep(&req, 0); |
| - | } |
| - | if (!openreadclose("params", &s, &len)) { |
| - | argv = split(s, '\n', &argc, 2, 1); |
| - | if (argv[argc - 1]) |
| - | argv[argc - 1] = 0; |
| - | else |
| - | argv[argc] = 0; |
| - | } else { |
| - | argv = (char **) xmalloc(2 * sizeof(char *)); |
| - | argv[1] = 0; |
| - | } |
| - | argv0 = (char *) xmalloc(PATH_MAX + 1); |
| - | if (!argv || !argv0) |
| - | goto abort; |
| - | if (readlink("run", argv0, PATH_MAX) < 0) { |
| - | if (errno != EINVAL) |
| - | goto abort; /* not a symbolic link */ |
| - | argv0 = strdup("./run"); |
| - | } |
| - | argv[0] = strrchr(argv0, '/'); |
| - | if (argv[0]) |
| - | argv[0]++; |
| - | else |
| - | argv[0] = argv0; |
| - | if (root[service].__stdin != 0) |
| - | dup2(root[service].__stdin, 0); |
| - | if (root[service].__stdout != 1) { |
| - | dup2(root[service].__stdout, 1); |
| - | dup2(root[service].__stdout, 2); |
| - | } |
| - | { |
| - | int i; |
| - | |
| - | for (i = 3; i < 1024; ++i) |
| - | close(i); |
| - | } |
| - | execve(argv0, argv, environ); |
| - | _exit(0); |
| - | abort: |
| - | free(argv0); |
| - | free(argv); |
| - | _exit(0); |
| - | default: |
| - | fd = open("sync", O_RDONLY); |
| - | if (fd >= 0) { |
| - | pid_t p2; |
| - | |
| - | close(fd); |
| - | p2 = waitpid(p, 0, 0); |
| - | return 1; |
| - | } |
| - | return p; |
| - | } |
| - | } |
| - | |
| - | /* start a service, return nonzero on error */ |
| - | static int startnodep(int service, int pause_flag) |
| - | { |
| - | /* step 1: see if the process is already up */ |
| - | if (isup(service)) |
| - | return 0; |
| - | |
| - | /* step 2: fork and exec service, put PID in data structure */ |
| - | if (chdir(MINITROOT) || chdir(root[service].name)) |
| - | return -1; |
| - | root[service].startedat = time(0); |
| - | root[service].pid = forkandexec(pause_flag, service); |
| - | return root[service].pid; |
| - | } |
| - | |
| - | static int startservice(int service, int pause_flag) |
| - | { |
| - | int dir = -1; |
| - | unsigned long len; |
| - | char *s = 0; |
| - | pid_t pid; |
| - | |
| - | if (service < 0) |
| - | return 0; |
| - | if (root[service].circular) |
| - | return 0; |
| - | root[service].circular = 1; |
| - | if (root[service].logservice >= 0) |
| - | startservice(root[service].logservice, pause_flag); |
| - | if (chdir(MINITROOT) || chdir(root[service].name)) |
| - | return -1; |
| - | if ((dir = open(".", O_RDONLY)) >= 0) { |
| - | if (!openreadclose("depends", &s, &len)) { |
| - | char **deps; |
| - | int depc, i; |
| - | |
| - | deps = split(s, '\n', &depc, 0, 0); |
| - | for (i = 0; i < depc; i++) { |
| - | int service_index; |
| - | |
| - | if (deps[i][0] == '#') |
| - | continue; |
| - | service_index = loadservice(deps[i]); |
| - | if (service_index >= 0 && root[service_index].pid != 1) |
| - | startservice(service_index, 0); |
| - | } |
| - | fchdir(dir); |
| - | } |
| - | pid = startnodep(service, pause_flag); |
| - | close(dir); |
| - | dir = -1; |
| - | return pid; |
| - | } |
| - | return 0; |
| - | } |
| - | |
| - | static void sulogin(void) |
| - | { |
| - | /* exiting on an initialization failure is not a good idea for init */ |
| - | char *argv[] = { "sulogin", 0 }; |
| - | execve("/sbin/sulogin", argv, environ); |
| - | exit(1); |
| - | } |
| - | |
| - | static void handlekilled(pid_t killed) |
| - | { |
| - | int i; |
| - | |
| - | if (killed == (pid_t) - 1) { |
| - | write(2, "all services exited.\n", 21); |
| - | exit(0); |
| - | } |
| - | if (killed == 0) |
| - | return; |
| - | i = findbypid(killed); |
| - | if (i >= 0) { |
| - | root[i].pid = 0; |
| - | if (root[i].respawn) { |
| - | circsweep(); |
| - | startservice(i, time(0) - root[i].startedat < 1); |
| - | } else { |
| - | root[i].startedat = time(0); |
| - | root[i].pid = 1; |
| - | } |
| - | } |
| - | } |
| - | |
| - | static void childhandler(void) |
| - | { |
| - | int status; |
| - | pid_t killed; |
| - | |
| - | do { |
| - | killed = waitpid(-1, &status, WNOHANG); |
| - | handlekilled(killed); |
| - | } while (killed && killed != (pid_t) - 1); |
| - | } |
| - | |
| - | static volatile int dowinch = 0; |
| - | static volatile int doint = 0; |
| - | |
| - | static void sigchild(int whatever) |
| - | { |
| - | } |
| - | static void sigwinch(int sig) |
| - | { |
| - | dowinch = 1; |
| - | } |
| - | static void sigint(int sig) |
| - | { |
| - | doint = 1; |
| - | } |
| - | |
| - | extern int minit_main(int argc, char *argv[]) |
| - | { |
| - | /* Schritt 1: argv[1] als Service nehmen und starten */ |
| - | struct pollfd pfd; |
| - | time_t last = time(0); |
| - | int nfds = 1; |
| - | int count = 0; |
| - | int i; |
| - | |
| - | infd = open("/etc/minit/in", O_RDWR); |
| - | outfd = open("/etc/minit/out", O_RDWR | O_NONBLOCK); |
| - | if (getpid() == 1) { |
| - | int fd; |
| - | |
| - | i_am_init = 1; |
| - | reboot(0); |
| - | if ((fd = open("/dev/console", O_RDWR | O_NOCTTY))) { |
| - | ioctl(fd, KDSIGACCEPT, SIGWINCH); |
| - | close(fd); |
| - | } else |
| - | ioctl(0, KDSIGACCEPT, SIGWINCH); |
| - | } |
| - | /* signal(SIGPWR,sighandler); don't know what to do about it */ |
| - | /* signal(SIGHUP,sighandler); ??? */ |
| - | { |
| - | struct sigaction sa; |
| - | |
| - | sigemptyset(&sa.sa_mask); |
| - | sa.sa_sigaction = 0; |
| - | sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; |
| - | sa.sa_handler = sigchild; |
| - | sigaction(SIGCHLD, &sa, 0); |
| - | sa.sa_handler = sigint; |
| - | sigaction(SIGINT, &sa, 0); /* ctrl-alt-del */ |
| - | sa.sa_handler = sigwinch; |
| - | sigaction(SIGWINCH, &sa, 0); /* keyboard request */ |
| - | } |
| - | if (infd < 0 || outfd < 0) { |
| - | puts("minit: could not open /etc/minit/in or /etc/minit/out\n"); |
| - | sulogin(); |
| - | nfds = 0; |
| - | } else |
| - | pfd.fd = infd; |
| - | pfd.events = POLLIN; |
| - | |
| - | for (i = 1; i < argc; i++) { |
| - | circsweep(); |
| - | if (startservice(loadservice(argv[i]), 0)) |
| - | count++; |
| - | } |
| - | circsweep(); |
| - | if (!count) |
| - | startservice(loadservice("default"), 0); |
| - | for (;;) { |
| - | char buf[1501]; |
| - | time_t now; |
| - | |
| - | if (doint) { |
| - | doint = 0; |
| - | startservice(loadservice("ctrlaltdel"), 0); |
| - | } |
| - | if (dowinch) { |
| - | dowinch = 0; |
| - | startservice(loadservice("kbreq"), 0); |
| - | } |
| - | childhandler(); |
| - | now = time(0); |
| - | if (now < last || now - last > 30) { |
| - | /* The system clock was reset. Compensate. */ |
| - | long diff = last - now; |
| - | int j; |
| - | |
| - | for (j = 0; j <= maxprocess; ++j) { |
| - | root[j].startedat -= diff; |
| - | } |
| - | } |
| - | last = now; |
| - | switch (poll(&pfd, nfds, 5000)) { |
| - | case -1: |
| - | if (errno == EINTR) { |
| - | childhandler(); |
| - | break; |
| - | } |
| - | opendevconsole(); |
| - | puts("poll failed!\n"); |
| - | sulogin(); |
| - | /* what should we do if poll fails?! */ |
| - | break; |
| - | case 1: |
| - | i = read(infd, buf, 1500); |
| - | if (i > 1) { |
| - | pid_t pid; |
| - | int idx = 0; |
| - | int tmp; |
| - | |
| - | buf[i] = 0; |
| - | |
| - | if (buf[0] != 's' && ((idx = findservice(buf + 1)) < 0)) |
| - | error: |
| - | write(outfd, "0", 1); |
| - | else { |
| - | switch (buf[0]) { |
| - | case 'p': |
| - | write(outfd, buf, fmt_ulong(buf, root[idx].pid)); |
| - | break; |
| - | case 'r': |
| - | root[idx].respawn = 0; |
| - | goto ok; |
| - | case 'R': |
| - | root[idx].respawn = 1; |
| - | goto ok; |
| - | case 'C': |
| - | if (kill(root[idx].pid, 0)) { /* check if still active */ |
| - | handlekilled(root[idx].pid); /* no!?! remove form active list */ |
| - | goto error; |
| - | } |
| - | goto ok; |
| - | break; |
| - | case 'P': |
| - | { |
| - | unsigned char *x = buf + strlen(buf) + 1; |
| - | unsigned char c; |
| - | |
| - | tmp = 0; |
| - | while ((c = *x++ - '0') < 10) |
| - | tmp = tmp * 10 + c; |
| - | } |
| - | if (tmp > 0) { |
| - | if (kill(tmp, 0)) |
| - | goto error; |
| - | pid = tmp; |
| - | } |
| - | root[idx].pid = tmp; |
| - | goto ok; |
| - | case 's': |
| - | idx = loadservice(buf + 1); |
| - | if (idx < 0) |
| - | goto error; |
| - | if (root[idx].pid < 2) { |
| - | root[idx].pid = 0; |
| - | circsweep(); |
| - | idx = startservice(idx, 0); |
| - | if (idx == 0) { |
| - | write(outfd, "0", 1); |
| - | break; |
| - | } |
| - | } |
| - | ok: |
| - | write(outfd, "1", 1); |
| - | break; |
| - | case 'u': |
| - | write(outfd, buf, |
| - | fmt_ulong(buf, time(0) - root[idx].startedat)); |
| - | } |
| - | } |
| - | } |
| - | break; |
| - | default: |
| - | break; |
| - | } |
| - | } |
| - | } |
| @@ -1,300 +0,0 @@ | |
| - | /* |
| - | * minit version 0.9.1 by Felix von Leitner |
| - | * ported to busybox by Glenn McGrath <[email protected]> |
| - | * |
| - | * This program is free software; you can redistribute it and/or modify |
| - | * it under the terms of the GNU General Public License as published by |
| - | * the Free Software Foundation; either version 2 of the License, or |
| - | * (at your option) any later version. |
| - | * |
| - | * This program is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| - | * GNU General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU General Public License |
| - | * along with this program; if not, write to the Free Software |
| - | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| - | */ |
| - | |
| - | #include <sys/fcntl.h> |
| - | #include <sys/file.h> |
| - | #include <signal.h> |
| - | #include <stdio.h> |
| - | #include <stdlib.h> |
| - | #include <string.h> |
| - | #include <unistd.h> |
| - | |
| - | #include "busybox.h" |
| - | |
| - | static int infd, outfd; |
| - | |
| - | static char buf[1500]; |
| - | |
| - | static unsigned int fmt_ulong(char *dest, unsigned long i) |
| - | { |
| - | register unsigned long len, tmp, len2; |
| - | |
| - | /* first count the number of bytes needed */ |
| - | for (len = 1, tmp = i; tmp > 9; ++len) |
| - | tmp /= 10; |
| - | if (dest) |
| - | for (tmp = i, dest += len, len2 = len + 1; --len2; tmp /= 10) |
| - | *--dest = (tmp % 10) + '0'; |
| - | return len; |
| - | } |
| - | |
| - | static void addservice(char *service) |
| - | { |
| - | char *service_ptr; |
| - | |
| - | if (strncmp(service, "/etc/minit/", 11) == 0) { |
| - | service += 11; |
| - | } |
| - | |
| - | while ((service_ptr = last_char_is(service, '/')) != NULL) { |
| - | *service_ptr = 0; |
| - | } |
| - | strncpy(buf + 1, service, 1400); |
| - | buf[1400] = 0; |
| - | } |
| - | |
| - | static int addreadwrite(char *service) |
| - | { |
| - | addservice(service); |
| - | write(infd, buf, strlen(buf)); |
| - | return read(outfd, buf, 1500); |
| - | } |
| - | |
| - | /* return PID, 0 if error */ |
| - | static pid_t __readpid(char *service) |
| - | { |
| - | int len; |
| - | |
| - | buf[0] = 'p'; |
| - | len = addreadwrite(service); |
| - | if (len < 0) |
| - | return 0; |
| - | buf[len] = 0; |
| - | return atoi(buf); |
| - | } |
| - | |
| - | /* return nonzero if error */ |
| - | static int respawn(char *service, int yesno) |
| - | { |
| - | int len; |
| - | |
| - | buf[0] = yesno ? 'R' : 'r'; |
| - | len = addreadwrite(service); |
| - | return (len != 1 || buf[0] == '0'); |
| - | } |
| - | |
| - | /* return nonzero if error */ |
| - | static int startservice(char *service) |
| - | { |
| - | int len; |
| - | |
| - | buf[0] = 's'; |
| - | len = addreadwrite(service); |
| - | return (len != 1 || buf[0] == '0'); |
| - | } |
| - | |
| - | extern int msvc_main(int argc, char **argv) |
| - | { |
| - | if (argc < 2) { |
| - | bb_show_usage(); |
| - | } |
| - | infd = bb_xopen("/etc/minit/in", O_WRONLY); |
| - | outfd = bb_xopen("/etc/minit/out", O_RDONLY); |
| - | |
| - | while (lockf(infd, F_LOCK, 1)) { |
| - | bb_perror_msg("could not aquire lock!\n"); |
| - | sleep(1); |
| - | } |
| - | |
| - | if (argc == 2) { |
| - | pid_t pid = __readpid(argv[1]); |
| - | |
| - | if (buf[0] != '0') { |
| - | int len; |
| - | int up_time; |
| - | |
| - | printf("%s: ", argv[1]); |
| - | if (pid == 0) |
| - | printf("down "); |
| - | else if (pid == 1) |
| - | printf("finished "); |
| - | else { |
| - | printf("up (pid %d) ", pid); |
| - | } |
| - | |
| - | buf[0] = 'u'; |
| - | len = addreadwrite(argv[1]); |
| - | if (len < 0) { |
| - | up_time = 0; |
| - | } else { |
| - | buf[len] = 0; |
| - | up_time = atoi(buf); |
| - | } |
| - | printf("%d seconds\n", up_time); |
| - | |
| - | if (pid == 0) |
| - | return 2; |
| - | else if (pid == 1) |
| - | return 3; |
| - | else |
| - | return 0; |
| - | } else { |
| - | bb_error_msg_and_die("no such service"); |
| - | } |
| - | } else { |
| - | int i; |
| - | int ret = 0; |
| - | int sig = 0; |
| - | pid_t pid; |
| - | |
| - | if (argv[1][0] == '-') { |
| - | switch (argv[1][1]) { |
| - | case 'g': |
| - | for (i = 2; i < argc; ++i) { |
| - | pid = __readpid(argv[i]); |
| - | if (pid < 2) { |
| - | if (pid == 1) { |
| - | bb_error_msg("%s, service termination", argv[i]); |
| - | } else { |
| - | bb_error_msg("%s, no such service", argv[i]); |
| - | } |
| - | ret = 1; |
| - | } |
| - | printf("%d\n", pid); |
| - | } |
| - | break; |
| - | case 'p': |
| - | sig = SIGSTOP; |
| - | goto dokill; |
| - | break; |
| - | case 'c': |
| - | sig = SIGCONT; |
| - | goto dokill; |
| - | break; |
| - | case 'h': |
| - | sig = SIGHUP; |
| - | goto dokill; |
| - | break; |
| - | case 'a': |
| - | sig = SIGALRM; |
| - | goto dokill; |
| - | break; |
| - | case 'i': |
| - | sig = SIGINT; |
| - | goto dokill; |
| - | break; |
| - | case 't': |
| - | sig = SIGTERM; |
| - | goto dokill; |
| - | break; |
| - | case 'k': |
| - | sig = SIGKILL; |
| - | goto dokill; |
| - | break; |
| - | case 'o': |
| - | for (i = 2; i < argc; ++i) |
| - | if (startservice(argv[i]) || respawn(argv[i], 0)) { |
| - | bb_error_msg("Couldnt not start %s\n", argv[i]); |
| - | ret = 1; |
| - | } |
| - | break; |
| - | case 'd': |
| - | for (i = 2; i < argc; ++i) { |
| - | pid = __readpid(argv[i]); |
| - | if (pid == 0) { |
| - | bb_error_msg("%s, no such service\n", argv[i]); |
| - | ret = 1; |
| - | } else if (pid == 1) |
| - | continue; |
| - | if (respawn(argv[i], 0) || kill(pid, SIGTERM) |
| - | || kill(pid, SIGCONT)); |
| - | } |
| - | break; |
| - | case 'u': |
| - | for (i = 2; i < argc; ++i) { |
| - | if (startservice(argv[i]) || respawn(argv[i], 1)) { |
| - | bb_error_msg("Couldnt not start %s\n", argv[i]); |
| - | ret = 1; |
| - | } |
| - | break; |
| - | } |
| - | case 'C': |
| - | for (i = 2; i < argc; ++i) { |
| - | int len; |
| - | |
| - | buf[0] = 'C'; |
| - | len = addreadwrite(argv[i]); |
| - | if (len != 1 || buf[0] == '0') { |
| - | bb_error_msg("%s has terminated or was killed\n", |
| - | argv[i]); |
| - | ret = 1; |
| - | } |
| - | } |
| - | break; |
| - | case 'P': |
| - | pid = atoi(argv[1] + 2); |
| - | if (pid > 1) { |
| - | char *tmp; |
| - | int len; |
| - | |
| - | buf[0] = 'P'; |
| - | addservice(argv[2]); |
| - | tmp = buf + strlen(buf) + 1; |
| - | tmp[fmt_ulong(tmp, pid)] = 0; |
| - | write(infd, buf, strlen(buf) + strlen(tmp) + 2); |
| - | len = read(outfd, buf, 1500); |
| - | if (len != 1 || buf[0] == '0') { |
| - | bb_error_msg_and_die("Couldnt not set pid of service %s\n", argv[2]); |
| - | } |
| - | } |
| - | break; |
| - | default: |
| - | bb_show_usage(); |
| - | } |
| - | } else { |
| - | bb_show_usage(); |
| - | } |
| - | return ret; |
| - | dokill: |
| - | for (i = 2; i < argc; i++) { |
| - | pid = __readpid(argv[i]); |
| - | if (!pid) { |
| - | bb_error_msg("%s no such service\n", argv[i]); |
| - | ret = 1; |
| - | } |
| - | if (kill(pid, sig)) { |
| - | bb_error_msg("%s, could not send signal %d to PID %d\n", |
| - | argv[i], sig, pid); |
| - | ret = 1; |
| - | } |
| - | } |
| - | return ret; |
| - | } |
| - | } |
| - | |
| - | /* |
| - | -u Up. If the service is not running, start it. If the service stops, |
| - | restart it. |
| - | -d Down. If the service is running, send it a TERM signal and then a CONT |
| - | signal. After it stops, do not restart it. |
| - | -o Once. If the service is not running, start it. Do not restart it if it |
| - | stops. |
| - | -r Tell supervise that the service is normally running; this affects status |
| - | messages. |
| - | -s Tell supervise that the service is normally stopped; this affects status |
| - | messages. |
| - | -p Pause. Send the service a STOP signal. |
| - | -c Continue. Send the service a CONT signal. |
| - | -h Hangup. Send the service a HUP signal. |
| - | -a Alarm. Send the service an ALRM signal. |
| - | -i Interrupt. Send the service an INT signal. |
| - | -t Terminate. Send the service a TERM signal. |
| - | -k Kill. Send the service a KILL signal. |
| - | -x Exit. supervise will quit as soon as the service is down. |
| - | */ |
| @@ -1,78 +0,0 @@ | |
| - | /* |
| - | * minit version 0.9.1 by Felix von Leitner |
| - | * ported to busybox by Glenn McGrath <[email protected]> |
| - | * |
| - | * This program is free software; you can redistribute it and/or modify |
| - | * it under the terms of the GNU General Public License as published by |
| - | * the Free Software Foundation; either version 2 of the License, or |
| - | * (at your option) any later version. |
| - | * |
| - | * This program is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| - | * GNU General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU General Public License |
| - | * along with this program; if not, write to the Free Software |
| - | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| - | */ |
| - | |
| - | #include <unistd.h> |
| - | #include <errno.h> |
| - | #include <stdlib.h> |
| - | #include <sys/fcntl.h> |
| - | |
| - | #include "busybox.h" |
| - | /* purpose: argv[1] is the full path to a PID file, |
| - | * argv+2 is the daemon to run. |
| - | * the daemon is expected to fork in the background and write its PID in |
| - | * the pid file. |
| - | */ |
| - | |
| - | extern int pidfilehack_main(int argc, char **argv) |
| - | { |
| - | int count = 0; |
| - | |
| - | if (argc < 3) { |
| - | bb_show_usage(); |
| - | |
| - | } |
| - | if (unlink(argv[2]) && (errno != ENOENT)) { |
| - | bb_perror_msg("could not remove pid file"); |
| - | } |
| - | switch (fork()) { |
| - | case -1: |
| - | bb_perror_msg("could not fork"); |
| - | return 2; |
| - | case 0: /* child */ |
| - | execv(argv[3], argv + 3); |
| - | bb_perror_msg("execvp failed"); |
| - | return 3; |
| - | } |
| - | do { |
| - | int fd = open(argv[2], O_RDONLY); |
| - | |
| - | if (fd >= 0) { |
| - | static char buf[100] = "-P"; |
| - | int len = read(fd, buf + 2, 100); |
| - | |
| - | close(fd); |
| - | if (len > 0) { |
| - | char *_argv[] = { "msvc", 0, 0, 0 }; |
| - | if (buf[len + 1] == '\n') { |
| - | buf[len + 1] = 0; |
| - | } else { |
| - | buf[len + 2] = 0; |
| - | } |
| - | _argv[1] = buf; |
| - | _argv[2] = argv[1]; |
| - | execvp(_argv[0], _argv); |
| - | bb_perror_msg("execvp failed"); |
| - | return 0; |
| - | } |
| - | } |
| - | sleep(1); |
| - | } while (++count < 30); |
| - | |
| - | return(0); |
| - | } |