#include <string.h>
#include <ctype.h>
#include <glob.h>
+#include <libgen.h>
#include <errno.h>
#ifdef HAVE_CONFIG_H
#define CH_SOCKET 0
#define CH_FORK 1
-static int parsefile(struct cfstate *s, FILE *in)
+static int parsefile(struct cfstate *s, FILE *in);
+
+static int doinclude(struct cfstate *s, char *spec)
{
- int i, o, ret;
+ int rv, i;
+ FILE *inc;
glob_t globm;
+ char *fbk, *dir, *fspec;
+
+ rv = 0;
+ fbk = s->file;
+ if(spec[0] == '/') {
+ fspec = spec;
+ } else {
+ dir = sstrdup(fbk);
+ fspec = sprintf3("%s/%s", dirname(dir), spec);
+ free(dir);
+ }
+ if(glob(fspec, 0, NULL, &globm))
+ return(0);
+ for(i = 0; i < globm.gl_pathc; i++) {
+ if((inc = fopen(globm.gl_pathv[i], "r")) != NULL) {
+ s->file = globm.gl_pathv[i];
+ if(parsefile(s, inc)) {
+ fclose(inc);
+ rv = 1;
+ goto out;
+ }
+ fclose(inc);
+ inc = NULL;
+ }
+ }
+
+out:
+ globfree(&globm);
+ s->file = fbk;
+ return(rv);
+}
+
+static int parsefile(struct cfstate *s, FILE *in)
+{
+ int i;
char line[1024];
int eof, argc;
int ind, indst[80], indl;
- char *p, **w, *fbk;
- FILE *inc;
+ char *p, **w;
s->lno = 0;
indst[indl = 0] = 0;
line[0] = 0;
}
s->lno++;
- for(p = line + strlen(line) - 1; p >= line; p--) {
- if(isspace(*p))
- *p = 0;
- else
- break;
+ if(line[0]) {
+ for(p = line + strlen(line) - 1; p >= line; p--) {
+ if(isspace(*p))
+ *p = 0;
+ else
+ break;
+ }
}
for(ind = 0, p = line; *p; p++) {
if(*p == ' ') {
if(indl == 0) {
if(!strcmp(w[0], "include")) {
- fbk = s->file;
for(i = 1; i < argc; i++) {
- if((ret = glob(w[i], 0, NULL, &globm)) == 0) {
- for(o = 0; o < globm.gl_pathc; o++) {
- if((inc = fopen(globm.gl_pathv[o], "r")) != NULL) {
- s->file = globm.gl_pathv[o];
- if(parsefile(s, inc)) {
- fclose(inc);
- globfree(&globm);
- freeca(w);
- return(1);
- }
- fclose(inc);
- }
- }
- globfree(&globm);
+ if(doinclude(s, w[i])) {
+ freeca(w);
+ return(1);
}
}
freeca(w);
- s->file = fbk;
continue;
}
}
free(s);
}
+char *findstdconf(char *name)
+{
+ char *path, *p, *p2, *t;
+
+ if((path = getenv("PATH")) == NULL)
+ return(NULL);
+ path = sstrdup(path);
+ for(p = strtok(path, ":"); p != NULL; p = strtok(NULL, ":")) {
+ if((p2 = strrchr(p, '/')) == NULL)
+ continue;
+ *p2 = 0;
+ if(!access(t = sprintf2("%s/etc/%s", p, name), R_OK)) {
+ free(path);
+ return(t);
+ }
+ free(t);
+ }
+ free(path);
+ return(NULL);
+}
+
static struct child *newchild(char *name, int type)
{
struct child *ch;
return(ch);
}
-int childhandle(struct child *ch, struct hthead *req, int fd)
+int childhandle(struct child *ch, struct hthead *req, int fd, void (*chinit)(void *), void *idata)
{
if(ch->type == CH_SOCKET) {
if(ch->fd < 0)
- ch->fd = stdmkchild(ch->argv);
+ ch->fd = stdmkchild(ch->argv, chinit, idata);
if(sendreq(ch->fd, req, fd)) {
- if(errno == EPIPE) {
+ if((errno == EPIPE) || (errno == ECONNRESET)) {
/* Assume that the child has crashed and restart it. */
close(ch->fd);
- ch->fd = stdmkchild(ch->argv);
+ ch->fd = stdmkchild(ch->argv, chinit, idata);
if(!sendreq(ch->fd, req, fd))
return(0);
}
return(-1);
}
} else if(ch->type == CH_FORK) {
- if(stdforkserve(ch->argv, req, fd) < 0)
+ if(stdforkserve(ch->argv, req, fd, chinit, idata) < 0)
return(-1);
}
return(0);