The canonical and current version in dpkg, is already in C, it is far more advanced containing many additional features and bug fixes, and is way more portable.
Signed-off-by: Guillem Jover <guil...@hadrons.org> --- COPYRIGHT | 9 - contrib/start-stop-daemon.README | 45 ---- contrib/start-stop-daemon.c | 429 ------------------------------- 3 files changed, 483 deletions(-) delete mode 100644 contrib/start-stop-daemon.README delete mode 100644 contrib/start-stop-daemon.c diff --git a/COPYRIGHT b/COPYRIGHT index a208043..403259b 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -19,12 +19,3 @@ On Debian GNU/Linux systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL-2'. Send patches to sysvinit-devel@nongnu.org - -Regarding the start-stop-daemon located in the contrib directory: - - * A rewrite of the original Debian's start-stop-daemon Perl script - * in C (faster - it is executed many times during system startup). - * - * Written by Marek Michalkiewicz <mar...@i17linuxb.ists.pwr.wroc.pl>, - * public domain. - diff --git a/contrib/start-stop-daemon.README b/contrib/start-stop-daemon.README deleted file mode 100644 index 6ce7710..0000000 --- a/contrib/start-stop-daemon.README +++ /dev/null @@ -1,45 +0,0 @@ -Start-stop-daemon is the program that is used by the Debian style init -scripts to start and stop services. This program is part of the "dpkg" -package by Ian Jackson. However there is also a seperate C version (the -original is in Perl) available written by Marek Michalkiewicz. I am including -it for your convinience. - -Note that the latest Debian dpkg packages (4.0.18 and later) contain -a much improved update-rc.d. This code is almost a year old. - -The original announcement follows: - - -From: Marek Michalkiewicz <mar...@i17linuxb.ists.pwr.wroc.pl> -Message-Id: <199606060324.faa19...@i17linuxb.ists.pwr.wroc.pl> -Subject: Fast start-stop-daemon in C -To: debian-de...@lists.debian.org -Date: Thu, 6 Jun 1996 05:24:18 +0200 (MET DST) - -Some time ago I wrote a faster C replacement for the start-stop-daemon -perl script. I use it for some time now (the most recent changes were -just a nicer help screen; the code is quite stable). - -This makes the system boot faster (especially on low end machines), -and important system startup scripts no longer depend on another big -package (perl). Maybe in the future we can get to the point where -a minimal system will work without perl installed at all (packages -which need it in {pre,post}{inst,rm} scripts would depend on perl). - -The only problem known so far to me is that I have to reinstall this -program after every dpkg upgrade which overwrites it with that nice -slooow perl script :-). - -Just compile this program and drop the binary in /usr/sbin instead -of the original /usr/sbin/start-stop-daemon perl script (make a copy -of it first, just in case). See below for source code. I placed it -in the public domain, but if it has to be GPL-ed to be included in -dpkg, just tell me. Including it in dpkg would close Bug#1670. - -I am posting it here so that it can be tested by more people than -just me. Bugs are unlikely though. - -Have fun, - -Marek - diff --git a/contrib/start-stop-daemon.c b/contrib/start-stop-daemon.c deleted file mode 100644 index 838154b..0000000 --- a/contrib/start-stop-daemon.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - * A rewrite of the original Debian's start-stop-daemon Perl script - * in C (faster - it is executed many times during system startup). - * - * Written by Marek Michalkiewicz <mar...@i17linuxb.ists.pwr.wroc.pl>, - * public domain. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <signal.h> -#include <errno.h> -#include <sys/stat.h> -#include <dirent.h> -#include <unistd.h> -#include <getopt.h> -#include <pwd.h> - -#define VERSION "version 0.3, 1996-06-05" - -static int testmode = 0; -static int quietmode = 0; -static int exitnodo = 1; -static int start = 0; -static int stop = 0; -static int signal_nr = 15; -static int user_id = -1; -static const char *userspec = NULL; -static const char *cmdname = NULL; -static char *execname = NULL; -static char *startas = NULL; -static const char *pidfile = NULL; -static const char *progname = ""; - -static struct stat exec_stat; - -struct pid_list { - struct pid_list *next; - int pid; -}; - -static struct pid_list *found = NULL; -static struct pid_list *killed = NULL; - -static void *xmalloc(int size); -static void push(struct pid_list **list, int pid); -static void do_help(void); -static void parse_options(int argc, char * const *argv); -static int pid_is_exec(int pid, const struct stat *esb); -static int pid_is_user(int pid, int uid); -static int pid_is_cmd(int pid, const char *name); -static void check(int pid); -static void do_pidfile(const char *name); -static void do_procfs(void); -static void do_stop(void); - -#ifdef __GNUC__ -static void fatal(const char *format, ...) - __attribute__((noreturn, format(printf, 1, 2))); -static void badusage(const char *msg) - __attribute__((noreturn)); -#else -static void fatal(const char *format, ...); -static void badusage(const char *msg); -#endif - -static void -fatal(const char *format, ...) -{ - va_list arglist; - - fprintf(stderr, "%s: ", progname); - va_start(arglist, format); - vfprintf(stderr, format, arglist); - va_end(arglist); - putc('\n', stderr); - exit(2); -} - - -static void * -xmalloc(int size) -{ - void *ptr; - - ptr = malloc(size); - if (ptr) - return ptr; - fatal("malloc(%d) failed", size); -} - - -static void -push(struct pid_list **list, int pid) -{ - struct pid_list *p; - - p = xmalloc(sizeof(*p)); - p->next = *list; - p->pid = pid; - *list = p; -} - - -static void -do_help(void) -{ -printf("start-stop-daemon for Debian Linux - small and fast C version written by\n" -"Marek Michalkiewicz <mar...@i17linuxb.ists.pwr.wroc.pl>, public domain. %s\n" -"\n" -"Usage:\n" -" start-stop-daemon -S|--start options ... -- arguments ...\n" -" start-stop-daemon -K|--stop options ...\n" -" start-stop-daemon -H|--help\n" -" start-stop-daemon -V|--version\n" -"\n" -"Options (at least one of --exec|--pidfile|--user is required):\n" -" -x|--exec <executable> program to start/check if it is running\n" -" -p|--pidfile <pid-file> pid file to check\n" -" -u|--user <username>|<uid> stop this user's processes\n" -" -n|--name <process-name> stop processes with this name\n" -" -s|--signal <signal> signal to send (default 15)\n" -" -a|--startas <pathname> program to start (default <executable>)\n" -" -t|--test test mode, don't do anything\n" -" -o|--oknodo exit status 0 (not 1) if nothing done\n" -" -q|--quiet | -v, --verbose\n" -"\n" -"Exit status: 0 = done 1 = nothing done (=> 0 if --oknodo) 2 = trouble\n", -VERSION); -} - - -static void -badusage(const char *msg) -{ - if (msg && *msg) - fprintf(stderr, "%s: %s\n", progname, msg); - fprintf(stderr, "Try `%s --help' for more information.\n", progname); - exit(2); -} - - -static void -parse_options(int argc, char * const *argv) -{ - static struct option longopts[] = { - { "help", 0, NULL, 'H'}, - { "stop", 0, NULL, 'K'}, - { "start", 0, NULL, 'S'}, - { "version", 0, NULL, 'V'}, - { "startas", 1, NULL, 'a'}, - { "name", 1, NULL, 'n'}, - { "oknodo", 0, NULL, 'o'}, - { "pidfile", 1, NULL, 'p'}, - { "quiet", 0, NULL, 'q'}, - { "signal", 1, NULL, 's'}, - { "test", 0, NULL, 't'}, - { "user", 1, NULL, 'u'}, - { "verbose", 0, NULL, 'v'}, - { "exec", 1, NULL, 'x'}, - { NULL, 0, NULL, 0} - }; - int c; - - for (;;) { - c = getopt_long(argc, argv, "HKSVa:n:op:qs:tu:vx:", - longopts, (int *) 0); - if (c == -1) - break; - switch (c) { - case 'H': /* --help */ - do_help(); - exit(0); - case 'K': /* --stop */ - stop = 1; - break; - case 'S': /* --start */ - start = 1; - break; - case 'V': /* --version */ - printf("start-stop-daemon " VERSION "\n"); - exit(0); - case 'a': /* --startas <pathname> */ - startas = optarg; - break; - case 'n': /* --name <process-name> */ - cmdname = optarg; - break; - case 'o': /* --oknodo */ - exitnodo = 0; - break; - case 'p': /* --pidfile <pid-file> */ - pidfile = optarg; - break; - case 'q': /* --quiet */ - quietmode = 1; - break; - case 's': /* --signal <signal> */ - if (sscanf(optarg, "%d", &signal_nr) != 1) - badusage("--signal takes a numeric argument"); - break; - case 't': /* --test */ - testmode = 1; - break; - case 'u': /* --user <username>|<uid> */ - userspec = optarg; - break; - case 'v': /* --verbose */ - quietmode = -1; - break; - case 'x': /* --exec <executable> */ - execname = optarg; - break; - default: - badusage(""); /* message printed by getopt */ - } - } - - if (start == stop) - badusage("need one of --start or --stop"); - - if (!execname && !pidfile && !userspec) - badusage("need at least one of --exec, --pidfile or --user"); - - if (!startas) - startas = execname; - - if (start && !startas) - badusage("--start needs --exec or --startas"); -} - - -static int -pid_is_exec(int pid, const struct stat *esb) -{ - struct stat sb; - char buf[32]; - - sprintf(buf, "/proc/%d/exe", pid); - if (stat(buf, &sb) != 0) - return 0; - return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino); -} - - -static int -pid_is_user(int pid, int uid) -{ - struct stat sb; - char buf[32]; - - sprintf(buf, "/proc/%d", pid); - if (stat(buf, &sb) != 0) - return 0; - return (sb.st_uid == uid); -} - - -static int -pid_is_cmd(int pid, const char *name) -{ - char buf[32]; - FILE *f; - int c; - - sprintf(buf, "/proc/%d/stat", pid); - f = fopen(buf, "r"); - if (!f) - return 0; - while ((c = getc(f)) != EOF && c != '(') - ; - if (c != '(') { - fclose(f); - return 0; - } - /* this hopefully handles command names containing ')' */ - while ((c = getc(f)) != EOF && c == *name) - name++; - fclose(f); - return (c == ')' && *name == '\0'); -} - - -static void -check(int pid) -{ - if (execname && !pid_is_exec(pid, &exec_stat)) - return; - if (userspec && !pid_is_user(pid, user_id)) - return; - if (cmdname && !pid_is_cmd(pid, cmdname)) - return; - push(&found, pid); -} - - -static void -do_pidfile(const char *name) -{ - FILE *f; - int pid; - - f = fopen(name, "r"); - if (f) { - if (fscanf(f, "%d", &pid) == 1) - check(pid); - fclose(f); - } -} - - -static void -do_procfs(void) -{ - DIR *procdir; - struct dirent *entry; - int foundany, pid; - - procdir = opendir("/proc"); - if (!procdir) - fatal("opendir /proc: %s", strerror(errno)); - - foundany = 0; - while ((entry = readdir(procdir)) != NULL) { - if (sscanf(entry->d_name, "%d", &pid) != 1) - continue; - foundany++; - check(pid); - } - closedir(procdir); - if (!foundany) - fatal("nothing in /proc - not mounted?"); -} - - -static void -do_stop(void) -{ - char what[1024]; - struct pid_list *p; - - if (cmdname) - strcpy(what, cmdname); - else if (execname) - strcpy(what, execname); - else if (pidfile) - sprintf(what, "process in pidfile `%s'", pidfile); - else if (userspec) - sprintf(what, "process(es) owned by `%s'", userspec); - else - fatal("internal error, please report"); - - if (!found) { - if (quietmode <= 0) - printf("no %s found; none killed.\n", what); - exit(exitnodo); - } - for (p = found; p; p = p->next) { - if (testmode) - printf("would send signal %d to %d.\n", - signal_nr, p->pid); - else if (kill(p->pid, signal_nr) == 0) - push(&killed, p->pid); - else - printf("%s: warning: failed to kill %d: %s\n", - progname, p->pid, strerror(errno)); - } - if (quietmode < 0 && killed) { - printf("stopped %s (pid", what); - for (p = killed; p; p = p->next) - printf(" %d", p->pid); - printf(").\n"); - } -} - - -int -main(int argc, char **argv) -{ - progname = argv[0]; - - parse_options(argc, argv); - argc -= optind; - argv += optind; - - if (execname && stat(execname, &exec_stat)) - fatal("stat %s: %s", execname, strerror(errno)); - - if (userspec && sscanf(userspec, "%d", &user_id) != 1) { - struct passwd *pw; - - pw = getpwnam(userspec); - if (!pw) - fatal("user `%s' not found\n", userspec); - - user_id = pw->pw_uid; - } - - if (pidfile) - do_pidfile(pidfile); - else - do_procfs(); - - if (stop) { - do_stop(); - exit(0); - } - - if (found) { - if (quietmode <= 0) - printf("%s already running.\n", execname); - exit(exitnodo); - } - if (testmode) { - printf("would start %s ", startas); - while (argc-- > 0) - printf("%s ", *argv++); - printf(".\n"); - exit(0); - } - if (quietmode < 0) - printf("starting %s ...\n", startas); - *--argv = startas; - execv(startas, argv); - fatal("unable to start %s: %s", startas, strerror(errno)); -} - -- 2.17.0.441.gb46fe60e1d