83 #include "gw-config.h"    87 #elif defined(__GNU__)    90 #elif defined(__CYGWIN__)    91 #elif defined(__FreeBSD__) || defined(__APPLE__)    94 #error Unknown architecture - cannot build start-stop-daemon   110 #include <sys/stat.h>   119 #include <sys/ioctl.h>   120 #include <sys/types.h>   121 #include <sys/termios.h>   126 #define _STRUCTURED_PROC 1   128 #include <sys/procfs.h>   136 #include <hurd/ihash.h>   163 static struct ps_context *
context;
   164 static struct proc_stat_list *procset;
   180 #if defined(OSLinux) || defined(OSHURD) || defined(SunOS) || defined(FreeBSD)   181 static int pid_is_user(
int pid, 
int uid);
   182 static int pid_is_cmd(
int pid, 
const char *
name);
   188 static int pid_is_exec(
int pid, 
const struct stat *esb);
   191 static void do_psinit(
void);
   197     __attribute__((noreturn, 
format(printf, 1, 2)));
   199     __attribute__((noreturn));
   211     va_start(arglist, 
format);
   212     vfprintf(stderr, 
format, arglist);
   252 start-stop-daemon for Debian GNU/Linux - small and fast C version written by\n\   253 Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>, public domain.\n"   257   start-stop-daemon -S|--start options ... -- arguments ...\n\   258   start-stop-daemon -K|--stop options ...\n\   259   start-stop-daemon -H|--help\n\   260   start-stop-daemon -V|--version\n\   262 Options (at least one of --exec|--pidfile|--user is required):\n\   263   -x|--exec <executable>        program to start/check if it is running\n\   264   -p|--pidfile <pid-file>       pid file to check\n\   265   -c|--chuid <name|uid[:group|gid]>\n\   266         change to this user/group before starting process\n\   267   -u|--user <username>|<uid>    stop processes owned by this user\n\   268   -n|--name <process-name>      stop processes with this name\n\   269   -s|--signal <signal>          signal to send (default TERM)\n\   270   -a|--startas <pathname>       program to start (default is <executable>)\n\   271   -b|--background               force the process to detach\n\   272   -m|--make-pidfile             create the pidfile before starting\n\   273   -t|--test                     test mode, don't do anything\n\   274   -o|--oknodo                   exit status 0 (not 1) if nothing done\n\   275   -q|--quiet                    be more quiet\n\   276   -v|--verbose                  be more verbose\n\   278 Exit status:  0 = done  1 = nothing done (=> 0 if --oknodo)  2 = trouble\n");
   283 start-stop-daemon for Debian GNU/Linux - small and fast C version written by\n\   284 Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>, public domain.\n"   288   start-stop-daemon -S options ... -- arguments ...\n\   289   start-stop-daemon -K options ...\n\   290   start-stop-daemon -H\n\   291   start-stop-daemon -V\n\   293 Options (at least one of --exec|--pidfile|--user is required):\n\   294   -x <executable>               program to start/check if it is running\n\   295   -p <pid-file>                 pid file to check\n\   296   -c <name|uid[:group|gid]>     change to this user/group before starting process\n\   297   -u <username>|<uid>           stop processes owned by this user\n\   298   -n <process-name>             stop processes with this name\n\   299   -s <signal>                   signal to send (default TERM)\n\   300   -a <pathname>                 program to start (default is <executable>)\n\   301   -b                            force the process to detach\n\   302   -m                            create the pidfile before starting\n\   303   -t                            test mode, don't do anything\n\   304   -o                            exit status 0 (not 1) if nothing done\n\   306   -v                            be more verbose\n\   308 Exit status:  0 = done  1 = nothing done (=> 0 if -o)  2 = trouble\n");
   320     fprintf(stderr, 
"Try `%s --help' for more information.\n", 
progname);
   322     fprintf(stderr, 
"Try `%s -H' for more information.\n", 
progname);
   373     static struct option longopts[] = {
   374         { 
"help",     0, NULL, 
'H'},
   375         { 
"stop",     0, NULL, 
'K'},
   376         { 
"start",    0, NULL, 
'S'},
   377         { 
"version",      0, NULL, 
'V'},
   378         { 
"startas",      1, NULL, 
'a'},
   379         { 
"name",     1, NULL, 
'n'},
   380         { 
"oknodo",   0, NULL, 
'o'},
   381         { 
"pidfile",      1, NULL, 
'p'},
   382         { 
"quiet",    0, NULL, 
'q'},
   383         { 
"signal",   1, NULL, 
's'},
   384         { 
"test",     0, NULL, 
't'},
   385         { 
"user",     1, NULL, 
'u'},
   386         { 
"chroot",   1, NULL, 
'r'},
   387         { 
"verbose",      0, NULL, 
'v'},
   388         { 
"exec",     1, NULL, 
'x'},
   389         { 
"chuid",    1, NULL, 
'c'},
   390         { 
"background",   0, NULL, 
'b'},
   391         { 
"make-pidfile", 0, NULL, 
'm'},
   399         c = getopt_long(argc, argv, 
"HKSVa:n:op:qr:s:tu:vx:c:bm",
   400                 longopts, (
int *) 0);
   402         c = 
getopt(argc, argv, 
"HKSVa:n:op:qr:s:tu:vx:c:bm");
   417             printf(
"start-stop-daemon " GW_VERSION 
"\n");
   473                 badusage (
"--signal takes a numeric argument or name of signal (KILL, INTR, ...)");
   480         badusage(
"need one of --start or --stop");
   482         badusage(
"need one of -S (start) or -K (stop)");
   486         badusage(
"need at least one of --exec, --pidfile or --user");
   492         badusage(
"--start needs --exec or --startas");
   495         badusage(
"--make-pidfile is only relevant with --pidfile");
   498         badusage(
"--background is only relevant with --start");
   504 pid_is_exec(
int pid, 
const struct stat *esb)
   509     sprintf(buf, 
"/proc/%d/exe", pid);
   510     if (stat(buf, &sb) != 0)
   512     return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino);
   517 pid_is_user(
int pid, 
int uid)
   522     sprintf(buf, 
"/proc/%d", pid);
   523     if (stat(buf, &sb) != 0)
   525     return ((
int) sb.st_uid == uid);
   530 pid_is_cmd(
int pid, 
const char *
name)
   536     sprintf(buf, 
"/proc/%d/stat", pid);
   540     while ((c = getc(f)) != EOF && c != 
'(')
   547     while ((c = getc(f)) != EOF && c == *
name)
   550     return (c == 
')' && *
name == 
'\0');
   556 pid_is_user(
int pid, 
int uid)
   560    struct proc_stat *pstat;
   562    sprintf(buf, 
"/proc/%d", pid);
   563    if (stat(buf, &sb) != 0)
   565    return (sb.st_uid == uid);
   566    pstat = proc_stat_list_pid_proc_stat (procset, pid);
   568        fatal (
"Error getting process information: NULL proc_stat struct");
   569    proc_stat_set_flags (pstat, PSTAT_PID | PSTAT_OWNER_UID);
   570    return (pstat->owner_uid == uid);
   574 pid_is_cmd(
int pid, 
const char *
name)
   576    struct proc_stat *pstat;
   577    pstat = proc_stat_list_pid_proc_stat (procset, pid);
   579        fatal (
"Error getting process information: NULL proc_stat struct");
   580    proc_stat_set_flags (pstat, PSTAT_PID | PSTAT_ARGS);
   581    return (!strcmp (
name, pstat->args));
   598 pid_is_user(
int pid, 
int uid)
   603    sprintf(buf, 
"/proc/%d", pid);
   604    if (stat(buf, &sb) != 0)
   606    return ((
int) sb.st_uid == uid);
   615 pid_is_cmd(
int pid, 
const char *
name)
   621    sprintf(buf, 
"/proc/%d/psinfo", pid);
   625    fread(&pid_info,
sizeof(psinfo_t),1,f);
   626    return (!strcmp(
name,pid_info.pr_fname));
   631 static int pid_is_user(
int pid, 
int uid)
   636  sprintf(buf, 
"/proc/%d", pid);
   637  if (stat(buf, &sb) != 0)
   639  return ((
int) sb.st_uid == uid);
   643 pid_is_cmd(
int pid, 
const char *
name)
   649     sprintf(buf, 
"/proc/%d/stat", pid);
   653     while ((c = getc(f)) != EOF && c != 
'(')
   660     while ((c = getc(f)) != EOF && c == *
name)
   663     return (c == 
')' && *
name == 
'\0');
   673 #elif defined(OSHURD)   692     f = fopen(
name, 
"r");
   694         if (fscanf(f, 
"%d", &pid) == 1)
   702 #if defined(OSLinux) || defined (SunOS) || defined(FreeBSD)   707     struct dirent *entry;
   710     procdir = opendir(
"/proc");
   712         fatal(
"opendir /proc: %s", strerror(errno));
   715     while ((entry = readdir(procdir)) != NULL) {
   716         if (sscanf(entry->d_name, 
"%d", &pid) != 1)
   723         fatal(
"nothing in /proc - not mounted?");
   730 check_all (
void *ptr)
   732    struct proc_stat *pstat = ptr;
   742    err = ps_context_create (getproc (), &
context);
   744        error (1, err, 
"ps_context_create");
   746    err = proc_stat_list_create (
context, &procset);
   748        error (1, err, 
"proc_stat_list_create");
   750    err = proc_stat_list_add_all (procset, 0, 0);
   752        error (1, err, 
"proc_stat_list_add_all");
   755    ihash_iterate (
context->procs, check_all);
   772         sprintf(what, 
"process in pidfile `%s'", 
pidfile);
   774         sprintf(what, 
"process(es) owned by `%s'", 
userspec);
   776         fatal(
"internal error, please report");
   780             printf(
"No %s found running; none killed.\n", what);
   785             printf(
"Would send signal %d to %d.\n",
   790             printf(
"%s: warning: failed to kill %d: %s\n",
   796         printf(
"Stopped %s (pid", what);
   798             printf(
" %d", p->
pid);
   853                 printf(
"%d pids were not killed\n", i);
   861             printf(
"%s already running.\n", 
execname);
   865         printf(
"Would start %s ", 
startas);
   867             printf(
"%s ", *argv++);
   881         printf(
"Starting %s...\n", 
startas);
   901             printf(
"Detatching to start %s...", 
startas);
   904             fatal(
"Unable to fork.\n");
   913         for (i=getdtablesize()-1; i>=0; --i) close(i);
   915         fd = open(
"/dev/tty", O_RDWR);
   916         ioctl(fd, TIOCNOTTY, 0);
   930         fd=open(
"/dev/null", O_RDWR); 
   935         FILE *pidf = fopen(
pidfile, 
"w");
   936         pid_t pidt = getpid();
   938             fatal(
"Unable to open pidfile `%s' for writing: %s", 
pidfile,
   940         fprintf(pidf, 
"%d\n", (
int)pidt);
   944     fatal(
"Unable to start %s: %s", 
startas, strerror(errno));
 
void error(int err, const char *fmt,...)
 
static char * changegroup
 
static const char * signal_str
 
static struct stat exec_stat
 
static const char * progname
 
static const char * pidfile
 
static void push(struct pid_list **list, int pid)
 
static void do_pidfile(const char *name)
 
static struct pid_list * found
 
static struct pid_list * killed
 
static void parse_options(int argc, char *const *argv)
 
static void badusage(const char *msg)
 
int getopt(int argc, char **argv, char *opts)
 
static const struct sigpair siglist[]
 
static void do_help(void)
 
static const char * cmdname
 
static void * xmalloc(int size)
 
int main(int argc, char **argv)
 
static int parse_signal(const char *signal_str, int *signal_nr)
 
static const char * userspec
 
static void fatal(const char *format,...)
 
static void check(int pid)
 
static XMLRPCDocument * msg