chiark / gitweb /
wip compile
authorIan Jackson <ian@liberator.(none)>
Tue, 27 Apr 2010 10:34:30 +0000 (11:34 +0100)
committerIan Jackson <ian@liberator.(none)>
Tue, 27 Apr 2010 10:34:30 +0000 (11:34 +0100)
backends/innduct.c

index 968a177..60cfea6 100644 (file)
@@ -162,6 +162,7 @@ perl -ne 'print if m/-8\<-/..m/-\>8-/; print "\f" if m/-\^L-/' backends/innduct.
 #include "storage.h"
 #include "nntp.h"
 #include "libinn.h"
+#include "inndcomm.h"
 
 #include <sys/uio.h>
 #include <sys/types.h>
@@ -179,6 +180,7 @@ perl -ne 'print if m/-8\<-/..m/-\>8-/; print "\f" if m/-\^L-/' backends/innduct.
 #include <assert.h>
 #include <stdlib.h>
 #include <glob.h>
+#include <time.h>
 
 #include <oop.h>
 #include <oop-read.h>
@@ -308,6 +310,7 @@ static int connection_setup_timeout=200, port=119, try_stream=1;
 static int inndcomm_flush_timeout=100;
 static int reconnect_delay_periods, flushfail_retry_periods, open_wait_periods;
 static int backlog_retry_minperiods, backlog_spontaneous_rescan_periods;
+static int spontaneous_flush_periods;
 static const char *inndconffile;
 
 static double nocheck_thresh_pct= 95.0;
@@ -467,10 +470,10 @@ static void logcore(int sysloglevel, const char *fmt, ...) {
 }
 
 static void logv(int sysloglevel, const char *pfx, int errnoval,
-                int exitstatus, const char *fmt, va_list al)
+                const char *fmt, va_list al)
      __attribute__((__format__(printf,5,0)));
 static void logv(int sysloglevel, const char *pfx, int errnoval,
-                int exitstatus, const char *fmt, va_list al) {
+                const char *fmt, va_list al) {
   char msgbuf[256]; /* NB do not call xvasprintf here or you'll recurse */
   vsnprintf(msgbuf,sizeof(msgbuf), fmt,al);
   msgbuf[sizeof(msgbuf)-1]= 0;
@@ -484,27 +487,38 @@ static void logv(int sysloglevel, const char *pfx, int errnoval,
         errnoval>=0 ? strerror(errnoval) : "");
 }
 
-#define logwrap(fn, pfx, sysloglevel, err, estatus)    \
+#define diewrap(fn, pfx, sysloglevel, err, estatus)            \
+  static void fn(const char *fmt, ...)                         \
+      __attribute__((__noreturn__,__format__(printf,1,2)));    \
+  static void fn(const char *fmt, ...) {                       \
+    va_list al;                                                        \
+    va_start(al,fmt);                                          \
+    logv(sysloglevel, pfx, err, fmt, al);                      \
+    exit(estatus);                                             \
+  }
+
+#define logwrap(fn, pfx, sysloglevel, err)             \
   static void fn(const char *fmt, ...)                 \
       __attribute__((__format__(printf,1,2)));         \
   static void fn(const char *fmt, ...) {               \
     va_list al;                                                \
     va_start(al,fmt);                                  \
-    logv(sysloglevel, pfx, err, estatus, fmt, al);     \
+    logv(sysloglevel, pfx, err, fmt, al);              \
+    va_end(al);                                                \
   }
 
-logwrap(sysdie,   " critical", LOG_CRIT,    errno, 16);
-logwrap(die,      " critical", LOG_CRIT,    -1,    16);
+diewrap(sysdie,   " critical", LOG_CRIT,    errno, 16);
+diewrap(die,      " critical", LOG_CRIT,    -1,    16);
 
-logwrap(sysfatal, " fatal",    LOG_ERR,     errno, 12);
-logwrap(fatal,    " fatal",    LOG_ERR,     -1,    12);
+diewrap(sysfatal, " fatal",    LOG_ERR,     errno, 12);
+diewrap(fatal,    " fatal",    LOG_ERR,     -1,    12);
 
-logwrap(syswarn,  " warning",  LOG_WARNING, errno, 0);
-logwrap(warn,     " warning",  LOG_WARNING, -1,    0);
+logwrap(syswarn,  " warning",  LOG_WARNING, errno);
+logwrap(warn,     " warning",  LOG_WARNING, -1);
 
-logwrap(notice,   "",          LOG_NOTICE,  -1,    0);
-logwrap(info,     " info",     LOG_INFO,    -1,    0);
-logwrap(debug,    " debug",    LOG_DEBUG,   -1,    0);
+logwrap(notice,   "",          LOG_NOTICE,  -1);
+logwrap(info,     " info",     LOG_INFO,    -1);
+logwrap(debug,    " debug",    LOG_DEBUG,   -1);
 
 
 /*========== utility functions etc. ==========*/
@@ -586,6 +600,11 @@ static void xunlink(const char *path, const char *what) {
   if (r) sysdie("can't unlink %s %s", path, what);
 }
 
+static time_t xtime(void) {
+  time_t now= time(0);
+  if (now==-1) sysdie("time(2) failed");
+}
+
 static void check_isreg(const struct stat *stab, const char *path,
                        const char *what) {
   if (!S_ISREG(stab->st_mode))
@@ -2079,13 +2098,13 @@ static void close_defer(void) {
   if (!defer)
     return;
 
-  xfstat(fileno(defer), &stab, path_defer, "defer file");
+  struct stat stab;
+  xfstat_isreg(fileno(defer), &stab, path_defer, "defer file");
 
   if (fclose(defer)) sysfatal("could not close defer file %s", path_defer);
   defer= 0;
 
-  time_t now= time(0);
-  if (now==-1) sysdie("time(2) failed");
+  time_t now= xtime();
 
   char *backlog= xasprintf("%s_backlog_%lu.%lu", feedfile,
                           (unsigned long)now,
@@ -2114,12 +2133,12 @@ static void search_backlog_file(void) {
   /* returns non-0 iff there are any backlog files */
 
   glob_t gl;
-  int r;
+  int r, i;
   struct stat stab;
   const char *oldest_path=0;
   time_t oldest_mtime, now;
 
-  if (backlog_input_file) return 3;
+  if (backlog_input_file) return;
 
  try_again:
 
@@ -2170,10 +2189,10 @@ static void search_backlog_file(void) {
       exit(0);
     }
     until_backlog_nextscan= backlog_spontaneous_rescan_periods;
-    return 0;
+    return;
   }
 
-  now= time();  if (now==-1) sysdie("time(2) failed");
+  now= xtime();
   double age= difftime(now, oldest_mtime);
   long age_deficiency= (backlog_retry_minperiods * PERIOD_SECONDS) - age;
 
@@ -2188,7 +2207,7 @@ static void search_backlog_file(void) {
     }
     inputfile_tailing_start(backlog_input_file);
     until_backlog_nextscan= -1;
-    return 1;
+    return;
   }
 
   until_backlog_nextscan= age_deficiency / PERIOD_SECONDS;
@@ -2199,7 +2218,7 @@ static void search_backlog_file(void) {
 
   debug("backlog scan: young age=%f deficiency=%ld nextscan=%d oldest=%s",
        age, age_deficiency, until_backlog_nextscan, oldest_path);
-  return 2;
+  return;
 }
 
 /*========== flushing the feed ==========*/
@@ -2209,7 +2228,7 @@ static pid_t inndcomm_child;
 static void *inndcomm_event(oop_source *lp, int fd, oop_event e, void *u) {
   assert(inndcomm_child);
   int status= xwaitpid(&inndcomm_child, "inndcomm");
-  loop->cancel_fd(fd);
+  cancel_fd_read_except(fd);
   close(fd);
 
   assert(!flushing_input_file);
@@ -2287,11 +2306,12 @@ void spawn_inndcomm_flush(const char *why) { /* Moved => Flushing */
 
   if (pipe(pipefds)) sysdie("create pipe for inndcomm child sentinel");
 
-  inndcomm_child= xfork();
+  inndcomm_child= xfork("inndcomm child");
 
   if (!inndcomm_child) {
-    static char flushargv[2]= { sitename, 0 };
+    const char *flushargv[2]= { sitename, 0 };
     char *reply;
+    int r;
 
     close(pipefds[0]);
 
@@ -2340,8 +2360,9 @@ static void postfork(const char *what) {
   postfork_stdio(defer);
 }
 
-#define EVERY(what, interval, body)                                         \
-  static const struct timeval what##_timeout = { 5, 0 };                    \
+#define EVERY(what, interval_sec, interval_usec, body)                      \
+  static const struct timeval what##_timeout =                              \
+            { interval_sec, interval_usec };                                \
   static void what##_schedule(void);                                        \
   static void *what##_timedout(oop_source *lp, struct timeval tv, void *u) { \
     { body }                                                                \
@@ -2351,13 +2372,13 @@ static void postfork(const char *what) {
     loop->on_time(loop, what##_timeout, what##_timedout, 0);                \
   }
 
-EVERY(filepoll, {5,0}, {
+EVERY(filepoll, 5,0, {
   if (main_input_file && main_input_file->readable_callback)
     filemon_callback(main_input_file);
 });
 
-#define DEBUGF_IPF(wh) " " #wh "=%p/%s:ip=%ld,off=%ld,fd=%d%s" \
-#define DEBUG_IPF(sh)                                          \
+#define DEBUGF_IPF(wh) " " #wh "=%p/%s:ip=%ld,off=%ld,fd=%d%s"
+#define DEBUG_IPF(wh)                                          \
   wh##_input_file, debug_ipf_path(wh##_input_file),            \
   wh##_input_file->inprogress, (long)wh##_input_file->offset,  \
   wh##_input_file->fd, wh##_input_file->rd ? "+" : ""
@@ -2366,10 +2387,10 @@ static const char *debug_ipf_path(InputFile *ipf) {
   return slash ? slash+1 : ipf->path;
 }
 
-EVERY(period, {PERIOD_SECONDS,0}, {
+EVERY(period, PERIOD_SECONDS,0, {
   debug("PERIOD"
        " sms=%s[%d] conns=%d queue=%d until_connect=%d"
-       " input_files" DEBUGF_IPF(main) DEBUGF_IPF(old) DEBUGF_FMT(flushing)
+       " input_files" DEBUGF_IPF(main) DEBUGF_IPF(old) DEBUGF_IPF(flushing)
        " children connecting=%ld inndcomm_child"
        ,
        sms_names[sms], sm_period_counter,
@@ -2389,78 +2410,91 @@ EVERY(period, {PERIOD_SECONDS,0}, {
 
 /*========== option parsing ==========*/
 
+static void vbadusage(const char *fmt, va_list al)
+     __attribute__((__noreturn__,__format__(printf,1,0)));
+static void vbadusage(const char *fmt, va_list al) {
+  abort();
+}
+static void badusage(const char *fmt, ...)
+     __attribute__((__noreturn__,__format__(printf,1,2)));
+static void badusage(const char *fmt, ...) {
+  va_list al;
+  va_start(al,fmt);
+  vbadusage(fmt,al);
+}
+
 enum OptFlags {
-  of_seconds= 001000u;
-  of_boolean= 002000u;
+  of_seconds= 001000u,
+  of_boolean= 002000u,
 };
 
 typedef struct Option Option;
 typedef void OptionParser(const Option*, const char *val);
 
 struct Option {
-  int short;
-  const char *long;
+  int shrt;
+  const char *lng;
   void *store;
   OptionParser *fn;
   int noarg;
 };
 
-void op_integer(const Option *o, const char *val) {
+static void op_integer(const Option *o, const char *val) {
   char *ep;
   errno= 0;
   unsigned long ul= strtoul(val,&ep,10);
   if (*ep || ep==val || errno || ul>INT_MAX)
-    badusage("bad integer value for %s",o->long);
+    badusage("bad integer value for %s",o->lng);
   int *store= o->store;
   *store= ul;
 }
 
-void op_double(const Option *o, const char *val) {
+static void op_double(const Option *o, const char *val) {
   int *store= o->store;
   char *ep;
   errno= 0;
   *store= strtod(val, &ep);
   if (*ep || ep==val || errno)
-    badusage("bad floating point value for %s",o->long);
+    badusage("bad floating point value for %s",o->lng);
 }
 
-void op_string(const Option *o, const char *val) {
+static void op_string(const Option *o, const char *val) {
   char **store= o->store;
   free(*store);
   *store= val;
 }
 
-void op_seconds(const Option *o, const char *val) {
+static void op_seconds(const Option *o, const char *val) {
   int *store= o->store;
   char *ep;
 
   double v= strtod(val,&ep);
-  if (ep==val) badusage("bad time/duration value for %s",o->long);
+  if (ep==val) badusage("bad time/duration value for %s",o->lng);
 
   if (!*ep || !strcmp(ep,"s")) unit= 1;
   else if (!strcmp(ep,"m")) unit= 60;
   else if (!strcmp(ep,"h")) unit= 3600;
   else if (!strcmp(ep,"d")) unit= 86400;
-  else badusage("bad units %s for time/duration value for %s",ep,o->long);
+  else badusage("bad units %s for time/duration value for %s",ep,o->lng);
 
   v *= unit;
   v= ceil(v);
-  if (v > INT_MAX) badusage("time/duration value for %s out of range",o->long);
+  if (v > INT_MAX) badusage("time/duration value for %s out of range",o->lng);
   *store= v;
 }
 
-void op_periods_rndup(const Option *o, const char *val) {
+static void op_periods_rndup(const Option *o, const char *val) {
   int *store= o->store;
   op_seconds(o,val);
   *store += PERIOD_SECONDS-1;
   *store /= PERIOD_SECONDS;
 }
 
-void op_periods_booltrue(const Option *o, const char *val) {
+static void op_periods_booltrue(const Option *o, const char *val) {
   int *store= o->store;
   *store= 1;
 }
-void op_periods_boolfalse(const Option *o, const char *val) {
+static void op_periods_boolfalse(const Option *o, const char *val) {
   int *store= o->store;
   *store= 0;
 }
@@ -2504,25 +2538,25 @@ int main(int argc, char **argv) {
        arg++;
        char *equals= strchr(arg,'=');
        int len= equals ? (equals - arg) : strlen(arg);
-       for (o=options; o->long; o++)
-         if (strlen(o->long) == len && !memcmp(o->long,arg,len))
+       for (o=options; o->lng; o++)
+         if (strlen(o->lng) == len && !memcmp(o->lng,arg,len))
            goto found_long;
        badusage("unknown long option --%s",arg);
       found_long:
        if (o->noarg) {
-         if (equals) badusage("option --%s does not take a value",o->long);
+         if (equals) badusage("option --%s does not take a value",o->lng);
          arg= 0;
        } else if (equals) {
          arg= equals+1;
        } else {
          arg= *++argv;
-         if (!arg) badusage("option --%s needs a value",o->long);
+         if (!arg) badusage("option --%s needs a value",o->lng);
        }
        o->fn(o, arg);
        break; /* eaten the whole argument now */
       }
-      for (o=options; o->long; o++)
-       if (a == o->short)
+      for (o=options; o->lng; o++)
+       if (a == o->shrt)
          goto found_short;
       badusage("unknown short option -%c",a);
     found_short:
@@ -2531,7 +2565,7 @@ int main(int argc, char **argv) {
       } else {
        if (!*++arg) {
          arg= *++argv;
-         if (!arg) badusage("option -%c needs a value",o->short);
+         if (!arg) badusage("option -%c needs a value",o->shrt);
        }
        o->fn(o,arg);
        break; /* eaten the whole argument now */