From 8783aac95bdba94c79beec79506482682a748f2b Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Wed, 18 Jun 2014 12:01:03 +0200 Subject: Update daemon.cc and add pidfile to miavd arguments. --- src/daemon.cc | 170 ++++++++++++++++++++++++++++++++++++++-------------------- src/daemon.h | 8 ++- src/miavd.cc | 12 ++--- 3 files changed, 124 insertions(+), 66 deletions(-) diff --git a/src/daemon.cc b/src/daemon.cc index 84ad8d9..2826484 100644 --- a/src/daemon.cc +++ b/src/daemon.cc @@ -3,7 +3,7 @@ * daemon.cc * * Thu Jun 9 10:27:59 CEST 2005 - * Copyright 2005 Bent Bisballe + * Copyright 2005 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ @@ -22,7 +22,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "daemon.h" #include @@ -30,6 +29,8 @@ #include #include #include +#include +#include // For getgrent and getgrent #include @@ -39,81 +40,136 @@ // For strcmp #include +// Resolve a group's name or id into a numeric gid +static gid_t get_gid(const char *grp) +{ + char *eptr; + gid_t xid = strtoul(grp, &eptr, 10); + struct group *gr; + errno = 0; // Per getgrnam(3) and getgrgid(3) manual page + if(!*eptr) + gr = getgrgid(xid); + else + gr = getgrnam(grp); + return !gr ? 0 : gr->gr_gid; +} + +// Resolve a user's name or id into a numeric uid with associated gid +static uid_t get_uid(const char *usr, gid_t *gid) +{ + char *eptr; + uid_t xid = strtoul(usr, &eptr, 10); + struct passwd *pw; + errno = 0; // Per getpwnam(3) and getpwuid(3) manual page + if(!*eptr) + pw = getpwuid(xid); + else + pw = getpwnam(usr); + if(!pw) + return 0; + if(!gid) + *gid = pw->pw_gid; + return pw->pw_uid; +} + Daemon::Daemon() {} Daemon::~Daemon() {} -int Daemon::run(const char *user, const char* group, bool foreground) +int Daemon::run(const char *user, const char* group, bool detach, + std::string pidfile) { - int f; - int fd; - - // Fetch user id - int uid = -1; - struct passwd *p = getpwent(); - while(p) { - if(strcmp(p->pw_name, user) == 0) uid = p->pw_uid; - p = getpwent(); - } - if(uid == -1) { - fprintf(stderr, "Could not find user \"%s\" in /etc/passwd file.\n", user); + // Fetch user and group IDs + gid_t gid = 0; + uid_t uid = 0; + if(user && *user) { + uid = get_uid(user, &gid); + if(errno) { + fprintf(stderr, "Could resolve user \"%s\"", user); + perror(""); + } } - // Fetch group id - int gid = -1; - struct group *g = getgrent(); - while(g) { - if(strcmp(g->gr_name, group) == 0) gid = g->gr_gid; - g = getgrent(); - } - if(gid == -1) { - fprintf(stderr, "Could not find group \"%s\" in /etc/group file.\n", group); + if(group && *group) { + gid = get_gid(group); + if(errno) { + fprintf(stderr, "Could not resolve group \"%s\"", group); + perror(""); + } } - if(chdir("/") == -1) fprintf(stderr, "Could not chdir to '/'.\n"); umask(0); - if(!foreground) { - f = fork(); - switch(f) { - case -1: // Fork error - perror("Fork in daemon.cc"); - return 1; - case 0: // Forked child - break; - default: // Parent - return 0; + /* + if(pidfile != "" ) { + FILE *fp = fopen(pidfile.c_str(), "r"); + if(fp != NULL) { + fclose(fp); + fprintf(stderr, "Could not write pid file \"%s\"" + " - file already exists.\n", + pidfile.c_str()); + return -1; } } + */ - // Switch to given group - if(setgid(gid) != 0) { - fprintf(stderr, "Failed to change to group \"%s\" (gid: %d), quitting.\n", group, gid); - perror(""); - fprintf(stderr, "Runnning daemon as current group\n"); + if(detach) { + if(daemon(0, 0) == -1) { + perror(""); + return -1; + } } - - // Switch to given user - if(setuid(uid) != 0) { - fprintf(stderr, "Failed to change to user \"%s\" (uid: %d), quitting.\n", user, uid); - perror(""); - fprintf(stderr, "Runnning daemon as current user\n"); + + if(pidfile != "" ) { + pid_t pid = getpid(); + + FILE *fp = fopen(pidfile.c_str(), "w"); + if(fp == NULL) { + fprintf(stderr, "Could not write pid file \"%s\"", pidfile.c_str()); + perror(""); + return -1; + } else { + fprintf(fp, "%lu", (unsigned long int)pid); + fclose(fp); + } + } + + if(gid) { + // Switch to given group + if(setgid(gid) != 0) { + fprintf(stderr, "Failed to change to group \"%s\" (gid: %d).\n", + group, gid); + perror(""); + fprintf(stderr, "Runnning daemon as current group\n"); + } } - - // Redirect stdin, stdout and stderr to /dev/null - fd = open("/dev/null", O_NOCTTY | O_RDWR, 0666); - - dup2(0, fd); - dup2(1, fd); - dup2(2, fd); + if(uid) { + // Switch to given user + if(setuid(uid) != 0) { + fprintf(stderr, "Failed to change to user \"%s\" (uid: %d).\n", + user, uid); + perror(""); + fprintf(stderr, "Runnning daemon as current user\n"); + } + } + setsid(); signal (SIGTERM, SIG_IGN); - if(!foreground) signal (SIGINT, SIG_IGN); - signal (SIGHUP, SIG_IGN); - - return daemon_main(); + + //signal (SIGHUP, SIG_IGN); + + // Don't disable Ctrl+c when running in foreground. + //if(detach) signal (SIGINT, SIG_IGN); + + int ret = daemon_main(); + + if(pidfile != "") { + unlink(pidfile.c_str()); + } + + return ret; } diff --git a/src/daemon.h b/src/daemon.h index 1ba88d4..7d8ddf8 100644 --- a/src/daemon.h +++ b/src/daemon.h @@ -3,7 +3,7 @@ * daemon.h * * Thu Jun 9 10:27:59 CEST 2005 - * Copyright 2005 Bent Bisballe + * Copyright 2005 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ @@ -27,6 +27,8 @@ #include +#include + class Daemon { public: Daemon(); @@ -35,10 +37,12 @@ public: /** * Use NOBODY_GROUP and NOBODY_USER if no privileges are needed to run. */ - int run(const char* user, const char* group, bool foreground); + int run(const char* user, const char* group, bool detach = true, + std::string pidfile = ""); private: virtual int daemon_main() = 0; + }; #endif/*__DAEMON_H__*/ diff --git a/src/miavd.cc b/src/miavd.cc index 89e8990..3fec6e0 100644 --- a/src/miavd.cc +++ b/src/miavd.cc @@ -59,9 +59,7 @@ static const char usage_str[] = " -h, --help Print this message and exit.\n" " -D, --debug ddd Enable debug messages on 'ddd'; see documentation for details\n" " -L, --logfile file Write output to file, instead of stderr.\n" - /* " -P, --pidfile file Write pid of the running daemon to file.\n" - */ ; int main(int argc, char *argv[]) @@ -73,7 +71,7 @@ int main(int argc, char *argv[]) char *user = NULL; char *group = NULL; bool foreground = false; - // std::string pidfile; + std::string pidfile; unsigned int hugin_flags = 0; @@ -88,7 +86,7 @@ int main(int argc, char *argv[]) {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'v'}, {"debug", required_argument, 0, 'D'}, - //{"pidfile", required_argument, 0, 'P'}, + {"pidfile", required_argument, 0, 'P'}, {"logfile", required_argument, 0, 'L'}, {0, 0, 0, 0} }; @@ -125,11 +123,11 @@ int main(int argc, char *argv[]) hugin_flags |= HUG_FLAG_USE_FILTER; hugin_filter = optarg; break; - /* + case 'P': pidfile = optarg; break; - */ + case '?': case 'h': printf("%s", version_str); @@ -170,5 +168,5 @@ int main(int argc, char *argv[]) if(user) cuser = user; if(group) cgroup = group; - return daemon.run(cuser, cgroup, foreground); + return daemon.run(cuser, cgroup, foreground, pidfile); } -- cgit v1.2.3