X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Fmain.c;h=463d8be0a379cc7b401b533b003e55d5b596a687;hb=bc222c94b892d2be70ef393b1523a3f48eaa60ee;hp=4bded58a17e426031bad5659f962bc71110c302a;hpb=1001e9965d257861e5ee75b62c59cc42659b0671;p=doldaconnect.git diff --git a/daemon/main.c b/daemon/main.c index 4bded58..463d8be 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -1,6 +1,6 @@ /* * Dolda Connect - Modular multiuser Direct Connect-style client - * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com) + * Copyright (C) 2004 Fredrik Tolf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +30,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include @@ -90,7 +91,6 @@ void childcallback(pid_t pid, void (*func)(pid_t, int, void *), void *data) new->pid = pid; new->callback = func; new->data = data; - new->finished = 0; new->prev = NULL; new->next = children; if(children != NULL) @@ -138,9 +138,6 @@ static void terminate(void) static void handler(int signum) { - pid_t pid; - int status; - struct child *child; FILE *dumpfile; extern int numfnetnodes, numtransfers, numdcpeers; @@ -154,18 +151,7 @@ static void handler(int signum) running = 0; break; case SIGCHLD: - while((pid = waitpid(-1, &status, WNOHANG)) > 0) - { - for(child = children; child != NULL; child = child->next) - { - if(child->pid == pid) - { - child->finished = 1; - child->status = status; - } - } - childrendone = 1; - } + childrendone = 1; break; case SIGUSR1: flog(LOG_NOTICE, "forking and dumping core upon SIGUSR1"); @@ -184,6 +170,32 @@ static void handler(int signum) } } +static void checkchildren(void) +{ + pid_t pid; + int status; + struct child *child; + + while((pid = waitpid(-1, &status, WNOHANG)) > 0) + { + for(child = children; child != NULL; child = child->next) + { + if(child->pid == pid) + { + child->callback(pid, status, child->data); + if(child == children) + children = child->next; + if(child->prev != NULL) + child->prev->next = child->next; + if(child->next != NULL) + child->next->prev = child->prev; + free(child); + break; + } + } + } +} + pid_t forksess(uid_t user, struct authhandle *auth, void (*ccbfunc)(pid_t, int, void *), void *data, ...) { int i, o; @@ -340,12 +352,12 @@ pid_t forksess(uid_t user, struct authhandle *auth, void (*ccbfunc)(pid_t, int, flog(LOG_WARNING, "could not setuid: %s", strerror(errno)); exit(127); } + putenv(sprintf2("HOME=%s", pwent->pw_dir)); + putenv(sprintf2("SHELL=%s", pwent->pw_shell)); + putenv(sprintf2("PATH=%s/bin:/usr/local/bin:/bin:/usr/bin", pwent->pw_dir)); } - putenv(sprintf2("HOME=%s", pwent->pw_dir)); - putenv(sprintf2("SHELL=%s", pwent->pw_shell)); putenv(sprintf2("USER=%s", pwent->pw_name)); putenv(sprintf2("LOGNAME=%s", pwent->pw_name)); - putenv(sprintf2("PATH=%s/bin:/usr/local/bin:/bin:/usr/bin", pwent->pw_dir)); chdir(pwent->pw_dir); return(0); } @@ -382,7 +394,6 @@ int main(int argc, char **argv) int delay, immsyslog; struct module *mod; struct timer *timer; - struct child *child; double now; now = ntime(); @@ -390,7 +401,7 @@ int main(int argc, char **argv) syslogfac = LOG_DAEMON; configfile = NULL; pidfile = NULL; - while((c = getopt(argc, argv, "p:C:f:hns")) != -1) + while((c = getopt(argc, argv, "p:C:f:hnsV")) != -1) { switch(c) { @@ -436,11 +447,14 @@ int main(int argc, char **argv) case 's': immsyslog = 1; break; + case 'V': + printf("%s", RELEASEINFO); + exit(0); case 'h': case ':': case '?': default: - printf("usage: doldacond [-hns] [-C configfile] [-p pidfile] [-f facility]\n"); + printf("usage: doldacond [-hnsV] [-C configfile] [-p pidfile] [-f facility]\n"); exit(c != 'h'); } } @@ -530,11 +544,10 @@ int main(int argc, char **argv) delay = (int)((timer->at - now) * 1000.0); } } + /* Of course, there's a race condition here that should be + * solved with pselect, but it doesn't matter a lot. */ if(childrendone) - { delay = 0; - childrendone = 0; - } pollsocks(delay); now = ntime(); do @@ -554,24 +567,11 @@ int main(int argc, char **argv) break; } } while(timer != NULL); - do + if(childrendone) { - for(child = children; child != NULL; child = child->next) - { - if(child->finished) - { - child->callback(child->pid, child->status, child->data); - if(child == children) - children = child->next; - if(child->prev != NULL) - child->prev->next = child->next; - if(child->next != NULL) - child->next->prev = child->prev; - free(child); - break; - } - } - } while(child != NULL); + childrendone = 0; + checkchildren(); + } } flog(LOG_INFO, "terminating..."); terminate();