/*----- configuration options -----*/
-/* when changing defaults, remember to update the manpage */
-static const char *sitename, *remote_host;
-static const char *feedfile, *path_run, *path_cli, *path_cli_dir;
-static int quiet_multiple=0;
-static int interactive=0, try_filemon=1;
-static int try_stream=1;
-static int port=119;
-static const char *inndconffile;
+extern const char *sitename, *remote_host;
+extern const char *feedfile, *path_run, *path_cli, *path_cli_dir;
+extern int quiet_multiple, interactive, try_filemon, try_stream, port;
+extern const char *inndconffile;
-static int max_connections=10;
-static int max_queue_per_conn=200;
-static int target_max_feedfile_size=100000;
-static int period_seconds=30;
-static int filepoll_seconds=5;
-static int max_queue_per_ipf=-1;
+extern int max_connections, max_queue_per_conn, target_max_feedfile_size;
+extern int period_seconds, filepoll_seconds, max_queue_per_ipf;
+extern int connection_setup_timeout, inndcomm_flush_timeout;
-static int connection_setup_timeout=200;
-static int inndcomm_flush_timeout=100;
-
-static double nocheck_thresh= 95.0; /* converted from percentage by main */
-static double nocheck_decay= 100; /* conv'd from articles to lambda by main */
+extern double nocheck_thresh;
+extern double nocheck_decay;
/* all these are initialised to seconds, and converted to periods in main */
-static int reconnect_delay_periods=1000;
-static int flushfail_retry_periods=1000;
-static int backlog_retry_minperiods=100;
-static int backlog_spontrescan_periods=300;
-static int spontaneous_flush_periods=100000;
-static int max_separated_periods=2000;
-static int need_activity_periods=1000;
-static int lowvol_thresh=3;
-static int lowvol_periods=1000;
-
-static double max_bad_data_ratio= 1; /* conv'd from percentage by main */
-static int max_bad_data_initial= 30;
- /* in one corrupt 4096-byte block the number of newlines has
- * mean 16 and standard deviation 3.99. 30 corresponds to z=+3.5 */
+extern int reconnect_delay_periods;
+extern int flushfail_retry_periods;
+extern int backlog_retry_minperiods;
+extern int backlog_spontrescan_periods;
+extern int spontaneous_flush_periods;
+extern int max_separated_periods;
+extern int need_activity_periods;
+extern int stats_log_periods;
+extern int lowvol_thresh;
+extern int lowvol_periods;
+
+extern double max_bad_data_ratio;
+extern int max_bad_data_initial;
/*----- statistics -----*/
art_Unsolicited, /* - sent body without check */
art_MaxState,
} ArtState;
-
-static const char *const artstate_names[]=
- { "Unchecked", "Wanted", "Unsolicited", 0 };
+extern const char *const artstate_names[]; /* xmit.c */
#define RESULT_COUNTS(RCS,RCN) \
RCS(sent) \
RCI_max
} ResultCountIndex;
+typedef enum {
+ read_ok, read_blank, read_err, nooffer_missing,
+ ECI_max
+} EventCountIndex;
/*----- transmission buffers -----*/
/*----- core operational data structure types -----*/
+typedef struct {
+ int results[art_MaxState][RCI_max];
+ int events[ECI_max];
+} Counts;
+
struct InputFile {
/* This is also an instance of struct oop_readable */
struct oop_readable readable; /* first */
long inprogress; /* includes queue.count and also articles in conns */
long autodefer; /* -1 means not doing autodefer */
- int counts[art_MaxState][RCI_max];
- int readcount_ok, readcount_blank, readcount_err, count_nooffer_missing;
+ Counts counts;
char path[];
};
char messageid[1];
};
+struct Conn {
+ ISNODE(Conn);
+ int fd; /* may be 0, meaning closed (during construction/destruction) */
+ oop_read *rd; /* likewise */
+ int oopwriting; /* since on_fd is not idempotent */
+ int max_queue, stream;
+ const char *quitting;
+ int since_activity; /* periods */
+ ArticleList waiting; /* not yet told peer */
+ ArticleList priority; /* peer says send it now */
+ ArticleList sent; /* offered/transmitted - in xmit or waiting reply */
+ struct iovec xmit[CONNIOVS];
+ XmitDetails xmitd[CONNIOVS];
+ int xmitu;
+};
+
#define SMS_LIST(X) \
X(NORMAL) \
X(FLUSHING) \
/*----- help.c -----*/
-static void syscrash(const char *fmt, ...) NORET_PRINTF(1,2);
-static void crash(const char *fmt, ...) NORET_PRINTF(1,2);
-static void info(const char *fmt, ...) PRINTF(1,2);
-static void dbg(const char *fmt, ...) PRINTF(1,2);
+void syscrash(const char *fmt, ...) NORET_PRINTF(1,2);
+void crash(const char *fmt, ...) NORET_PRINTF(1,2);
+void info(const char *fmt, ...) PRINTF(1,2);
+void dbg(const char *fmt, ...) PRINTF(1,2);
void logv(int sysloglevel, const char *pfx, int errnoval,
const char *fmt, va_list al) PRINTF(5,0);
void xclose_perhaps(int *fd, const char *what, const char *what2);
pid_t xfork(const char *what);
-static void on_fd_read_except(int fd, oop_call_fd callback);
+void on_fd_read_except(int fd, oop_call_fd callback);
void cancel_fd_read_except(int fd);
void report_child_status(const char *what, int status);
time_t xtime(void);
void xsigaction(int signo, const struct sigaction *sa);
void xsigsetdefault(int signo);
+void raise_default(int signo) NORET;
void xgettimeofday(struct timeval *tv_r);
void xsetnonblock(int fd, int nonb);
return errnoval==EWOULDBLOCK || errnoval==EAGAIN;
}
-/*----- innduct.c -----*/
+#define INNLOGSETS(INNLOGSET) \
+ INNLOGSET(die, "fatal", LOG_ERR) \
+ INNLOGSET(warn, "warning", LOG_WARNING) \
+ INNLOGSET(notice, "notice", LOG_NOTICE) \
+ INNLOGSET(trace, "trace", LOG_NOTICE)
+#define INNLOGSET_DECLARE(fn, pfx, sysloglevel) \
+ void duct_log_##fn(int l, const char *fmt, va_list al, int errval) \
+ PRINTF(3,0);
+INNLOGSETS(INNLOGSET_DECLARE)
+
+/*----- duct.c -----*/
void postfork(void);
+void period(void);
+
+/*----- cli.c -----*/
+
+void cli_init(void);
+void cli_stdio(void);
/*----- conn.c -----*/
void conn_closefd(Conn *conn, const char *msgprefix);
+void check_idle_conns(void);
+int conn_busy(Conn *conn);
+void conn_dispose(Conn *conn);
+
+void vconnfail(Conn *conn, const char *fmt, va_list al) PRINTF(2,0);
+void connfail(Conn *conn, const char *fmt, ...) PRINTF(2,3);
+
+int allow_connect_start(void);
+void connect_start(void);
/*----- defer.c -----*/
void poll_backlog_file(void);
+void search_backlog_file(void);
+void open_defer(void);
+void close_defer(void);
+
+/*----- filemon.c -----*/
+
+int filemon_method_init(void);
+void filemon_method_dump_info(FILE *f);
+
+void filemon_start(InputFile *ipf);
+void filemon_stop(InputFile *ipf);
/*----- infile.c -----*/
void filepoll(void);
+void inputfile_reading_start(InputFile *ipf);
+void inputfile_reading_stop(InputFile *ipf);
+void inputfile_reading_pause(InputFile *ipf);
+void inputfile_reading_resume(InputFile *ipf);
+ /* pause and resume are idempotent, and no-op if not done _reading_start */
+
+InputFile *open_input_file(const char *path);
+void close_input_file(InputFile *ipf); /* does not free */
+char *dbg_report_ipf(InputFile *ipf);
+
+void tailing_make_readable(InputFile *ipf);
+
+/*----- recv.c -----*/
+
+extern const oop_rd_style peer_rd_style;
+oop_rd_call peer_rd_ok, peer_rd_err;
+
+void article_done(Article *art, int whichcount);
+
/*----- statemc.c -----*/
-sig_atomic_t terminate_sig_flag;
+void statemc_check_flushing_done(void);
+void statemc_check_backlog_done(void);
+
+extern sig_atomic_t terminate_sig_flag;
+void statemc_period_poll(void);
+void statemc_lock(void);
+void init_signals(void);
+void statemc_init(void);
+void showstats(void);
+
+#define SMS(newstate, periods, why) \
+ (statemc_setstate(sm_##newstate,(periods),#newstate,(why)))
+void statemc_setstate(StateMachineState newsms, int periods,
+ const char *forlog, const char *why);
+
+void statemc_start_flush(const char *why); /* Normal => Flushing */
+void spawn_inndcomm_flush(const char *why); /* Moved => Flushing */
+int trigger_flush_ok(const char *why /* 0 means timeout */);
+ /* => Flushing,FLUSHING, ret 1; or ret 0 */
+
+void preterminate(void);
/*----- xmit.c -----*/
void inputfile_queue_check_expired(InputFile *ipf);
+void check_assign_articles(void);
+void queue_check_input_done(void);
+void check_reading_pause_resume(InputFile *ipf);
+
+void conn_maybe_write(Conn *conn);
+void conn_make_some_xmits(Conn *conn);
+void *conn_write_some_xmits(Conn *conn);
+
+void xmit_free(XmitDetails *d);
+
+int article_check_expired(Article *art /* must be queued, not conn */);
+void article_autodefer(InputFile *ipf, Article *art);
+void article_defer(Article *art /* not on a queue */, int whichcount);
+void autodefer_input_file(InputFile *ipf);
/*----- external linkage for debug/dump only -----*/
-pid_t connecting_child;
-pid_t inndcomm_child;
+extern pid_t connecting_child;
+extern int connecting_fdpass_sock;
+extern pid_t inndcomm_child;
/*========== general operational variables ==========*/
-/* innduct.c */
+/* duct.c */
extern oop_source *loop;
extern ConnList conns;
extern char *path_lock, *path_flushing, *path_defer, *path_dump;
extern int *lowvol_perperiod;
extern int lowvol_circptr;
extern int lowvol_total; /* does not include current period */
+extern int until_stats_log;
/* statemc.c */
extern StateMachineState sms;