chiark / gitweb /
Merge branch 'master' of login.chiark.greenend.org.uk:public-git/inn-innduct
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Mon, 3 May 2010 12:35:28 +0000 (13:35 +0100)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Mon, 3 May 2010 12:35:28 +0000 (13:35 +0100)
backends/innduct.c
doc/man/innduct.8

index 609cf7951f9e1fa3be9db346e61d5a2b8d11c27d..a7679334ca196e01445d645f5135017f4e425b26 100644 (file)
  *  with GPLv3.  If not then please let me know.  -Ian Jackson.)
  */
 
-/*
- * todo
- *  specify perms of /tmp/innduct.control
- */
-
-/*
- * debugging rune:
- *  build-lfs/backends/innduct --connection-timeout=30 --no-daemon -C ../inn.conf -f `pwd`/fee sit localhost
- */
-
 /*
  * Newsfeeds file entries should look like this:
  *     host.name.of.site[/exclude,exclude,...]\
@@ -361,11 +351,12 @@ static void connfail(Conn *conn, const char *fmt, ...)         PRINTF(2,3);
 static const oop_rd_style peer_rd_style;
 static oop_rd_call peer_rd_err, peer_rd_ok;
 
+
 /*----- configuration options -----*/
 /* when changing defaults, remember to update the manpage */
 
 static const char *sitename, *remote_host;
-static const char *feedfile, *realsockdir="/tmp/innduct.control";
+static const char *feedfile, *path_control;
 static int quiet_multiple=0;
 static int become_daemon=1, try_filemon=1;
 static int try_stream=1;
@@ -527,8 +518,7 @@ struct Conn {
 /* main initialises */
 static oop_source *loop;
 static ConnList conns;
-static char *path_lock, *path_flushing, *path_defer;
-static char *path_control, *path_dump;
+static char *path_lock, *path_flushing, *path_defer, *path_dump;
 static char *globpat_backlog;
 static pid_t self_pid;
 
@@ -1010,8 +1000,6 @@ static void *control_master_readable(oop_source *lp, int master,
   }while(0)
 
 static void control_init(void) {
-  char *real=0;
-  
   union {
     struct sockaddr sa;
     struct sockaddr_un un;
@@ -1020,66 +1008,24 @@ static void control_init(void) {
   memset(&sa,0,sizeof(sa));
   int maxlen= sizeof(sa.un.sun_path);
 
-  int reallen= readlink(path_control, sa.un.sun_path, maxlen);
-  if (reallen<0) {
-    if (errno != ENOENT)
-      NOCONTROL("readlink control socket symlink path %s", path_control);
-  }
-  if (reallen >= maxlen) {
-    debug("control socket symlink path too long (r=%d)",reallen);
-    xunlink(path_control, "old (overlong) control socket symlink");
-    reallen= -1;
-  }
-  
-  if (reallen<0) {
-    struct stat stab;
-    int r= lstat(realsockdir,&stab);
-    if (r) {
-      if (errno != ENOENT) NOCONTROL("lstat real socket dir %s", realsockdir);
-
-      r= mkdir(realsockdir, 0700);
-      if (r) NOCONTROL("mkdir real socket dir %s", realsockdir);
-
-    } else {
-      uid_t self= geteuid();
-      if (!S_ISDIR(stab.st_mode) ||
-         stab.st_uid != self ||
-         stab.st_mode & 0007) {
-       warn("no control socket, because real socket directory"
-            " is somehow wrong (ISDIR=%d, uid=%lu (exp.%lu), mode %lo)",
-            !!S_ISDIR(stab.st_mode),
-            (unsigned long)stab.st_uid, (unsigned long)self,
-            (unsigned long)stab.st_mode & 0777UL);
-       goto nocontrol;
-      }
-    }
-
-    real= xasprintf("%s/s%lx.%lx", realsockdir,
-                   (unsigned long)xtime(), (unsigned long)self_pid);
-    int reallen= strlen(real);
-
-    if (reallen >= maxlen) {
-      warn("no control socket, because tmpnam gave overly-long path"
-          " %s", real);
-      goto nocontrol;
-    }
-    r= symlink(real, path_control);
-    if (r) NOCONTROL("make control socket path %s a symlink to real"
-                    " socket path %s", path_control, real);
-    memcpy(sa.un.sun_path, real, reallen);
-  }
+  int pathlen= strlen(path_control);
+  if (pathlen > maxlen)
+    NOCONTROL("control socket path %s too long (%d>%d)",
+             path_control, pathlen, maxlen);
 
-  int r= unlink(sa.un.sun_path);
+  int r= unlink(path_control);
   if (r && errno!=ENOENT)
-    NOCONTROL("remove old real socket %s", sa.un.sun_path);
+    NOCONTROL("remove old control socket %s", path_control);
 
   control_master= socket(PF_UNIX, SOCK_STREAM, 0);
   if (control_master<0) NOCONTROL("create new control socket");
 
-  sa.un.sun_family= AF_UNIX;
   int sl= strlen(sa.un.sun_path) + offsetof(struct sockaddr_un, sun_path);
+  sa.un.sun_family= AF_UNIX;
+  memcpy(sa.un.sun_path, path_control, pathlen);
+
   r= bind(control_master, &sa.sa, sl);
-  if (r) NOCONTROL("bind to real socket path %s", sa.un.sun_path);
+  if (r) NOCONTROL("bind to control socket path %s", sa.un.sun_path);
 
   r= listen(control_master, 5);
   if (r) NOCONTROL("listen");
@@ -1087,12 +1033,11 @@ static void control_init(void) {
   xsetnonblock(control_master, 1);
 
   loop->on_fd(loop, control_master, OOP_READ, control_master_readable, 0);
-  info("control socket ok, real path %s", sa.un.sun_path);
+  info("control socket ok, listening on %s", path_control);
 
   return;
 
  nocontrol:
-  free(real);
   xclose_perhaps(&control_master, "control master",0);
   return;
 }
@@ -3421,10 +3366,11 @@ CCMD(dump) {
   }
 
   fprintf(f,"paths");
+  DUMPV("%s", , feedfile);
+  DUMPV("%s", , path_control);
   DUMPV("%s", , path_lock);
   DUMPV("%s", , path_flushing);
   DUMPV("%s", , path_defer);
-  DUMPV("%s", , path_control);
   DUMPV("%s", , path_dump);
   DUMPV("%s", , globpat_backlog);
   fprintf(f,"\n");
@@ -3608,7 +3554,7 @@ static const Option innduct_options[]= {
 {0,"no-filemon",         0,       &try_filemon,              op_setint, 0   },
 {'C',"inndconf",         "F",     &inndconffile,             op_string      },
 {'P',"port",             "PORT",  &port,                     op_integer     },
-{0,"ctrl-sock-dir",      0,       &realsockdir,              op_string      },
+{0,"cli",                0,       &path_control,             op_string      },
 {0,"help",               0,       0,                         help           },
 
 {0,"max-connections",    "N",     &max_connections,          op_integer     },
@@ -3658,6 +3604,14 @@ static void convert_to_periods_rndup(int *store) {
   *store /= period_seconds;
 }
 
+static void assemble_path(const char **path_io, const char *suffix,
+                         const char *what) {
+  const char *const specified= *path_io;
+  if (!specified[0]) badusage("%s, if specified, must be nonempty", what);
+  if (specified[strlen(specified)-1]=='/')
+    *path_io= xasprintf("%s%s%s", specified, sitename, suffix);
+}
+
 int main(int argc, char **argv) {
   if (!argv[1]) {
     printusage(stderr);
@@ -3699,14 +3653,12 @@ int main(int argc, char **argv) {
   if (max_bad_data_ratio < 0 || max_bad_data_ratio > 100)
     badusage("bad input data ratio must be between 0..100");
   max_bad_data_ratio *= 0.01;
+  
+  if (!feedfile) feedfile= xasprintf("%s/%s",innconf->pathoutgoing,sitename);
+  else assemble_path(&feedfile, "", "feed filename");
 
-  if (!feedfile) {
-    feedfile= xasprintf("%s/%s",innconf->pathoutgoing,sitename);
-  } else if (!feedfile[0]) {
-    badusage("feed filename must be nonempty");
-  } else if (feedfile[strlen(feedfile)-1]=='/') {
-    feedfile= xasprintf("%s%s",feedfile,sitename);
-  }
+  if (path_control) path_control= xasprintf("%s_cli", feedfile);
+  else assemble_path(&path_control, "%s_cli", "control socket path");
 
   if (max_queue_per_ipf<0)
     max_queue_per_ipf= max_queue_per_conn * 2;
@@ -3722,7 +3674,6 @@ int main(int argc, char **argv) {
   path_lock=        xasprintf("%s_lock",      feedfile);
   path_flushing=    xasprintf("%s_flushing",  feedfile);
   path_defer=       xasprintf("%s_defer",     feedfile);
-  path_control=     xasprintf("%s_control",   feedfile);
   path_dump=        xasprintf("%s_dump",      feedfile);
   globpat_backlog=  xasprintf("%s_backlog*",  feedfile);
 
@@ -3767,7 +3718,7 @@ int main(int argc, char **argv) {
 
   int val= 1;
   r= SMsetup(SM_PREOPEN, &val); if (!r) warn("SMsetup SM_PREOPEN failed");
-  r= SMinit(); if (!r) die("storage manager initialisation (SMinit) failed");
+//  r= SMinit(); if (!r) die("storage manager initialisation (SMinit) failed");
 
   if (!become_daemon)
     control_stdio();
index 580f317ed853af04e96c463253e3b87fb1c4913a..055d083085466bc77731e9e0a0751a0cae9a355b 100644 (file)
@@ -106,19 +106,20 @@ Read
 instead of the default
 .BR inn.conf .
 .TP
-.BI \-\-ctrl-sock-dir= DIR
-Use
-.I DIR
-as the directory to contain the actual control socket.  See
-CONTROLLING INNDUCT, below.
-If
-.I DIR
-does not exist it will be created with mode 0700; if it does
-exist it must not be a symlink and must be owned by the user running
-innduct and have no access for "other".  If the control socket cannot
-be set up (for this or any other reason), a warning is logged, but
-such situations are not fatal for innduct's startup.  The default is
-.BR /tmp/innduct.control .
+.BR \-\-cli= \fIDIR\fR / |\fIPATH\fR
+Bind the control command line socket to
+.IB DIR / site _cli
+(if the value ends with a
+.BR /)
+or
+.I PATH
+(if it doesn't).  See CONTROLLING INNDUCT, below.
+This option may be essential, if the
+path to
+.I feedfile
+is too long, as there is a fairly short limit on the paths to AF_UNIX
+sockets.  The default is
+.IR feedfile \fB_cli\fR.  
 .TP
 .BI \-\-port= PORT
 Connect to port
@@ -317,29 +318,22 @@ If you want to stop innduct you can send it SIGTERM or SIGINT, or the
 control command, in which case it will report statistics so far and
 quickly exit.  If innduct receives SIGKILL nothing will be broken or
 corrupted; you just won't see some of the article stats.
+.LP
 innduct listens on an AF_UNIX socket, and provides a command-line
 interface which can be used to trigger various events and for
-debugging.
-.LP
-The socket is called
-.IB feedfile _control
+debugging.  The socket is called
+.IB feedfile _cli
 and when connected reads and writes lines (with unix line endings).
 It can most easily be accessed with a program like
 .I netcat-openbsd
 (eg
 .B nc.openbsd -U
-.IR feedfile \fB_control\fR)
+.IR feedfile \fB_cli\fR)
 or
 .IR socat .
-The CLI has as a prompt
+The prompt is
 .IR site \fB|\fR.
 .LP
-Because there is a fairly short limit on the length of pathnames used
-for AF_UNIX sockets, innduct actually creates the socket with a unique
-name in a different dedicated subdirectory of /tmp, and makes
-.IB feedfile _control
-a symlink to the real socket.
-.LP
 The following control commands are supported:
 .TP
 .B h
@@ -491,6 +485,10 @@ safely remove backlog files.  \fIsomething\fR may not contain \fB#\fR
 you rename it to match the pattern \fIfeedfile\fR\fB_backlog\fR*, as
 otherwise innduct may find and process the file and read it to EOF
 before you have finished creating it.
+.IP \fIfeedfile\fR_cli
+.IX Item "control command line socket"
+Default AF_UNIX listening socket for the control command line.  See
+CONTROLLING INNDUCT, above.
 .IP \fIfeedfile\fR_dump
 .IX Item "debug dump file"
 On request via a control connection innduct dumps a summary of its