X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=lib%2Fcf.c;h=9d3fb766c2b44babe008f0e3448eb9fb63d1cd88;hb=8ea85a4e33fac0e5df05ee0ba96600d0f241ca64;hp=bd4aba339dbf8c8378562c71e59b985461d29c35;hpb=f2b4b0310b2992d2e3281247f138c27b3da140cc;p=ashd.git diff --git a/lib/cf.c b/lib/cf.c index bd4aba3..9d3fb76 100644 --- a/lib/cf.c +++ b/lib/cf.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #ifdef HAVE_CONFIG_H @@ -44,6 +45,7 @@ struct stdchild { char **envp; int fd; int agains; + time_t lastrep; }; static int parsefile(struct cfstate *s, FILE *in); @@ -355,26 +357,35 @@ static char **expandargs(struct stdchild *sd) return(ret); } -static int stdhandle(struct child *ch, struct hthead *req, int fd, void (*chinit)(void *), void *idata) +struct sidata { + struct stdchild *sd; + void (*sinit)(void *); + void *sdata; +}; + +static void stdinit(void *data) +{ + struct sidata *d = data; + int i; + + for(i = 0; d->sd->envp[i]; i += 2) + putenv(sprintf2("%s=%s", d->sd->envp[i], d->sd->envp[i + 1])); + if(d->sinit != NULL) + d->sinit(d->sdata); +} + +static int stdhandle(struct child *ch, struct hthead *req, int fd, void (*chinit)(void *), void *sdata) { struct stdchild *sd = ch->pdata; int serr; char **args; - - void stdinit(void *data) - { - int i; - - for(i = 0; sd->envp[i]; i += 2) - putenv(sprintf2("%s=%s", sd->envp[i], sd->envp[i + 1])); - if(chinit != NULL) - chinit(data); - } + struct sidata idat; if(sd->type == CH_SOCKET) { + idat = (struct sidata) {.sd = sd, .sinit = chinit, .sdata = sdata}; if(sd->fd < 0) { args = expandargs(sd); - sd->fd = stdmkchild(args, stdinit, idata); + sd->fd = stdmkchild(args, stdinit, &idat); freeca(args); } if(sendreq2(sd->fd, req, fd, MSG_NOSIGNAL | MSG_DONTWAIT)) { @@ -383,15 +394,17 @@ static int stdhandle(struct child *ch, struct hthead *req, int fd, void (*chinit /* Assume that the child has crashed and restart it. */ close(sd->fd); args = expandargs(sd); - sd->fd = stdmkchild(args, stdinit, idata); + sd->fd = stdmkchild(args, stdinit, &idat); freeca(args); if(!sendreq2(sd->fd, req, fd, MSG_NOSIGNAL | MSG_DONTWAIT)) goto ok; serr = errno; } if(serr == EAGAIN) { - if(sd->agains++ == 0) + if(sd->agains++ == 0) { flog(LOG_WARNING, "request to child %s denied due to buffer overload", ch->name); + sd->lastrep = time(NULL); + } } else { flog(LOG_ERR, "could not pass on request to child %s: %s", ch->name, strerror(serr)); close(sd->fd); @@ -400,13 +413,13 @@ static int stdhandle(struct child *ch, struct hthead *req, int fd, void (*chinit return(-1); } ok: - if(sd->agains > 0) { + if((sd->agains > 0) && ((time(NULL) - sd->lastrep) > 10)) { flog(LOG_WARNING, "%i requests to child %s were denied due to buffer overload", sd->agains, ch->name); sd->agains = 0; } } else if(sd->type == CH_FORK) { args = expandargs(sd); - if(stdforkserve(args, req, fd, chinit, idata) < 0) { + if(stdforkserve(args, req, fd, chinit, sdata) < 0) { freeca(args); return(-1); }