/*
* Dolda Connect - Modular multiuser Direct Connect-style client
- * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com)
+ * Copyright (C) 2004 Fredrik Tolf <fredrik@dolda2000.com>
*
* 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
#include <sys/wait.h>
#include <stdarg.h>
#include <fcntl.h>
+#include <sys/select.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
new->pid = pid;
new->callback = func;
new->data = data;
- new->finished = 0;
new->prev = NULL;
new->next = children;
if(children != NULL)
static void handler(int signum)
{
- pid_t pid;
- int status;
- struct child *child;
FILE *dumpfile;
extern int numfnetnodes, numtransfers, numdcpeers;
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");
}
}
+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;
close(i);
}
}
- setpgrp();
+ setpgid(0, 0);
signal(SIGHUP, SIG_IGN);
errno = 0;
#ifdef HAVE_KEYUTILS
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);
}
int delay, immsyslog;
struct module *mod;
struct timer *timer;
- struct child *child;
double now;
+ now = ntime();
immsyslog = nofork = 0;
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)
{
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');
}
}
preinit(0);
if(configfile == NULL)
{
- if((configfile = findconfigfile()) == NULL)
+ if((configfile = findfile("doldacond.conf", NULL, 0)) == NULL)
{
flog(LOG_CRIT, "could not find a configuration file");
exit(1);
fprintf(pfstream, "%i\n", getpid());
fclose(pfstream);
}
+ flog(LOG_INFO, "startup took %f seconds", ntime() - now);
running = 1;
reinit = 0;
while(running)
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
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();