/*
 * DEFS.H
 *
 *
 *
 * (c)Copyright 1997, Matthew Dillon, All Rights Reserved.  Refer to
 *    the COPYRIGHT file in the base directory of this distribution
 *    for specific rights granted.
 *
 * Modified 12/4/1997 to include support for compressed data streams.
 * Modifications (c) 1997, Christopher M Sedore, All Rights Reserved.
 * Modifications may be distributed freely as long as this copyright
 * notice is included without modification.
 *
 */

#include "config.h"

#include <sys/types.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/socket.h>		/* internet sockets	*/
#include <sys/un.h>		/* unix domain sockets	*/
#include <sys/mman.h>		/* mmap()		*/
#ifdef _AIX
#include <sys/select.h>
#endif
#if USE_SYSV_DIR
#include <dirent.h>
typedef struct dirent den_t;
#else
#include <sys/dir.h>
typedef struct direct den_t;
#endif
#include <netinet/in.h>		/* internet sockets	*/
#include <netinet/tcp.h>	/* TCP_NODELAY sockopt  */
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <utime.h>

#if USE_BSTRING_H
#include <bstring.h>
#endif

#if HAS_PROC_TITLE
#include <libutil.h>
#endif

#if USE_POLL
#include <poll.h>		/* poll()		*/
#endif

#if USE_PCOMMIT_SHM || USE_SPAM_SHM || USE_CANCEL_SHM
#include <sys/ipc.h>		/* SYSV shared memory	*/
#include <sys/shm.h>		/* SYSV shared memory	*/
#endif

#include <stdarg.h>
#include <stddef.h>
#if USE_STRINGS_H
#include <strings.h>
#endif
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <netdb.h>		/* internet sockets	*/
#include <arpa/inet.h>
#include <signal.h>
#include <syslog.h>
#include <pwd.h>
#include <grp.h>
#include <math.h>
#include <fcntl.h>

#ifdef	POST_HIDENNTPPOSTHOST
#include	<md5.h>
#endif
#ifdef	POST_CRYPTXTRACE
#if __FreeBSD_version > 470100
#include        <openssl/des.h>
#else
#include	<des.h>
#endif
#endif
#ifdef	NETREMOTE_ENABLED
#if __FreeBSD_version > 470100
#include        <openssl/des.h>
#else
#include	<des.h>
#endif
#endif
#ifdef	RADIUS_ENABLED
#include	<radlib.h>
#endif
#ifdef	USE_ZLIB
#include	<zlib.h>
#endif

typedef signed char	int8;
typedef short		int16;
typedef int		int32;
typedef unsigned char	uint8;
typedef unsigned short	uint16;
typedef unsigned int	uint32;

#define Prototype extern
#define arysize(ary)	(sizeof(ary)/sizeof((ary)[0]))

/*
 * diablo.config
 */

#define HASH_PRIME	0
#define HASH_CRC	1
#define HASH_OCRC	2

#define	CONF_FEEDER	0x01
#define	CONF_READER	0x02

/*
 * The read group name hash type
 * This cannot be > 9. 10+ are used for directory numbers
 */
#define	HASHGRP_NONE	0
#define	HASHGRP_CRC	1
#define	HASHGRP_32MD5	2
#define	HASHGRP_64MD5	3
#define	HASHGRP_HIER	4

#define HASHGRPTYPE_OVER	0x1000
#define HASHGRPTYPE_DATA	0x2000

#define	GRPFTYPE_OVER	0
#define	GRPFTYPE_DATA	1

#define	HASHGRP_DIR_NUM	1	/* Dirs per level specified as a number */
#define	HASHGRP_DIR_BIT	2	/* Dirs per level specified as bytes of hash */

typedef struct GroupHashType {
    int	gh_type;		/* The HASHGRP_ type */
    int gh_sigbytes;		/* Number of significant hash bytes */
    int gh_dirtype;		/* Algorithm for choosing dirs per level */
    int gh_dirlvl;		/* Directory levels */
    int gh_dirinfo[10];		/* Number of directories per level */
} GroupHashType;

#define ACTIVE_OFF	0
#define ACTIVE_ON	1

typedef struct PathListType {
    char *pathent;
    int pathtype;
    struct PathListType *next;
} PathListType;

typedef struct CacheDirType {
	int dt_dirlvl;		/* Directory levels */
	int dt_dirinfo[10];	/* Number of dirs per level */
} CacheDirType;

typedef struct BindList {
    struct BindList *bl_Next;
    char        *bl_Port;
    char        *bl_Host;
} BindList;

struct DiabloOpts {
    int HashMethod;
    int HashSize;
    int CompatHashMethod;
    int FeederXRefSlave;
    int FeederXRefSync;
    int FeederActiveEnabled;
    int FeederActiveDrop;
    int FeederAutoAddToActive;
    int FeederRTStats;
    int ReaderForks;
    int ReaderThreads;
    int ReaderFeedForks;
    int ReaderDns;
    int ReaderCacheMode;
    int ReaderCacheHashSize;
    int ReaderXOverMode;
    int ReaderAutoAddToActive;
    int ReaderDetailLog;
    int RememberSecs;
    int FeederMaxAcceptAge;
    int MaxPerRemote;
    int HostCacheRebuildTime;
    int DisplayAdminVersion;
    int RejectArtsWithNul;
    int FeederBufferSize;
    int FeederMaxArtSize;
    int ReaderMaxArtSize;
    int WireFormat;
    int FeederArtTypes;
    int FeederPreloadArt;
    int SpoolPreloadArt;
    char *SpamFilterOpt;
    char *FeederPathHost;
    char *FeederXRefHost;
    char *FeederHostName;
    char *FeederFilter;
    char *ReaderXRefHost;
    char *ReaderXRefSlaveHost;
    char *ReaderPathHost;
    char *ReaderHostName;
    char *ReaderCrashHandler;
    char *NewsAdmin;
    char *NewsMaster;
    PathListType *PathList;
    char *FeederBindHost;
    char *FeederPort;
    char *ReaderBindHost;
    char *ReaderPort;
    char *ReaderBan;
    CacheDirType ReaderCacheDirs;
    GroupHashType ReaderGroupHashMethod;
    char *PgpVerifyArgs[10];
} DiabloOpts;

/*
 * History
 */

typedef struct {
    int32	h1;
    int32	h2;
} hash_t;

typedef struct {
    uint64_t    h1;
    uint64_t    h2;
} md5hash_t;

typedef struct HistHead {
    uint32	hmagic;		/* 0xA1B2C3D4			*/
    uint32	hashSize;	/* entries in hash table	*/
    uint16	version;	/* version of history file	*/
    uint16	henSize;	/* size of history entry	*/
    uint16	headSize;	/* size of history header	*/
} HistHead;

#define HMAGIC		((uint32)0xA1B2C3D4)
#define HDEADMAGIC	((uint32)0xDEADF5E6)
#define HVERSION	2

/*
 * Dreaderd cache scoreboard
 *
 * cache consist of :
 * - an header (CacheHitHead)
 * - an hash (uint32[chh_hashSize]) pointing to a list of CacheHitEntry
 * - entries (CacheHitEntry)
 */

#define CHMAGIC		((uint32)0xD1C2B3A4)
#define CHVERSION	1

typedef struct CacheHitHead {
    uint32	chh_magic;	/* 0xD1C2B3A4			*/
    uint32	chh_version;	/* version of scoreboard	*/
    uint32	chh_hashSize;	/* entries in hash table	*/
    uint32	chh_newEntry;	/* next entry to add		*/
    uint32	chh_end;	/* number of byte in mmap	*/
    time_t	chh_lastExpired; /* last expiration date	*/
} CacheHitHead;

typedef struct CacheHash_t {		/* hash key for scoreboad cache	*/
    uint64_t    h1;
    uint64_t    h2;
    int		iter;
} CacheHash_t;

typedef struct CacheHitEntry {
    struct CacheHitHead	che_hash; /* group hash			*/
    uint32	che_Next;	/* linking entries		*/
    int		che_ReadArt;	/* number of read articles	*/
    uint32	che_Hits;	/* number of cache hits		*/
    uint32	che_LastHi;	/* to compute number of new articles */
    uint32	che_NewArt;	/* number of new articles */
} CacheHitEntry;

/*
 * History file entry.  The filename is calculated from the gmt start
 * (calculates the directory), and file id.  Each incoming process
 * allocates its own file & id and appends to it.
 *
 * The exp value is:
 *  0		= instant-expired
 *  1 - 100	= expire slot
 *  101 - 200	= spool partition
 *  0x1000	= unused
 *  0x2000	= unused
 *  0x4000	= expired/rejected
 *  0x8000	= header-only
 *
 *  h.iter == -1 for rejected articles
 */

typedef uint32  HistIndex;

typedef struct History {
    HistIndex 	next;		/* next link			*/
    uint32	gmt;		/* expire slot number		*/
    hash_t	hv;		/* hash value			*/
    uint16 	iter;		/* file id 			*/
    uint16	exp;		/* hours relative to gmt minutes */
    uint32	boffset;	/* starting offset in file	*/
    int32	bsize;		/* size of article		*/
} History;

#define EXPF_HEADONLY	0x8000	/* header-only flag (in exp field) */
#define EXPF_EXPIRED	0x4000
#define EXPF_FLAGS	0x0FFF
#define H_NOFLAGS(n)	((uint16)((n) & EXPF_FLAGS))
#define H_EXPIRED(n)	((uint16)((n) & EXPF_EXPIRED))
#define H_SPOOL(n)      ((uint16)(H_NOFLAGS(n) > 100 && H_NOFLAGS(n) < 500 ? \
				H_NOFLAGS(n) - 100 : 0))


/*
 * Internal spamfilter
 */

typedef struct SpamInfo {
    md5hash_t	BodyHash;
    char	*PostingHost;
    md5hash_t	PostingHostHash;
    int		Lines;
    char	*MsgId;
    hash_t	MsgIdHash;
} SpamInfo;

/*
 * Pre/PostCommit cache
 */

#define PC_PRECOMM		0x001
#define PC_POSTCOMM		0x002
#define PC_DELCOMM		0x004

/*
 * Article header - prepended to all articles written to the spool.
 *
 * All articles on spool consist of:
 *	SpoolArtHdr
 *	Article
 *	Nul
 *
 *	SpoolArtHdr.StoreLen = SpoolArtHdr + Article + Nul
 *	SpoolArtHdr.HeadLen  = SpoolArtHdr
 *	SpoolArtHdr.ArtLen   = Article
 */

#define	STORE_MAGIC1		0xff
#define	STORE_MAGIC2		0x99

#define	STOREAPI_REVISION	1

#define	STORETYPE_TEXT		0x01
#define	STORETYPE_GZIP		0x02
#define	STORETYPE_WIRE		0x04

typedef struct SpoolArtHdr {
    uint8 Magic1;
    uint8 Magic2;
    uint8 Version;
    uint8 HeadLen;		/* Length of this header */
    uint8 StoreType;
    uint32 ArtHdrLen;		/* Size of stored article header */
    uint32 ArtLen;		/* Total article size (including \r\n) */
    uint32 StoreLen;		/* Size of article on disk */
    uint8 HdrEnd;		/* Nul */
} SpoolArtHdr;

/*
 * FeedValid()
 */

#define FEED_VALID		0
#define FEED_MAXCONNECT		-1
#define FEED_MISSINGLABEL	-2

#define OD_HARTS        256     /* modulo for data files, POWER OF 2    */
#define OD_HMASK        (OD_HARTS-1)

/*
 * Newsfeed stuff
 */

#define	MAXSTREAM	16	/* Minimum is 2 */

typedef struct NewslinkInfo {
    char		*li_HostName;
    int			li_Port;		/* 0 = default NNTP */
    int			li_StartDelay;
    int			li_TransmitBuf;
    int			li_ReceiveBuf;
    int			li_QoS;			/* 0 = default, don't set it */
    char		*li_BindAddress;
    int			li_MaxParallel;
    int			li_NoStream;
    int			li_DelayFeed;
    int			li_DelayInFeed;
    int			li_RealTime;
    int			li_Notify;
    int			li_MaxQueueFile;
    int			li_HeadFeed;
    int			li_PreserveBytes;
    int			li_GenLines;
    int			li_Check;
    int			li_MaxStream;
    int			li_Priority;
    int			li_Compress;
    int			li_QueueSkip;
    int			li_ArticleStat;
    char		*li_LogArts;
    char		*li_Hours;
} NewslinkInfo;

typedef struct LabelList {
    char		*label;
    struct LabelList	*next;
} LabelList;

typedef struct ArtTypeList {
    int			arttype;
    int			negate;
    struct ArtTypeList	*next;
} ArtTypeList;

typedef struct HashFeed {
    int			hf_Begin;		/* hashfeed begin-range */
    int			hf_End;			/* hashfeed end-range */
    int			hf_Mod;			/* hashfeed mod value */
} HashFeed;

/*
 * RunProgPipe()
 */

#define RPF_STDIN	0x0001
#define RPF_STDOUT	0x0002
#define RPF_STDERR	0x0004

/*
 *  Parameters for ArticleFileName()
 */
#define	ARTFILE_DIR		0x01
#define	ARTFILE_FILE		0x02
#define	ARTFILE_DIR_REL		0x04
#define	ARTFILE_FILE_REL	0x08

#define HGF_FAST	0x01
#define HGF_NOSEARCH	0x02
#define HGF_MLOCK	0x03
#define HGF_READONLY	0x04
#define HGF_EXCHECK	0x08

typedef struct Node {
    struct Node		*no_Next;
    int32		no_Value;
    const char		*no_Name;
    const char		*no_Name2;
    void		*no_Data;
} Node;

#define MAXLINE		16384
#define MAXMSGIDLEN	250
#define MAXGNAME	256
#define MAXFORKS	512
#define MAXFEEDS	128
#define MAXFDS		(MAXFORKS+MAXFEEDS+32)
#define MAXDIABLOFDCACHE 8
#if MAXFDS > FD_SETSIZE
#undef MAXFDS
#define MAXFDS FD_SETSIZE
#endif

/*
 * Define a list of groups. Used when checking a newsgroup list
 */
typedef struct GroupList {
    char *group;
    struct GroupList *next;
} GroupList;   

/*
 * Spool allocation structures
 */

#define MAX_SPOOL_OBJECTS	100

/*
 * Spool allocation strategies
 */
#define SPOOL_ALLOC_NONE	0x00
#define SPOOL_ALLOC_SEQ		0x01	/* Default sequential alloc */
#define SPOOL_ALLOC_SPACE	0x02	/* Choose spool with most space free */
#define SPOOL_ALLOC_SINGLE	0x03	/* Write all feeds to a single spool */

#define	SPOOL_MAX_FILE_SIZE	1073741824	/* Max size of spool files */

/*
 * Expire methods
 */
#define EXM_SYNC		0
#define EXM_DIRSIZE		1

typedef struct SpoolObject {
    uint16		so_SpoolNum;
    double		so_MinFree;		/* bytes */
    long		so_MinFreeFiles;	/* free inodes */
    double		so_MaxSize;		/* bytes */
    long		so_KeepTime;		/* secs */
    uint32		so_DirTime;
    int			so_SpoolDirs;
    int			so_ExpireMethod;
    int			so_CompressLvl;
    char		so_Path[PATH_MAX];
    struct SpoolObject	*so_Next;
} SpoolObject;

typedef struct MetaSpool {
    char		ms_Name[32];
    double		ms_MaxSize;		/* bytes */
    int			ms_MaxCross;
    long		ms_KeepTime;		/* secs */
    ArtTypeList		*ms_ArtTypes;
    HashFeed		ms_HashFeed;
    LabelList		*ms_Label;
    int			ms_RejectArts;
    int			ms_DontStore;
    int			ms_AllocationStrategy;
    int			ms_ReAllocInterval;
    int			ms_NumSpoolObjects;
    SpoolObject		*ms_SpoolObjects[MAX_SPOOL_OBJECTS];
    SpoolObject		*ms_AllocatedSpool;
    int			ms_NextAllocation;
    struct MetaSpool	*ms_Next;
} MetaSpool;

typedef struct GroupExpire {
    char                ex_Wild[255];
    MetaSpool		*ex_MetaSpool;
    SpoolObject		*ex_AllocatedSpool;
    struct GroupExpire	*ex_Next;
} GroupExpire;

/*
 * Overview expire structure
 */
typedef struct OverExpire {
    char                oe_Wild[255];
    int                 oe_InitArts;		/* expireover */
    int                 oe_MinArts;		/* expireover */
    int                 oe_MaxArts;		/* expireover */
    double              oe_ExpireDays;		/* expireover */
    struct OverExpire	*oe_Next;
} OverExpire;

#define MAXSIMUL	5	/* maximum simultanious from same label */

#define RCOK		0	/* article accepted		*/
#define RCALREADY	1	/* we already have this article	*/
#define RCTRYAGAIN	2	/* something went wrong, requeue it for later */
#define RCREJECT	3	/* there is something wrong with your article */
#define RCERROR		4	/* an unexpected error occured  */

#define XLOCK_SH	1
#define XLOCK_EX	2
#define XLOCK_UN	3
#define XLOCK_NB	0x10

#define MAXFEEDTABLE	256

#define	RTSTATS_NONE	1
#define	RTSTATS_LABEL	2
#define	RTSTATS_HOST	3

#define	FSTATS_IN		1
#define	FSTATS_INDETAIL		2
#define	FSTATS_OUT		3
#define	FSTATS_SPOOL		4
#define	FSTATS_SPOOLDETAIL	5

typedef struct SentStats {
    time_t	TimeStart;
    time_t	DeltaStart;
    int		ConnectCnt;
    int		OfferedCnt;
    int		AcceptedCnt;
    int		RefusedCnt;
    int		RejectedCnt;
    int		DeferredCnt;
    int		DeferredFailCnt;
    double	RejectedBytes;
    double	AcceptedBytes;
    int		ConnectTotal;
    int		OfferedTotal;
    int		AcceptedTotal;
    int		RefusedTotal;
    int		RejectedTotal;
    int		DeferredTotal;
    int		DeferredFailTotal;
    double	RejectedBytesTotal;
    double	AcceptedBytesTotal;
} SentStats;

#define STATS_OTHER		0	/* dummy			*/
#define STATS_OFFERED		1	/* offered (ihave/check)	*/
#define STATS_ACCEPTED		2	/* accepted			*/
#define STATS_RECEIVED		3	/* received			*/
#define STATS_REFUSED		4	/* refused			*/
#define STATS_REF_HISTORY	5	/* ref, in history		*/
#define STATS_REF_PRECOMMIT	6	/* ref, offered by another host	*/
#define STATS_REF_POSTCOMMIT	7	/* ref, in history cache	*/
#define STATS_REF_BADMSGID	8	/* ref, bad msgid		*/
#define STATS_IHAVE		9	/* ihave			*/
#define STATS_CHECK		10	/* check			*/
#define STATS_TAKETHIS		11	/* takethis			*/
#define STATS_CONTROL		12	/* control message		*/
#define STATS_REJECTED		13	/* rejected			*/
#define STATS_REJ_FAILSAFE	14	/* rej, failsafe		*/
#define STATS_REJ_MISSHDRS	15	/* rej, missing headers		*/
#define STATS_REJ_TOOOLD	16	/* rej, too old			*/
#define STATS_REJ_GRPFILTER	17	/* rej, incoming grp filter	*/
#define STATS_REJ_INTSPAMFILTER	18	/* rej, internal spam filter	*/
#define STATS_REJ_EXTSPAMFILTER	19	/* rej, external spam filter	*/
#define STATS_REJ_INCFILTER	20	/* rej, incoming filter		*/
#define STATS_REJ_NOSPOOL	21	/* rej, no spool object		*/
#define STATS_REJ_IOERROR	22	/* rej, io error		*/
#define STATS_REJ_NOTINACTV	23	/* rej, not in active file	*/
#define STATS_REJ_PATHTAB	24	/* rej, TAB in Path: header	*/
#define STATS_REJ_NGTAB		25	/* rej, TAB in Newsgroups: hdr	*/
#define STATS_REJ_POSDUP	26	/* rej, dup detected after receive */
#define STATS_REJ_HDRERROR	27	/* rej, dup or missing headers	*/
#define STATS_REJ_TOOSMALL	28      /* rej, article too small	*/
#define STATS_REJ_ARTINCOMPL	29	/* rej, article incomplete	*/
#define STATS_REJ_ARTNUL	30	/* rej, article has a nul	*/
#define STATS_REJ_NOBYTES	31	/* rej, header only, no Bytes:	*/
#define STATS_REJ_PROTOERR	32	/* rej, protocol error		*/
#define STATS_REJ_MSGIDMIS	33	/* rej, msgid mismatch		*/
#define STATS_REJ_ERR		34	/* rej, unknown error		*/
#define STATS_REJ_TOOBIG	35	/* rej, too big			*/
#define STATS_NSLOTS		36

typedef struct RecStats {
    time_t	TimeStart;
    int		ConnectCnt;
    int		Stats[STATS_NSLOTS];
    double	ReceivedBytes;
    double	AcceptedBytes;
    double	RejectedBytes;
} RecStats;

#define	STATS_S_STAT		1
#define	STATS_S_STATMISS	2
#define	STATS_S_STATEXP		3
#define	STATS_S_STATERR		4
#define	STATS_S_ARTICLE		5
#define	STATS_S_ARTICLEMISS	6
#define	STATS_S_ARTICLEEXP	7
#define	STATS_S_ARTICLEERR	8
#define	STATS_S_HEAD		9
#define	STATS_S_HEADMISS	10
#define	STATS_S_HEADEXP		11
#define	STATS_S_HEADERR		12
#define	STATS_S_BODY		13
#define	STATS_S_BODYMISS	14
#define	STATS_S_BODYEXP		15
#define	STATS_S_BODYERR		16
#define	STATS_S_NSLOTS		17

typedef struct SpoolStats {
    time_t	TimeStart;
    int		ConnectCnt;
    int		Arts[STATS_S_NSLOTS];
    double	ArtsBytesSent;
} SpoolStats;

typedef struct FeedStats {
    int		version;
    char	hostname[255];
    int		region;
    RecStats	RecStats;
    SpoolStats	SpoolStats;
    SentStats	SentStats;
} FeedStats;

/*
 * Additions to support compressed streams
 * cmsedore@maxwell.syr.edu 12/4/97
 */

#ifdef USE_ZLIB

#define COMPRESS_BUFFER_LENGTH 8192

typedef struct compressBuffer {
  char			cb_Buf[COMPRESS_BUFFER_LENGTH];
  int			cb_compressHoldoverCount;
  int			dataError;
  double		orig,decomp;
  z_stream		z_str;
} CompressBuffer;

#endif

typedef struct Buffer {
    int			bu_Beg;
    int			bu_NLScan;
    int			bu_End;
    int			bu_BufMax;	/* normal maximum	*/
    int			bu_DataMax;	/* extended maximum	*/
    int			bu_Fd;
#ifdef USE_ZLIB
    gzFile		*bu_gzFile;
    int			bu_gzWrote;
    CompressBuffer	*bu_CBuf;
#else
    char		*bu_CBuf;
    char		*bu_gzFile;
#endif
    int			bu_BufSize;
    int			bu_Error;
    char		*bu_Data;	/* included/extended buffer	*/
    char		bu_Buf[1024];	/* included buffer		*/
} Buffer;

typedef struct LogInfo {
    const char		**Pat;
    const char		*Ident;
    FILE		*Fd;
    time_t		NextCheck;
    int			UseSyslog;
    int			Disabled;
    int			LastInode;
    int			Pid;
    char		Fname[PATH_MAX];
} LogInfo;


#define XADV_WILLNEED	1
#define XADV_SEQUENTIAL	2

#include "lib/mem.h"
#include "lib/kpdb.h"
#include "lib/ctl.h"
#include "lib/dmd5.h"

/*
 * Article types that diablo can determine when receiving an article
 */

#define		ARTTYPE_NONE		0x000000

#define		ARTTYPE_DEFAULT		0x000001
#define		ARTTYPE_CONTROL		0x000002
#define		ARTTYPE_CANCEL		0x000004

#define		ARTTYPE_MIME		0x000100
#define		ARTTYPE_BINARY		0x000200
#define		ARTTYPE_UUENCODE	0x000400
#define		ARTTYPE_BASE64		0x000800
#define		ARTTYPE_MULTIPART	0x001000
#define		ARTTYPE_HTML		0x002000
#define		ARTTYPE_PS		0x004000
#define		ARTTYPE_BINHEX		0x008000
#define		ARTTYPE_PARTIAL		0x010000
#define		ARTTYPE_PGPMESSAGE	0x020000
#define		ARTTYPE_YENC		0x040000
#define		ARTTYPE_BOMMANEWS	0x080000
#define		ARTTYPE_UNIDATA		0x100000

#define		ARTTYPE_ALL		0xFFFFFF

/*
 * Data for maintaining an easily accessable list of IP numbers
 */
typedef struct IPList {
    md5hash_t il_hash;
    char *il_ip;
    int il_count;
    time_t il_expire;
    struct IPList *il_next;
} IPList;

IPList *IPHash;

/*
 * MISC
 */

#ifndef LOG_PERROR
#define LOG_PERROR	0
#endif
#ifndef INADDR_NONE
#define INADDR_NONE	((unsigned long)-1)
#endif

#ifndef NI_MAXHOST
#ifdef INET6
#define	NI_MAXHOST	1025
#else
#define	NI_MAXHOST	256
#endif
#endif

/*
 * This is very messy because sa_len doesn't exist as part of the sockaddr
 * structure on some OS's. So much for getting it right with IPv6.
 */
#ifdef INET6
#if HAS_SA_LEN
#define SA_LEN(x) ( (x)->sa_len )
#else
#define SA_LEN(x) ( \
	((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : \
	((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : \
	0)
#endif	/* HAS_SA_LEN */
#else
#define SA_LEN(x) ( \
	((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : \
	0)
#endif	/* INET6 */


#ifndef TEST
#include "obj/lib-protos.h"
#endif

/*
 * can't use Prototype stuff for functions which may
 * already be prototyped.
 */

#if USE_STRERROR
char *strerror(int e);
#endif

/*
 * hack
 */

#if USE_MEMMOVE
void *memmove(char *dst0, const char *src0, size_t length);
#endif

/*
 * If setproctitle() exists, stprintf() is macro'd to it directly, otherwise
 * we use argv stuffing.
 */

#if HAS_PROC_TITLE
#define stprintf	setproctitle
#endif

/*
 * If we don't have snprintf() we have to supply it.  snprintf() is 
 * absolutely critical.
 */

#if HAVE_SNPRINTF == 0

int snprintf(char *str, size_t size, const char *format, ...);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);

#endif

#if HAVE_STRSEP == 0

char *strsep(register char **stringp, register const char *delim);

#endif

#if USE_INTERNAL_VSYSLOG

void vsyslog(int priority, const char *msg, va_list va);

#endif

#ifdef DMALLOC
#include <dmalloc.h>
#endif


syntax highlighted by Code2HTML, v. 0.9.1