X-Git-Url: http://git.dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Faccesslog.c;h=35a1e32a6e3d173b498b13a7455d558cca9dd6b1;hb=472abd3cd62e50a4e9d2bfc5368547e6325ed31b;hp=13e60ff03a0076248be997e3f0338cd4a79328c1;hpb=9701afc5058b7817b6a290817b138b483d506318;p=ashd.git diff --git a/src/accesslog.c b/src/accesslog.c index 13e60ff..35a1e32 100644 --- a/src/accesslog.c +++ b/src/accesslog.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #ifdef HAVE_CONFIG_H #include @@ -36,10 +38,12 @@ #define DEFFORMAT "%{%Y-%m-%d %H:%M:%S}t %m %u %A \"%G\"" static int ch; +static char *outname = NULL; static FILE *out; static int flush = 1; static char *format; -static time_t now; +static struct timeval now; +static volatile int reopen = 0; static void qputs(char *s, FILE *o) { @@ -64,7 +68,6 @@ static void logitem(struct hthead *req, char o, char *d) { char *h, *p; char buf[1024]; - struct timeval tv; switch(o) { case '%': @@ -98,18 +101,17 @@ static void logitem(struct hthead *req, char o, char *d) case 't': if(!*d) d = "%a, %d %b %Y %H:%M:%S %z"; - strftime(buf, sizeof(buf), d, localtime(&now)); + strftime(buf, sizeof(buf), d, localtime(&now.tv_sec)); qputs(buf, out); break; case 'T': if(!*d) d = "%a, %d %b %Y %H:%M:%S %z"; - strftime(buf, sizeof(buf), d, gmtime(&now)); + strftime(buf, sizeof(buf), d, gmtime(&now.tv_sec)); qputs(buf, out); break; case 's': - gettimeofday(&tv, NULL); - fprintf(out, "%06i", (int)tv.tv_usec); + fprintf(out, "%06i", (int)now.tv_usec); break; case 'A': logitem(req, 'h', "X-Ash-Address"); @@ -161,7 +163,7 @@ static void logreq(struct hthead *req) static void serve(struct hthead *req, int fd) { - now = time(NULL); + gettimeofday(&now, NULL); if(sendreq(ch, req, fd)) { flog(LOG_ERR, "accesslog: could not pass request to child: %s", strerror(errno)); exit(1); @@ -169,9 +171,31 @@ static void serve(struct hthead *req, int fd) logreq(req); } +static void sighandler(int sig) +{ + if(sig == SIGHUP) + reopen = 1; +} + +static void reopenlog(void) +{ + FILE *new; + + if(outname == NULL) { + flog(LOG_WARNING, "accesslog: received SIGHUP but logging to stdout, so ignoring"); + return; + } + if((new = fopen(outname, "a")) == NULL) { + flog(LOG_WARNING, "accesslog: could not reopen log file `%s' on SIGHUP: %s", outname, strerror(errno)); + return; + } + fclose(out); + out = new; +} + static void usage(FILE *out) { - fprintf(out, "usage: accesslog [-hFa] [-f FORMAT] OUTFILE CHILD [ARGS...]\n"); + fprintf(out, "usage: accesslog [-hFa] [-f FORMAT] [-p PIDFILE] OUTFILE CHILD [ARGS...]\n"); } int main(int argc, char **argv) @@ -180,9 +204,11 @@ int main(int argc, char **argv) struct hthead *req; int fd; struct pollfd pfd[2]; + char *pidfile; + FILE *pidout; - optarg = NULL; - while((c = getopt(argc, argv, "+hFaf:")) >= 0) { + pidfile = NULL; + while((c = getopt(argc, argv, "+hFaf:p:")) >= 0) { switch(c) { case 'h': usage(stdout); @@ -193,6 +219,9 @@ int main(int argc, char **argv) case 'f': format = optarg; break; + case 'p': + pidfile = optarg; + break; case 'a': format = "%A - - [%{%d/%b/%Y:%H:%M:%S %z}t] \"%m %u %v\" - - \"%R\" \"%G\""; break; @@ -207,7 +236,11 @@ int main(int argc, char **argv) } if(format == NULL) format = DEFFORMAT; - if(!strcmp(argv[optind], "-")) { + if(!strcmp(argv[optind], "-")) + outname = NULL; + else + outname = argv[optind]; + if(outname == NULL) { out = stdout; } else { if((out = fopen(argv[optind], "a")) == NULL) { @@ -216,10 +249,30 @@ int main(int argc, char **argv) } } if((ch = stdmkchild(argv + optind + 1, NULL, NULL)) < 0) { - flog(LOG_ERR, "accesslog: could fork child: %s", strerror(errno)); + flog(LOG_ERR, "accesslog: could not fork child: %s", strerror(errno)); exit(1); } + signal(SIGHUP, sighandler); + if(pidfile) { + if(!strcmp(pidfile, "-")) { + if(!outname) { + flog(LOG_ERR, "accesslog: cannot derive PID file name without an output file"); + exit(1); + } + pidfile = sprintf2("%s.pid", outname); + } + if((pidout = fopen(pidfile, "w")) == NULL) { + flog(LOG_ERR, "accesslog: could not open PID file %s for writing: %s", pidfile); + exit(1); + } + fprintf(pidout, "%i\n", (int)getpid()); + fclose(pidout); + } while(1) { + if(reopen) { + reopenlog(); + reopen = 0; + } memset(pfd, 0, sizeof(pfd)); pfd[0].fd = 0; pfd[0].events = POLLIN; @@ -245,5 +298,7 @@ int main(int argc, char **argv) if(pfd[1].revents & POLLHUP) break; } + if(pidfile != NULL) + unlink(pidfile); return(0); }