diff options
| author | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2003-07-26 09:16:00 +0000 |
|---|---|---|
| committer | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2003-07-26 09:16:00 +0000 |
| commit | ec886971ccf2b40fdeba282095e4fd537cde01f5 (patch) | |
| tree | 80ceac0ee76ad0bee1838252ced4f0cfd097659c | |
| parent | 3518555621b8f58d6a90e4f14c2a07348c23eddc (diff) | |
| download | busybox-w32-ec886971ccf2b40fdeba282095e4fd537cde01f5.tar.gz busybox-w32-ec886971ccf2b40fdeba282095e4fd537cde01f5.tar.bz2 busybox-w32-ec886971ccf2b40fdeba282095e4fd537cde01f5.zip | |
Move start_stop_daemon to debianutils.
Cleanup run_parts a bit and add long opts
git-svn-id: svn://busybox.net/trunk/busybox@7113 69ca8d6d-28ef-0310-b511-8ec308f3f277
| -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 | |||
