/* 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;
static int period_seconds=60;
static int filepoll_seconds=5;
static int max_queue_per_ipf=-1;
-static int realsockdir_any_perms=0;
static int connection_setup_timeout=200;
static int inndcomm_flush_timeout=100;
/* 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;
}while(0)
static void control_init(void) {
- char *real=0;
-
union {
struct sockaddr sa;
struct sockaddr_un un;
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 if (!realsockdir_any_perms) {
- 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");
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;
}
}
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");
{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,"no-ctrl-sock-dir-perms-check",0,&realsockdir_any_perms, op_setint, 0 },
+{0,"cli", 0, &path_control, op_string },
{0,"help", 0, 0, help },
{0,"max-connections", "N", &max_connections, op_integer },
*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);
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;
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);
instead of the default
.BR inn.conf .
.TP
-.BI \-\-ctrl-sock-dir= CTRL-SOCK-DIR
-Use
-.I CTRL-SOCK-DIR
-as the directory to contain the actual control socket. See
-CONTROLLING INNDUCT, below.
-If
-.I CTRL-SOCK-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 .
-.TP
-.BI \-\-no-ctrl-sock-dir-perms-check
-Use an existing
-.I CTRL-SOCK-DIR
-even if it has unexpected permissions and ownership. Note that this
-is not safe with the default value of
-.IR CTRL-SOCK-DIR .
+.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
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
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