1 /* $Id: innd.h 7858 2008-06-05 18:51:20Z iulius $
3 ** Many of the data types used here have abbreviations, such as CT
4 ** for CHANNELTYPE. Here are a list of the conventions and meanings:
10 ** FNL Funnel, into which other feeds pour
11 ** FT Feed type -- how a site gets told about new articles
12 ** ICD In-core data (primarily the active and sys files)
13 ** LC Local NNTP connection-receiving channel
14 ** CC Control channel (used by ctlinnd)
15 ** NC NNTP client channel
17 ** NGH Newgroup hashtable
18 ** PROC A process (used to feed a site)
20 ** RC Remote NNTP connection-receiving channel
21 ** RCHAN A channel in "read" state
22 ** SITE Something that gets told when we get an article
23 ** WCHAN A channel in "write" state
24 ** WIP Work-In-Progress, keeps track of articles before committed.
31 #include "portable/time.h"
32 #include "portable/socket.h"
40 #include "inn/buffer.h"
41 #include "inn/history.h"
42 #include "inn/messages.h"
43 #include "inn/timer.h"
49 /* TCL defines EXTERN, so undef it after inclusion since we use it. */
57 typedef short SITEIDX;
58 #define NOSITE ((SITEIDX) -1)
64 /* Used for storing group subscriptions for feeds. */
65 #define SUB_DEFAULT false
66 #define SUB_NEGATE '!'
67 #define SUB_POISON '@'
69 /* Special characters for newsfeeds entries. */
70 #define NF_FIELD_SEP ':'
71 #define NF_SUBFIELD_SEP '/'
75 ** Server's operating mode.
77 typedef enum _OPERATINGMODE {
84 typedef struct _LISTBUFFER {
92 ** What program to handoff a connection to.
94 typedef enum _HANDOFF {
103 typedef enum _ARTHEADERTYPE {
104 HTreq, /* Drop article if this is missing */
105 HTobs, /* obsolete header but keep untouched */
106 HTstd, /* Standard optional header */
107 HTsav /* Save header, but may be deleted from article */
112 ** Entry in the header table.
114 typedef struct _ARTHEADER {
117 int Size; /* Length of Name. */
124 typedef struct _HDRCONTENT {
125 char * Value; /* don't copy, shows where it begins */
126 int Length; /* Length of Value(tailing CRLF is not
127 included. -1 if duplicated */
132 ** A way to index into the header table.
134 #define HDR_FOUND(_x) (hc[(_x)].Length > 0)
135 #define HDR_PARSE_START(_x) hc[(_x)].Value[hc[_x].Length] = '\0'
136 #define HDR(_x) (hc[(_x)].Value)
137 /* HDR_LEN does not includes trailing "\r\n" */
138 #define HDR_LEN(_x) (hc[(_x)].Length)
139 #define HDR_PARSE_END(_x) hc[(_x)].Value[hc[_x].Length] = '\r'
142 #define HDR__APPROVED 0
143 #define HDR__CONTROL 1
145 #define HDR__DISTRIBUTION 3
146 #define HDR__EXPIRES 4
149 #define HDR__MESSAGE_ID 7
150 #define HDR__NEWSGROUPS 8
152 #define HDR__REPLY_TO 10
153 #define HDR__SENDER 11
154 #define HDR__SUBJECT 12
155 #define HDR__SUPERSEDES 13
156 #define HDR__BYTES 14
157 #define HDR__ALSOCONTROL 15
158 #define HDR__REFERENCES 16
160 #define HDR__KEYWORDS 18
161 #define HDR__XTRACE 19
162 #define HDR__DATERECEIVED 20
163 #define HDR__POSTED 21
164 #define HDR__POSTINGVERSION 22
165 #define HDR__RECEIVED 23
166 #define HDR__RELAYVERSION 24
167 #define HDR__NNTPPOSTINGHOST 25
168 #define HDR__FOLLOWUPTO 26
169 #define HDR__ORGANIZATION 27
170 #define HDR__CONTENTTYPE 28
171 #define HDR__CONTENTBASE 29
172 #define HDR__CONTENTDISPOSITION 30
173 #define HDR__XNEWSREADER 31
174 #define HDR__XMAILER 32
175 #define HDR__XNEWSPOSTER 33
176 #define HDR__XCANCELLEDBY 34
177 #define HDR__XCANCELEDBY 35
178 #define HDR__CANCELKEY 36
179 #define HDR__USER_AGENT 37
180 #define HDR__X_ORIGINAL_MESSAGE_ID 38
181 #define HDR__CANCEL_LOCK 39
182 #define HDR__CONTENT_TRANSFER_ENCODING 40
184 #define HDR__INJECTION_INFO 42
185 #define HDR__LIST_ID 43
186 #define HDR__MIME_VERSION 44
187 #define HDR__ORIGINATOR 45
188 #define HDR__X_AUTH 46
189 #define HDR__X_COMPLAINTS_TO 47
190 #define HDR__X_FACE 48
191 #define HDR__X_HTTP_USERAGENT 49
192 #define HDR__X_HTTP_VIA 50
193 #define HDR__X_MODBOT 51
194 #define HDR__X_MODTRACE 52
195 #define HDR__X_NO_ARCHIVE 53
196 #define HDR__X_ORIGINAL_TRACE 54
197 #define HDR__X_ORIGINATING_IP 55
198 #define HDR__X_PGP_KEY 56
199 #define HDR__X_PGP_SIG 57
200 #define HDR__X_POSTER_TRACE 58
201 #define HDR__X_POSTFILTER 59
202 #define HDR__X_PROXY_USER 60
203 #define HDR__X_SUBMISSIONS_TO 61
204 #define HDR__X_USENET_PROVIDER 62
205 #define HDR__IN_REPLY_TO 63
206 #define HDR__INJECTION_DATE 64
207 #define HDR__NNTP_POSTING_DATE 65
209 #define MAX_ARTHEADER 66
212 ** Miscellaneous data we want to keep on an article. All the fields
213 ** are not always valid.
215 typedef struct _ARTDATA {
216 int Body; /* where body begins in article
217 it indicates offset from bp->Data */
218 char * Poster; /* Sender otherwise From in article */
219 char * Replyto; /* Reply-To otherwise From in article */
220 time_t Posted; /* when article posted */
221 time_t Arrived; /* when article arrived */
222 time_t Expires; /* when article should be expired */
223 int Lines; /* number of body lines */
224 int HeaderLines; /* number of header lines */
225 long BytesValue; /* size of stored article, "\r\n" is
227 char Bytes[16]; /* generated Bytes header */
228 int BytesLength; /* generated Bytes header length */
229 char * BytesHeader; /* where Bytes header begins in
231 char TokenText[(sizeof(TOKEN) * 2) + 3];
232 /* token of stored article */
233 LISTBUFFER Newsgroups; /* newsgroup list */
234 int Groupcount; /* number of newsgroups */
235 int Followcount; /* number of folloup to newsgroups */
236 char * Xref; /* generated Xref header */
237 int XrefLength; /* generated Xref header length */
238 int XrefBufLength; /* buffer length of generated Xref
240 LISTBUFFER Distribution; /* distribution list */
241 const char * Feedsite; /* who gives me this article */
242 int FeedsiteLength; /* length of Feedsite */
243 LISTBUFFER Path; /* path name list */
244 int StoredGroupLength; /* 1st newsgroup name in Xref */
245 char * Replic; /* replication data */
246 int ReplicLength; /* length of Replic */
247 HASH * Hash; /* Message-ID hash */
248 struct buffer Headers; /* buffer for headers which will be sent
250 struct buffer Overview; /* buffer for overview data */
251 int CRwithoutLF; /* counter for '\r' without '\n' */
252 int LFwithoutCR; /* counter for '\n' without '\r' */
253 long CurHeader; /* where current header starts.
254 this is used for folded header
255 it indicates offset from bp->Data */
256 bool NullHeader; /* contains NULL in current header */
257 long LastTerminator; /* where last '.' exists. only set if
258 it exists at the begining of line
259 it indicates offset from bp->Data */
260 long LastCR; /* where last CR exists
261 it indicates offset from bp->Data */
262 long LastCRLF; /* where last CRLF exists.
263 indicates where last LF exists
264 it indicates offset from bp->Data */
265 HDRCONTENT HdrContent[MAX_ARTHEADER];
266 /* includes system headers info */
267 bool AddAlias; /* Whether Pathalias should be added
269 bool Hassamepath; /* Whether this article matches Path */
270 bool Hassamecluster; /* Whether this article matches
275 ** Set of channel types.
277 typedef enum _CHANNELTYPE {
292 ** The state a channel is in. Interpretation of this depends on the
293 ** channel's type. Used mostly by CTnntp channels.
295 typedef enum _CHANNELSTATE {
314 #define SAVE_AMT 10 /* used for eating article/command */
317 ** I/O channel, the heart of the program. A channel has input and output
318 ** buffers, and functions to call when there is input to be read, or when
319 ** all the output was been written. Many callback functions take a
320 ** pointer to a channel, so set up a typedef for that.
322 #define PRECOMMITCACHESIZE 128
324 typedef void (*innd_callback_t)(struct _CHANNEL *);
326 typedef struct _CHANNEL {
335 unsigned long Duplicate;
336 unsigned long Unwanted_s;
337 unsigned long Unwanted_f;
338 unsigned long Unwanted_d;
339 unsigned long Unwanted_g;
340 unsigned long Unwanted_u;
341 unsigned long Unwanted_o;
345 unsigned long Check_send;
346 unsigned long Check_deferred;
347 unsigned long Check_got;
348 unsigned long Check_cybercan;
349 unsigned long Takethis;
350 unsigned long Takethis_Ok;
351 unsigned long Takethis_Err;
353 unsigned long Ihave_Duplicate;
354 unsigned long Ihave_Deferred;
355 unsigned long Ihave_SendIt;
356 unsigned long Ihave_Cybercan;
367 struct sockaddr_storage Address;
368 innd_callback_t Reader;
369 innd_callback_t WriteDone;
372 innd_callback_t Waker;
378 struct buffer Sendid;
379 HASH CurrentMessageIDHash;
380 struct _WIP * PrecommitWIP[PRECOMMITCACHESIZE];
381 int PrecommitiCachenext;
390 long Start; /* where current cmd/article starts
391 it indicates offset from bp->Data */
392 long Next; /* next pointer to read
393 it indicates offset from bp->Data */
394 char Error[SMBUF]; /* error buffer */
395 ARTDATA Data; /* used for processing article */
396 struct _CHANNEL *nextcp; /* linked list for each incoming site */
399 #define DEFAULTNGBOXSIZE 64
402 ** A newsgroup has a name in different formats, and a high-water count,
403 ** also kept in different formats. It also has a list of sites that
406 typedef struct _NEWSGROUP {
407 long Start; /* Offset into the active file */
411 ARTNUM Filenum; /* File name to use */
413 int PostCount; /* Have we already put it here? */
415 char * Rest; /* Flags, NOT NULL TERMINATED */
420 struct _NEWSGROUP * Alias;
425 ** How a site is fed.
427 typedef enum _FEEDTYPE {
439 ** Diablo-style hashed feeds or hashfeeds.
441 #define HASHFEED_QH 1
442 #define HASHFEED_MD5 2
444 typedef struct _HASHFEEDLIST {
450 struct _HASHFEEDLIST *next;
455 ** A site may reject something in its subscription list if it has
456 ** too many hops, or a bad distribution.
458 typedef struct _SITE {
463 char ** Distributions;
473 bool DontWantNonExist;
474 bool NeedOverviewCreation;
475 bool FeedwithoutOriginator;
490 char FileFlags[FEED_MAXFLAGS + 1];
499 struct buffer FNLnames;
503 struct buffer Buffer;
506 HASHFEEDLIST * HashFeedList;
513 ** A process is something we start up to send articles.
515 typedef enum _PROCSTATE {
523 ** We track our children and collect them synchronously.
525 typedef struct _PROCESS {
535 ** A work in progress entry, an article that we've been offered but haven't
538 typedef struct _WIP {
539 HASH MessageID; /* Hash of the messageid. Doing it like
540 this saves us from haveing to allocate
541 and deallocate memory a lot, and also
542 means lookups are faster. */
543 time_t Timestamp; /* Time we last looked at this MessageID */
544 CHANNEL *Chan; /* Channel that this message is associated
546 struct _WIP *Next; /* Next item in this bucket */
550 ** Supported timers. If you add new timers to this list, also add them to
551 ** the list of tags in chan.c.
554 TMR_IDLE = TMR_APPLICATION, /* Server is completely idle. */
555 TMR_ARTCLEAN, /* Analyzing an incoming article. */
556 TMR_ARTWRITE, /* Writing an article. */
557 TMR_ARTCNCL, /* Processing a cancel message. */
558 TMR_SITESEND, /* Sending an article to feeds. */
559 TMR_OVERV, /* Generating overview information. */
560 TMR_PERL, /* Perl filter. */
561 TMR_PYTHON, /* Python filter. */
562 TMR_NNTPREAD, /* Reading NNTP data from the network. */
563 TMR_ARTPARSE, /* Parsing an article. */
564 TMR_ARTLOG, /* Logging article disposition. */
565 TMR_DATAMOVE, /* Moving data. */
572 ** In-line macros for efficiency.
574 ** Set or append data to a channel's output buffer.
576 #define WCHANset(cp, p, l) buffer_set(&(cp)->Out, (p), (l))
577 #define WCHANappend(cp, p, l) buffer_append(&(cp)->Out, (p), (l))
580 ** Mark that an I/O error occurred, and block if we got too many.
582 #define IOError(WHEN, e) \
584 if (--ErrorCount <= 0 || (e) == ENOSPC) \
585 ThrottleIOError(WHEN); \
592 ** Do not change "extern" to "EXTERN" in the Global data. The ones
593 ** marked with "extern" are initialized in innd.c. The ones marked
594 ** with "EXTERN" are not explicitly initialized in innd.c.
596 #if defined(DEFINE_DATA)
597 # define EXTERN /* NULL */
599 # define EXTERN extern
601 extern const ARTHEADER ARTheaders[MAX_ARTHEADER];
602 extern bool BufferedLogs;
603 EXTERN bool AnyIncoming;
605 EXTERN bool ICDneedsetup;
606 EXTERN bool NeedHeaders;
607 EXTERN bool NeedOverview;
608 EXTERN bool NeedPath;
609 EXTERN bool NeedStoredGroup;
610 EXTERN bool NeedReplicdata;
611 extern bool NNRPTracing;
612 extern bool StreamingOff;
614 EXTERN struct buffer Path;
615 EXTERN struct buffer Pathalias;
616 EXTERN struct buffer Pathcluster;
617 EXTERN char * ModeReason; /* NNTP reject message */
618 EXTERN char * NNRPReason; /* NNRP reject message */
619 EXTERN char * Reservation; /* Reserved lock message */
620 EXTERN char * RejectReason; /* NNTP reject message */
621 EXTERN FILE * Errlog;
623 extern char LogName[];
624 extern int ErrorCount;
625 EXTERN int ICDactivedirty;
626 EXTERN int MaxOutgoing;
628 EXTERN SITEIDX nSites;
629 EXTERN int PROCneedscan;
630 EXTERN NEWSGROUP ** GroupPointers;
631 EXTERN NEWSGROUP * Groups;
632 extern OPERATINGMODE Mode;
633 EXTERN sig_atomic_t GotTerminate;
636 EXTERN struct timeval TimeOut;
637 EXTERN TIMEINFO Now; /* Reasonably accurate time */
638 EXTERN bool ThrottledbyIOError;
639 EXTERN char * NCgreeting;
640 EXTERN struct history *History;
643 ** Table size for limiting incoming connects. Do not change the table
644 ** size unless you look at the code manipulating it in rc.c.
646 #define REMOTETABLESIZE 128
649 ** Setup the default values. The REMOTETIMER being zero turns off the
650 ** code to limit incoming connects.
652 #define REMOTELIMIT 2
653 #define REMOTETIMER 0
654 #define REMOTETOTAL 60
655 #define REJECT_TIMEOUT 10
656 extern int RemoteLimit; /* Per host limit. */
657 extern time_t RemoteTimer; /* How long to remember connects. */
658 extern int RemoteTotal; /* Total limit. */
662 ** Function declarations.
664 extern void InndHisOpen(void);
665 extern void InndHisClose(void);
666 extern bool InndHisWrite(const char *key, time_t arrived,
667 time_t posted, time_t expires,
669 extern bool InndHisRemember(const char *key);
670 extern void InndHisLogStats(void);
671 extern bool FormatLong(char *p, unsigned long value, int width);
672 extern bool NeedShell(char *p, const char **av, const char **end);
673 extern char ** CommaSplit(char *text);
674 extern void SetupListBuffer(int size, LISTBUFFER *list);
675 extern char * MaxLength(const char *p, const char *q);
676 extern pid_t Spawn(int niceval, int fd0, int fd1, int fd2,
678 extern void CleanupAndExit(int x, const char *why);
679 extern void FileGlue(char *p, const char *n1, char c, const char *n2);
680 extern void JustCleanup(void);
681 extern void ThrottleIOError(const char *when);
682 extern void ThrottleNoMatchError(void);
683 extern void ReopenLog(FILE *F);
684 extern void xchown(char *p);
686 extern bool ARTidok(const char *MessageID);
687 extern bool ARTreadschema(void);
688 extern const char * ARTreadarticle(char *files);
689 extern char * ARTreadheader(char *files);
690 extern bool ARTpost(CHANNEL *cp);
691 extern void ARTcancel(const ARTDATA *Data,
692 const char *MessageID, bool Trusted);
693 extern void ARTclose(void);
694 extern void ARTsetup(void);
695 extern void ARTprepare(CHANNEL *cp);
696 extern void ARTparse(CHANNEL *cp);
698 extern bool CHANsleeping(CHANNEL *cp);
699 extern CHANNEL * CHANcreate(int fd, CHANNELTYPE Type,
701 innd_callback_t Reader,
702 innd_callback_t WriteDone);
703 extern CHANNEL * CHANiter(int *cp, CHANNELTYPE Type);
704 extern CHANNEL * CHANfromdescriptor(int fd);
705 extern char * CHANname(const CHANNEL *cp);
706 extern int CHANreadtext(CHANNEL *cp);
707 extern void CHANclose(CHANNEL *cp, const char *name);
708 extern void CHANreadloop(void);
709 extern void CHANsetup(int i);
710 extern void CHANshutdown(void);
711 extern void CHANtracing(CHANNEL *cp, bool Flag);
712 extern void CHANsetActiveCnx(CHANNEL *cp);
714 extern void RCHANadd(CHANNEL *cp);
715 extern void RCHANremove(CHANNEL *cp);
717 extern void SCHANadd(CHANNEL *cp, time_t Waketime, void *Event,
718 innd_callback_t Waker, void *Argument);
719 extern void SCHANremove(CHANNEL *cp);
720 extern void SCHANwakeup(void *Event);
722 extern bool WCHANflush(CHANNEL *cp);
723 extern void WCHANadd(CHANNEL *cp);
724 extern void WCHANremove(CHANNEL *cp);
725 extern void WCHANsetfrombuffer(CHANNEL *cp, struct buffer *bp);
727 extern void CCcopyargv(char *av[]);
728 extern const char * CCaddhist(char *av[]);
729 extern const char * CCblock(OPERATINGMODE NewMode, char *reason);
730 extern const char * CCcancel(char *av[]);
731 extern const char * CCcheckfile(char *av[]);
733 extern bool ICDnewgroup(char *Name, char *Rest);
734 extern char * ICDreadactive(char **endp);
735 extern bool ICDchangegroup(NEWSGROUP *ngp, char *Rest);
736 extern void ICDclose(void);
737 extern bool ICDrenumberactive(void);
738 extern bool ICDrmgroup(NEWSGROUP *ngp);
739 extern void ICDsetup(bool StartSites);
740 extern void ICDwrite(void);
741 extern void ICDwriteactive(void);
743 extern void CCclose(void);
744 extern void CCsetup(void);
746 extern void KEYgenerate(HDRCONTENT *, const char *body,
747 const char *orig, size_t length);
749 extern void LCclose(void);
750 extern void LCsetup(void);
752 extern int NGsplit(char *p, int size, LISTBUFFER *List);
753 extern NEWSGROUP * NGfind(const char *Name);
754 extern void NGclose(void);
755 extern CHANNEL * NCcreate(int fd, bool MustAuthorize, bool IsLocal);
756 extern void NGparsefile(void);
757 extern bool NGrenumber(NEWSGROUP *ngp);
758 extern bool NGlowmark(NEWSGROUP *ngp, long lomark);
760 extern void NCclearwip(CHANNEL *cp);
761 extern void NCclose(void);
762 extern void NCsetup(void);
763 extern void NCwritereply(CHANNEL *cp, const char *text);
764 extern void NCwriteshutdown(CHANNEL *cp, const char *text);
767 extern char * PLartfilter(const ARTDATA *Data, char *artBody, long artLen, int lines);
768 extern char * PLmidfilter(char *messageID);
769 extern void PLmode(OPERATINGMODE mode, OPERATINGMODE NewMode,
771 extern char * PLstats(void);
772 extern void PLxsinit(void);
774 extern int PROCwatch(pid_t pid, int site);
775 extern void PROCunwatch(int process);
776 /* extern void PROCclose(bool Quickly); */
777 extern void PROCscan(void);
778 extern void PROCsetup(int i);
780 extern int RClimit(CHANNEL *cp);
781 extern bool RCnolimit(CHANNEL *cp);
782 extern bool RCauthorized(CHANNEL *cp, char *pass);
783 extern int RCcanpost(CHANNEL *cp, char *group);
784 extern char * RChostname(const CHANNEL *cp);
785 extern char * RClabelname(CHANNEL *cp);
786 extern void RCclose(void);
787 extern void RChandoff(int fd, HANDOFF h);
788 extern void RCreadlist(void);
789 extern void RCsetup(int i);
791 extern bool SITEfunnelpatch(void);
792 extern bool SITEsetup(SITE *sp);
793 extern bool SITEwantsgroup(SITE *sp, char *name);
794 extern bool SITEpoisongroup(SITE *sp, char *name);
795 extern char ** SITEreadfile(const bool ReadOnly);
796 extern SITE * SITEfind(const char *p);
797 extern SITE * SITEfindnext(const char *p, SITE *sp);
798 extern const char * SITEparseone(char *Entry, SITE *sp,
799 char *subbed, char *poison);
800 extern void SITEchanclose(CHANNEL *cp);
801 extern void SITEdrop(SITE *sp);
802 extern void SITEflush(SITE *sp, const bool Restart);
803 extern void SITEflushall(const bool Restart);
804 extern void SITEforward(SITE *sp, const char *text);
805 extern void SITEfree(SITE *sp);
806 extern void SITEinfo(struct buffer *bp, SITE *sp, bool Verbose);
807 extern void SITEparsefile(bool StartSite);
808 extern void SITEprocdied(SITE *sp, int process, PROCESS *pp);
809 extern void SITEsend(SITE *sp, ARTDATA *Data);
810 extern void SITEwrite(SITE *sp, const char *text);
812 extern void STATUSinit(void);
813 extern void STATUSmainloophook(void);
815 extern void WIPsetup(void);
816 extern WIP * WIPnew(const char *messageid, CHANNEL *cp);
817 extern void WIPprecomfree(CHANNEL *cp);
818 extern void WIPfree(WIP *wp);
819 extern bool WIPinprogress(const char *msgid, CHANNEL *cp,
821 extern WIP * WIPbyid(const char *mesageid);
822 extern WIP * WIPbyhash(const HASH hash);
825 ** TCL globals and functions
828 extern Tcl_Interp * TCLInterpreter;
829 extern bool TCLFilterActive;
830 extern struct buffer * TCLCurrArticle;
831 extern ARTDATA * TCLCurrData;
833 extern void TCLfilter(bool value);
834 extern void TCLreadfilter(void);
835 extern void TCLsetup(void);
836 extern void TCLclose(void);
840 ** Python globals and functions
843 extern bool PythonFilterActive;
845 void PYfilter(bool value);
846 extern const char * PYcontrol(char **av);
847 extern int PYreadfilter(void);
848 extern char * PYartfilter(const ARTDATA *Data, char *artBody, long artLen, int lines);
849 extern char * PYmidfilter(char *messageID, int msglen);
850 extern void PYmode(OPERATINGMODE mode, OPERATINGMODE newmode,
852 extern void PYsetup(void);
853 extern void PYclose(void);
854 #endif /* DO_PYTHON */