"Fossies" - the Fresh Open Source Software Archive 
Member "leafnode-1.12.0/configutil.c" (28 Dec 2021, 22255 Bytes) of package /linux/misc/leafnode-1.12.0.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "configutil.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
1.11.12_vs_1.12.0.
1 /*
2 libutil -- read config file
3
4 Written by Arnt Gulbrandsen <agulbra@troll.no> and copyright 1995
5 Troll Tech AS, Postboks 6133 Etterstad, 0602 Oslo, Norway, fax +47
6 22646949.
7 Modified by Cornelius Krasel <krasel@wpxx02.toxi.uni-wuerzburg.de>
8 and Randolf Skerka <Randolf.Skerka@gmx.de>.
9 Copyright of the modifications 1997.
10 Modified by Kent Robotti <robotti@erols.com>. Copyright of the
11 modifications 1998.
12 Modified by Markus Enzenberger <enz@cip.physik.uni-muenchen.de>.
13 Copyright of the modifications 1998.
14 Modified by Cornelius Krasel <krasel@wpxx02.toxi.uni-wuerzburg.de>.
15 Copyright of the modifications 1998, 1999.
16 Modified and copyright of the modifications 2002 by Ralf Wildenhues
17 <ralf.wildenhues@gmx.de>.
18 Modified and copyright of the modifications 2001 - 2021 by Matthias Andree
19 <matthias.andree@gmx.de>.
20
21 See file COPYING for restrictions on the use of this software.
22 */
23
24 #include "leafnode.h"
25 #include "validatefqdn.h"
26 #include "ln_log.h"
27 #include "strlcpy.h"
28
29 #include <ctype.h>
30 #include <errno.h>
31 #include <sys/types.h>
32 #include <limits.h>
33 #include <netdb.h>
34 #include <netinet/in.h>
35 #ifndef __LCLINT__
36 #include <arpa/inet.h>
37 #endif
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <syslog.h>
42 #include <unistd.h>
43 #include <sys/stat.h>
44 #include <sys/resource.h>
45
46 #define COREFILESIZE 1024*1024*64
47 #define TOKENSIZE 4096
48
49 #include "groupselect.h"
50
51 #ifndef min
52 #define min(a,b) ((a < b) ? (a) : (b))
53 #endif
54
55 /*
56 * misc. global variables, documented in leafnode.h
57 */
58 time_t expire = 0;
59 int expiredays = 0;
60 struct expire_entry *expire_base;
61 unsigned long artlimit = 0;
62 unsigned long initiallimit = 0;
63 long crosspostlimit = 0;
64 int create_all_links = 0;
65 int delaybody = 0;
66 int db_situ = 0;
67 int debugmode = 0; /* if 1, log lots of stuff via syslog */
68 int maxage = 10;
69 int article_despite_filter = 0;
70 long maxlines = 0;
71 long minlines = 0;
72 unsigned long maxbytes = 0;
73 static int linebuffer = 0; /* if 1, make stdout and stderr explicitly
74 line buffered, GNU libc makes them fully buffered
75 if redirected to files */
76 int timeout_long = 7;
77 int timeout_short = 2;
78 int timeout_active = 90;
79 int timeout_client = 15*60; /* when newsreader is idle for this many seconds, disconnect */
80 int timeout_fetchnews = 5*60; /* wait at most this many seconds for server replies in fetchnews */
81 int clamp_maxage = 1; /* if 1, maxage will be lowered to
82 * groupexpire or expire if the
83 * applicable parameter is lower than
84 * maxage, to prevent duplicate fetches
85 * after a premature exit of
86 * fetchnews. */
87 int allowstrangers = 0;
88 char *filterfile;
89 struct server *servers = NULL;
90 int allow_8bit_headers = 0;
91 char *newsadmin;
92 unsigned long timeout_lock = 5UL;
93
94 /** parse the line in \a l, breaking it into param and value at the "="
95 * delimiter. The right-hand side can be quoted with double quotes,
96 * inside these a backslash escapes a quote that is part of the string.
97 * \return success
98 */
99 static int parse_line(
100 /*@unique@*/ char *l /** input, will be modified */,
101 /*@out@*/ char *param /** output, left-hand side */,
102 /*@out@*/ char *value /** output, right-hand side */);
103
104 /* parse a line, destructively */
105 static int
106 parse_line(char *l, char *param, char *value)
107 {
108 char *p, *start;
109 size_t le, len;
110 enum modes { plain, quoted } mode = plain;
111
112 p = l;
113 /* skip leading spaces, read parameter */
114 SKIPLWS(p);
115 le = strcspn(p, "=#");
116 /* strip trailing space */
117 while(le && strchr(" \t", p[le-1])) le--;
118 len = min(le, TOKENSIZE - 1);
119 if (!len) return 0;
120 memcpy(param, p, len);
121 param[len] = '\0';
122 p += le;
123
124 SKIPLWS(p);
125 if (*p++ != '=')
126 return 0;
127 SKIPLWS(p);
128
129 /* strip trailing blanks from input */
130 le = strlen(p);
131 while (le--) {
132 if (p[le] == ' ' || p[le] == '\t')
133 p[le] = '\0';
134 else
135 break;
136 }
137
138 start = value;
139 /* read value */
140 for (le = 0 ; le < TOKENSIZE - 1 ; le ++) {
141 char c = *p++;
142 if (mode == plain) {
143 if (c == '#' || c == '\0') {
144 /* strip trailing blanks */
145 while(value > start && strchr(" \t", value[-1])) value--;
146 break;
147 }
148 if (c == '"') { mode = quoted; continue; }
149 *value++ = c;
150 } else if (mode == quoted) {
151 if (c == '\\') {
152 if (*p) {
153 *value++ = *p++; continue;
154 } else
155 return 0;
156 }
157 if (c == '\0') return 0;
158 if (c == '"') break;
159 *value++ = c;
160 } else {
161 abort();
162 }
163 }
164 *value = '\0';
165 return 1;
166 }
167
168 /*
169 05/25/97 - T. Sweeney - Modified to read user name and password for AUTHINFO.
170 Security questionable as password is stored in
171 plaintext in insecure file.
172 1999-07-15 - Matthias Andree
173 Set p and q defaults to 0
174 */
175
176 /* parses value into timeout_lock, returns 0 for success, -1 for error */
177 static int read_timeout_lock(
178 const char *value, /* input */
179 const char *source /* where did value come from */) {
180 char *t;
181 unsigned long u;
182
183 errno = 0;
184 u = strtoul(value, &t, 10);
185 if ((u != 0 || errno == 0)
186 && t > value
187 && (!*t || isspace((unsigned char)*t)))
188 {
189 timeout_lock = u;
190 if (debugmode) {
191 if (timeout_lock) {
192 syslog(LOG_DEBUG,
193 "%s: waiting %lu second%s for lockfile",
194 source, timeout_lock, PLURAL(timeout_lock));
195 } else {
196 syslog(LOG_DEBUG,
197 "%s: waiting indefinitely for lockfile", source);
198 }
199 }
200 return 0;
201 } else {
202 ln_log(LNLOG_SERR, LNLOG_CTOP, "error: cannot parse lockfile value \"%s\" from %s", value, source);
203 return -1;
204 }
205 }
206
207 int
208 readconfig(int logtostderr)
209 {
210 struct server *p = 0, *q = 0;
211 struct rlimit corelimit;
212 struct expire_entry *ent = NULL, *prev = NULL;
213 FILE *f;
214 char *l;
215 char *param, *value;
216 char s[SIZE_s + 1];
217 unsigned long curline = 0;
218
219 artlimit = 0;
220 param = critmalloc(TOKENSIZE, "allocating space for parsing");
221 value = critmalloc(TOKENSIZE, "allocating space for parsing");
222
223 xsnprintf(s, SIZE_s, "%s/config", sysconfdir);
224 if ((f = fopen(s, "r")) == NULL) {
225 syslog(LOG_ERR, "cannot open %s", s);
226 free(param);
227 free(value);
228 return 0;
229 }
230 while ((l = getaline(f))) {
231 ++curline;
232 if (parse_line(l, param, value)) {
233 if (strcmp("username", param) == 0) {
234 if (p) {
235 if (p->username != NULL)
236 free(p->username);
237 p->username = critstrdup(value, "readconfig");
238 if (debugmode)
239 syslog(LOG_DEBUG, "config: found username for %s",
240 p->name);
241 } else
242 syslog(LOG_ERR, "config: no server for username %s", value);
243 } else if (strcmp("password", param) == 0) {
244 if (p) {
245 if (p->password != NULL)
246 free(p->password);
247 p->password = critstrdup(value, "readconfig");
248 if (debugmode)
249 syslog(LOG_DEBUG, "config: found password for %s",
250 p->name);
251 } else
252 syslog(LOG_ERR, "config: no server for password");
253 } else if (strcmp("timeout", param) == 0) {
254 if (p) {
255 p->timeout = atoi(value);
256 if (debugmode)
257 syslog(LOG_DEBUG, "config: timeout is %d second%s",
258 p->timeout, PLURAL(p->timeout));
259 } else
260 syslog(LOG_ERR, "config: no server for timeout");
261 } else if (strcmp("allowSTRANGERS", param) == 0) {
262 if (value && strlen(value)) {
263 if (atoi(value) == 42)
264 allowstrangers = 1;
265 if (debugmode)
266 syslog(LOG_DEBUG,
267 "config: allowstrangers is %s",
268 allowstrangers ? "set" : "unset");
269 }
270 } else if (strcmp("create_all_links", param) == 0) {
271 if (value && strlen(value)) {
272 create_all_links = atoi(value);
273 if (create_all_links && debugmode)
274 syslog(LOG_DEBUG,
275 "config: link articles in all groups");
276 }
277 } else if (strcmp("expire", param) == 0) {
278 int i = atoi(value);
279 if (i >= (INT_MAX / SECONDS_PER_DAY))
280 i = (INT_MAX / SECONDS_PER_DAY) - 1;
281 if (i <= 0) {
282 ln_log(LNLOG_SERR, LNLOG_CTOP, "config: expire must be positive, not %d, abort", i);
283 exit(1);
284 }
285 expiredays = i;
286 expire = time(NULL) - (time_t) (SECONDS_PER_DAY * i);
287 if (debugmode)
288 syslog(LOG_DEBUG, "config: expire is %d day%s", i, PLURAL(i));
289 } else if (strcmp("newsadmin", param) == 0) {
290 if (debugmode)
291 syslog(LOG_DEBUG, "config: newsadmin is %s", value);
292 newsadmin = critstrdup(value, "readconfig");
293 } else if (strcmp("filterfile", param) == 0) {
294 if (debugmode)
295 syslog(LOG_DEBUG, "config: filterfile is %s", value);
296 filterfile = critstrdup(value, "readconfig");
297 } else if ((strcmp("hostname", param) == 0) ||
298 (strcmp("fqdn", param) == 0)) {
299 if (debugmode)
300 syslog(LOG_DEBUG, "config: hostname is %s", value);
301 (void)xstrlcpy(fqdn, value, sizeof(fqdn));
302 } else if ((strcmp("maxcrosspost", param) == 0) ||
303 (strcmp("maxgroups", param) == 0)) {
304 /* maxgroups is for compatibility with leafnode+ */
305 crosspostlimit = strtol(value, NULL, 10);
306 if (debugmode)
307 syslog(LOG_DEBUG, "config: crosspostlimit is %ld group%s",
308 crosspostlimit, PLURAL(crosspostlimit));
309 } else if (strcmp("article_despite_filter", param) == 0) {
310 article_despite_filter = atoi(value) ? 1 : 0;
311 if (debugmode)
312 syslog(LOG_DEBUG, "config: article_despite_filter is %s",
313 article_despite_filter ? "TRUE" : "FALSE");
314 } else if (strcmp("clamp_maxage", param) == 0) {
315 clamp_maxage = atoi(value);
316 if (debugmode)
317 syslog(LOG_DEBUG, "config: clamp_maxage is %s",
318 clamp_maxage ? "TRUE" : "FALSE");
319 } else if (strcmp("maxlines", param) == 0) {
320 maxlines = strtol(value, NULL, 10);
321 if (debugmode)
322 syslog(LOG_DEBUG, "config: postings have max. %ld line%s",
323 maxlines, PLURAL(maxlines));
324 } else if (strcmp("minlines", param) == 0) {
325 minlines = strtol(value, NULL, 10);
326 if (debugmode)
327 syslog(LOG_DEBUG, "config: postings have min. %ld line%s",
328 minlines, PLURAL(minlines));
329 } else if (strcmp("maxbytes", param) == 0) {
330 maxbytes = strtoul(value, NULL, 10);
331 if (debugmode)
332 syslog(LOG_DEBUG,
333 "config: postings have max. %lu byte%s",
334 maxbytes, PLURAL(maxbytes));
335 } else if (strcmp("linebuffer", param) == 0) {
336 linebuffer = atoi(value);
337 if (debugmode)
338 syslog(LOG_DEBUG, "config: linebuffer is %d", linebuffer);
339 } else if (strcmp("allow_8bit_headers", param) == 0) {
340 allow_8bit_headers = atoi(value);
341 if (debugmode)
342 syslog(LOG_DEBUG, "config: allow_8bit_headers is %d",
343 allow_8bit_headers);
344 } else if (strcmp("debugmode", param) == 0) {
345 int d;
346 d = atoi(value);
347 debugmode = d > debugmode ? d : debugmode;
348 if (debugmode)
349 syslog(LOG_DEBUG, "config: debugmode is %d", debugmode);
350 } else if (strcmp("delaybody_in_situ", param) == 0) {
351 db_situ = atoi(value);
352 if (debugmode)
353 syslog(LOG_DEBUG, "config: delaybody_in_situ is %d (default 0)",
354 db_situ);
355 } else if (strcmp("delaybody", param) == 0) {
356 delaybody = atoi(value);
357 if (debugmode)
358 syslog(LOG_DEBUG, "config: delaybody is %d (default 0)",
359 delaybody);
360 } else if (strcmp("timeout_short", param) == 0) {
361 timeout_short = atoi(value);
362 if (debugmode)
363 syslog(LOG_DEBUG, "config: timeout_short is %d day%s",
364 timeout_short, PLURAL(timeout_short));
365 } else if (strcmp("timeout_long", param) == 0) {
366 timeout_long = atoi(value);
367 if (debugmode)
368 syslog(LOG_DEBUG, "config: timeout_long is %d day%s",
369 timeout_long, PLURAL(timeout_long));
370 } else if (strcmp("timeout_active", param) == 0) {
371 timeout_active = atoi(value);
372 if (debugmode)
373 syslog(LOG_DEBUG, "config: timeout_active is %d day%s",
374 timeout_active, PLURAL(timeout_active));
375 } else if (strcmp("timeout_client", param) == 0) {
376 timeout_client = atoi(value);
377 if (debugmode)
378 syslog(LOG_DEBUG, "config: timeout_client is %d second%s",
379 timeout_client, PLURAL(timeout_client));
380 } else if (strcmp("timeout_fetchnews", param) == 0) {
381 timeout_fetchnews = atoi(value);
382 if (debugmode)
383 syslog(LOG_DEBUG, "config: timeout_fetchnews is %d second%s",
384 timeout_fetchnews, PLURAL(timeout_fetchnews));
385 } else if (strcmp("timeout_lock", param) == 0) {
386 read_timeout_lock(value, "config");
387 } else if (strncmp("groupexpire", param, 11) == 0) {
388 char *m;
389 m = param;
390 while (*m && !(isspace((unsigned char)*m)))
391 m++;
392 while (isspace((unsigned char)*m))
393 m++;
394 if (m && *m) {
395 time_t e, i = (time_t) atol(value);
396 if (i >= (INT_MAX / SECONDS_PER_DAY))
397 i = (INT_MAX / SECONDS_PER_DAY) - 1;
398 if (debugmode) {
399 if ((long)i < 0)
400 syslog(LOG_DEBUG,
401 "config: groupexpire for %s is %ld (never)",
402 m, (long)i);
403 else if (i == 0) {
404 fprintf(stderr,
405 "config: groupexpire for %s is 0, which is treated as \"use the default expire\"\n", m);
406 syslog(LOG_INFO,
407 "config: groupexpire for %s is 0, which is treated as \"use the default expire\"",
408 m);
409 } else
410 syslog(LOG_DEBUG,
411 "config: groupexpire for %s is %ld day%s",
412 m, (long)i, PLURAL(i));
413 }
414 e = time(NULL) - (time_t) (SECONDS_PER_DAY * i);
415 ent = (struct expire_entry *)
416 critmalloc(sizeof(struct expire_entry), "readconfig");
417 ent->group = critstrdup(m, "readconfig");
418 ent->days = i;
419 ent->xtime = e;
420 ent->next = prev;
421 prev = ent;
422 }
423 } else if ((strcmp("maxage", param) == 0) ||
424 (strcmp("maxold", param) == 0)) {
425 /* maxold is for compatibility with leafnode+ */
426 maxage = atoi(value);
427 #if LONG_MAX / 86400 <= INT_MAX
428 if (maxage > LONG_MAX / 86400)
429 {
430 maxage = 24854; /* 32-bit: LONG_MAX / 86400 - 1 */
431 ln_log(LNLOG_SWARNING, LNLOG_CTOP,
432 "warning: config: maxage cannot exceed %d, "
433 "please fix %s", maxage, s);
434 }
435 #endif
436 if (debugmode)
437 syslog(LOG_DEBUG, "config: maxage is %d", maxage);
438 } else if (strcmp("maxfetch", param) == 0) {
439 artlimit = strtoul(value, NULL, 10);
440 if (debugmode)
441 syslog(LOG_DEBUG, "config: maxfetch is %lu", artlimit);
442 } else if (strcmp("port", param) == 0) {
443 unsigned long pp = strtoul(value, NULL, 10);
444 if (p) {
445 if (pp == 0 || pp > 65535) {
446 syslog(LOG_ERR,
447 "config: invalid port number for nntpport %s",
448 value);
449 } else {
450 p->port = (unsigned int)pp;
451 if (debugmode)
452 syslog(LOG_DEBUG, "config: nntpport is %u",
453 p->port);
454 }
455 } else {
456 syslog(LOG_ERR, "config: no server for nntpport %s", value);
457 }
458 } else if (strcmp("noactive", param) == 0) {
459 long tmp;
460 errno = 0;
461 tmp = strtol(value,NULL,10);
462 if (errno) {
463 syslog(LOG_ERR, "config: invalid value \"%s\" for noactive", value);
464 } else {
465 if (p) {
466 p->updateactive = !tmp;
467 if (debugmode)
468 syslog(LOG_DEBUG, "config: %s active file updates for %s",
469 p->updateactive ? "enabled" : "no", p->name);
470 } else {
471 syslog(LOG_ERR, "config: no server for noactive = %s",
472 value);
473 }
474 }
475 } else if (strcmp("noxover", param) == 0) {
476 if (p) {
477 p->noxover = TRUE;
478 if (debugmode)
479 syslog(LOG_DEBUG, "config: no XOVER for %s",
480 p->name);
481 } else
482 syslog(LOG_ERR, "config: no server for noxover = %s", value);
483 } else if (strcmp("nodesc", param) == 0) {
484 if (p) {
485 p->descriptions = !atoi(value);
486 if (debugmode)
487 syslog(LOG_DEBUG, "config: %s LIST NEWSGROUPS for %s",
488 p->descriptions ? "enabled" : "no", p->name);
489 } else
490 syslog(LOG_ERR, "config: no server for nodesc = %s", value);
491 } else if (strcmp("nopost", param) == 0) {
492 if (p) {
493 p->nopost = atoi(value);
494 if (debugmode)
495 syslog(LOG_DEBUG, "config: nopost for %s is %d",
496 p->name, p->nopost);
497 } else
498 syslog(LOG_ERR, "config: no server for nopost = %s", value);
499 } else if (strcmp("post_anygroup", param) == 0) {
500 if (p) {
501 p->post_anygroup = atoi(value);
502 if (debugmode)
503 syslog(LOG_DEBUG, "config: post_anygroup for %s is %d",
504 p->name, p->nopost);
505 } else
506 syslog(LOG_ERR, "config: no server for post_anygroup = %s", value);
507 } else if (strcmp("noread", param) == 0) {
508 if (p) {
509 p->noread = atoi(value);
510 if (debugmode)
511 syslog(LOG_DEBUG, "config: noread for %s is %d",
512 p->name, p->noread);
513 } else
514 syslog(LOG_ERR, "config: no server for noread = %s", value);
515 } else if (strcmp("only_groups_match_all", param) == 0) {
516 if (p) {
517 p->only_groups_match_all = atoi(value);
518 if (debugmode)
519 syslog(LOG_DEBUG, "config: only_groups_match_all for %s is %d",
520 p->name, p->only_groups_match_all);
521 } else
522 syslog(LOG_ERR, "config: no server for only_groups_match_all = %s", value);
523 } else if (strcmp("initialfetch", param) == 0) {
524 initiallimit = strtoul(value, NULL, 10);
525 if (debugmode)
526 syslog(LOG_DEBUG, "config: initialfetch is %lu",
527 initiallimit);
528 } else if ((strcmp("server", param) == 0) ||
529 (strcmp("supplement", param) == 0)) {
530 if (debugmode)
531 syslog(LOG_DEBUG, "config: server is %s", value);
532 p = (struct server *)critmalloc(sizeof(struct server),
533 "allocating space for server");
534 p->name = critstrdup(value, "readconfig");
535 p->descriptions = TRUE;
536 p->next = NULL;
537 p->timeout = 30; /* default 30 seconds */
538 p->port = 0;
539 p->username = NULL;
540 p->password = NULL;
541 p->nopost = 0;
542 p->noread = 0;
543 p->noxover = 0;
544 p->post_anygroup = 0;
545 p->updateactive = TRUE;
546 p->group_pcre = NULL;
547 p->only_groups_match_all = 0;
548 if (servers == NULL)
549 servers = p;
550 else
551 q->next = p;
552 q = p;
553 } else if (0 == strcmp("only_groups_pcre", param)) {
554 pcre2_code_8 *re = gs_compile((unsigned char *)value);
555 if (!re) exit(2);
556 if (p) {
557 p->group_pcre = re;
558 if (debugmode)
559 syslog(LOG_DEBUG, "config: only_groups_pcre for %s is %s",
560 p->name, value);
561 } else {
562 free(re);
563 syslog(LOG_ERR, "config: no server for nopost = %s", value);
564 }
565 } else {
566 ln_log(LNLOG_SERR, LNLOG_CTOP,
567 "config: unknown line %lu: \"%s = %s\"", curline,
568 param, value);
569 }
570 } else {
571 size_t i;
572 if ((i = strspn(l, " \t")) < strlen(l) && l[i] != '#') {
573 ln_log(LNLOG_SERR, LNLOG_CTOP,
574 "config: malformatted line %lu: \"%s\"", curline,
575 l);
576 }
577 }
578 }
579 if (maxage != 0 && maxage > expiredays && clamp_maxage == 0) {
580 ln_log(LNLOG_SERR, LNLOG_CTOP,
581 "config: maxage (%d) > expire (%d). This can cause duplicate download. Please fix your configuration, maxage must not be greater than expire.",
582 maxage, expiredays);
583 exit(1);
584 }
585 debug = debugmode;
586
587 if (!newsadmin) {
588 const char t[] = NEWS_USER;
589 newsadmin = critmalloc(strlen(fqdn) + strlen(t) + 2, "readconfig");
590 strcpy(newsadmin, t); /* RATS: ignore */
591 strcat(newsadmin, "@");
592 strcat(newsadmin, fqdn); /* RATS: ignore */
593 }
594
595 expire_base = ent;
596 fclose(f);
597 free(param);
598 free(value);
599
600 if (servers == NULL) {
601 syslog(LOG_ERR, "no server declaration in config file");
602 return 0;
603 }
604 if (!expire)
605 syslog(LOG_ERR, "no expire declaration in config file");
606
607 /* check for duplicate server configurations */
608 {
609 unsigned short port = 0;
610 struct servent *sp = getservbyname("nntp", "tcp");
611 if (sp) port = ntohs(sp->s_port);
612
613 for (p = servers; p ; p=p->next) {
614 for (q = p->next ; q ; q=q->next) {
615 unsigned short pp = p->port, qp = q->port;
616 if (!pp) pp = port;
617 if (!qp) qp = port;
618 if (!pp || !qp) {
619 syslog(LOG_ERR, "Cannot resolve service \"nntp\" protocol \"tcp\".");
620 fprintf(stderr, "Cannot resolve service \"nntp\" protocol \"tcp\".\n");
621 return 0;
622 }
623 if (pp != qp) continue;
624 if (strcasecmp(p->name, q->name)) continue;
625 syslog(LOG_ERR, "Duplicate definition for server %s port %u", p->name, (unsigned int)pp);
626 fprintf(stderr, "Duplicate definition for server %s port %u\n", p->name, (unsigned int)pp);
627 return 0;
628 }
629 }
630 }
631
632 if (debugmode > 1) {
633 getrlimit(RLIMIT_CORE, &corelimit);
634 corelimit.rlim_cur = COREFILESIZE;
635 if (setrlimit(RLIMIT_CORE, &corelimit) < 0 && debugmode)
636 syslog(LOG_DEBUG, "Changing core file size failed: %m");
637 corelimit.rlim_cur = 0;
638 getrlimit(RLIMIT_CORE, &corelimit);
639 if (debugmode)
640 syslog(LOG_DEBUG, "Core file size: %d", (int)corelimit.rlim_cur);
641 }
642
643 l = getenv("LN_LOCK_TIMEOUT");
644 if (l && *l)
645 read_timeout_lock(l, "LN_LOCK_TIMEOUT");
646
647 if (linebuffer) {
648 fflush(stdout);
649 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
650 fflush(stderr);
651 setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
652 }
653
654 validatefqdn(logtostderr);
655
656 if (debugmode && verbose) {
657 puts("");
658 puts("WARNING: Make sure that syslog.conf captures news.debug logging");
659 puts("-------- and obtain your debug output from syslog.");
660 puts("WARNING: The screen output below is not sufficient. Check syslog!");
661 puts("");
662 sleep(3);
663 }
664 return 1;
665 }
666
667 /*
668 1997-05-27 - T. Sweeney - Find a group in the expireinfo linked list and return
669 its expire time. Otherwise, return zero.
670 */
671 static struct expire_entry *
672 lookup_expireent(char *group)
673 {
674 struct expire_entry *a;
675
676 a = expire_base;
677 while (a != NULL) {
678 if (ngmatch(a->group, group) == 0)
679 return a;
680 a = a->next;
681 }
682 return NULL;
683 }
684
685 static void
686 freeserver(struct server *a) {
687 if (a->group_pcre) pcre2_code_free_8(a->group_pcre);
688 if (a->name) free(a->name);
689 if (a->username) free(a->username);
690 if (a->password) free(a->password);
691 free(a);
692 }
693
694 void /* exported for exclusive use in nntpd.c */
695 freeservers(void) {
696 struct server *i = servers, *n;
697
698 while(i != NULL) {
699 n = i->next;
700 freeserver(i);
701 i = n;
702 }
703 servers = NULL;
704 }
705
706
707 void
708 freeexpire(void)
709 {
710 struct expire_entry *a, *b;
711
712 a = expire_base;
713 while(a)
714 {
715 b = a->next;
716 free(a->group);
717 free(a);
718 a = b;
719 }
720 }
721
722 void freeconfig(void) {
723 freeservers();
724 if (newsadmin)
725 free(newsadmin);
726 freefilter();
727 if (filterfile)
728 free(filterfile);
729 freegetaline();
730 freeexpire();
731 (void)lookup(LOOKUP_FREE);
732 freelastreply();
733 }
734
735 time_t lookup_expire(char *group)
736 {
737 struct expire_entry *e;
738 e = lookup_expireent(group);
739 if (e) return e->xtime;
740 return 0;
741 }
742
743 int lookup_expiredays(char *group)
744 {
745 struct expire_entry *e;
746 e = lookup_expireent(group);
747 if (e) return e->days;
748 return 0;
749 }