/* * This file is copyrighted material. See the file COPYING for licensing * conditions. */ /* $Id: leafnode.h,v 1.93 2005/06/08 14:06:15 emma Exp $ */ #ifndef LEAFNODE_H #define LEAFNODE_H #include "critmem.h" /* I wish the world were a happy place */ #ifndef TRUE #define TRUE (1) #endif #ifndef FALSE #define FALSE (0) #endif #define PLURAL(no) (((no) == 1) ? "" : "s") /* limits.h may contain PATH_MAX but shall not if the system has variable * length limits here */ #include #ifndef PATH_MAX /* just some random limit - we'll use this as a starting point * for dynamically growing memory only */ #define PATH_MAX 4096 #endif #define PORTFILENAMECSET "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._-" #include #include /* va_list */ #include /* FILE * */ #include /* sigjmp_buf */ #include "system.h" /* time.h */ #include "config.h" /* FreeSGI barfs on #ifdef HAVE_CONFIG_H */ #ifdef HAVE_AP_CONFIG_H #define AP_CONFIG_H #endif #ifdef HAVE_ERRNO_H #include #include #endif #ifndef HAVE_ERRNO_H extern int errno; #endif /* HAVE_ERRNO_H */ /* from strdup.c */ #ifndef HAVE_STRDUP char *strdup(const char *); #endif /* from snprintf.c */ #ifndef HAVE_WORKING_SNPRINTF int ln_snprintf(char *str, size_t n, const char *format, ...) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif ; int ln_vsnprintf(char *str, size_t n, const char *format, va_list ap); #define snprintf ln_snprintf #define vsnprintf ln_vsnprintf #endif int xsnprintf(/*@out@*/ char *str, size_t n, const char *format, ...) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif ; /* map LOG_NEWS onto LOG_DAEMON where the former doesn't exist */ #include #if !defined( LOG_NEWS ) #define LOG_NEWS LOG_DAEMON #endif /* define LOG_CONS if missing */ #if !defined( LOG_CONS ) #define LOG_CONS 0 /* if it isn't supported, make do without */ #endif #define SECONDS_PER_DAY ( 24L * 60 * 60 ) /* Limit on the number of message bodies marked for download per group. */ #define BODY_DOWNLOAD_LIMIT 2048 /* initialize global variables */ int initvars(char *progname); /* converts a message-id to a file name, the return value points into a static array */ #define LOOKUP_FREE ((const char *)-2) /*@dependent@*/ const char *lookup(const char *msgid); /*@dependent@*/ char *getaline(FILE * f); /* reads one line, regardless of length */ /*@dependent@*/ char *mgetaline(FILE * f); /* dito, with timeout */ void mgetaline_settimeout(unsigned int); /* set timeout for mgetaline */ extern sigjmp_buf timeout; extern RETSIGTYPE timer(int sig); /* changes (and optionally creates) directory */ int chdirgroup(const char *group, int creatdir); /* * newsgroup management */ struct newsgroup { unsigned long first; unsigned long last; char *name; char *desc; time_t age; }; int isinteresting(const char *groupname); void insertgroup(const char *name, long unsigned first, long unsigned last, time_t date); extern void changegroupdesc(const char *groupname, const char *description); extern void newgroupdesc(const char *groupname, const char *description); void mergegroups(void); /*@null@*//*@dependent@*/ struct newsgroup *xfindgroup(struct newsgroup *active, const char *name, unsigned long size); /*@null@*//*@dependent@*/ struct newsgroup *findgroup(const char *name); void readactive(void); int writeactive(void); void fakeactive(void); void freeactive(/*@null@*/ struct newsgroup *act); extern char *activeread(void); extern int killactiveread(void); extern size_t activesize; /*@null@*/ extern struct newsgroup *active; extern size_t oldactivesize; /*@null@*/ extern struct newsgroup *oldactive; /* translation from message-id to article number, used in fetch and expire */ void clearidtree(void); void insertmsgid( /*@unique@*/ const char *msgid); int findmsgid(const char *msgid); typedef int (*tmihook)(const char *); int traverseidtree(tmihook h); /* -----------here starts the new stuff-----------------*/ /* * a linear list of strings */ struct stringlist { struct stringlist *next; char string[1]; }; void prependtolist(struct stringlist **list, /*@unique@*/ const char *newentry); /*@null@*//*@dependent@*/ struct stringlist **lfindinlist(struct stringlist **haystack, char *needle, size_t len); /* find a stringlist element by doing a linear search */ char *findinlist(struct stringlist *haystack, char *needle); /* find a string in a stringlist by doing a linear search */ void freelist( /*@only@*/ struct stringlist *list); /* free memory occupied by a stringlist */ /* * filterfile.c -- PCRE filtering of articles */ void readfilter(char *filterfile); void freefilter(void); int dofilter(char *h); /* * artutil.c -- handling article files */ void store(const char *filename, FILE * filehandle, const char *newsgroups, const char *msgid); /* * find a certain header in an article and return it */ /*@null@*//*@only@*/ char *getheader(const char *filename, const char *header); /*@null@*//*@only@*/ char *fgetheader(FILE * f, const char *header); /* * the strings in config.c */ extern const char *spooldir; extern const char *sysconfdir; extern const char *version; extern const char *lockfile; /* * global variables from config file. These are defined in configutil.c */ struct expire_entry { struct expire_entry *next; char *group; time_t xtime; int days; }; struct server { struct server *next; char *name; /* Servername */ char *username; char *password; pcre *group_pcre; unsigned int port; int descriptions; /* download descriptions as well */ int timeout; /* timeout in seconds before we give up */ int nopost; /* if set, do not try to post to this server */ int noread; /* if set, do not try to fetch articles from this server */ int updateactive; /* update the active file of this server */ int post_anygroup; /* if set, do not check if the group is on the server, but just post */ int noxover; /* if set, use XHDR for overview */ int only_groups_match_all; /* if set, any unmatched group (refer to group_pcre) prevents the post */ }; extern int date_is_evil; /* skip DATE check on servers known bad */ extern int stat_is_evil; /* use HEAD instead of STAT to figure if a posting is available upstream, workaround for broken NewsCache */ extern time_t expire; /* articles not touched since this time get deleted */ extern int expiredays; extern struct expire_entry *expire_base; /* expire for certain groups */ extern unsigned long artlimit; /* max # of articles to read per group in one go */ extern unsigned long initiallimit; /* max # of articles to read at first time */ extern long crosspostlimit; /* crossposting limit, to reduce spam */ extern int delaybody; /* delay download of message body */ extern int db_situ; /* delaybody: keep original article number */ extern int debugmode; /* log lots of stuff via syslog */ extern int create_all_links; /* store articles even in uninteresting groups */ extern int maxage; /* max age of articles */ extern long maxlines; /* max length of articles in lines */ extern long minlines; /* min length of articles in lines */ extern unsigned long maxbytes; /* max length of articles in bytes */ extern int timeout_short; /* don't fetch groups that have been accidentally accessed after that many days */ extern int timeout_long; /* don't fetch groups that have been accessed that many days */ extern int timeout_active; /* reread active file after that many days */ extern int timeout_client; /* activity timeout for clients in seconds */ extern int timeout_fetchnews; /* response deadline for upstream in seconds */ extern int clamp_maxage; /* limit maxage to applicable group/global expire? */ extern int article_despite_filter; /* request and discard body if filterfile is defined, for high-latency, high-throughput links */ extern char *filterfile; /* filename where filter resides */ extern struct server *servers; /* list of servers to use */ extern int allowstrangers; /* if addresses not local to our links are allowed to connect */ extern int allow_8bit_headers; /* if 8bit junk in headers is allowed */ extern char *newsadmin; /* address of news administrator, default: news@%s with %s = fqdn */ extern unsigned long timeout_lock; /* lock file timeout */ /* * other global variables */ #define SIZE_lineout 1024 extern char last_command[SIZE_lineout + 1]; extern char lineout[SIZE_lineout + 1]; /* defined in nntputil.c */ extern /*@relnull@*/ /*@dependent@*/ FILE *nntpin; extern /*@relnull@*/ /*@dependent@*/ FILE *nntpout; #define SIZE_s (8192) #define FQDNLEN 255 extern char fqdn[FQDNLEN + 1]; /* my name, and my naming myself */ extern int verbose; /* verbosity level, for fetch and texpire */ extern int debug; /* debug level */ /* * misc prototypes */ int try_lock(unsigned long); int handover_lock(pid_t); void putaline(void); void retry(void); void readexpire(void); int readconfig(int logtostderr); void freeexpire(void); void freeservers(void); void freeconfig(void); void lowercase(char *string); int ngmatch(const char *pattern, const char *string); void overrun(void); void replaceinlist(struct stringlist **haystack, char *needle, size_t len); time_t lookup_expire(char *group); int lookup_expiredays(char *group); int log_unlink(const char *f, int ignore_enoent); /* int rename(const char *old, const char *new); */ /* to avoid barfing of Digital Unix */ /* * stuff from nntputil.c */ int authenticate(const struct server*); /* authenticate ourselves at a server */ /*@dependent@*//*@null@*/ char *lastreply(void); /* last line frpm nntpreply */ int nntpreply(const struct server*); /* decode an NNTP reply number */ int nntpconnect(const struct server *upstream); /* connect to upstream server */ void nntpdisconnect(void); /* disconnect from upstream server */ void nntpquit(void); /* send QUIT, then disconnect from upstream server */ void freelastreply(void); /*@dependent@*/ const char *rfctime(void); /* An rfc type date */ int safe_mkstemp(char *); /* permission safe mkstemp wrapper */ /* from syslog.c */ void myopenlog(const char *ident); /* from mkstemp.c */ #ifndef HAVE_MKSTEMP int mkstemp(char *); #endif /* from getline.c */ #ifndef HAVE_GETLINE ssize_t getline(char **, size_t *, FILE *); /* fgets replacement */ #endif void freegetaline(void); #ifndef HAVE_TIMEGM time_t timegm(struct tm *tm); #endif /* from mysetvbuf.c */ int mysetvbuf(FILE *stream, char *buf, int mode, size_t size); /* from wildmat.c */ int wildmat(const char *, const char *); /* from mysetvbuf.c */ int mysetvbuf(FILE *stream, char *buf, int mode , size_t size); /* from getfoldedline.c */ /*@null@*/ /*@only@*/ char *getfoldedline(FILE * f, char *(*reader)(FILE *)); /* reads one line, regardless of length, returns malloc()ed string! */ /* from writes.c (ln-2) */ ssize_t writes(int fd, const char *string); void fixxover(void); /* from grouplist.c */ /*@null@*/ struct stringlist *get_grouplist(void); /* checkpeerlocal.c */ int checkpeerlocal(int sock); /* pcre_extract.c */ int pcre_extract(const char *input, const char *pattern, /*@out@*/ char **output, size_t num); void pcre_extract_free(char **vec, int count); size_t xstrlcpy(/*@out@*/ char *dst, const char *src, size_t size); /* xoverutil.c */ struct xoverinfo { char *text; int exists; }; /*@null@*/ extern struct xoverinfo *xoverinfo; extern unsigned long xfirst; extern unsigned long xlast; int getxover(void); /* set xoverinfo, return 0 on error, nonzero else */ int legalxoverline(const char *xover, /*@out@*/ const char **errmsg); void freexover(void); /* agetcwd.c */ int agetcwd(/*@out@*/ char **buf, /*@out@*/ size_t *capa); #ifdef CHECKGROUPORDER void checkgrouporder(void); #endif /* CHECKGROUPORDER */ #define SKIPLWS(p) while (*(p) && isspace((unsigned char) *(p))) { (p)++; } #endif /* #ifndef LEAFNODE_H */