/* $Id: daemon.c,v 1.11 2003/05/20 16:38:38 doug Exp $
*
* This file is part of EXACT.
*
* EXACT is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* EXACT is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EXACT; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include "config.h"
#include "logger.h"
#include "conffile.h"
#include "daemon.h"
void dofork(int s) {
pid_t p=fork();
switch(p) {
case -1: // error
logger(LOG_ERR, "Fatal Error when forking\n");
exit(61);
break;
case 0: // we are the child
if(s) {
fprintf(stderr, "Child sleeping - attach gdb to %d\n",
(int)getpid());
sleep(10);
}
break;
default: // we are the parent
exit(0);
break;
}
}
void sesslead() {
pid_t p=setsid();
if(p==-1) {
logger(LOG_ERR, "Fatal Error while running setsid\n");
exit(62);
}
}
void rootdir() {
int ret;
ret=chdir("/");
if(ret==-1) {
logger(LOG_ERR, "Fatal Error while changing to root dir\n");
exit(63);
}
}
void reopenfds() {
close(0);
close(1);
//close(2);
}
void usergroup() {
if(conffile_param("group")) {
struct group *g=getgrnam(conffile_param("group"));
if(g) {
if(setgid(g->gr_gid)) {
logger(LOG_CRIT, "unable to change gid to %d\n", g->gr_gid);
exit(64);
}
setegid(g->gr_gid);
} else {
logger(LOG_CRIT, "group %d does not exist\n", conffile_param("group"));
exit(65);
}
}
if(conffile_param("user")) {
struct passwd *p=getpwnam(conffile_param("user"));
if(p) {
if(setuid(p->pw_uid)) {
logger(LOG_CRIT, "unable to change uid to %d\n", p->pw_uid);
exit(66);
}
seteuid(p->pw_uid);
} else {
logger(LOG_CRIT, "user %s does not exist\n", conffile_param("user"));
exit(67);
}
}
}
void daemonize(int f, int s) {
#ifdef HAVE_WORKING_FORK
logger(LOG_DEBUG, "changing user and group\n");
usergroup(); // change to appropriate user and group
if(!f) {
logger(LOG_DEBUG, "forking\n");
dofork(0); // so the parent can exit, returning control
sesslead(); // become a process group and session group leader
logger(LOG_DEBUG, "forking\n");
dofork(s); // session group leader exits. we can never regain terminal.
}
logger(LOG_DEBUG, "changing dir\n");
rootdir(); // to ensure no directory is kept in use
logger(LOG_DEBUG, "setting umask\n");
umask(0); // so no weird perms are inherited
logger(LOG_DEBUG, "freopening stdin, stdout and stderr\n");
//reopenfds(); // so stdin, stdout and stderr are sensible
#else
// other stuff
#endif
}
syntax highlighted by Code2HTML, v. 0.9.1