#include "gw-config.h"#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>#include <signal.h>#include <sys/stat.h>#include <dirent.h>#include <unistd.h>#include <getopt.h>#include <pwd.h>#include <grp.h>#include <sys/ioctl.h>#include <sys/types.h>#include <sys/termios.h>#include <fcntl.h>Include dependency graph for start-stop-daemon.c:

Go to the source code of this file.
Data Structures | |
| struct | pid_list |
| struct | sigpair |
Defines | |
| #define | _STRUCTURED_PROC 1 |
Functions | |
| void * | xmalloc (int size) |
| void | push (struct pid_list **list, int pid) |
| void | do_help (void) |
| void | parse_options (int argc, char *const *argv) |
| void | check (int pid) |
| void | do_pidfile (const char *name) |
| int | do_stop (void) |
| void | fatal (const char *format,...) |
| void | badusage (const char *msg) |
| int | parse_signal (const char *signal_str, int *signal_nr) |
| int | main (int argc, char **argv) |
Variables | |
| int | testmode = 0 |
| int | quietmode = 0 |
| int | exitnodo = 1 |
| int | start = 0 |
| int | stop = 0 |
| int | background = 0 |
| int | mpidfile = 0 |
| int | signal_nr = 15 |
| const char * | signal_str = NULL |
| int | user_id = -1 |
| int | runas_uid = -1 |
| int | runas_gid = -1 |
| const char * | userspec = NULL |
| char * | changeuser = NULL |
| char * | changegroup = NULL |
| char * | changeroot = NULL |
| const char * | cmdname = NULL |
| char * | execname = NULL |
| char * | startas = NULL |
| const char * | pidfile = NULL |
| const char * | progname = "" |
| stat | exec_stat |
| pid_list * | found = NULL |
| pid_list * | killed = NULL |
| const struct sigpair | siglist [] |
| int | sigcount = sizeof (siglist) / sizeof (siglist[0]) |
|
|
Definition at line 126 of file start-stop-daemon.c. |
|
|
Definition at line 314 of file start-stop-daemon.c. References progname. Referenced by parse_options(). 00315 {
00316 if (msg)
00317 fprintf(stderr, "%s: %s\n", progname, msg);
00318
00319 #ifndef SunOS
00320 fprintf(stderr, "Try `%s --help' for more information.\n", progname);
00321 #else
00322 fprintf(stderr, "Try `%s -H' for more information.\n", progname);
00323 #endif
00324
00325 exit(2);
00326 }
|
|
|
Definition at line 668 of file start-stop-daemon.c. References cmdname, exec_stat, execname, found, push(), user_id, and userspec. Referenced by do_pidfile(). 00669 {
00670 #if defined(OSLinux)
00671 if (execname && !pid_is_exec(pid, &exec_stat))
00672 return;
00673 #elif defined(OSHURD)
00674 /* I will try this to see if it works */
00675 if (execname && !pid_is_cmd(pid, execname))
00676 return;
00677 #endif
00678 if (userspec && !pid_is_user(pid, user_id))
00679 return;
00680 if (cmdname && !pid_is_cmd(pid, cmdname))
00681 return;
00682 push(&found, pid);
00683 }
|
Here is the call graph for this function:

|
|
Definition at line 244 of file start-stop-daemon.c. References GW_VERSION. Referenced by parse_options(). 00245 {
00246
00247 /*Print the help for systems that have getopt long*/
00248
00249 #ifndef SunOS /*Solaris doesn't*/
00250
00251 printf("\
00252 start-stop-daemon for Debian GNU/Linux - small and fast C version written by\n\
00253 Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>, public domain.\n"
00254 GW_VERSION "\n\
00255 \n\
00256 Usage:\n\
00257 start-stop-daemon -S|--start options ... -- arguments ...\n\
00258 start-stop-daemon -K|--stop options ...\n\
00259 start-stop-daemon -H|--help\n\
00260 start-stop-daemon -V|--version\n\
00261 \n\
00262 Options (at least one of --exec|--pidfile|--user is required):\n\
00263 -x|--exec <executable> program to start/check if it is running\n\
00264 -p|--pidfile <pid-file> pid file to check\n\
00265 -c|--chuid <name|uid[:group|gid]>\n\
00266 change to this user/group before starting process\n\
00267 -u|--user <username>|<uid> stop processes owned by this user\n\
00268 -n|--name <process-name> stop processes with this name\n\
00269 -s|--signal <signal> signal to send (default TERM)\n\
00270 -a|--startas <pathname> program to start (default is <executable>)\n\
00271 -b|--background force the process to detach\n\
00272 -m|--make-pidfile create the pidfile before starting\n\
00273 -t|--test test mode, don't do anything\n\
00274 -o|--oknodo exit status 0 (not 1) if nothing done\n\
00275 -q|--quiet be more quiet\n\
00276 -v|--verbose be more verbose\n\
00277 \n\
00278 Exit status: 0 = done 1 = nothing done (=> 0 if --oknodo) 2 = trouble\n");
00279
00280 #else /* Deal with systems that don't have getopt long, like Solaris*/
00281
00282 printf("\
00283 start-stop-daemon for Debian GNU/Linux - small and fast C version written by\n\
00284 Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>, public domain.\n"
00285 GW_VERSION "\n\
00286 \n\
00287 Usage:\n\
00288 start-stop-daemon -S options ... -- arguments ...\n\
00289 start-stop-daemon -K options ...\n\
00290 start-stop-daemon -H\n\
00291 start-stop-daemon -V\n\
00292 \n\
00293 Options (at least one of --exec|--pidfile|--user is required):\n\
00294 -x <executable> program to start/check if it is running\n\
00295 -p <pid-file> pid file to check\n\
00296 -c <name|uid[:group|gid]> change to this user/group before starting process\n\
00297 -u <username>|<uid> stop processes owned by this user\n\
00298 -n <process-name> stop processes with this name\n\
00299 -s <signal> signal to send (default TERM)\n\
00300 -a <pathname> program to start (default is <executable>)\n\
00301 -b force the process to detach\n\
00302 -m create the pidfile before starting\n\
00303 -t test mode, don't do anything\n\
00304 -o exit status 0 (not 1) if nothing done\n\
00305 -q be more quiet\n\
00306 -v be more verbose\n\
00307 \n\
00308 Exit status: 0 = done 1 = nothing done (=> 0 if -o) 2 = trouble\n");
00309 #endif /*No more OS ( getopt ) specific stuff this function... */
00310 }
|
|
|
Definition at line 687 of file start-stop-daemon.c. Referenced by main(). 00688 {
00689 FILE *f;
00690 int pid;
00691
00692 f = fopen(name, "r");
00693 if (f) {
00694 if (fscanf(f, "%d", &pid) == 1)
00695 check(pid);
00696 fclose(f);
00697 }
00698 }
|
Here is the call graph for this function:

|
|
Definition at line 761 of file start-stop-daemon.c. References cmdname, execname, exitnodo, fatal(), killed, pid_list::next, pid_list::pid, pidfile, progname, push(), quietmode, signal_nr, and userspec. Referenced by main(). 00762 {
00763 char what[1024];
00764 struct pid_list *p;
00765 int retval = 0;
00766
00767 if (cmdname)
00768 strcpy(what, cmdname);
00769 else if (execname)
00770 strcpy(what, execname);
00771 else if (pidfile)
00772 sprintf(what, "process in pidfile `%s'", pidfile);
00773 else if (userspec)
00774 sprintf(what, "process(es) owned by `%s'", userspec);
00775 else
00776 fatal("internal error, please report");
00777
00778 if (!found) {
00779 if (quietmode <= 0)
00780 printf("No %s found running; none killed.\n", what);
00781 exit(exitnodo);
00782 }
00783 for (p = found; p; p = p->next) {
00784 if (testmode)
00785 printf("Would send signal %d to %d.\n",
00786 signal_nr, p->pid);
00787 else if (kill(p->pid, signal_nr) == 0)
00788 push(&killed, p->pid);
00789 else {
00790 printf("%s: warning: failed to kill %d: %s\n",
00791 progname, p->pid, strerror(errno));
00792 retval += exitnodo;
00793 }
00794 }
00795 if (quietmode < 0 && killed) {
00796 printf("Stopped %s (pid", what);
00797 for (p = killed; p; p = p->next)
00798 printf(" %d", p->pid);
00799 printf(").\n");
00800 }
00801 return retval;
00802 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 206 of file start-stop-daemon.c. References progname. Referenced by do_stop(), main(), and xmalloc(). 00207 {
00208 va_list arglist;
00209
00210 fprintf(stderr, "%s: ", progname);
00211 va_start(arglist, format);
00212 vfprintf(stderr, format, arglist);
00213 va_end(arglist);
00214 putc('\n', stderr);
00215 exit(2);
00216 }
|
|
||||||||||||
|
Definition at line 806 of file start-stop-daemon.c. References changegroup, changeroot, changeuser, do_pidfile(), do_stop(), exec_stat, execname, exitnodo, fatal(), mpidfile, parse_options(), pidfile, progname, quietmode, runas_gid, runas_uid, startas, user_id, and userspec. 00807 {
00808 progname = argv[0];
00809
00810 parse_options(argc, argv);
00811 argc -= optind;
00812 argv += optind;
00813
00814 if (execname && stat(execname, &exec_stat))
00815 fatal("stat %s: %s", execname, strerror(errno));
00816
00817 if (userspec && sscanf(userspec, "%d", &user_id) != 1) {
00818 struct passwd *pw;
00819
00820 pw = getpwnam(userspec);
00821 if (!pw)
00822 fatal("user `%s' not found\n", userspec);
00823
00824 user_id = pw->pw_uid;
00825 }
00826
00827 if (changegroup && sscanf(changegroup, "%d", &runas_gid) != 1) {
00828 struct group *gr = getgrnam(changegroup);
00829 if (!gr)
00830 fatal("group `%s' not found\n", changegroup);
00831 runas_gid = gr->gr_gid;
00832 }
00833 if (changeuser && sscanf(changeuser, "%d", &runas_uid) != 1) {
00834 struct passwd *pw = getpwnam(changeuser);
00835 if (!pw)
00836 fatal("user `%s' not found\n", changeuser);
00837 runas_uid = pw->pw_uid;
00838 if (changegroup == NULL) { /* pass the default group of this user */
00839 changegroup = ""; /* just empty */
00840 runas_gid = pw->pw_gid;
00841 }
00842 }
00843
00844 if (pidfile)
00845 do_pidfile(pidfile);
00846 else
00847 do_procinit();
00848
00849 if (stop) {
00850 int i = do_stop();
00851 if (i) {
00852 if (quietmode <= 0)
00853 printf("%d pids were not killed\n", i);
00854 exit(1);
00855 }
00856 exit(0);
00857 }
00858
00859 if (found) {
00860 if (quietmode <= 0)
00861 printf("%s already running.\n", execname);
00862 exit(exitnodo);
00863 }
00864 if (testmode) {
00865 printf("Would start %s ", startas);
00866 while (argc-- > 0)
00867 printf("%s ", *argv++);
00868 if (changeuser != NULL) {
00869 printf(" (as user %s[%d]", changeuser, runas_uid);
00870 if (changegroup != NULL)
00871 printf(", and group %s[%d])", changegroup, runas_gid);
00872 else
00873 printf(")");
00874 }
00875 if (changeroot != NULL)
00876 printf(" in directory %s", changeroot);
00877 printf(".\n");
00878 exit(0);
00879 }
00880 if (quietmode < 0)
00881 printf("Starting %s...\n", startas);
00882 *--argv = startas;
00883 if (changeroot != NULL) {
00884 if (chdir(changeroot) < 0)
00885 fatal("Unable to chdir() to %s", changeroot);
00886 if (chroot(changeroot) < 0)
00887 fatal("Unable to chroot() to %s", changeroot);
00888 }
00889 if (changeuser != NULL) {
00890 if (setgid(runas_gid))
00891 fatal("Unable to set gid to %d", runas_gid);
00892 if (initgroups(changeuser, runas_gid))
00893 fatal("Unable to set initgroups() with gid %d", runas_gid);
00894 if (setuid(runas_uid))
00895 fatal("Unable to set uid to %s", changeuser);
00896 }
00897
00898 if (background) { /* ok, we need to detach this process */
00899 int i, fd;
00900 if (quietmode < 0)
00901 printf("Detatching to start %s...", startas);
00902 i = fork();
00903 if (i<0) {
00904 fatal("Unable to fork.\n");
00905 }
00906 if (i) { /* parent */
00907 if (quietmode < 0)
00908 printf("done.\n");
00909 exit(0);
00910 }
00911 /* child continues here */
00912 /* now close all extra fds */
00913 for (i=getdtablesize()-1; i>=0; --i) close(i);
00914 /* change tty */
00915 fd = open("/dev/tty", O_RDWR);
00916 ioctl(fd, TIOCNOTTY, 0);
00917 close(fd);
00918 chdir("/");
00919 umask(022); /* set a default for dumb programs */
00920 #ifndef FreeBSD
00921 setpgrp(); /* set the process group */
00922 #else
00923 setpgrp(0, runas_gid); /* set the process group */
00924 #endif
00925 fd=open("/dev/null", O_RDWR); /* stdin */
00926 dup(fd); /* stdout */
00927 dup(fd); /* stderr */
00928 }
00929 if (mpidfile && pidfile != NULL) { /* user wants _us_ to make the pidfile :) */
00930 FILE *pidf = fopen(pidfile, "w");
00931 pid_t pidt = getpid();
00932 if (pidf == NULL)
00933 fatal("Unable to open pidfile `%s' for writing: %s", pidfile,
00934 strerror(errno));
00935 fprintf(pidf, "%d\n", (int)pidt);
00936 fclose(pidf);
00937 }
00938 execv(startas, argv);
00939 fatal("Unable to start %s: %s", startas, strerror(errno));
00940 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 369 of file start-stop-daemon.c. References background, badusage(), changegroup, changeroot, changeuser, cmdname, do_help(), execname, exitnodo, getopt(), GW_VERSION, mpidfile, optarg, option, parse_signal(), pidfile, quietmode, signal_nr, signal_str, start, startas, stop, testmode, and userspec. Referenced by main(). 00370 {
00371
00372 #if HAVE_GETOPT_LONG
00373 static struct option longopts[] = {
00374 { "help", 0, NULL, 'H'},
00375 { "stop", 0, NULL, 'K'},
00376 { "start", 0, NULL, 'S'},
00377 { "version", 0, NULL, 'V'},
00378 { "startas", 1, NULL, 'a'},
00379 { "name", 1, NULL, 'n'},
00380 { "oknodo", 0, NULL, 'o'},
00381 { "pidfile", 1, NULL, 'p'},
00382 { "quiet", 0, NULL, 'q'},
00383 { "signal", 1, NULL, 's'},
00384 { "test", 0, NULL, 't'},
00385 { "user", 1, NULL, 'u'},
00386 { "chroot", 1, NULL, 'r'},
00387 { "verbose", 0, NULL, 'v'},
00388 { "exec", 1, NULL, 'x'},
00389 { "chuid", 1, NULL, 'c'},
00390 { "background", 0, NULL, 'b'},
00391 { "make-pidfile", 0, NULL, 'm'},
00392 { NULL, 0, NULL, 0}
00393 };
00394 #endif
00395 int c;
00396
00397 for (;;) {
00398 #if HAVE_GETOPT_LONG
00399 c = getopt_long(argc, argv, "HKSVa:n:op:qr:s:tu:vx:c:bm",
00400 longopts, (int *) 0);
00401 #else
00402 c = getopt(argc, argv, "HKSVa:n:op:qr:s:tu:vx:c:bm");
00403 #endif
00404 if (c == -1)
00405 break;
00406 switch (c) {
00407 case 'H': /* --help */
00408 do_help();
00409 exit(0);
00410 case 'K': /* --stop */
00411 stop = 1;
00412 break;
00413 case 'S': /* --start */
00414 start = 1;
00415 break;
00416 case 'V': /* --version */
00417 printf("start-stop-daemon " GW_VERSION "\n");
00418 exit(0);
00419 case 'a': /* --startas <pathname> */
00420 startas = optarg;
00421 break;
00422 case 'n': /* --name <process-name> */
00423 cmdname = optarg;
00424 break;
00425 case 'o': /* --oknodo */
00426 exitnodo = 0;
00427 break;
00428 case 'p': /* --pidfile <pid-file> */
00429 pidfile = optarg;
00430 break;
00431 case 'q': /* --quiet */
00432 quietmode = 1;
00433 break;
00434 case 's': /* --signal <signal> */
00435 signal_str = optarg;
00436 break;
00437 case 't': /* --test */
00438 testmode = 1;
00439 break;
00440 case 'u': /* --user <username>|<uid> */
00441 userspec = optarg;
00442 break;
00443 case 'v': /* --verbose */
00444 quietmode = -1;
00445 break;
00446 case 'x': /* --exec <executable> */
00447 execname = optarg;
00448 break;
00449 case 'c': /* --chuid <username>|<uid> */
00450 /* we copy the string just in case we need the
00451 * argument later. */
00452 changeuser = strdup(optarg);
00453 changeuser = strtok(changeuser, ":");
00454 changegroup = strtok(NULL, ":");
00455 break;
00456 case 'r': /* --chroot /new/root */
00457 changeroot = optarg;
00458 break;
00459 case 'b': /* --background */
00460 background = 1;
00461 break;
00462 case 'm': /* --make-pidfile */
00463 mpidfile = 1;
00464 break;
00465 default:
00466 badusage(NULL); /* message printed by getopt */
00467 }
00468 }
00469
00470 if (signal_str != NULL) {
00471 if (sscanf (signal_str, "%d", &signal_nr) != 1) {
00472 if (parse_signal (signal_str, &signal_nr) != 0) {
00473 badusage ("--signal takes a numeric argument or name of signal (KILL, INTR, ...)");
00474 }
00475 }
00476 }
00477
00478 if (start == stop)
00479 #ifndef SunOS
00480 badusage("need one of --start or --stop");
00481 #else
00482 badusage("need one of -S (start) or -K (stop)");
00483 #endif
00484
00485 if (!execname && !pidfile && !userspec)
00486 badusage("need at least one of --exec, --pidfile or --user");
00487
00488 if (!startas)
00489 startas = execname;
00490
00491 if (start && !startas)
00492 badusage("--start needs --exec or --startas");
00493
00494 if (mpidfile && pidfile == NULL)
00495 badusage("--make-pidfile is only relevant with --pidfile");
00496
00497 if (background && !start)
00498 badusage("--background is only relevant with --start");
00499
00500 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 356 of file start-stop-daemon.c. References name, siglist, sigpair::signal, signal_nr, and signal_str. Referenced by parse_options(). 00357 {
00358 int i;
00359 for (i = 0; i < sigcount; i++) {
00360 if (strcmp (signal_str, siglist[i].name) == 0) {
00361 *signal_nr = siglist[i].signal;
00362 return 0;
00363 }
00364 }
00365 return -1;
00366 }
|
|
||||||||||||
|
Definition at line 232 of file start-stop-daemon.c. References pid_list::next, pid_list::pid, and xmalloc(). Referenced by check(), and do_stop(). 00233 {
00234 struct pid_list *p;
00235
00236 p = xmalloc(sizeof(*p));
00237 p->next = *list;
00238 p->pid = pid;
00239 *list = p;
00240 }
|
Here is the call graph for this function:

|
|
Definition at line 220 of file start-stop-daemon.c. References fatal(), malloc, and size. Referenced by push(). 00221 {
00222 void *ptr;
00223
00224 ptr = malloc(size);
00225 if (ptr)
00226 return ptr;
00227 fatal("malloc(%d) failed", size);
00228 }
|
Here is the call graph for this function:

|
|
Definition at line 144 of file start-stop-daemon.c. Referenced by parse_options(). |
|
|
Definition at line 153 of file start-stop-daemon.c. Referenced by main(), and parse_options(). |
|
|
Definition at line 154 of file start-stop-daemon.c. Referenced by main(), and parse_options(). |
|
|
Definition at line 152 of file start-stop-daemon.c. Referenced by main(), and parse_options(). |
|
|
Definition at line 155 of file start-stop-daemon.c. Referenced by check(), do_stop(), and parse_options(). |
|
|
Definition at line 161 of file start-stop-daemon.c. |
|
|
Definition at line 156 of file start-stop-daemon.c. Referenced by check(), do_stop(), main(), and parse_options(). |
|
|
Definition at line 141 of file start-stop-daemon.c. Referenced by do_stop(), main(), and parse_options(). |
|
|
Definition at line 173 of file start-stop-daemon.c. Referenced by check(). |
|
|
Definition at line 174 of file start-stop-daemon.c. Referenced by do_stop(). |
|
|
Definition at line 145 of file start-stop-daemon.c. Referenced by main(), and parse_options(). |
|
|
Definition at line 158 of file start-stop-daemon.c. Referenced by do_stop(), main(), and parse_options(). |
|
|
Definition at line 159 of file start-stop-daemon.c. |
|
|
Definition at line 140 of file start-stop-daemon.c. Referenced by do_stop(), main(), and parse_options(). |
|
|
Definition at line 150 of file start-stop-daemon.c. Referenced by main(). |
|
|
Definition at line 149 of file start-stop-daemon.c. Referenced by main(). |
|
|
Definition at line 354 of file start-stop-daemon.c. |
|
|
Initial value: {
{ "ABRT", SIGABRT },
{ "ALRM", SIGALRM },
{ "FPE", SIGFPE },
{ "HUP", SIGHUP },
{ "ILL", SIGILL },
{ "INT", SIGINT },
{ "KILL", SIGKILL },
{ "PIPE", SIGPIPE },
{ "QUIT", SIGQUIT },
{ "SEGV", SIGSEGV },
{ "TERM", SIGTERM },
{ "USR1", SIGUSR1 },
{ "USR2", SIGUSR2 },
{ "CHLD", SIGCHLD },
{ "CONT", SIGCONT },
{ "STOP", SIGSTOP },
{ "TSTP", SIGTSTP },
{ "TTIN", SIGTTIN },
{ "TTOU", SIGTTOU }
}
Definition at line 333 of file start-stop-daemon.c. Referenced by parse_signal(). |
|
|
Definition at line 146 of file start-stop-daemon.c. Referenced by do_stop(), parse_options(), and parse_signal(). |
|
|
Definition at line 147 of file start-stop-daemon.c. Referenced by parse_options(), and parse_signal(). |
|
|
Definition at line 142 of file start-stop-daemon.c. Referenced by parse_options(). |
|
|
Definition at line 157 of file start-stop-daemon.c. Referenced by main(), and parse_options(). |
|
|
Definition at line 143 of file start-stop-daemon.c. Referenced by parse_options(). |
|
|
Definition at line 139 of file start-stop-daemon.c. Referenced by parse_options(). |
|
|
Definition at line 148 of file start-stop-daemon.c. |
|
|
Definition at line 151 of file start-stop-daemon.c. Referenced by check(), do_stop(), main(), and parse_options(). |