accesslog: Fixed another typo.
[ashd.git] / src / accesslog.c
index 4961483..27663c4 100644 (file)
@@ -24,6 +24,7 @@
 #include <sys/poll.h>
 #include <time.h>
 #include <sys/time.h>
+#include <signal.h>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #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 +67,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 +100,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 +162,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 +170,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] [-o OUTFILE] CHILD [ARGS...]\n");
+    fprintf(out, "usage: accesslog [-hFa] [-f FORMAT] OUTFILE CHILD [ARGS...]\n");
 }
 
 int main(int argc, char **argv)
@@ -180,17 +203,12 @@ int main(int argc, char **argv)
     struct hthead *req;
     int fd;
     struct pollfd pfd[2];
-    char *outfile;
     
-    optarg = NULL;
-    while((c = getopt(argc, argv, "+hFaf:o:")) >= 0) {
+    while((c = getopt(argc, argv, "+hFaf:")) >= 0) {
        switch(c) {
        case 'h':
            usage(stdout);
            exit(0);
-       case 'o':
-           outfile = optarg;
-           break;
        case 'F':
            flush = 0;
            break;
@@ -205,25 +223,34 @@ int main(int argc, char **argv)
            exit(1);
        }
     }
-    if(optind >= argc) {
+    if(argc - optind < 2) {
        usage(stderr);
        exit(1);
     }
     if(format == NULL)
        format = DEFFORMAT;
-    if(outfile != NULL) {
-       if((out = fopen(outfile, "a")) == NULL) {
-           flog(LOG_ERR, "accesslog: could not open %s for logging: %s", outfile, strerror(errno));
+    if(!strcmp(argv[optind], "-"))
+       outname = NULL;
+    else
+       outname = argv[optind];
+    if(outname == NULL) {
+       out = stdout;
+    } else {
+       if((out = fopen(argv[optind], "a")) == NULL) {
+           flog(LOG_ERR, "accesslog: could not open %s for logging: %s", argv[optind], strerror(errno));
            exit(1);
        }
-    } else {
-       out = stdout;
     }
-    if((ch = stdmkchild(argv + optind, NULL, NULL)) < 0) {
-       flog(LOG_ERR, "accesslog: could fork child: %s", strerror(errno));
+    if((ch = stdmkchild(argv + optind + 1, NULL, NULL)) < 0) {
+       flog(LOG_ERR, "accesslog: could not fork child: %s", strerror(errno));
        exit(1);
     }
+    signal(SIGHUP, sighandler);
     while(1) {
+       if(reopen) {
+           reopenlog();
+           reopen = 0;
+       }
        memset(pfd, 0, sizeof(pfd));
        pfd[0].fd = 0;
        pfd[0].events = POLLIN;