1 /* 2 * This file is copyrighted material. See the file COPYING for licensing 3 * conditions. 4 */ 5 6 /* $Id: leafnode.h,v 1.95 2008/08/07 20:19:41 emma Exp $ */ 7 8 #ifndef LEAFNODE_H 9 #define LEAFNODE_H 10 11 #include "config.h" 12 13 /* newer glibc needs this so it doesn't complain about _BSD_SOURCE */ 14 #ifndef _DEFAULT_SOURCE 15 #define _DEFAULT_SOURCE 16 #endif 17 18 #ifndef _GNU_SOURCE 19 #define _GNU_SOURCE 20 #endif 21 #ifndef _BSD_SOURCE 22 #define _BSD_SOURCE 23 #endif 24 25 #include "critmem.h" 26 27 /* I wish the world were a happy place */ 28 #ifndef TRUE 29 #define TRUE (1) 30 #endif 31 #ifndef FALSE 32 #define FALSE (0) 33 #endif 34 35 #define PLURAL(no) (((no) == 1) ? "" : "s") 36 37 /* limits.h may contain PATH_MAX but shall not if the system has variable 38 * length limits here */ 39 #include <limits.h> 40 #ifndef PATH_MAX 41 /* just some random limit - we'll use this as a starting point 42 * for dynamically growing memory only */ 43 #define PATH_MAX 4096 44 #endif 45 46 #define PORTFILENAMECSET "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._-" 47 48 #include <pcre.h> 49 #include <stdarg.h> /* va_list */ 50 #include <stdio.h> /* FILE * */ 51 #include <setjmp.h> /* sigjmp_buf */ 52 #include "system.h" /* time.h */ 53 54 #ifdef HAVE_AP_CONFIG_H 55 #define AP_CONFIG_H 56 #endif 57 58 #include <errno.h> 59 60 /* from strdup.c */ 61 #ifndef HAVE_STRDUP 62 char *strdup(const char *); 63 #endif 64 65 /* from snprintf.c */ 66 #ifndef HAVE_WORKING_SNPRINTF 67 int ln_snprintf(char *str, size_t n, const char *format, ...) 68 #ifdef __GNUC__ 69 __attribute__ ((format(printf, 3, 4))) 70 #endif 71 ; 72 int ln_vsnprintf(char *str, size_t n, const char *format, va_list ap); 73 #define snprintf ln_snprintf 74 #define vsnprintf ln_vsnprintf 75 #endif 76 77 int xsnprintf(/*@out@*/ char *str, size_t n, const char *format, ...) 78 #ifdef __GNUC__ 79 __attribute__ ((format(printf, 3, 4))) 80 #endif 81 ; 82 83 /* map LOG_NEWS onto LOG_DAEMON where the former doesn't exist */ 84 #include <syslog.h> 85 #if !defined( LOG_NEWS ) 86 #define LOG_NEWS LOG_DAEMON 87 #endif 88 /* define LOG_CONS if missing */ 89 #if !defined( LOG_CONS ) 90 #define LOG_CONS 0 /* if it isn't supported, make do without */ 91 #endif 92 93 #define SECONDS_PER_DAY ( 24L * 60 * 60 ) 94 95 /* Limit on the number of message bodies marked for download per group. */ 96 #define BODY_DOWNLOAD_LIMIT 2048 97 98 /* initialize global variables */ 99 int initvars(char *progname); 100 101 /* converts a message-id to a file name, the return value points into 102 a static array */ 103 #define LOOKUP_FREE ((const char *)-2) 104 /*@dependent@*/ const char *lookup(const char *msgid); 105 106 /*@dependent@*/ 107 char *getaline(FILE * f); /* reads one line, regardless of length */ 108 /*@dependent@*/ 109 char *mgetaline(FILE * f); /* dito, with timeout */ 110 void mgetaline_settimeout(unsigned int); /* set timeout for mgetaline */ 111 extern sigjmp_buf timeout; 112 extern void timer(int sig); 113 114 /* changes (and optionally creates) directory */ 115 int chdirgroup(const char *group, int creatdir); 116 117 /* 118 * newsgroup management 119 */ 120 struct newsgroup { 121 unsigned long first; 122 unsigned long last; 123 char *name; 124 char *desc; 125 time_t age; 126 }; 127 128 int isinteresting(const char *groupname); 129 void insertgroup(const char *name, long unsigned first, long unsigned last, 130 time_t date); 131 extern void changegroupdesc(const char *groupname, const char *description); 132 extern void newgroupdesc(const char *groupname, const char *description); 133 void mergegroups(void); 134 /*@null@*//*@dependent@*/ 135 struct newsgroup *xfindgroup(struct newsgroup *active, const char *name, 136 unsigned long size); 137 /*@null@*//*@dependent@*/ 138 struct newsgroup *findgroup(const char *name); 139 void readactive(void); 140 int writeactive(void); 141 void fakeactive(void); 142 void freeactive(/*@null@*/ struct newsgroup *act); 143 extern char *activeread(void); 144 extern int killactiveread(void); 145 146 extern size_t activesize; 147 /*@null@*/ extern struct newsgroup *active; 148 extern size_t oldactivesize; 149 /*@null@*/ extern struct newsgroup *oldactive; 150 151 /* translation from message-id to article number, used in fetch and expire */ 152 153 void clearidtree(void); 154 void insertmsgid( /*@unique@*/ const char *msgid); 155 int findmsgid(const char *msgid); 156 typedef int (*tmihook)(const char *); 157 int traverseidtree(tmihook h); 158 159 /* -----------here starts the new stuff-----------------*/ 160 161 /* 162 * a linear list of strings 163 */ 164 struct stringlist { 165 struct stringlist *next; 166 char string[1]; 167 }; 168 169 void 170 prependtolist(struct stringlist **list, /*@unique@*/ const char *newentry); 171 172 /*@null@*//*@dependent@*/ 173 struct stringlist **lfindinlist(struct stringlist **haystack, char *needle, size_t len); 174 /* find a stringlist element by doing a linear search */ 175 char *findinlist(struct stringlist *haystack, char *needle); 176 /* find a string in a stringlist by doing a linear search */ 177 void freelist( /*@only@*/ struct stringlist *list); 178 /* free memory occupied by a stringlist */ 179 180 /* 181 * filterfile.c -- PCRE filtering of articles 182 */ 183 void readfilter(char *filterfile); 184 void freefilter(void); 185 int dofilter(char *h); 186 187 /* 188 * artutil.c -- handling article files 189 */ 190 void store(const char *filename, 191 FILE * filehandle, const char *newsgroups, const char *msgid); 192 193 /* 194 * find a certain header in an article and return it 195 */ 196 /*@null@*//*@only@*/ char *getheader(const char *filename, const char *header); 197 /*@null@*//*@only@*/ char *fgetheader(FILE * f, const char *header); 198 199 /* 200 * the strings in config.c 201 */ 202 extern const char *spooldir; 203 extern const char *sysconfdir; 204 extern const char *version; 205 extern const char *lockfile; 206 207 /* 208 * global variables from config file. These are defined in configutil.c 209 */ 210 struct expire_entry { 211 struct expire_entry *next; 212 char *group; 213 time_t xtime; 214 int days; 215 }; 216 217 struct server { 218 struct server *next; 219 char *name; /* Servername */ 220 char *username; 221 char *password; 222 pcre *group_pcre; 223 unsigned int port; 224 int descriptions; /* download descriptions as well */ 225 int timeout; /* timeout in seconds before we give up */ 226 int nopost; /* if set, do not try to post to this server */ 227 int noread; /* if set, do not try to fetch articles from 228 this server */ 229 int updateactive; /* update the active file of this server, BITFIELD: 1 = from command line, 2 = automatically set */ 230 int post_anygroup; /* if set, do not check if the group is on the 231 server, but just post */ 232 int noxover; /* if set, use XHDR for overview */ 233 int only_groups_match_all; /* if set, any unmatched group (refer to 234 group_pcre) prevents the post */ 235 }; 236 237 extern int date_is_evil; /* skip DATE check on servers known bad */ 238 extern int stat_is_evil; /* use HEAD instead of STAT to figure if a 239 posting is available upstream, workaround for broken NewsCache */ 240 extern time_t expire; /* articles not touched since this time get deleted */ 241 extern int expiredays; 242 extern struct expire_entry *expire_base; 243 /* expire for certain groups */ 244 extern unsigned long artlimit; /* max # of articles to read per group in one go */ 245 extern unsigned long initiallimit; 246 /* max # of articles to read at first time */ 247 extern long crosspostlimit; 248 /* crossposting limit, to reduce spam */ 249 extern int delaybody; /* delay download of message body */ 250 extern int db_situ; /* delaybody: keep original article number */ 251 extern int debugmode; /* log lots of stuff via syslog */ 252 extern int create_all_links; 253 /* store articles even in uninteresting groups */ 254 extern int maxage; /* max age of articles */ 255 extern long maxlines; /* max length of articles in lines */ 256 extern long minlines; /* min length of articles in lines */ 257 extern unsigned long maxbytes; /* max length of articles in bytes */ 258 extern int timeout_short; /* don't fetch groups that have been 259 accidentally accessed after that many days */ 260 extern int timeout_long; /* don't fetch groups that have been accessed 261 that many days */ 262 extern int timeout_active; /* reread active file after that many days */ 263 extern int timeout_client; /* activity timeout for clients in seconds */ 264 extern int timeout_fetchnews; /* response deadline for upstream in seconds */ 265 extern int clamp_maxage; /* limit maxage to applicable group/global expire? */ 266 extern int article_despite_filter; /* request and discard body if filterfile is defined, for high-latency, high-throughput links */ 267 extern char *filterfile; /* filename where filter resides */ 268 extern struct server *servers; /* list of servers to use */ 269 extern int allowstrangers; /* if addresses not local to our links 270 are allowed to connect */ 271 extern int allow_8bit_headers; /* if 8bit junk in headers is allowed */ 272 extern char *newsadmin; /* address of news administrator, default: news@%s with %s = fqdn */ 273 extern unsigned long timeout_lock; /* lock file timeout */ 274 275 /* 276 * other global variables 277 */ 278 #define SIZE_lineout 1024 279 extern char last_command[SIZE_lineout + 1]; 280 extern char lineout[SIZE_lineout + 1]; 281 282 /* defined in nntputil.c */ 283 extern /*@relnull@*/ /*@dependent@*/ FILE *nntpin; 284 extern /*@relnull@*/ /*@dependent@*/ FILE *nntpout; 285 286 #define SIZE_s (8192) 287 #define FQDNLEN 255 288 extern char fqdn[FQDNLEN + 1]; /* my name, and my naming myself */ 289 290 extern int verbose; /* verbosity level, for fetch and texpire */ 291 extern int debug; /* debug level */ 292 293 /* 294 * misc prototypes 295 */ 296 int try_lock(unsigned long); 297 int handover_lock(pid_t); 298 void putaline(void); 299 void retry(void); 300 void readexpire(void); 301 int readconfig(int logtostderr); 302 void freeexpire(void); 303 void freeservers(void); 304 void freeconfig(void); 305 void lowercase(char *string); 306 int ngmatch(const char *pattern, const char *string); 307 void overrun(void); 308 void replaceinlist(struct stringlist **haystack, char *needle, size_t len); 309 time_t lookup_expire(char *group); 310 int lookup_expiredays(char *group); 311 int log_unlink(const char *f, int ignore_enoent); 312 313 /* int rename(const char *old, const char *new); */ 314 /* to avoid barfing of Digital Unix */ 315 316 /* 317 * stuff from nntputil.c 318 */ 319 int authenticate(const struct server*); /* authenticate ourselves at a server */ 320 /*@dependent@*//*@null@*/ 321 char *lastreply(void); /* last line frpm nntpreply */ 322 int nntpreply(const struct server*); /* decode an NNTP reply number */ 323 int nntpconnect(const struct server *upstream); 324 /* connect to upstream server */ 325 void nntpdisconnect(void); /* disconnect from upstream server */ 326 void nntpquit(void); /* send QUIT, then disconnect from upstream server */ 327 void freelastreply(void); 328 329 /*@dependent@*/ 330 const char *rfctime(void); /* An rfc type date */ 331 332 int safe_mkstemp(char *); /* permission safe mkstemp wrapper */ 333 /* from syslog.c */ 334 void myopenlog(const char *ident); 335 336 /* from mkstemp.c */ 337 #ifndef HAVE_MKSTEMP 338 int mkstemp(char *); 339 #endif 340 341 /* from getline.c */ 342 #ifndef HAVE_GETLINE 343 ssize_t getline(char **, size_t *, FILE *); /* fgets replacement */ 344 #endif 345 void freegetaline(void); 346 347 #ifndef HAVE_TIMEGM 348 time_t timegm(struct tm *tm); 349 #endif 350 351 /* from wildmat.c */ 352 int wildmat(const char *, const char *); 353 354 /* from getfoldedline.c */ 355 /*@null@*/ /*@only@*/ 356 char *getfoldedline(FILE * f, char *(*reader)(FILE *)); 357 /* reads one line, regardless of length, returns malloc()ed string! */ 358 359 /* from writes.c (ln-2) */ 360 ssize_t writes(int fd, const char *string); 361 362 void fixxover(void); 363 364 /* from grouplist.c */ 365 /*@null@*/ struct stringlist *get_grouplist(void); 366 367 /* checkpeerlocal.c */ 368 int checkpeerlocal(int sock); 369 370 /* pcre_extract.c */ 371 int pcre_extract(const char *input, const char *pattern, /*@out@*/ char **output, size_t num); 372 void pcre_extract_free(char **vec, int count); 373 size_t xstrlcpy(/*@out@*/ char *dst, const char *src, size_t size); 374 375 /* xoverutil.c */ 376 struct xoverinfo { 377 char *text; 378 int exists; 379 }; 380 381 /*@null@*/ extern struct xoverinfo *xoverinfo; 382 extern unsigned long xfirst; 383 extern unsigned long xlast; 384 385 int getxover(void); /* set xoverinfo, return 0 on error, nonzero else */ 386 387 int legalxoverline(const char *xover, /*@out@*/ const char **errmsg); 388 void freexover(void); 389 390 /* agetcwd.c */ 391 int agetcwd(/*@out@*/ char **buf, /*@out@*/ size_t *capa); 392 393 #ifdef CHECKGROUPORDER 394 void checkgrouporder(void); 395 #endif /* CHECKGROUPORDER */ 396 397 #define SKIPLWS(p) while (*(p) && isspace((unsigned char) *(p))) { (p)++; } 398 #endif /* #ifndef LEAFNODE_H */ 399