1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/limits.h>
#include <signal.h>
#include <wait.h>
#include <pwd.h>
#include "log.h"
#include "socket.h"
#include "config.h"
// test if we are running in inetd mode
int IsInetd(void)
{
struct stat buf;
if(!fstat(0, &buf)) if(S_ISSOCK(buf.st_mode)) return(1);
return(0);
}
// retrieve login and homedir of user `uid'
int UserInfo(int uid, char **name, char **home)
{
struct passwd *pw;
if(!(pw=getpwuid(uid))) return(-1);
*name=pw->pw_name;
*home=pw->pw_dir;
return(0);
}
// close open files
void CloseFiles(int f)
{
int i;
for(i=f; i<NR_OPEN; i++) close(i);
}
// delete my pidfile
static void delpidfile(void)
{
unlink(config.pidfile);
}
// become background process
void BgProcess(void)
{
FILE *fd;
CloseFiles(1);
if(inetd) return;
switch(fork()) {
case -1:
LogError("fork");
case 0:
/* write my process ID into /var/run/gidentd.pid */
if(config.pidfile) {
umask(0022);
if(!(fd=fopen(config.pidfile,"w")))
Log("unable to open pidfile %s: %s", config.pidfile, strerror(errno));
else {
fprintf(fd, "%i\n", getpid());
atexit(delpidfile);
fclose(fd);
}
}
break;
default:
exit(0);
}
if(setsid()==-1) {
LogError("setsid");
}
}
// signal handler
static void sighandler(int s)
{
switch(s) {
case SIGCHLD:
while(waitpid(-1, NULL, WNOHANG)>0);
break;
case SIGTERM:
Log("received SIGTERM, exiting");
exit(0);
}
}
// install signal handler for signal sig
static void addsig(int sig)
{
struct sigaction act;
act.sa_handler=sighandler;
sigemptyset(&act.sa_mask);
act.sa_flags=SA_RESTART;
if(sigaction(sig, &act, NULL)) {
LogError("sigaction");
}
}
// install signal handlers
void SetSigs(void)
{
addsig(SIGCHLD);
addsig(SIGTERM);
}
|