1 /* $Id$ */
2 /******************************************************************************
3 * FIDOCONFIG --- library for fidonet configs
4 ******************************************************************************
5 * Copyright (C) 1998-1999
6 *
7 * Matthias Tichy
8 *
9 * Fido: 2:2433/1245 2:2433/1247 2:2432/605.14
10 * Internet: mtt@tichy.de
11 *
12 * Grimmestr. 12 Buchholzer Weg 4
13 * 33098 Paderborn 40472 Duesseldorf
14 * Germany Germany
15 *
16 * This file is part of FIDOCONFIG.
17 *
18 * This library is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU Library General Public
20 * License as published by the Free Software Foundation; either
21 * version 2 of the License, or (at your option) any later version.
22 *
23 * This library is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * Library General Public License for more details.
27 *
28 * You should have received a copy of the GNU Library General Public
29 * License along with this library; see file COPYING. If not, write to the Free
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 *****************************************************************************/
32
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <time.h>
38 #include <errno.h>
39 #include <assert.h>
40 #include <stdarg.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <limits.h>
44 #include <huskylib/compiler.h>
45
46 #ifdef HAS_UNISTD_H
47 # include <unistd.h>
48 #endif
49
50 #ifdef HAS_IO_H
51 # include <io.h>
52 #endif
53
54 #ifdef HAS_PWD_H
55 # include <pwd.h>
56 #endif
57
58 #ifdef HAS_GRP_H
59 # include <grp.h>
60 #endif
61
62 #ifdef HAS_SYSEXITS_H
63 #include <sysexits.h>
64 #endif
65 #ifdef HAS_SYS_SYSEXITS_H
66 #include <sys/sysexits.h>
67 #endif
68
69 #ifdef HAS_SYS_WAIT_H
70 #include <sys/wait.h>
71 #endif
72
73 #ifdef HAS_PROCESS_H
74 # include <process.h>
75 #endif
76
77 #ifdef HAS_STRINGS_H
78 # include <strings.h>
79 #endif
80
81 #include <huskylib/huskylib.h>
82
83 /* export functions from DLL */
84 #define DLLEXPORT
85 #include <huskylib/huskyext.h>
86
87 /* smapi */
88 #include <smapi/msgapi.h>
89
90 /* fidoconfig */
91 #include "fidoconf.h"
92 #include "common.h"
93 #include "findtok.h"
94 #include "tokens.h"
95 #include "grptree.h"
96
97 int fc_trycreate=0; /* Try to create nonexistant directories (defined in line.c) */
98 char *actualKeyword, *actualLine;
99 int actualLineNr;
100 char wasError = 0;
101 char CommentChar = '#';
102 int _carbonrule = CC_AND;
103
104 static s_link linkDefined;
105 static ps_robot curRobot = NULL; /* current robot */
106
fc_copyString(char * str,char ** pmem)107 int fc_copyString(char *str, char **pmem)
108 {
109 if (str==NULL) {
110 printf("Line %d: There is a parameter missing after %s!\n", actualLineNr, actualKeyword);
111 return 1;
112 }
113
114 return copyString(stripRoundingChars(str, "\""), pmem);
115 }
116
fc_copyStringWOstrip(char * str,char ** pmem)117 int fc_copyStringWOstrip(char *str, char **pmem)
118 {
119 if (str==NULL) {
120 printf("Line %d: There is a parameter missing after %s!\n", actualLineNr, actualKeyword);
121 return 1;
122 }
123 return copyString(str, pmem);
124 }
125
126
127 /*
128 create new address array by copying the old one
129 */
130
fc_copyAddressArray(unsigned int count,ps_addr sourceAddr,ps_addr * destAddr)131 int fc_copyAddressArray(unsigned int count, ps_addr sourceAddr, ps_addr *destAddr)
132 {
133 int rc = 0;
134
135 if (count > 0) /* we have addresses to copy */
136 {
137 *destAddr = malloc(sizeof(hs_addr) * count);
138 if (*destAddr != NULL)
139 memcpy(*destAddr, sourceAddr, sizeof(hs_addr) * count);
140 else
141 rc = 1; /* error */
142 }
143 else /* nothing to do */
144 {
145 *destAddr = NULL; /* reset pointer */
146 }
147
148 return rc;
149 }
150
151
152 #if 0
153 #define getRestOfLine() stripLeadingChars(strtok(NULL, "\0"), " \t")
154 #else
getRestOfLine(void)155 char *getRestOfLine(void) {
156 return stripLeadingChars(strtok(NULL, "\0"), " \t");
157 }
158 #endif
159
prErr(char * string,...)160 void prErr ( char *string, ...)
161 {
162 va_list ap;
163
164 printf("\"%s\", line %d: ", getCurConfName(), actualLineNr);
165 va_start(ap, string);
166 vprintf(string, ap);
167 va_end(ap);
168 putchar('\n');
169
170 }
171
getDescription(void)172 char *getDescription(void)
173 {
174 char *descBuf = NULL, *token;
175 int quoted=0, length;
176
177 while ((token=strtok(NULL," \t"))!=NULL)
178 {
179 xstrscat (&descBuf, token, " ", NULLP);
180 if (*token=='\"' && !quoted)
181 {
182 quoted=1;
183 if (token[1] == '\0') continue;
184 }
185 if (quoted && token[strlen(token)-1]=='\"') break;
186 if (!quoted) break;
187 }
188
189 if (descBuf == NULL)
190 {
191 prErr( "Error in area description!");
192 return NULL;
193 }
194
195 descBuf[length=(strlen(descBuf)-1)] = '\0'; /* remove trailing space */
196 if (quoted)
197 {
198 /* out. cut '"' */
199 descBuf[--length] = '\0';
200 memmove(descBuf, descBuf+1, length);
201 }
202
203 return descBuf;
204 }
205
parseVersion(char * token,s_fidoconfig * config)206 int parseVersion(char *token, s_fidoconfig *config)
207 {
208 char buffer[10], *temp = token;
209 int i = 0;
210
211 /* if there is no token return error... */
212 if (token==NULL) {
213 prErr( "There is a version number missing after %s!", actualKeyword);
214 return 1;
215 }
216
217 while (isdigit(*temp) && i<9) {
218 buffer[i] = *temp;
219 i++; temp++;
220 }
221 buffer[i] = 0;
222
223 config->cfgVersionMajor = atoi(buffer);
224
225 temp++; /* eat . */
226 i = 0;
227
228 while (isdigit(*temp) && i<9) {
229 buffer[i] = *temp;
230 i++; temp++;
231 }
232 buffer[i] = 0;
233
234 config->cfgVersionMinor = atoi(buffer);
235
236 return 0;
237 }
238
239 #define checkRobot() if (!curRobot) printRobotError();
printRobotError(void)240 void printRobotError(void)
241 {
242 prErr( "Keyword %s must appear inside robot section!", actualKeyword);
243 exit(EX_CONFIG);
244 }
245
printLinkError(void)246 void printLinkError(void)
247 {
248 prErr( "You must define a link first before you use %s!", actualKeyword);
249 exit(EX_CONFIG);
250 }
251
printAddrError(void)252 void printAddrError(void)
253 {
254 prErr("The main address must be defined before any areas!");
255 exit(EX_CONFIG);
256 }
257
getDescrLink(s_fidoconfig * config)258 s_link *getDescrLink(s_fidoconfig *config)
259 {
260 if (config->describeLinkDefaults) { /* describing defaults for links */
261 return config->linkDefaults;
262 } else {
263 if (config->linkCount) {
264 return config->links[config->linkCount-1];
265 } else {
266 printLinkError();
267 return NULL;
268 }
269 }
270 }
271
getDescrAnnDef(s_fidoconfig * config)272 ps_anndef getDescrAnnDef(s_fidoconfig *config)
273 {
274 if (config->ADCount) {
275 return &config->AnnDefs[config->ADCount-1];
276 } else {
277 prErr( "You must define a AnnAreaTag first before you use %s!", actualKeyword);
278 exit(EX_CONFIG);
279 }
280 return NULL;
281 }
282
283
parseAddress(char * token,s_fidoconfig * config)284 int parseAddress(char *token, s_fidoconfig *config)
285 {
286 char *aka;
287 hs_addr parsedaddr = {0};
288
289 if (token==NULL) {
290 prErr( "An address after %s is missing!", actualKeyword);
291 return 1;
292 }
293
294 aka = strtok(token, " \t"); /* only look at aka */
295 if (aka == NULL) {
296 prErr( "An address after %s is missing!", actualKeyword);
297 return 1;
298 }
299
300 if (parseFtnAddrZS(aka, &(parsedaddr)) & FTNADDR_ERROR) {
301 prErr( "The address after %s is invalid!", actualKeyword);
302 return 1;
303 }
304
305 config->addr = srealloc(config->addr, sizeof(hs_addr)*(config->addrCount+1));
306 memcpy(&(config->addr[config->addrCount]), &parsedaddr, sizeof(hs_addr));
307 config->addrCount++;
308
309 return 0;
310 }
311
parseRemap(char * token,s_fidoconfig * config)312 int parseRemap(char *token, s_fidoconfig *config)
313 {
314 char *param1, *param2, *param3;
315 int r=0, r2, r3;
316 s_remap remap;
317
318 if (token==NULL) {
319 prErr( "All parameters after %s are missing!", actualKeyword);
320 return 1;
321 }
322
323 memset(&remap, 0, sizeof(remap));
324
325 param1 = strtok(token, ",\t");
326 if (param1 == NULL) {
327 prErr( "Missing Name or * (1st field) after %s!", actualKeyword);
328 return 1;
329 }
330 if (strcmp(param1,"*")==0) {
331 param1=NULL;
332 }
333
334 param2 = strtok(NULL, ",\t");
335 if (param2 == NULL) {
336 prErr( "Address or * (2nd field) after %s is missing!",actualKeyword);
337 return 1;
338 }
339
340 param3 = strtok(NULL, " \t");
341 if (param3 == NULL) {
342 prErr( "Address (3rd field) after %s is missing!", actualKeyword);
343 return 1;
344 }
345
346 if (strcmp(param2,"*")!=0)
347 r2 = parseFtnAddrZS(param2, &(remap.oldaddr));
348 r3 = parseFtnAddrZS(param3, &(remap.newaddr));
349
350 if ( param1==NULL && remap.oldaddr.zone==0) {
351 prErr( "One of the two first Parameters must not be \"*\"");
352 r = 1;
353 }
354 if (r3 & FTNADDR_ERROR) {
355 prErr( "Invalid address in the 3rd Parameter (\"param3\")");
356 r = 1;
357 }
358 if (r == 0) { /* All OK, allocate memory and store data */
359 if (param1) { /* Name for rerouting if not "*" */
360 remap.toname=sstrdup(param1);
361 }
362 config->remaps = srealloc(config->remaps,
363 (config->remapCount+1)*sizeof(s_remap));
364 memcpy(&config->remaps[config->remapCount], &remap, sizeof(remap));
365 config->remapCount++;
366 }
367
368 return r;
369 }
370
371 /* Parse and check/create directory
372 *
373 */
parsePath(char * token,char ** var,char ** alreadyDefined)374 int parsePath(char *token, char **var, char **alreadyDefined)
375 {
376
377 if (*var != NULL) {
378 if (alreadyDefined==NULL || *alreadyDefined) {
379 prErr("Duplicate path!");
380 return 1;
381 }
382 nfree(*var);
383 }
384 if (token == NULL) {
385 prErr("A path after %s is missing!", actualKeyword);
386 return 1;
387 }
388 if (*token && token[strlen(token)-1] == PATH_DELIM)
389 Strip_Trailing(token, PATH_DELIM);
390 xscatprintf(var, "%s%c", token, (char) PATH_DELIM);
391 if (alreadyDefined) *alreadyDefined=*var;
392
393 if (!direxist(*var)) {
394 if (fc_trycreate)
395 if (_createDirectoryTree(*var)) {
396 prErr( "Path %s not found, can't create: %s", *var, strerror(errno));
397 return 1;
398 }else
399 { prErr( "Path %s created succesfully.", *var); }
400 else{
401 prErr( "Path %s not found!", *var);
402 return 1;
403 }
404 }
405 return 0;
406 }
407
parseAreaPath(char * token,char ** var,char ** alreadyDefined)408 int parseAreaPath(char *token, char **var, char **alreadyDefined)
409 {
410 /* char *p, *q, *osvar; */
411
412 if (*var != NULL) {
413 if (alreadyDefined==NULL || *alreadyDefined) {
414 prErr("Duplicate path!");
415 return 1;
416 }
417 nfree(*var);
418 }
419 if (token == NULL) {
420 prErr("A path after %s is missing!", actualKeyword);
421 return 1;
422 }
423 if (stricmp(token, "passthrough")==0) {
424 fc_copyString(token, &(*var));
425 if (alreadyDefined) *alreadyDefined=*var;
426 return 0;
427 }
428 if (*token && token[strlen(token)-1] == PATH_DELIM)
429 Strip_Trailing(token, PATH_DELIM);
430 xscatprintf(var, "%s%c", token, (char) PATH_DELIM);
431 if (alreadyDefined) *alreadyDefined=*var;
432
433 if (!direxist(*var)) {
434 if (fc_trycreate)
435 if (_createDirectoryTree(*var)) {
436 prErr( "Path %s not found, can't create: %s", *var, strerror(errno));
437 return 1;
438 }else
439 { prErr( "Path %s created succesfully.", *var); }
440 else{
441 prErr( "Path %s not found!", *var);
442 return 1;
443 }
444 }
445 return 0;
446 }
447
parseAreaPathExpand(char * token,char ** var,char ** alreadyDefined)448 int parseAreaPathExpand(char *token, char **var, char **alreadyDefined)
449 {
450 char *p;
451
452 if (*var != NULL) {
453 if (alreadyDefined==NULL || *alreadyDefined) {
454 prErr("Duplicate path!");
455 return 1;
456 }
457 nfree(*var);
458 }
459 if (token == NULL) {
460 prErr("A path after %s is missing!", actualKeyword);
461 return 1;
462 }
463 if (stricmp(token, "passthrough")==0) {
464 fc_copyString(token, &(*var));
465 if (alreadyDefined) *alreadyDefined=*var;
466 return 0;
467 }
468 p = vars_expand(sstrdup(token));
469 if (*p == '\0' || p[strlen(p)-1] != PATH_DELIM) {
470 xscatprintf(var, "%s%c", token, (char) PATH_DELIM);
471 xscatprintf(&p, "%c", (char) PATH_DELIM);
472 } else {
473 *var = sstrdup(token);
474 }
475 if (alreadyDefined) *alreadyDefined=*var;
476
477 if (!direxist(p)) {
478 if (fc_trycreate)
479 if (_createDirectoryTree(p)) {
480 prErr( "Path %s not found, can't create: %s", p, strerror(errno));
481 nfree(p);
482 return 1;
483 }else
484 { prErr( "Path %s created succesfully.", p); }
485 else{
486 prErr( "Path %s not found!", p);
487 nfree(p);
488 return 1;
489 }
490 }
491 nfree(p);
492 return 0;
493 }
494
parsePathNoCheck(char * token,char ** var,char ** alreadyDefined)495 int parsePathNoCheck(char *token, char **var, char **alreadyDefined)
496 {
497 if (*var != NULL) {
498 if (alreadyDefined==NULL || *alreadyDefined) {
499 prErr("Duplicate path!");
500 return 1;
501 }
502 nfree(*var);
503 }
504
505 if (token == NULL) {
506 prErr("A path after %s is missing!", actualKeyword);
507 return 1;
508 }
509
510 if (*token && token[strlen(token)-1] == PATH_DELIM)
511 Strip_Trailing(token, PATH_DELIM);
512 xscatprintf(var, "%s%c", token, (char) PATH_DELIM);
513 if (alreadyDefined) *alreadyDefined=*var;
514
515 return 0;
516 }
517
parsePublic(char * token,s_fidoconfig * config)518 int parsePublic(char *token, s_fidoconfig *config)
519 {
520 if (token == NULL) {
521 prErr( "A path after %s is missing!", actualKeyword);
522 return 1;
523 }
524 config->publicDir = srealloc(config->publicDir, sizeof(char *)*(config->publicCount+1));
525 config->publicDir[config->publicCount] = NULL;
526
527 if (*token && token[strlen(token)-1] == PATH_DELIM)
528 Strip_Trailing(token, PATH_DELIM);
529 xscatprintf(&(config->publicDir[config->publicCount]), "%s%c", token, (char) PATH_DELIM);
530
531 if (!direxist(config->publicDir[config->publicCount])) {
532 if (fc_trycreate)
533 if (_createDirectoryTree(token)) {
534 prErr( "Path %s not found, can't create: %s", token, strerror(errno));
535 return 1;
536 }else
537 { prErr( "Path %s created succesfully.", token); }
538 else{
539 prErr( "Path %s not found!", token);
540 return 1;
541 }
542 }
543
544 config->publicCount++;
545 return 0;
546 }
547
parseOwner(char * token,unsigned int * uid,unsigned int * gid)548 int parseOwner(char *token, unsigned int *uid, unsigned int *gid)
549 {
550 #ifdef __UNIX__
551 struct passwd *pw;
552 struct group *grp;
553 char *name, *group, *p;
554
555 if (token == NULL) {
556 prErr( "There are parameters missing after %s!", actualKeyword);
557 return 1;
558 }
559
560 p = strchr(token, '.');
561 if (p) {
562 *p = '\0';
563 name = token; group = p + 1;
564 } else {
565 name = token; group = NULL;
566 };
567
568 if (name != NULL) {
569 pw = getpwnam(name);
570
571 if (*name && pw == NULL) {
572 prErr( "User name %s is unknown to OS !", name);
573 return 1;
574 }
575 *uid = pw ? pw->pw_uid : (unsigned int)-1;
576
577 };
578
579 if (group != NULL) {
580 grp = getgrnam(group);
581
582 if ((*group) && grp == NULL) {
583 prErr( "Group name %s is unknown to OS !", group);
584 return 1;
585 }
586 *gid = grp ? grp->gr_gid : (unsigned int)-1;
587 }
588 #else
589 unused(token); unused(uid); unused(gid);
590 #endif
591 return 0;
592 }
593
parseNumber(char * token,int radix,unsigned * level)594 int parseNumber(char *token, int radix, unsigned *level) {
595 char *end = NULL;
596 unsigned long result;
597
598 if (token == NULL) {
599 prErr("Parameter after %s is missing!", actualKeyword);
600 return 1;
601 }
602
603 result = strtoul(token, &end, radix);
604
605 if (!(*end == '\0' && *token != '\0') || result == unsigned_long_max) {
606 prErr("Error in number representation : %s . %s!", token, end);
607 return 1;
608 }
609
610 *level = (unsigned) result;
611 return 0;
612 }
613
parseSeenBy2D(char * token,hs_addr ** addr,unsigned int * count)614 int parseSeenBy2D(char *token, hs_addr **addr, unsigned int *count)
615 {
616 const char *next;
617 unsigned int maxcount = *count;
618
619 if (token==NULL) {
620 prErr("An address after %s is missing!", actualKeyword);
621 return 1;
622 }
623
624 while (*token) {
625 while(!isdigit(*token)) token++;
626
627 if(*count >= maxcount) /* realloc once per 10 iteration */
628 {
629 maxcount = *count+10;
630 (*addr) = srealloc(*addr, sizeof(hs_addr)*maxcount);
631 memset(*addr+*count, 0, sizeof(hs_addr)*10);
632 }
633
634 if(parseFtnAddrZ(token, &(*addr)[*count], FTNADDR_2D, &next) & FTNADDR_ERROR)
635 return 1;
636
637 token = (char*)next;
638
639 (*count)++;
640
641 if (*token == ')') break;
642 }
643 if(maxcount > *count)
644 (*addr) = srealloc(*addr, sizeof(hs_addr)*(*count));
645 return 0;
646 }
647
getLinkRescanAccess(s_area * area,s_link * link)648 int getLinkRescanAccess(s_area *area, s_link *link)
649 {
650 int rescan = 0;
651
652 if (area->msgbType != MSGTYPE_PASSTHROUGH) {
653 if (link->numRescanGrp > 0) {
654 rescan = link->denyRescan;
655 if (grpInArray(area->group,link->RescanGrp,link->numRescanGrp))
656 rescan = (!link->denyRescan);
657 } else
658 rescan = (!link->denyRescan);
659 }
660
661 return rescan;
662 }
663
setLinkAccess(s_fidoconfig * config,s_area * area,s_arealink * arealink)664 void setLinkAccess(s_fidoconfig *config, s_area *area, s_arealink *arealink)
665 {
666 s_link *link=arealink->link;
667
668 if (link->numOptGrp > 0) {
669 /* default set export on, import on, mandatory off, manual off */
670 arealink->aexport = 1;
671 arealink->import = 1;
672 arealink->mandatory = 0;
673 arealink->manual = 0;
674
675 if (grpInArray(area->group,link->optGrp,link->numOptGrp)) {
676 arealink->aexport = link->aexport;
677 arealink->import = link->import;
678 arealink->mandatory = link->mandatory;
679 arealink->manual = link->manual;
680 }
681
682 } else {
683 arealink->aexport = link->aexport;
684 arealink->import = link->import;
685 arealink->mandatory = link->mandatory;
686 arealink->manual = link->manual;
687 }
688
689 arealink->rescan = getLinkRescanAccess(area, link);
690
691 if (area->mandatory) arealink->mandatory = 1;
692 if (area->manual) arealink->manual = 1;
693 if ((area->levelread > link->level) || ((link->Pause & area->areaType) && (!area->noPause))) arealink->aexport = 0;
694 if (area->levelwrite > link->level) arealink->import = 0;
695
696 if (area->group) {
697 if (link->numAccessGrp) {
698 if (config->numPublicGroup) {
699 if (!grpInArray(area->group,link->AccessGrp,link->numAccessGrp) &&
700 !grpInArray(area->group,config->PublicGroup,config->numPublicGroup)) {
701 arealink->aexport = 0;
702 arealink->import = 0;
703 }
704 } else if (!grpInArray(area->group,link->AccessGrp,link->numAccessGrp)) {
705 arealink->aexport = 0;
706 arealink->import = 0;
707 }
708 } else if (config->numPublicGroup) {
709 if (!grpInArray(area->group,config->PublicGroup,config->numPublicGroup)) {
710 arealink->aexport = 0;
711 arealink->import = 0;
712 }
713 }
714 }
715
716 }
717
718
parseAreaOption(s_fidoconfig * config,char * option,s_area * area)719 int parseAreaOption( s_fidoconfig *config, char *option, s_area *area)
720 {
721 char *error;
722 char *token;
723 char *iOption;
724 char *iToken;
725 size_t i;
726 long il;
727
728 if (option == NULL) {
729 prErr("There are parameters missing after %s!", actualKeyword);
730 return 1;
731 }
732
733 iOption = strLower(sstrdup(option));
734 if (strcmp(iOption, "b")==0) {
735 if( area->areaType == ECHOAREA ) {
736 token = strtok(NULL, " \t");
737 if (token == NULL) {
738 prErr("An msgbase type is missing after -b in areaOptions!");
739 nfree(iOption);
740 return 1;
741 }
742 if ( area->msgbType == MSGTYPE_PASSTHROUGH ) {
743 /* MsgBase type is already defined */
744 nfree(iOption);
745 return 0;
746 }
747
748 iToken = strLower(sstrdup(token));
749 if (strcasecmp(iToken, "squish")==0) {
750 area->msgbType = MSGTYPE_SQUISH;
751 }
752 else if (strcasecmp(iToken, "jam")==0) {
753 area->msgbType = MSGTYPE_JAM;
754 }
755 else if (strcasecmp(iToken, "msg")==0) {
756 area->msgbType = MSGTYPE_SDM;
757 }
758 else
759 {
760 prErr("MsgBase type %s not valid after -b in areaOptions!", token);
761 nfree(iOption);
762 nfree(iToken);
763 return 1;
764 }
765 nfree(iToken);
766 iToken = NULL;
767 } else {
768 prErr("Option '-b' is allowed for echoareas and localareas only!");
769 nfree(iOption);
770 return 1; /* error */
771 }
772 }
773 else if (strcasecmp(iOption, "pass")==0) {
774 area->msgbType = MSGTYPE_PASSTHROUGH;
775 }
776 else if (strcmp(iOption, "p")==0) {
777 token = strtok(NULL, " \t");
778 if (token == NULL) {
779 prErr("A number after -p in areaOptions is missing!");
780 nfree(iOption);
781 return 1;
782 }
783 area->nopack = 0;
784 il = strtol(token, &error, 0);
785 if ((error != NULL) && (*error != '\0')) {
786 prErr("The number after -p in areaOptions is wrong!");
787 nfree(iOption);
788 return 1; /* error occured; */
789 }
790 if(area->areaType == ECHOAREA) {
791 area->purge = il<0? config->EchoAreaDefault.purge : (unsigned) il ;
792 }
793 else if(area->areaType == FILEAREA) {
794 area->purge = il<0? config->FileAreaDefault.purge : (unsigned) il ;
795 }
796 }
797 else if (strcmp(iOption, "$m")==0) {
798 if( area->areaType == ECHOAREA ) {
799 token = strtok(NULL, " \t");
800 if (token == NULL) {
801 prErr("A number after -$m in areaOptions is missing!");
802 nfree(iOption);
803 return 1;
804 }
805 area->nopack = 0;
806 il = strtol(token, &error, 0);
807 if ((error != NULL) && (*error != '\0')) {
808 prErr("The number after -$m in areaOptions is wrong!");
809 nfree(iOption);
810 return 1; /* error */
811 }
812 area->max = il<0? config->EchoAreaDefault.max : (unsigned) il ;
813 }else{
814 prErr("Option '-$m' is allowed for echoareas and localareas only!");
815 nfree(iOption);
816 return 1; /* error */
817 }
818 }
819 else if (strcmp(iOption, "a")==0) {
820 token = strtok(NULL, " \t");
821 if (token == NULL)
822 {
823 prErr("Address after -a in areaOptions is missing!");
824 nfree(iOption);
825 return 1;
826 }
827 area->useAka = getAddr(config, token);
828 if (area->useAka == NULL) {
829 prErr("%s not found as address.", token);
830 nfree(iOption);
831 return 1;
832 }
833 }
834 else if (strcmp(iOption, "lr")==0) {
835 token = strtok(NULL, " \t");
836 if (token == NULL) {
837 prErr("A number after -lr in areaOptions is missing!");
838 nfree(iOption);
839 return 1;
840 }
841 for (i=0; i<strlen(token); i++) {
842 if (isdigit(token[i]) == 0) break;
843 }
844 if (i != strlen(token)) {
845 prErr("The number after -lr in areaOptions is wrong!");
846 nfree(iOption);
847 return 1;
848 }
849 il = strtol(token, &error, 0);
850 if ((error != NULL) && (*error != '\0')) {
851 prErr("The number after -lr in areaOptions is wrong!");
852 nfree(iOption);
853 return 1; /* error occured; */
854 }
855 if (il<0) {
856 prErr("The number after -lr in areaOptions is wrong (negative values not alloved)!");
857 nfree(iOption);
858 return 1; /* error occured; */
859 }
860 area->levelread = (unsigned) il ;
861
862 /* if link was added before -lr setting it must be updated */
863 for(i=0;i<area->downlinkCount;++i)
864 setLinkAccess( config, area, area->downlinks[i]);
865
866 }
867 else if (strcmp(iOption, "lw")==0) {
868 token = strtok(NULL, " \t");
869 if (token == NULL) {
870 prErr("A number after -lw in areaOptions is missing!");
871 nfree(iOption);
872 return 1;
873 }
874 for (i=0; i<strlen(token); i++) {
875 if (isdigit(token[i]) == 0) break;
876 }
877 if (i != strlen(token)) {
878 prErr("The number after -lw in areaOptions is wrong!");
879 nfree(iOption);
880 return 1;
881 }
882 il = strtol(token, &error, 0);
883 if ((error != NULL) && (*error != '\0')) {
884 prErr("The number after -lw in areaOptions is wrong!");
885 nfree(iOption);
886 return 1; /* error occured; */
887 }
888 if (il<0) {
889 prErr("The number after -lw in areaOptions is wrong (negative values not alloved)!");
890 nfree(iOption);
891 return 1; /* error occured; */
892 }
893 area->levelwrite = (unsigned) il ;
894 /* if link was added before -lw setting it must be updated */
895 for(i=0;i<area->downlinkCount;++i)
896 setLinkAccess( config, area, area->downlinks[i]);
897
898 }
899 else if (strcmp(iOption, "tooold")==0) {
900 if( area->areaType == ECHOAREA ) {
901 token = strtok(NULL, " \t");
902 if (token == NULL) {
903 prErr("A number after %s in areaOptions is missing!",iOption);
904 nfree(iOption);
905 return 1;
906 }
907 for (i=0; i<strlen(token); i++) {
908 if (isdigit(token[i]) == 0) break;
909 }
910 if (i != strlen(token)) {
911 prErr("The number after %s in areaOptions is wrong!",iOption);
912 nfree(iOption);
913 return 1;
914 }
915 il = strtol(token, &error, 0);
916 if ((error != NULL) && (*error != '\0')) {
917 prErr("The number after %s in areaOptions is wrong!",iOption);
918 nfree(iOption);
919 return 1; /* error occured; */
920 }
921 if (il<0) {
922 prErr("The number after %s in areaOptions is wrong (negative values not allowed)!",iOption);
923 nfree(iOption);
924 return 1; /* error occured; */
925 }
926 area->tooOld = (unsigned) il ;
927 }else{
928 prErr("Option '%s' is allowed for echoareas only!",iOption);
929 nfree(iOption);
930 return 1; /* error */
931 }
932 }
933 else if (strcmp(iOption, "toonew")==0) {
934 if( area->areaType == ECHOAREA ) {
935 token = strtok(NULL, " \t");
936 if (token == NULL) {
937 prErr("A number after %s in areaOptions is missing!",iOption);
938 nfree(iOption);
939 return 1;
940 }
941 for (i=0; i<strlen(token); i++) {
942 if (isdigit(token[i]) == 0) break;
943 }
944 if (i != strlen(token)) {
945 prErr("The number after %s in areaOptions is wrong!",iOption);
946 nfree(iOption);
947 return 1;
948 }
949 il = strtol(token, &error, 0);
950 if ((error != NULL) && (*error != '\0')) {
951 prErr("The number after %s in areaOptions is wrong!",iOption);
952 nfree(iOption);
953 return 1; /* error occured; */
954 }
955 if (il<0) {
956 prErr("The number after %s in areaOptions is wrong (negative values not allowed)!",iOption);
957 nfree(iOption);
958 return 1; /* error occured; */
959 }
960 area->tooNew = (unsigned) il ;
961 }else{
962 prErr("Option '%s' is allowed for echoareas only!",iOption);
963 nfree(iOption);
964 return 1; /* error */
965 }
966 }
967 else if (strcmp(iOption, "tinysb")==0) {
968
969 if( area->areaType == ECHOAREA ) {
970 area->tinySB = 1;
971 } else {
972 prErr("Option '-tinysb' is allowed for echoareas only!");
973 nfree(iOption);
974 return 1; /* error */
975 }
976 }
977 else if (strcmp(iOption, "notinysb")==0) {
978 if( area->areaType == ECHOAREA ) {
979 area->tinySB = 0;
980 }else{
981 prErr("Option '-notinysb' is allowed for echoareas only!");
982 nfree(iOption);
983 return 1; /* error */
984 }
985 }
986 else if (strcmp(iOption, "killsb")==0) {
987 if( area->areaType == ECHOAREA ) {
988 area->killSB = 1;
989 }else{
990 prErr("Option '-killsb' is allowed for echoareas only!");
991 nfree(iOption);
992 return 1; /* error */
993 }
994 }
995 else if (strcmp(iOption, "nokillsb")==0) {
996 if( area->areaType == ECHOAREA ) {
997 area->killSB = 0;
998 }else{
999 prErr("Option '-nokillsb' is allowed for echoareas only!");
1000 nfree(iOption);
1001 return 1; /* error */
1002 }
1003 }
1004 else if (strcmp(iOption, "keepunread")==0) {
1005 if( area->areaType == ECHOAREA ) {
1006 area->keepUnread = 1;
1007 }else{
1008 prErr("Option '-keepunread' is allowed for echoareas and localareas only!");
1009 nfree(iOption);
1010 return 1; /* error */
1011 }
1012 }
1013 else if (strcmp(iOption, "nokeepunread")==0) {
1014 if( area->areaType == ECHOAREA ) {
1015 area->keepUnread = 0;
1016 }else{
1017 prErr("Option '-nokeepunread' is allowed for echoareas and localareas only!");
1018 nfree(iOption);
1019 return 1; /* error */
1020 }
1021 }
1022 else if (strcmp(iOption, "killread")==0) {
1023 if( area->areaType == ECHOAREA ) {
1024 area->killRead = 1;
1025 }else{
1026 prErr("Option '%s' is allowed for echoareas and localareas only!",iOption);
1027 nfree(iOption);
1028 return 1; /* error */
1029 }
1030 }
1031 else if (strcmp(iOption, "nokillread")==0) {
1032 if( area->areaType == ECHOAREA ) {
1033 area->killRead = 0;
1034 }else{
1035 prErr("Option '%s' is allowed for echoareas and localareas only!",iOption);
1036 nfree(iOption);
1037 return 1; /* error */
1038 }
1039 }
1040
1041 else if (strcmp(iOption, "h")==0) area->hide = 1;
1042 else if (strcmp(iOption, "hide")==0) area->hide = 1;
1043 else if (strcmp(iOption, "nohide")==0) area->hide = 0;
1044 else if (strcmp(iOption, "k")==0) area->killMsgBase = 1;
1045 else if (strcmp(iOption, "kill")==0) area->killMsgBase = 1;
1046 else if (strcmp(iOption, "nokill")==0) area->killMsgBase = 0;
1047 else if (strcmp(iOption, "manual")==0) area->manual = 1;
1048 else if (strcmp(iOption, "nomanual")==0) area->manual = 0;
1049 else if (strcmp(iOption, "nopause")==0) area->noPause = 1;
1050 else if (strcmp(iOption, "pause")==0) area->noPause = 0;
1051 else if (strcmp(iOption, "nolink")==0) area->nolink = 1;
1052 else if (strcmp(iOption, "link")==0) area->nolink = 0;
1053 else if (strcmp(iOption, "mandatory")==0) area->mandatory = 1;
1054 else if (strcmp(iOption, "nomandatory")==0) area->mandatory = 0;
1055 else if (strcmp(iOption, "debug")==0) area->debug = 1;
1056 else if (strcmp(iOption, "nodebug")==0) area->debug = 0;
1057 else if (strcmp(iOption, "dosfile")==0) {
1058 if( area->areaType == ECHOAREA ) {
1059 area->DOSFile = 1;
1060 }else{
1061 prErr("Option '%s' is allowed for echoareas and localareas only!",iOption);
1062 nfree(iOption);
1063 return 1; /* error */
1064 }
1065 }
1066 else if (strcmp(iOption, "nodosfile")==0) {
1067 if( area->areaType == ECHOAREA ) {
1068 area->DOSFile = 0;
1069 }else{
1070 prErr("Option '%s' is allowed for echoareas and localareas only!",iOption);
1071 nfree(iOption);
1072 return 1; /* error */
1073 }
1074 }
1075 else if (strcmp(iOption, "paused")==0) area->paused = 1;
1076 else if (strcmp(iOption, "noautoareapause")==0) area->noautoareapause = 1;
1077 else if (strcmp(iOption, "autoareapause")==0) area->noautoareapause = 0;
1078 else if (strcmp(iOption, "nopack")==0) area->nopack = 1;
1079 else if (strcmp(iOption, "pack")==0) area->nopack = 0;
1080 else if (strcmp(iOption, "ccoff")==0) {
1081 if( area->areaType == ECHOAREA ) {
1082 area->ccoff=1;
1083 }else{
1084 prErr("Option '%s' is allowed for echoareas and localareas only!",iOption);
1085 nfree(iOption);
1086 return 1; /* error */
1087 }
1088 }
1089 else if (strcmp(iOption, "noccoff")==0) {
1090 if( area->areaType == ECHOAREA ) {
1091 area->ccoff=0;
1092 }else{
1093 prErr("Option '%s' is allowed for echoareas and localareas only!",iOption);
1094 nfree(iOption);
1095 return 1; /* error */
1096 }
1097 }
1098 else if (strcmp(iOption, "ccon")==0) {
1099 if( area->areaType == ECHOAREA ) {
1100 area->ccoff=0;
1101 }else{
1102 prErr("Option '%s' is allowed for echoareas and localareas only!",iOption);
1103 nfree(iOption);
1104 return 1; /* error */
1105 }
1106 }
1107 else if (strcmp(iOption, "keepsb")==0) {
1108 if( area->areaType == ECHOAREA ) {
1109 area->keepsb=1;
1110 }else{
1111 prErr("Option '%s' is allowed for echoareas and localareas only!",iOption);
1112 nfree(iOption);
1113 return 1; /* error */
1114 }
1115 }
1116 else if (strcmp(iOption, "nokeepsb")==0) {
1117 if( area->areaType == ECHOAREA ) {
1118 area->keepsb=0;
1119 }else{
1120 prErr("Option '%s' is allowed for echoareas and localareas only!",iOption);
1121 nfree(iOption);
1122 return 1; /* error */
1123 }
1124 }
1125 else if (strcmp(iOption, "sendorig")==0) {
1126 if( area->areaType == FILEAREA ) {
1127 area->sendorig = 1;
1128 }else{
1129 prErr("Option '%s' is allowed for fileareas only!",iOption);
1130 nfree(iOption);
1131 return 1; /* error */
1132 }
1133 }
1134 else if (strcmp(iOption, "nosendorig")==0) {
1135 if( area->areaType == FILEAREA ) {
1136 area->sendorig = 0;
1137 }else{
1138 prErr("Option '%s' is allowed for fileareas only!",iOption);
1139 nfree(iOption);
1140 return 1; /* error */
1141 }
1142 }
1143 else if (strcmp(iOption, "crc")==0) {
1144 if( area->areaType == FILEAREA ) {
1145 area->noCRC = 0;
1146 }else{
1147 prErr("Option '%s' is allowed for fileareas only!",iOption);
1148 nfree(iOption);
1149 return 1; /* error */
1150 }
1151 }
1152 else if (strcmp(iOption, "nocrc")==0) {
1153 if( area->areaType == FILEAREA ) {
1154 area->noCRC = 1;
1155 }else{
1156 prErr("Option '%s' is allowed for fileareas only!",iOption);
1157 nfree(iOption);
1158 return 1; /* error */
1159 }
1160 }
1161 else if (strcmp(iOption, "replace")==0) {
1162 if( area->areaType == FILEAREA ) {
1163 area->noreplace = 0;
1164 }else{
1165 prErr("Option '%s' is allowed for fileareas only!",iOption);
1166 nfree(iOption);
1167 return 1; /* error */
1168 }
1169 }
1170 else if (strcmp(iOption, "noreplace")==0) {
1171 if( area->areaType == FILEAREA ) {
1172 area->noreplace = 1;
1173 }else{
1174 prErr("Option '%s' is allowed for fileareas only!",iOption);
1175 nfree(iOption);
1176 return 1; /* error */
1177 }
1178 }
1179 else if (strcmp(iOption, "rename")==0) {
1180 if( area->areaType == FILEAREA ) {
1181 area->rename = 1;
1182 }else{
1183 prErr("Option '%s' is allowed for fileareas only!",iOption);
1184 nfree(iOption);
1185 return 1; /* error */
1186 }
1187 }
1188 else if (strcmp(iOption, "norename")==0) {
1189 if( area->areaType == FILEAREA ) {
1190 area->rename = 0;
1191 }else{
1192 prErr("Option '%s' is allowed for fileareas only!",iOption);
1193 nfree(iOption);
1194 return 1; /* error */
1195 }
1196 }
1197 else if (strcmp(iOption, "sbkeepall")==0) {
1198 if( area->areaType == ECHOAREA ) {
1199 area->sbkeep_all = 1;
1200 }else{
1201 prErr("Option '%s' is allowed for echoareas only!",iOption);
1202 nfree(iOption);
1203 return 1; /* error */
1204 }
1205 }
1206 else if (strcmp(iOption, "nosbkeepall")==0) {
1207 if( area->areaType == ECHOAREA ) {
1208 area->sbkeep_all = 0;
1209 }else{
1210 prErr("Option '%s' is allowed for echoareas only!",iOption);
1211 nfree(iOption);
1212 return 1; /* error */
1213 }
1214 }
1215 else if (strcmp(iOption, "diz")==0) {
1216 if( area->areaType == FILEAREA ) {
1217 area->nodiz = 0;
1218 }else{
1219 prErr("Option '%s' is allowed for fileareas only!",iOption);
1220 nfree(iOption);
1221 return 1; /* error */
1222 }
1223 }
1224 else if (strcmp(iOption, "nodiz")==0) {
1225 if( area->areaType == FILEAREA ) {
1226 area->nodiz = 1;
1227 }else{
1228 prErr("Option '%s' is allowed for fileareas only!",iOption);
1229 nfree(iOption);
1230 return 1; /* error */
1231 }
1232 }
1233 else if (strcmp(iOption, "dupecheck")==0) {
1234 token = strtok(NULL, " \t");
1235 if (token == NULL) {
1236 prErr("Missing dupeCheck parameter!");
1237 nfree(iOption);
1238 return 1;
1239 }
1240 if (stricmp(token, "off")==0) area->dupeCheck = dcOff;
1241 else if (stricmp(token, "move")==0) area->dupeCheck = dcMove;
1242 else if (stricmp(token, "del")==0) area->dupeCheck = dcDel;
1243 else {
1244 prErr("Wrong dupeCheck parameter!");
1245 nfree(iOption);
1246 return 1; /* error */
1247 }
1248 }
1249 else if (strcmp(iOption, "dupehistory")==0) {
1250 token = strtok(NULL, " \t");
1251 if (token == NULL) {
1252 prErr("Number is missing after -dupehistory in areaOptions!");
1253 nfree(iOption);
1254 return 1;
1255 }
1256 area->dupeHistory = (unsigned) strtol(token, &error, 0);
1257 if ((error != NULL) && (*error != '\0')) {
1258 prErr("Number is wrong after -dupeHistory in areaOptions!");
1259 nfree(iOption);
1260 return 1; /* error occured; */
1261 }
1262 }
1263 /* val: -scan listed|manual|never */
1264 else if (strcmp(iOption, "scan")==0) {
1265 if (area->areaType != ECHOAREA) {
1266 prErr("Option '%s' is allowed for echoareas and localareas only!", iOption);
1267 nfree(iOption);
1268 return 1; /* error */
1269 }
1270 token = strtok(NULL, " \t");
1271 if (token == NULL) {
1272 prErr("Scan parameter is missing!");
1273 nfree(iOption);
1274 return 1;
1275 }
1276 if (stricmp(token, "never")==0) area->scanMode = smNever;
1277 else if (stricmp(token, "manual")==0) area->scanMode = smManual;
1278 else if (stricmp(token, "listed")==0) area->scanMode = smListed;
1279 else {
1280 prErr("Wrong scan parameter!");
1281 nfree(iOption);
1282 return 1; /* error */
1283 }
1284 }
1285 /* /val */
1286 else if (strcmp(iOption, "g")==0) {
1287 token = strtok(NULL, " \t");
1288 if (token == NULL) {
1289 nfree(iOption);
1290 return 1;
1291 }
1292 /* dmitry: this overrides group in EchoAreaDefaults */
1293 nfree(area->group);
1294 area->group = sstrdup(token);
1295 }
1296 else if (strcmp(iOption, "$")==0) ;
1297 else if (strcmp(iOption, "0")==0) ;
1298 else if (strcmp(iOption, "d")==0) {
1299 if ((area->description=getDescription())==NULL) {
1300 nfree(iOption);
1301 return 1;
1302 }
1303 }
1304 else if (strncmp(iOption, "sbadd(", 6)==0) {
1305 if( area->areaType == ECHOAREA ) {
1306 parseSeenBy2D(iOption,&(area->sbadd),&(area->sbaddCount));
1307 } else {
1308 prErr("Option '%s' is allowed for echoareas only!",iOption);
1309 nfree(iOption);
1310 return 1; /* error */
1311 }
1312 }
1313 else if (strncmp(iOption, "sbign(", 6)==0) {
1314 if( area->areaType == ECHOAREA ) {
1315 parseSeenBy2D(iOption,&(area->sbign),&(area->sbignCount));
1316 } else {
1317 prErr("Option '%s' is allowed for echoareas only!",iOption);
1318 nfree(iOption);
1319 return 1; /* error */
1320 }
1321 }
1322 else if (strncmp(iOption, "sbstrip(", 8)==0) {
1323 if( area->areaType == ECHOAREA ) {
1324 parseSeenBy2D(iOption,&(area->sbstrip),&(area->sbstripCount));
1325 } else {
1326 prErr("Option '%s' is allowed for echoareas only!",iOption);
1327 nfree(iOption);
1328 return 1; /* error */
1329 }
1330 }
1331 else if (strncmp(iOption, "sbkeep(", 7)==0) {
1332 if( area->areaType == ECHOAREA ) {
1333 parseSeenBy2D(iOption,&(area->sbkeep),&(area->sbkeepCount));
1334 }else{
1335 prErr("Option '%s' is allowed for echoareas only!",iOption);
1336 nfree(iOption);
1337 return 1; /* error */
1338 }
1339 }
1340 else if (strcmp(iOption, "r")==0) {
1341 if (area->def_subscribing!=RW) {
1342 prErr("Can't mix area options \"-r\" and \"-w\"!");
1343 nfree(iOption);
1344 return 1;
1345 }
1346 area->def_subscribing = RO;
1347 }
1348 else if (strcmp(iOption, "w")==0) {
1349 if (area->def_subscribing!=RW) {
1350 prErr("Can't mix area options \"-r\" and \"-w\"!");
1351 nfree(iOption);
1352 return 1;
1353 }
1354 area->def_subscribing = WO;
1355 }
1356 else {
1357 prErr("unknown area option \"-%s\"!", option);
1358 nfree(iOption);
1359 return 1;
1360 }
1361
1362 nfree(iOption);
1363 return 0;
1364 }
1365
parseLinkOption(s_arealink * alink,char * token)1366 int parseLinkOption(s_arealink *alink, char *token)
1367 {
1368 char *iToken;
1369
1370 if (token == NULL) {
1371 prErr("Parameters after %s are missing!", actualKeyword);
1372 return 1;
1373 }
1374 iToken = strLower(sstrdup(token));
1375 if (strcmp(iToken, "r")==0) alink->import = 0;
1376 else if (strcmp(iToken, "w")==0) alink->aexport = 0;
1377 else if (strcmp(iToken, "mn")==0) alink->mandatory = 1;
1378 else if (strcmp(iToken, "def")==0) alink->defLink = 1;
1379 else {
1380 nfree(iToken);
1381 return 1;
1382 }
1383
1384 nfree(iToken);
1385 return 0;
1386 }
1387
parseAreaLink(s_fidoconfig * config,s_area * area,char * tok)1388 int parseAreaLink(s_fidoconfig *config, s_area *area, char *tok)
1389 {
1390 s_arealink *arealink;
1391 s_link *link;
1392
1393 if (tok == NULL) {
1394 prErr("Parameters after %s are missing!", actualKeyword);
1395 return 1;
1396 }
1397
1398 if ((link = getLinkForArea(config, tok, area)) == NULL) {
1399 prErr("no links like \"%s\" in config!", tok);
1400 return 1;
1401 }
1402 if (isLinkOfArea(link, area)) {
1403 prErr("link %s is subscribed twice!", tok);
1404 return 0;
1405 }
1406
1407 area->downlinks = srealloc(area->downlinks, sizeof(s_arealink*)*(area->downlinkCount+1));
1408 area->downlinks[area->downlinkCount] = (s_arealink*)scalloc(1, sizeof(s_arealink));
1409 area->downlinks[area->downlinkCount]->link = link;
1410
1411 arealink = area->downlinks[area->downlinkCount];
1412 area->downlinkCount++;
1413
1414 setLinkAccess(config, area, arealink);
1415
1416 return 0;
1417 }
1418
1419 /*
1420 useDefs
1421 uses enum pauses { NOPAUSE, ECHOAREA, FILEAREA } for choosing defaults
1422 */
parseArea(s_fidoconfig * config,char * token,s_area * area,int useDefs)1423 int parseArea(s_fidoconfig *config, char *token, s_area *area, int useDefs)
1424 {
1425 char *tok, addr[24], *ptr;
1426 unsigned int rc = 0, i,j;
1427 int toklen;
1428 grp_t *group;
1429 e_pauses aType = area->areaType;
1430
1431 if (token == NULL) {
1432 prErr("Parameters after %s are missing!", actualKeyword);
1433 return 1;
1434 }
1435
1436 /* memset(area, '\0', sizeof(s_area)); */
1437 area->scanMode = smNone; /* val: just to be sure it's set */
1438
1439 /* need add checking for area->areaType == 0 aka NOPAUSE ) */
1440
1441 if (useDefs) { /* copy defaults */
1442 /* echo|file diffs */
1443 if(area->areaType == ECHOAREA) {
1444 memcpy(area,&(config->EchoAreaDefault),sizeof(s_area));
1445 }
1446 else if(area->areaType == FILEAREA) {
1447 memcpy(area,&(config->FileAreaDefault),sizeof(s_area));
1448 }
1449 /* default has perhaps groups */
1450 /* perhaps a description */
1451 /* perhaps downlinks */
1452 /* areaName==NULL */
1453 /* fileName==NULL */
1454 /* perhaps other settings*/
1455 /* allways an useAka */
1456 } else { /* netmail - don't copy defaults */
1457 memset(area, 0, sizeof(s_area));
1458 }
1459 area->areaType = aType;
1460
1461 tok = strtok(token, " \t");
1462 if (tok == NULL) {
1463 prErr("An areaname after %s is missing!", actualKeyword);
1464 return 1; /* if there is no areaname */
1465 }
1466
1467 if (useDefs && (group = findGroupForArea(tok)) != NULL )
1468 memcpy(area, group->area,sizeof(s_area));
1469
1470 area->areaName= (char *) smalloc(strlen(tok)+1);
1471 if (*tok=='\"' && tok[strlen(tok)-1]=='\"' && tok[1]) {
1472 strcpy(area->areaName, tok+1);
1473 area->areaName[strlen(area->areaName)-1] = '\0';
1474 } else
1475 strcpy(area->areaName, tok);
1476
1477 if (token[strlen(tok)] == '\0')
1478 token[strlen(tok)] = ' ';
1479
1480
1481 /* copy default group
1482 * fc_freeEchoArea() and parseAreaOption() will free this memory */
1483 if(area->group!=NULL)
1484 area->group=sstrdup(area->group);
1485 area->description=NULL;
1486
1487 /* not poiting to the links of the default --> .. */
1488 if(area->downlinkCount){
1489 j=area->downlinkCount;
1490 area->downlinkCount=0; /* was copied from default but there were no downlinks added really */
1491 area->downlinks=NULL;
1492 /* so now add default downlinks */
1493
1494 /* echo|file diffs */
1495 if(area->areaType == ECHOAREA) {
1496 for(i=0;i<j;++i)
1497 rc += parseAreaLink(config, area, aka2str(( (config->EchoAreaDefault).downlinks[i]->link->hisAka )));
1498 } else if(area->areaType == FILEAREA) {
1499 for(i=0;i<j;++i)
1500 rc += parseAreaLink(config, area, aka2str(( (config->FileAreaDefault).downlinks[i]->link->hisAka )));
1501 }
1502 }
1503
1504 /* copy SEEN-BY arrays from default */
1505 if(area->areaType == ECHOAREA) /* just for echoareas */
1506 {
1507 rc += fc_copyAddressArray(area->sbaddCount, (config->EchoAreaDefault).sbadd, &(area->sbadd));
1508 rc += fc_copyAddressArray(area->sbignCount, (config->EchoAreaDefault).sbign, &(area->sbign));
1509 rc += fc_copyAddressArray(area->sbkeepCount, (config->EchoAreaDefault).sbkeep, &(area->sbkeep));
1510 rc += fc_copyAddressArray(area->sbstripCount, (config->EchoAreaDefault).sbstrip, &(area->sbstrip));
1511 }
1512
1513 /* area->fperm = area->uid = area->gid = -1;*/
1514 if(!area->fperm && !area->uid && !area->gid)
1515 area->fperm = area->uid = area->gid = (UINT)-1;
1516
1517 /* area->msgbType = MSGTYPE_SDM;*/
1518 if(!area->msgbType)
1519 area->msgbType= MSGTYPE_SQUISH;
1520
1521 /* area->useAka = config->addr;*/
1522
1523 if(area->useAka==NULL)
1524 area->useAka = config->addr;
1525
1526 /* set default parameters of dupebase */
1527 if(!area->dupeHistory)
1528 area->dupeHistory = 7;
1529
1530 /* set defaults for MS-DOS */
1531 #ifdef __DOS__
1532 area->DOSFile = 1;
1533 #endif
1534
1535 tok = strtok(token, " \t");
1536 tok = strtok(NULL, " \t");
1537
1538 if (tok==NULL) {
1539 /* was default settings.. */
1540 if (area->msgbType==MSGTYPE_PASSTHROUGH) return 0;
1541 else {
1542 prErr("A pathname is missing %s!", actualLine);
1543 return 2; /* if there is no filename */
1544 }
1545 }
1546
1547 toklen=strlen(tok); /* points to '\0' */
1548 if (stricmp(tok, "passthrough") != 0) {
1549 /* perhaps passthrough in default, so this does not have to be */
1550 /* a filename */
1551
1552 /* is it a filename? */
1553 ptr=tok;
1554 while(*ptr && *ptr != PATH_DELIM && !isspace(*ptr))
1555 ++ptr;
1556 if(*ptr==PATH_DELIM){
1557 /* yes it is a filename :=) */
1558 /* msgbase on disk */
1559 area->fileName = (char *) scalloc(1,toklen + 2);
1560 strcpy(area->fileName, tok);
1561 if((area->areaType == FILEAREA) && (tok[toklen-1]!=PATH_DELIM))
1562 area->fileName[toklen] = PATH_DELIM;
1563
1564 tok = strtok(NULL, " \t");
1565 }else if(area->msgbType!=MSGTYPE_PASSTHROUGH){
1566 /* was not a filename, and default not passthrough */
1567 prErr("A pathname is missing %s!", actualLine);
1568 return 2; /* if there is no filename */
1569 }
1570
1571 }else{
1572 /* passthrough area */
1573 /* area->fileName = NULL; was copied from default */
1574 area->msgbType = MSGTYPE_PASSTHROUGH;
1575 tok = strtok(NULL, " \t");
1576 }
1577
1578
1579 while (tok != NULL) {
1580
1581
1582 if(tok[0]=='-') {
1583 rc += parseAreaOption(config, tok+1, area);
1584 if (rc) return rc;
1585 }
1586 else if ((isdigit(*tok) || (*tok=='*')) && (patmat(tok, "*:*/*") || patmat(tok, "*:*/*.*"))) {
1587
1588 if (strchr(tok, '*')) {
1589 /* link mask present: set mandatory for all links matched. */
1590 j = area->downlinkCount;
1591 for (i=0; i<config->linkCount; i++) {
1592 strcpy(addr, aka2str(config->links[i]->hisAka));
1593 if (patmat(addr, tok)) {
1594 parseAreaLink(config,area,addr);
1595 area->downlinks[area->downlinkCount-1]->mandatory = 1;
1596 } else if (config->links[i]->hisAka.point==0) {
1597 strcat(addr, ".0");
1598 if (patmat(addr, tok)) {
1599 parseAreaLink(config,area,addr);
1600 area->downlinks[area->downlinkCount-1]->mandatory = 1;
1601 }
1602 }
1603 }
1604 tok = strtok(NULL, " \t");
1605 while (tok) {
1606 if (tok[0]!='-') break;
1607 for (i=j; i<area->downlinkCount; i++) {
1608 if (parseLinkOption(area->downlinks[i], tok+1))
1609 break;
1610 }
1611 if (i<area->downlinkCount) break;
1612 tok = strtok(NULL, " \t");
1613 }
1614 continue;
1615 }
1616
1617 rc += parseAreaLink(config, area, tok);
1618 if (rc) return rc;
1619
1620 tok = strtok(NULL, " \t");
1621 while (tok) {
1622 if (tok[0]=='-') {
1623 if (parseLinkOption(area->downlinks[area->downlinkCount-1], tok+1))
1624 break;
1625 tok = strtok(NULL, " \t");
1626 } else break;
1627 }
1628 continue;
1629 }
1630 else {
1631 prErr("Error in areaOptions token=%s!", tok);
1632 rc +=1;
1633 }
1634 tok = strtok(NULL, " \t");
1635 }
1636
1637 if(area->description==NULL && config->EchoAreaDefault.description!=NULL)
1638 area->description=sstrdup(config->EchoAreaDefault.description);
1639
1640 return rc;
1641 }
1642
parseAreaDefault(s_fidoconfig * config,char * token,s_area * adef,int cleanup)1643 int parseAreaDefault(s_fidoconfig *config, char *token, s_area *adef, int cleanup)
1644 {
1645 char *tok, addr[24];
1646 unsigned int rc = 0, i;
1647
1648
1649 /* default has perhaps groups */
1650 /* perhaps a description */
1651 /* perhaps downlinks */
1652 /* areaName==NULL */
1653 /* fileName==NULL */
1654 /* perhaps other settings*/
1655 /* allways an useAka */
1656
1657
1658 /* cleanup */
1659 if (cleanup) {
1660 e_pauses aType = adef->areaType;
1661 fc_freeEchoArea(adef);
1662 memset(adef, '\0', sizeof(s_area));
1663 adef->useAka = config->addr;
1664 adef->areaType = aType;
1665 adef->fperm = adef->uid = adef->gid = (UINT)-1;
1666 adef->msgbType = MSGTYPE_SDM;
1667 /* set default parameters of dupebase */
1668 adef->dupeHistory = 7; /* 7 days */
1669 /* val: set defaul scan mode */
1670 adef->scanMode = smNone;
1671 /* set defaults for MS-DOS */
1672 #ifdef __DOS__
1673 adef->DOSFile = 1;
1674 #endif
1675 }
1676
1677 if (token == NULL) /* all defaults off */
1678 return 0;
1679 if(!strncasecmp(token,"off",3))
1680 return 0; /* default off */
1681
1682 tok = strtok(token, " \t");
1683 if (tok == NULL) { /* does this ever happen?? */
1684 prErr("Parameters after %s are missing!", actualKeyword);
1685 return 2;
1686 }
1687
1688 while (tok != NULL) {
1689 if (stricmp(tok, "passthrough") == 0) {
1690 /* passthrough area */
1691 /* adef->fileName = NULL;*/
1692 adef->msgbType = MSGTYPE_PASSTHROUGH;
1693 }else if(tok[0]=='-') {
1694 rc += parseAreaOption(config, tok+1, adef);
1695 if (rc) return rc;
1696 }else if ((isdigit(*tok) || (*tok=='*')) && (patmat(tok, "*:*/*") || patmat(tok, "*:*/*.*"))) {
1697 if (strchr(tok, '*')) {
1698 for (i=0; i<config->linkCount; i++) {
1699 sprintf(addr, "%s", aka2str(config->links[i]->hisAka));
1700 if (patmat(addr, tok)) {
1701 parseAreaLink(config,adef,addr);
1702 adef->downlinks[adef->downlinkCount-1]->mandatory = 1;
1703 }
1704 }
1705 tok = strtok(NULL, " \t");
1706 continue;
1707 }
1708 rc += parseAreaLink(config, adef, tok);
1709 if (rc) return rc;
1710 tok = strtok(NULL, " \t");
1711 while (tok) {
1712 if (tok[0]=='-') {
1713 if (parseLinkOption(adef->downlinks[adef->downlinkCount-1], tok+1))
1714 break;
1715 tok = strtok(NULL, " \t");
1716 } else break;
1717 }
1718 continue;
1719 }
1720 else {
1721 prErr("Error in areaOptions token=%s!", tok);
1722 rc +=1;
1723 }
1724 tok = strtok(NULL, " \t");
1725 }
1726
1727 return rc;
1728 }
1729
parseAreaGroup(char * values)1730 int parseAreaGroup(char *values)
1731 {
1732 char *ptr = NULL;
1733 char *name;
1734 char *patternList;
1735
1736 if (!values || !strlen(values)) {
1737 prErr("Error in areaGroup definition - no name specified!");
1738 return 1;
1739 }
1740
1741 ptr = strchr(values, ' ');
1742 if (!ptr)
1743 ptr = strchr(values, '\t');
1744 if (!ptr) {
1745 prErr("Error in areaGroup definition - no patterns specified!");
1746 return 2;
1747 }
1748
1749 name = scalloc(ptr - values + 1, 1);
1750 sstrncpy(name, values, ptr - values);
1751 while((*ptr == ' ') || (*ptr == '\t')) ptr++;
1752
1753 if (!strlen(ptr)) {
1754 prErr("Error in areaGroup definition - no patterns specified!");
1755 return 2;
1756 }
1757
1758 patternList = sstrdup(ptr);
1759 addPatternToGrpTree(name, patternList);
1760
1761 return 0;
1762 }
1763
parseAreaGroupDefaults(s_fidoconfig * config,char * values)1764 int parseAreaGroupDefaults(s_fidoconfig *config, char *values)
1765 {
1766 char *ptr = NULL;
1767 char *name;
1768 char *params;
1769 grp_t *g;
1770
1771 if (!values || !strlen(values)) {
1772 prErr("Error in areaGroup definition - no name specified!");
1773 return 1;
1774 }
1775
1776 ptr = strchr(values, ' ');
1777 if (!ptr)
1778 ptr = strchr(values, '\t');
1779 if (!ptr) {
1780 prErr("Error in areaGroupDefaults definition - no patterns specified!");
1781 return 2;
1782 }
1783
1784 name = scalloc(ptr - values + 1, 1);
1785 sstrncpy(name, values, ptr - values);
1786 while((*ptr == ' ') || (*ptr == '\t')) ptr++;
1787
1788 if (!strlen(ptr)) {
1789 prErr("Error in areaGroupDefaults definition - no parameters specified!");
1790 return 2;
1791 }
1792
1793 g = findGroupByName(name);
1794 if (!g) {
1795 prErr("Group %s is undefined, please define it first using 'areaGroup' token!");
1796 return 3;
1797 }
1798
1799 params = sstrdup(ptr);
1800 memcpy(g->area, &(config->EchoAreaDefault), sizeof(s_area));
1801 parseAreaDefault(config, params, g->area, 0);
1802
1803 nfree(params);
1804 nfree(name);
1805 return 0;
1806 }
1807
parseEchoArea(char * token,s_fidoconfig * config)1808 int parseEchoArea(char *token, s_fidoconfig *config)
1809 {
1810 int rc;
1811 s_area *area;
1812
1813 if (config->addr == NULL)
1814 {
1815 printAddrError();
1816 }
1817 if (token == NULL) {
1818 prErr("Parameters after %s are missing!", actualKeyword);
1819 return 1;
1820 }
1821
1822 config->echoAreas = srealloc(config->echoAreas, sizeof(s_area)*(config->echoAreaCount+1));
1823 area = &(config->echoAreas[config->echoAreaCount]);
1824 area->areaType = ECHOAREA;
1825 rc = parseArea(config, token, area, 1);
1826 config->echoAreaCount++;
1827 return rc;
1828 }
1829
parseNetMailArea(char * token,s_fidoconfig * config)1830 int parseNetMailArea(char *token, s_fidoconfig *config)
1831 {
1832 int rc;
1833 s_area *area;
1834
1835 if (config->addr == NULL)
1836 {
1837 printAddrError();
1838 }
1839 if (token == NULL) {
1840 prErr("Parameters after %s are missing!", actualKeyword);
1841 return 1;
1842 }
1843
1844 config->netMailAreas = srealloc(config->netMailAreas, sizeof(s_area)*(config->netMailAreaCount+1));
1845 area = &(config->netMailAreas[config->netMailAreaCount]);
1846 area->areaType = ECHOAREA;
1847 rc = parseArea(config, token, area, 0);
1848 config->netMailAreaCount++;
1849 return rc;
1850 }
1851
parseFileArea(char * token,s_fidoconfig * config)1852 int parseFileArea(char *token, s_fidoconfig *config)
1853 {
1854 int rc;
1855 s_area *area;
1856
1857 if (config->addr == NULL)
1858 {
1859 printAddrError();
1860 }
1861 if (token == NULL) {
1862 prErr("Parameters after %s are missing!", actualKeyword);
1863 return 1;
1864 }
1865
1866 config->fileAreas = srealloc(config->fileAreas,
1867 sizeof(s_area)*(config->fileAreaCount+1));
1868
1869 area = &(config->fileAreas[config->fileAreaCount]);
1870 area->areaType = FILEAREA;
1871 rc = parseArea(config, token, area, 1);
1872 config->fileAreaCount++;
1873 return rc;
1874 }
1875
parseBbsArea(const s_fidoconfig * config,char * token,s_bbsarea * area)1876 int parseBbsArea(const s_fidoconfig *config, char *token, s_bbsarea *area)
1877 {
1878 char *tok;
1879 int rc = 0;
1880
1881 unused(config);
1882
1883 if (token == NULL) {
1884 prErr("Parameters after %s are missing!", actualKeyword);
1885 return 1;
1886 }
1887
1888 memset(area, 0, sizeof(s_bbsarea));
1889
1890 tok = strtok(token, " \t");
1891 if (tok == NULL) {
1892 prErr("An areaname after %s is missing!", actualKeyword);
1893 return 1; /* if there is no areaname */
1894 }
1895
1896 area->areaName= (char *) smalloc(strlen(tok)+1);
1897 strcpy(area->areaName, tok);
1898
1899 tok = strtok(NULL, " \t");
1900 if (tok == NULL) {
1901 prErr("A pathname is missing %s!", actualLine);
1902 return 2; /* if there is no filename */
1903 }
1904
1905 if (tok[strlen(tok)-1] == PATH_DELIM) {
1906 area->pathName = (char *) smalloc(strlen(tok)+1);
1907 strcpy(area->pathName, tok);
1908 } else {
1909 area->pathName = (char *) smalloc(strlen(tok)+2);
1910 strcpy(area->pathName, tok);
1911 area->pathName[strlen(tok)] = PATH_DELIM;
1912 area->pathName[strlen(tok)+1] = '\0';
1913 }
1914
1915 tok = strtok(NULL, " \t");
1916
1917 while (tok != NULL) {
1918 if (stricmp(tok, "-d")==0) {
1919 if ((area->description=getDescription())==NULL)
1920 rc += 1;
1921 }
1922 else {
1923 prErr("Error in areaOptions token=%s!", tok);
1924 rc +=1;
1925 return rc;
1926 }
1927 tok = strtok(NULL, " \t");
1928 }
1929
1930 return rc;
1931 }
1932
parseBbsAreaStatement(char * token,s_fidoconfig * config)1933 int parseBbsAreaStatement(char *token, s_fidoconfig *config)
1934 {
1935 int rc;
1936
1937 if (token == NULL) {
1938 prErr("Parameters after %s are missing!", actualKeyword);
1939 return 1;
1940 }
1941
1942 config->bbsAreas = srealloc(config->bbsAreas,
1943 sizeof(s_bbsarea)*(config->bbsAreaCount+1));
1944 rc = parseBbsArea(config, token,
1945 &(config->bbsAreas[config->bbsAreaCount]));
1946 config->bbsAreaCount++;
1947 return rc;
1948 }
1949
parseLink(char * token,s_fidoconfig * config)1950 int parseLink(char *token, s_fidoconfig *config)
1951 {
1952
1953 s_link *clink;
1954 s_link *deflink;
1955
1956 if (token == NULL) {
1957 prErr("A name after %s is missing!", actualKeyword);
1958 return 1;
1959 }
1960
1961 config->describeLinkDefaults=0; /* Stop describing of link defaults if it was */
1962
1963 config->links = srealloc(config->links, sizeof(ps_link)*(config->linkCount+1));
1964
1965 config->links[config->linkCount] = scalloc(1,sizeof(s_link));
1966
1967 clink = config->links[config->linkCount];
1968
1969 if (config->linkDefaults) {
1970
1971 memcpy(clink, deflink = config->linkDefaults, sizeof(s_link));
1972
1973 clink->name = sstrdup(deflink->name);
1974
1975 clink->defaultPwd = sstrdup(deflink->defaultPwd);
1976
1977 if (deflink->pktPwd != deflink->defaultPwd ) {
1978 clink->pktPwd = sstrdup (deflink->pktPwd);
1979 } else {
1980 clink->pktPwd = clink->defaultPwd;
1981 }
1982 if (deflink->ticPwd != deflink->defaultPwd ) {
1983 clink->ticPwd = sstrdup (deflink->ticPwd);
1984 } else {
1985 clink->ticPwd = clink->defaultPwd;
1986 }
1987 if (deflink->areafix.pwd != deflink->defaultPwd ) {
1988 clink->areafix.pwd = sstrdup (deflink->areafix.pwd);
1989 } else {
1990 clink->areafix.pwd = clink->defaultPwd;
1991 }
1992 if (deflink->filefix.pwd != deflink->defaultPwd ) {
1993 clink->filefix.pwd = sstrdup (deflink->filefix.pwd);
1994 } else {
1995 clink->filefix.pwd = clink->defaultPwd;
1996 }
1997 if (deflink->bbsPwd != deflink->defaultPwd ) {
1998 clink->bbsPwd = sstrdup(deflink->bbsPwd);
1999 } else {
2000 clink->bbsPwd = clink->defaultPwd;
2001 }
2002 if (deflink->sessionPwd != deflink->defaultPwd ) {
2003 clink->sessionPwd = sstrdup (deflink->sessionPwd);
2004 } else {
2005 clink->sessionPwd = clink->defaultPwd;
2006 }
2007 clink->handle = sstrdup (deflink->handle);
2008 clink->email = sstrdup (deflink->email);
2009 clink->emailFrom = sstrdup (deflink->emailFrom);
2010 clink->emailSubj = sstrdup (deflink->emailSubj);
2011 clink->LinkGrp = sstrdup (deflink->LinkGrp);
2012 clink->AccessGrp = copyGroups(deflink->AccessGrp, deflink->numAccessGrp);
2013 clink->areafix.autoCreateFile = sstrdup (deflink->areafix.autoCreateFile);
2014 clink->filefix.autoCreateFile = sstrdup (deflink->filefix.autoCreateFile);
2015 clink->areafix.autoCreateDefaults = sstrdup (deflink->areafix.autoCreateDefaults);
2016 clink->filefix.autoCreateDefaults = sstrdup (deflink->filefix.autoCreateDefaults);
2017 clink->areafix.fwdFile = sstrdup (deflink->areafix.fwdFile);
2018 clink->filefix.fwdFile = sstrdup (deflink->filefix.fwdFile);
2019 clink->areafix.denyFwdFile = sstrdup (deflink->areafix.denyFwdFile);
2020 clink->filefix.denyFwdFile = sstrdup (deflink->filefix.denyFwdFile);
2021 clink->areafix.name = sstrdup (deflink->areafix.name);
2022 clink->filefix.name = sstrdup (deflink->filefix.name);
2023 clink->areafix.baseDir = sstrdup (deflink->areafix.baseDir);
2024 clink->filefix.baseDir = sstrdup (deflink->filefix.baseDir);
2025 clink->areafix.reportsFlags = sstrdup (deflink->areafix.reportsFlags);
2026 clink->filefix.reportsFlags = sstrdup (deflink->filefix.reportsFlags);
2027 clink->filefix.baseDir = sstrdup (deflink->filefix.baseDir);
2028 clink->optGrp = copyGroups(deflink->optGrp, deflink->numOptGrp);
2029 clink->areafix.frMask = copyGroups(deflink->areafix.frMask, deflink->areafix.numFrMask);
2030 clink->filefix.frMask = copyGroups(deflink->filefix.frMask, deflink->filefix.numFrMask);
2031 clink->areafix.dfMask = copyGroups(deflink->areafix.dfMask, deflink->areafix.numDfMask);
2032 clink->filefix.dfMask = copyGroups(deflink->filefix.dfMask, deflink->filefix.numDfMask);
2033
2034 } else {
2035
2036 memset(clink, 0, sizeof(s_link));
2037
2038 /* Set defaults like in parseLinkDefaults() */
2039
2040 /* set areafix default to on */
2041 clink->areafix.on = 1;
2042 clink->filefix.on = 1;
2043
2044 /* set defaults to export, import, mandatory (0), manual (0) */
2045 clink->aexport = 1;
2046 clink->import = 1;
2047 clink->ourAka = &(config->addr[0]);
2048
2049 /* set default maxUnpackedNetmail */
2050 clink->maxUnpackedNetmail = 100;
2051
2052 /* set FileFixFSC87Subset default to on */
2053 clink->FileFixFSC87Subset = 1;
2054 }
2055
2056 clink->name = (char *) smalloc (strlen(token)+1);
2057 strcpy(clink->name, token);
2058 clink->handle = clink->name;
2059
2060 config->linkCount++;
2061 memset(&linkDefined, 0, sizeof(linkDefined));
2062 return 0;
2063 }
2064
parseAnnDef(char * token,s_fidoconfig * config)2065 int parseAnnDef(char *token, s_fidoconfig *config)
2066 {
2067 ps_anndef cAnnDef;
2068
2069 if (token == NULL) {
2070 prErr("A name after %s is missing!", actualKeyword);
2071 return 1;
2072 }
2073 config->AnnDefs = srealloc(config->AnnDefs, sizeof(s_anndef)*(config->ADCount+1));
2074 cAnnDef = &(config->AnnDefs[config->ADCount]);
2075 memset(cAnnDef, 0, sizeof(s_anndef));
2076
2077 cAnnDef->annAreaTag = sstrdup(token);
2078 config->ADCount++;
2079 return 0;
2080 }
2081
parseAnnDefAddres(char * token,s_fidoconfig * config,int i)2082 int parseAnnDefAddres(char *token, s_fidoconfig *config, int i)
2083 {
2084 ps_anndef cAnnDef = NULL;
2085 hs_addr* addr;
2086 if (token == NULL) {
2087 prErr("A name after %s is missing!", actualKeyword);
2088 return 1;
2089 }
2090 cAnnDef = getDescrAnnDef(config);
2091 addr = scalloc(1,sizeof(hs_addr));
2092 parseFtnAddrZS(token, addr);
2093
2094 if( i == 1)
2095 cAnnDef->annaddrto = addr;
2096 if( i == 2)
2097 cAnnDef->annaddrfrom = addr;
2098
2099 return 0;
2100 }
2101
2102
parseNodelist(char * token,s_fidoconfig * config)2103 int parseNodelist(char *token, s_fidoconfig *config)
2104 {
2105 if (token == NULL) {
2106 prErr("A name after %s is missing!", actualKeyword);
2107 return 1;
2108 }
2109
2110 config->nodelists = srealloc(config->nodelists, sizeof(s_nodelist)*(config->nodelistCount+1));
2111 memset(&(config->nodelists[config->nodelistCount]), 0, sizeof(s_nodelist));
2112 config->nodelists[config->nodelistCount].nodelistName =
2113 (char *) smalloc (strlen(token)+1);
2114 strcpy(config->nodelists[config->nodelistCount].nodelistName, token);
2115
2116 config->nodelists[config->nodelistCount].format = fts5000;
2117
2118 config->nodelists[config->nodelistCount].delAppliedDiff = 0;
2119
2120 config->nodelistCount++;
2121 return 0;
2122 }
2123
parseBool(char * token,unsigned int * value)2124 int parseBool (char *token, unsigned int *value)
2125 {
2126 char *iToken;
2127
2128 if (token == NULL) {
2129 *value = 1;
2130 return 0;
2131 }
2132
2133 iToken = strLower(sstrdup(token));
2134 if ((strcmp(iToken, "on")==0) || (strcmp(iToken, "yes")==0) || (strcmp(iToken, "1")==0)) *value = 1;
2135 else if ((strcmp(iToken, "off")==0) || (strcmp(iToken, "no")==0) || (strcmp(iToken, "0")==0)) *value = 0;
2136 else {
2137 nfree(iToken);
2138 return 2;
2139 }
2140 nfree(iToken);
2141 return 0;
2142 }
2143
parseAutoPause(char * token,unsigned * autoPause)2144 int parseAutoPause(char *token, unsigned *autoPause)
2145 {
2146 char *ptr;
2147
2148 if (token == NULL) {
2149 prErr("A parameter after %s is missing!", actualKeyword);
2150 return 1;
2151 } /* endif */
2152
2153 for (ptr = token; *ptr; ptr++) {
2154 if (!isdigit(*ptr)) {
2155 prErr("A parameter after %s is missing!", actualKeyword);
2156 return 1;
2157 } /* endif */
2158 } /* endfor */
2159
2160 *autoPause = (unsigned)atoi(token);
2161
2162 return 0;
2163 }
2164
parsePause(char * token,unsigned * Pause)2165 int parsePause(char *token, unsigned *Pause)
2166 {
2167 if ((token == NULL) || (stricmp(token,"on") == 0) ) {
2168 *Pause = ECHOAREA|FILEAREA;
2169 }
2170 else if(stricmp(token,"earea") == 0)
2171 *Pause |= ECHOAREA;
2172 else if(stricmp(token,"farea") == 0)
2173 *Pause |= FILEAREA;
2174 else if (stricmp(token,"off") == 0)
2175 *Pause = NOPAUSE;
2176 else {
2177 prErr("Wrong Pause parameter!");
2178 return 1; /* error */
2179 }
2180 return 0;
2181 }
2182
parseUInt(char * token,unsigned int * uint)2183 int parseUInt(char *token, unsigned int *uint) {
2184 long var=0;
2185
2186 if (token == NULL) {
2187 prErr("A parameter after %s is missing!", actualKeyword);
2188 return 1;
2189 }
2190 sscanf(token, "%ld", &var);
2191 if( var<0 ) {
2192 prErr("The negative value of %s is invalid!", actualKeyword);
2193 return 1;
2194 }
2195 *uint = (unsigned int)var;
2196
2197 return 0;
2198 }
2199
parseOctal(char * token,unsigned int * octal)2200 int parseOctal(char *token, unsigned int *octal) {
2201
2202 if (token == NULL) {
2203 prErr("A parameter after %s is missing!", actualKeyword);
2204 return 1;
2205 }
2206 sscanf(token, "%o", octal);
2207 return 0;
2208 }
2209
parsePWD(char * token,char ** pwd)2210 int parsePWD(char *token, char **pwd) {
2211
2212 if (token == NULL) { /* return empty password */
2213 *pwd = (char *) smalloc(1);
2214 (*pwd)[0] = '\0';
2215 return 0;
2216 }
2217
2218 *pwd = sstrdup(token);
2219 if (*pwd == NULL) return 1;
2220 else return 0;
2221 }
2222
parseHandle(char * token,s_fidoconfig * config)2223 int parseHandle(char *token, s_fidoconfig *config) {
2224 s_link *clink;
2225
2226 if (token == NULL) {
2227 prErr("A parameter after %s is missing!", actualKeyword);
2228 return 1;
2229 }
2230
2231 clink = getDescrLink(config);
2232
2233 clink->handle = (char *) smalloc (strlen(token)+1);
2234 strcpy(clink->handle, token);
2235 return 0;
2236 }
2237
2238 /* Return 0 if OK, 1 if invalid parameter, 2 if another error */
parseRoute(char * token,s_fidoconfig * config,s_route ** route,unsigned * count,e_id id)2239 int parseRoute(char *token, s_fidoconfig *config, s_route **route,
2240 unsigned *count, e_id id) {
2241 char *option;
2242 char *iOption;
2243 int rc = 0;
2244 s_route *actualRoute;
2245
2246 if (token == NULL) {
2247 prErr("A parameter after %s is missing!", actualKeyword);
2248 return 1;
2249 }
2250
2251 option = strtok(token, " \t");
2252 if (option == NULL) {
2253 prErr("A parameter after %s is missing!", actualKeyword);
2254 return 1;
2255 }
2256
2257 *route = srealloc(*route, sizeof(s_route)*(*count+1));
2258 actualRoute = &(*route)[*count];
2259 memset(actualRoute, '\0', sizeof(s_route));
2260
2261 actualRoute->id = id; actualRoute->flavour = flUndef;
2262
2263 while (option != NULL) {
2264 iOption = strLower(sstrdup(option));
2265 if (strcmp(iOption, "hold")==0) actualRoute->flavour = flHold;
2266 else if (strcmp(iOption, "normal")==0) actualRoute->flavour = flNormal;
2267 else if (strcmp(iOption, "crash")==0) actualRoute->flavour = flCrash;
2268 else if (strcmp(iOption, "direct")==0) actualRoute->flavour = flDirect;
2269 else if (strcmp(iOption, "immediate")==0) actualRoute->flavour = flImmediate;
2270 else if (strcmp(iOption, "hub")==0) actualRoute->routeVia = hub;
2271 else if (strcmp(iOption, "host")==0) actualRoute->routeVia = host;
2272 else if (strcmp(iOption, "boss")==0) actualRoute->routeVia = boss;
2273 else if (strcmp(iOption, "noroute")==0) actualRoute->routeVia = noroute;
2274 else if (strcmp(iOption, "no-route")==0) actualRoute->routeVia = noroute;
2275 else if (strcmp(iOption, "nopack")==0) actualRoute->routeVia = nopack;
2276 else if (strcmp(iOption, "no-pack")==0) actualRoute->routeVia = nopack;
2277 else if (isdigit(option[0]) || (option[0] == '*') || (option[0] == '?')) {
2278 if ((actualRoute->routeVia == 0) && (actualRoute->target == NULL)) {
2279 actualRoute->target = getLink(config, option);
2280 actualRoute->viaStr = (char *) smalloc(strlen(option)+1);
2281 strcpy(actualRoute->viaStr, option);
2282 }
2283 else {
2284 if (actualRoute->pattern == NULL) {
2285 /* 2 for additional .0 if needed */
2286 actualRoute->pattern = (char *) smalloc(strlen(option)+2+1);
2287 strcpy(actualRoute->pattern, option);
2288 if ((strchr(option, '.')==NULL) && (strchr(option, '*')==NULL)) {
2289 strcat(actualRoute->pattern, ".0");
2290 }
2291 (*count)++;
2292 } else {
2293 /* add new Route for additional patterns */
2294 *route = srealloc(*route, sizeof(s_route)*(*count+1));
2295 actualRoute = &(*route)[*count];
2296 memcpy(actualRoute,&(*route)[(*count)-1],sizeof(s_route));
2297 if ((*route)[(*count)-1].viaStr != NULL)
2298 actualRoute->viaStr = sstrdup((*route)[(*count)-1].viaStr);
2299
2300 /* 2 for additional .0 if needed */
2301 actualRoute->pattern = (char *) smalloc(strlen(option)+2+1);
2302 strcpy(actualRoute->pattern, option);
2303 if ((strchr(option, '.')==NULL) && (strchr(option, '*')==NULL)) {
2304 strcat(actualRoute->pattern, ".0");
2305 }
2306 (*count)++;
2307 }
2308
2309 }
2310 if ((actualRoute->target == NULL) && (actualRoute->routeVia == 0)) {
2311 prErr("Link %s not found in Route statement!", actualRoute->viaStr);
2312 rc = 2;
2313 }
2314 }
2315 nfree(iOption);
2316 option = strtok(NULL, " \t");
2317 }
2318 /* set flavour if it isn't specified in the statement */
2319 /* and routeVia is not 'nopack' */
2320 if (actualRoute->flavour == flUndef && actualRoute->routeVia != nopack)
2321 {
2322 if (actualRoute->target == NULL)
2323 {
2324 prErr("You must either specify flavour or use defined link as target");
2325 rc = 2;
2326 }
2327 else
2328 actualRoute->flavour = actualRoute->target->netMailFlavour;
2329 }
2330
2331 return rc;
2332 }
2333
parsePack(char * line,s_fidoconfig * config)2334 int parsePack(char *line, s_fidoconfig *config) {
2335
2336 char *p, *c;
2337 s_pack *pack;
2338
2339 if (line == NULL) {
2340 prErr("A parameter after %s is missing!", actualKeyword);
2341 return 1;
2342 }
2343
2344 /* check for no link definition was before */
2345 if(config->linkCount > 0)
2346 {
2347 prErr("Unable to add commandline for packer after link definition!");
2348 return 2;
2349 }
2350
2351 p = strtok(line, " \t");
2352 c = getRestOfLine();
2353 if ((p != NULL) && (c != NULL)) {
2354
2355 /* add new pack statement */
2356 config->packCount++;
2357 config->pack = srealloc(config->pack, config->packCount * sizeof(s_pack));
2358
2359 /* fill new pack statement */
2360 pack = &(config->pack[config->packCount-1]);
2361 pack->packer = (char *) smalloc(strlen(p)+1);
2362 strcpy(pack->packer, p);
2363 pack->call = (char *) smalloc(strlen(c)+1);
2364 strcpy(pack->call, c);
2365 if( strncasecmp(pack->call,ZIPINTERNAL,strlen(ZIPINTERNAL)) )
2366 {
2367 if (strstr(pack->call, "$a")==NULL) {
2368 prErr("$a missing in pack statement %s!", actualLine);
2369 return 2;
2370 }
2371 if (strstr(pack->call, "$f")==NULL) {
2372 prErr("$f missing in pack statement %s!", actualLine);
2373 return 2;
2374 }
2375 }
2376 return 0;
2377 } else {
2378 prErr("A parameter after %s is missing!", actualKeyword);
2379 return 1;
2380 }
2381 }
2382
parseUnpack(char * line,s_fidoconfig * config)2383 int parseUnpack(char *line, s_fidoconfig *config)
2384 {
2385 char *p, *c;
2386 char *error;
2387 s_unpack *unpack;
2388 unsigned char code;
2389 int i;
2390
2391 if (line == NULL)
2392 {
2393 prErr("A parameter after %s is missing!", actualKeyword);
2394 return 1;
2395 }
2396
2397 /* ToDo: Create replacement for strtok which handles "str" */
2398
2399 /* Skip white spaces */
2400 for (p = line; (*p == ' ') || (*p == '\t'); p++);
2401
2402 if (*p != '\0')
2403 {
2404 if (*p == '\"')
2405 {
2406 /* skip till next double qoute */
2407 for (c = ++p; (*c != '\"') && (*c != '\0'); c++);
2408 }
2409 else
2410 {
2411 /* skip till next white space */
2412 for (c = p; (*c != ' ') && (*c != '\t') && (*c != '\0'); c++);
2413 }
2414
2415 if (*c != '\0')
2416 {
2417 *c++ = '\0';
2418 stripLeadingChars(c, " \t");
2419 }
2420 }
2421 else
2422 c = NULL;
2423
2424 if ((p != NULL) && (c != NULL))
2425 {
2426 /* add new unpack statement */
2427 config->unpackCount++;
2428 config->unpack = srealloc(config->unpack, config->unpackCount * sizeof(s_unpack));
2429
2430 /* fill new unpack statement */
2431 unpack = &(config->unpack[config->unpackCount-1]);
2432 unpack->call = (char *) smalloc(strlen(p)+1);
2433 strcpy(unpack->call, p);
2434
2435 if( strncasecmp(unpack->call,ZIPINTERNAL,strlen(ZIPINTERNAL)) )
2436 {
2437 /* zipInternal is not used */
2438 if (strstr(unpack->call, "$a")==NULL)
2439 {
2440 prErr("$a missing in unpack statement %s!", actualLine);
2441 return 2;
2442 }
2443 }
2444
2445 p = strtok(c, " \t"); /* p contains offset now */
2446 c = strtok(NULL, " \t"); /* c contains match code now */
2447
2448 if ((p == NULL) || (c == NULL))
2449 {
2450 prErr("offset or match code missing in unpack statement %s!", actualLine);
2451 return 1;
2452 }
2453
2454 unpack->offset = (unsigned) strtol(p, &error, 0);
2455
2456 if ((error != NULL) && (*error != '\0'))
2457 {
2458 prErr("The number is wrong for offset in unpack!");
2459 return 1; /* error occured; */
2460 }
2461
2462 unpack->matchCode = (unsigned char *) smalloc(strlen(c) / 2 + 1);
2463 unpack->mask = (unsigned char *) smalloc(strlen(c) / 2 + 1);
2464
2465 /* parse matchcode statement */
2466 /* this looks a little curvy, I know. Remember, I programmed this at 23:52 :) */
2467 for (i = 0, error = NULL; c[i] != '\0' && error == NULL; i++)
2468 {
2469 code = (unsigned char) toupper(c[i]);
2470 /* if code equals to '?' set the corresponding bits of mask[] to 0 */
2471 unpack->mask[i / 2] = i % 2 == 0 ? (code != '?' ? 0xF0 : 0) :
2472 unpack->mask[i / 2] | (code != '?' ? 0xF : 0);
2473
2474 /* find the numeric representation of hex code */
2475 /* if this is a '?' code equals to 0 */
2476 code = (isdigit(code) ? code - '0' :
2477 (isxdigit(code) ? code - 'A' + 10 :
2478 (code == '?' ? 0 : (error = c + i, 0xFF))));
2479 unpack->matchCode[i / 2] = i % 2 == 0 ? code << 4 : unpack->matchCode[i / 2] | code;
2480 }
2481
2482 if (error)
2483 {
2484 prErr("matchCode can\'t contain %c in unpack statement %s!", *error, actualLine);
2485 return 1;
2486 }
2487
2488 if (i % 2 != 0)
2489 {
2490 prErr("matchCode must be byte-aligned in unpack statement %s!", actualLine);
2491 return 1;
2492 }
2493
2494 unpack->codeSize = i / 2;
2495
2496 return 0;
2497 }
2498 else
2499 {
2500 prErr("A parameter after %s is missing!", actualKeyword);
2501 return 1;
2502 }
2503 }
2504
2505 #if 0
2506 static int f_accessable(char *token)
2507 {
2508 /* We don't need a real fexist function here, and we don't want to */
2509 /* be dependent on SMAPI just because of this. For us, it is enough */
2510 /* to see if the file is accessible */
2511 /* BUT WE DON'T KNOW ABOUT DIRS! */
2512
2513 #ifdef __UNIX__
2514 struct stat sb;
2515
2516 if (stat(token, &sb))
2517 return 0; /* cannot stat the file */
2518 if (access(token, R_OK))
2519 return 0; /* cannot access the file */
2520 return 1;
2521 #else
2522 FILE *f = fopen(token, "rb");
2523 if (f == NULL)
2524 return 0;
2525 fclose(f);
2526 return 1;
2527 #endif
2528 }
2529 #endif
2530
parseFileName(char * line,char ** name,char ** alreadyDefined)2531 int parseFileName(char *line, char **name, char **alreadyDefined) {
2532 char *token;
2533
2534 if (*name != NULL) {
2535 if (alreadyDefined == NULL || *alreadyDefined) {
2536 prErr("Duplicate file name!");
2537 return 1;
2538 }
2539 nfree(*name);
2540 }
2541
2542 if (line == NULL) {
2543 prErr("A parameter after %s is missing!", actualKeyword);
2544 return 1;
2545 }
2546
2547 if (line[0]=='\"') {
2548 token=(char *) smalloc (strlen(line)+1);
2549 sscanf(line,"\"%[^\"]s",token);
2550 }
2551 else
2552 token = strtok(line, " \t");
2553
2554 if (token == NULL) {
2555 prErr("A parameter after %s is missing!", actualKeyword);
2556 return 1;
2557 }
2558 /* if (f_accessable(token)) { */
2559 if (fexist(token)) { /* fexist knows about dirs */
2560 /* (*name) = smalloc(strlen(token)+1); */
2561 /* strcpy((*name), token); */
2562 xstrcat(name, token);
2563 if (alreadyDefined) *alreadyDefined=*name;
2564 } else {
2565 prErr("File not found or no permission: %s!", token);
2566 if (line[0]=='\"')
2567 nfree(token);
2568 return 2;
2569 }
2570 if (line[0]=='\"')
2571 nfree(token);
2572 return 0;
2573 }
2574
2575 /* Parse loglevels string
2576 Expand ranges like x-y;
2577 Ignore spaces & etc (recognizes digits & letters only).
2578 */
parseLoglevels(char * line,char ** loglevels)2579 int parseLoglevels(char *line, char **loglevels) {
2580 char *ll, *temp; /* Array for store */
2581 char *p=line;
2582 int i,k;
2583
2584 if(!line) {
2585 prErr("A parameter after %s is missing!", actualKeyword);
2586 return 1;
2587 }
2588
2589 ll = calloc(256,sizeof(char));
2590 if( !ll ) {
2591 prErr( "Low memory!" );
2592 return 1;
2593 }
2594
2595 while( *p ){ /* scan string */
2596 if( isdigit(*p) || isalpha(*p) )
2597 ll[(int)*p] = 1;
2598 else if( *p=='-' && p!=*loglevels )
2599 for( i=*(p-1), k=*(p+1) ; i && i<k ; i++ )
2600 ll[i]=1;
2601 p++;
2602 }
2603
2604 p = temp = smalloc('z'-'a'+'Z'-'A'+'9'-'0'+4);
2605 for( i='0'; i<='9'; i++ )
2606 if( ll[i] ) *(p++)=i;
2607 for( i='A'; i<='Z'; i++ )
2608 if( ll[i] ) *(p++)=i;
2609 for( i='a'; i<='z'; i++ )
2610 if( ll[i] ) *(p++)=i;
2611 *p='\0';
2612
2613 *loglevels = sstrdup(temp);
2614
2615 nfree(temp);
2616 nfree(ll);
2617 return 0;
2618 }
2619
parsePackerDef(char * line,s_fidoconfig * config,s_pack ** packerDef)2620 int parsePackerDef(char *line, s_fidoconfig *config, s_pack **packerDef) {
2621
2622 unsigned int i;
2623
2624 if (line == NULL) {
2625 prErr("A parameter after %s is missing!", actualKeyword);
2626 return 1;
2627 }
2628
2629 if (stricmp(line,"none")==0) {
2630 (*packerDef) = NULL;
2631 return 0;
2632 }
2633
2634 for(i = 0; i < config->packCount; i++)
2635 if (stricmp(line, config->pack[i].packer)==0) {
2636 (*packerDef) = &(config->pack[i]);
2637 return 0;
2638 }
2639
2640 prErr("Packer %s not found for packer statement!", line);
2641 return 2;
2642 }
2643
parseFlavour(char * line,e_flavour * flavour)2644 int parseFlavour(char *line, e_flavour *flavour)
2645 {
2646 char *iLine;
2647
2648 if (line == NULL) {
2649 prErr("A parameter after %s is missing!", actualKeyword);
2650 return 1;
2651 }
2652
2653 iLine = strLower(sstrdup(line));
2654 if (strcmp(iLine, "hold")==0) *flavour = flHold;
2655 else if (strcmp(iLine, "normal")==0) *flavour = flNormal;
2656 else if (strcmp(iLine, "direct")==0) *flavour = flDirect;
2657 else if (strcmp(iLine, "crash")==0) *flavour = flCrash;
2658 else if (strcmp(iLine, "immediate")==0) *flavour = flImmediate;
2659 else {
2660 prErr("Unknown %s value %s!", actualKeyword, line);
2661 nfree(iLine);
2662 return 2;
2663 }
2664 nfree(iLine);
2665 return 0;
2666 }
2667
parseAttr(char * token,char ** attrs,long * bitattr)2668 int parseAttr(char *token, char **attrs, long *bitattr) {
2669 char *p;
2670 int parsed;
2671
2672 nfree(*attrs);
2673 *bitattr = 0;
2674
2675 parsed = parseAttrString(token, attrs, bitattr, &p);
2676 assert(parsed >= 0); /* Should be */
2677 if(*p != '\0') {
2678 prErr("Unknown flag %s!", p);
2679 nfree(*attrs);
2680 return 2;
2681 }
2682 return 0;
2683 }
2684
parseUUEechoAreas(char * token,char ** grp[],unsigned int * count)2685 int parseUUEechoAreas(char *token, char **grp[], unsigned int *count) {
2686
2687 if (token == NULL) {
2688 prErr("Parameters after %s are missing!", actualKeyword);
2689 return 1;
2690 }
2691 *grp = srealloc(*grp, sizeof(char*)*(*count+1));
2692 (*grp)[*count] = sstrdup(token);
2693 (*count)++;
2694 return 0;
2695 }
2696
2697 /* Parse strings like "token1, token2,token3 token4" into s_str_array */
parseStringList(char * token,s_str_array ** ss)2698 int parseStringList(char *token, s_str_array **ss)
2699 {
2700
2701 assert(token != NULL && ss != NULL);
2702 nfree(*ss);
2703 *ss = makeStrArray(token);
2704 return 0;
2705 }
2706
parseGrp(char * token,char ** grp[],unsigned int * count)2707 int parseGrp(char *token, char **grp[], unsigned int *count) {
2708 char *p;
2709
2710 p = token;
2711 while (*p && strchr(" \t,", *p)) p++;
2712 if (!*p) return 0;
2713 for (*count=1; ;(*count)++) {
2714 while (*p && !strrchr(" \t,", *p)) p++;
2715 while (*p && strchr(" \t,", *p)) p++;
2716 if (!*p) break;
2717 }
2718 p = token;
2719 while (*p && strchr(" \t,", *p)) p++;
2720 *grp = smalloc(sizeof(char *)*(*count) + strlen(p) + 1);
2721 (*grp)[0]=(char *)(*grp+(*count));
2722 strcpy((*grp)[0], p);
2723 p = (*grp)[0];
2724 (*count)=1;
2725 for (;;)
2726 {
2727 while (*p && !strrchr(" \t,", *p)) p++;
2728 if (!*p) break;
2729 *p++ = '\0';
2730 while (*p && strchr(" \t,", *p)) p++;
2731 if (!*p) break;
2732 (*grp)[(*count)++] = p;
2733 }
2734
2735 return 0;
2736 }
2737
2738 /* and the parseGroup: */
2739 /* i make some checking... maybe it is better check if the pointer exist from */
2740 /* copyString function? */
2741 /* i removed some checking... ;-) */
2742 /* groups may be copied from linkDefaults */
2743
parseGroup(char * token,s_fidoconfig * config,int i)2744 int parseGroup(char *token, s_fidoconfig *config, int i)
2745 {
2746 s_link *link = NULL;
2747 ps_anndef cAnnDef = NULL;
2748
2749 if (token == NULL)
2750 {
2751 prErr("A parameter after %s is missing!", actualKeyword);
2752 return 1;
2753 }
2754
2755 if (i != 2)
2756 link = getDescrLink(config);
2757 if (i == 6 || i == 7)
2758 cAnnDef = getDescrAnnDef(config);
2759
2760 switch (i) {
2761 case 0:
2762 if (link->AccessGrp) freeGroups(link->AccessGrp, link->numAccessGrp);
2763 link->AccessGrp = NULL;
2764 link->numAccessGrp = 0;
2765 parseGrp(token, &(link->AccessGrp), &(link->numAccessGrp));
2766 break;
2767
2768 case 1:
2769 nfree(link->LinkGrp);
2770 fc_copyString(token, &link->LinkGrp);
2771 break;
2772
2773 case 2:
2774 if (config->numPublicGroup != 0) {
2775 prErr("Duplicate parameter after %s!", actualKeyword);
2776 return 1;
2777 }
2778 parseGrp(token, &(config->PublicGroup), &(config->numPublicGroup));
2779 break;
2780
2781 case 3:
2782 if (link->optGrp) freeGroups(link->optGrp, link->numOptGrp);
2783 link->optGrp = NULL;
2784 link->numOptGrp = 0;
2785 parseGrp(token, &(link->optGrp), &(link->numOptGrp));
2786 break;
2787
2788 case 4:
2789 if (link->areafix.frMask) freeGroups(link->areafix.frMask, link->areafix.numFrMask);
2790 link->areafix.frMask = NULL;
2791 link->areafix.numFrMask = 0;
2792 parseGrp(token, &(link->areafix.frMask), &(link->areafix.numFrMask));
2793 break;
2794 case 14:
2795 if (link->filefix.frMask) freeGroups(link->filefix.frMask, link->filefix.numFrMask);
2796 link->filefix.frMask = NULL;
2797 link->filefix.numFrMask = 0;
2798 parseGrp(token, &(link->filefix.frMask), &(link->filefix.numFrMask));
2799 break;
2800
2801 case 5:
2802 if (link->areafix.dfMask) freeGroups(link->areafix.dfMask, link->areafix.numDfMask);
2803 link->areafix.dfMask = NULL;
2804 link->areafix.numDfMask = 0;
2805 parseGrp(token, &(link->areafix.dfMask), &(link->areafix.numDfMask));
2806 break;
2807 case 15:
2808 if (link->filefix.dfMask) freeGroups(link->filefix.dfMask, link->filefix.numDfMask);
2809 link->filefix.dfMask = NULL;
2810 link->filefix.numDfMask = 0;
2811 parseGrp(token, &(link->filefix.dfMask), &(link->filefix.numDfMask));
2812 break;
2813
2814 case 6:
2815 if (cAnnDef->annInclude) freeGroups(cAnnDef->annInclude, cAnnDef->numbI);
2816 cAnnDef->annInclude = NULL;
2817 cAnnDef->numbI = 0;
2818 parseGrp(token, &(cAnnDef->annInclude), &(cAnnDef->numbI));
2819 break;
2820
2821 case 7:
2822 if (cAnnDef->annExclude) freeGroups(cAnnDef->annExclude, cAnnDef->numbE);
2823 cAnnDef->annExclude = NULL;
2824 cAnnDef->numbE = 0;
2825 parseGrp(token, &(cAnnDef->annExclude), &(cAnnDef->numbE));
2826 break;
2827
2828 case 8:
2829 if (link->RescanGrp) freeGroups(link->RescanGrp, link->numRescanGrp);
2830 link->RescanGrp = NULL;
2831 link->numRescanGrp = 0;
2832 parseGrp(token, &(link->RescanGrp), &(link->numRescanGrp));
2833 break;
2834 default:
2835 break;
2836 }
2837
2838
2839
2840 return 0;
2841 }
2842
parseLocalArea(char * token,s_fidoconfig * config)2843 int parseLocalArea(char *token, s_fidoconfig *config)
2844 {
2845 int rc;
2846 s_area *area;
2847
2848 if (token == NULL) {
2849 prErr("Parameters after %s are missing!", actualKeyword);
2850 return 1;
2851 }
2852
2853 config->localAreas = srealloc(config->localAreas, sizeof(s_area)*(config->localAreaCount+1));
2854 area = &(config->localAreas[config->localAreaCount]);
2855 area->areaType = ECHOAREA;
2856
2857 area->areaType = ECHOAREA;
2858 rc = parseArea(config, token, area, 0);
2859 config->localAreaCount++;
2860 return rc;
2861 }
2862
parseCarbonRule(char * token,s_fidoconfig * config)2863 int parseCarbonRule(char *token, s_fidoconfig *config)
2864 {
2865 s_carbon *cb=&(config->carbons[config->carbonCount-1]);
2866
2867 if (token == NULL) {
2868 prErr("OR|AND|NOT after %s is missing!", actualKeyword);
2869 return 1;
2870 }
2871
2872 /* rules are valid for the expressions that follow */
2873 /* but carbonRule AND also involves cb */
2874 /* expressions can start with NOT, but not with AND */
2875 if (stricmp(token,"NOT")==0) {
2876 _carbonrule = CC_NOT|CC_AND;
2877 if(config->carbonCount>0 && (cb->areaName==NULL && cb->move!=2)) /* no action */
2878 cb->rule |= CC_AND; /* AND NOT .. with next expr */
2879 }
2880
2881 else if (stricmp(token,"OR")==0) {
2882 _carbonrule = CC_OR; /* =0 */
2883 if (config->carbonCount)
2884 cb->rule &= CC_NOT;
2885 }
2886
2887 else if (stricmp(token,"AND")==0) {
2888 _carbonrule = CC_AND;
2889 if(config->carbonCount>0 && (cb->areaName==NULL && cb->move!=2)) /* no action */
2890 cb->rule |= CC_AND;
2891 }
2892
2893 else {
2894 prErr("OR|AND|NOT after %s is missing!", actualKeyword);
2895 return 1;
2896 }
2897 return 0;
2898 }
2899
parseCarbon(char * token,s_fidoconfig * config,e_carbonType ctype)2900 int parseCarbon(char *token, s_fidoconfig *config, e_carbonType ctype)
2901 {
2902 int c=config->carbonCount;
2903 s_carbon *cb;
2904
2905
2906 if (token == NULL) {
2907 prErr("Parameters after %s are missing!", actualKeyword);
2908 return 1;
2909 }
2910
2911
2912 config->carbonCount++;
2913 config->carbons = srealloc(config->carbons,sizeof(s_carbon)*(config->carbonCount));
2914
2915 cb=&(config->carbons[c]);
2916 memset(cb, 0, sizeof(s_carbon));
2917
2918 cb->ctype = ctype;
2919 cb->rule=_carbonrule;
2920
2921 if(ctype==ct_addr)
2922 {
2923 parseFtnAddrZS(token, &(cb->addr));
2924 }
2925 else {
2926 /* strip trailing "" */
2927 if (token[0]=='"' && token[strlen(token)-1]=='"') {
2928 token++;
2929 token[strlen(token)-1]='\0';
2930 }
2931 /* fc_copyString(token, &(cb->str)); */
2932 xstrcat(&(cb->str),token);
2933 }
2934
2935 return 0;
2936 }
2937
parseCarbonArea(char * token,s_fidoconfig * config,int move)2938 int parseCarbonArea(char *token, s_fidoconfig *config, int move) {
2939
2940 char *areaName,*reason;
2941 int c=config->carbonCount-1;
2942 s_carbon *cb=&(config->carbons[c]);
2943
2944 if (token == NULL) {
2945 prErr("Parameters after %s are missing!", actualKeyword);
2946 return 1;
2947 }
2948
2949 if(!config->carbonCount || (cb->str==NULL && cb->addr.zone==0)){
2950 prErr("No carbon codition specified before %s", actualKeyword);
2951 return 1;
2952 }
2953
2954 if(cb->move==CC_delete){
2955 prErr("CarbonDelete was specified before %s", actualKeyword);
2956 return 1;
2957 }
2958
2959 if(cb->extspawn){
2960 prErr("Extspawn was specified before %s", actualKeyword);
2961 return 1;
2962 }
2963
2964 if(cb->areaName!=NULL){
2965 prErr("CarbonArea already defined before %s", actualKeyword);
2966 return 1;
2967 }
2968
2969
2970 fc_copyString(token, &(cb->areaName));
2971 cb->move = move;
2972 _carbonrule=CC_AND; /* default */
2973 cb->rule&=CC_NOT; /* switch AND off */
2974
2975 /* checking area*/
2976 /* it is possible to have several groups of expressions and each of them */
2977 /* should have a carbonArea in the last expression */
2978 /* so now the area is known, the previous expressions must be checked */
2979 areaName = cb->areaName;
2980 reason = cb->reason;
2981
2982 while(c--){
2983 cb--;
2984 /* this was the end of a previous set expressions */
2985 if(cb->areaName!=NULL) /* carboncopy, -move or extspawn */
2986 break;
2987 /* this was the end of a previous set expressions */
2988 if(cb->move==CC_delete) /* carbondelete */
2989 break;
2990 fc_copyString(areaName, &(cb->areaName));
2991 if(reason)
2992 fc_copyString(reason, &(cb->reason));
2993 cb->move = move;
2994 }
2995
2996 return 0;
2997 }
2998
parseCarbonDelete(char * token,s_fidoconfig * config)2999 int parseCarbonDelete(char *token, s_fidoconfig *config) {
3000
3001 unsigned int c=config->carbonCount-1;
3002 s_carbon *cb=&(config->carbons[c]);
3003
3004 if (token != NULL) {
3005 prErr("There are extra parameters after %s!", actualKeyword);
3006 return 1;
3007 }
3008
3009 /* if (config->carbonCount == 0) {*/
3010 if(config->carbonCount == 0 || (cb->str==NULL && cb->addr.zone==0)){
3011 prErr("No carbon condition specified before %s", actualKeyword);
3012 return 1;
3013 }
3014
3015 if(cb->extspawn){
3016 prErr("CarbonExtern was specified before %s", actualKeyword);
3017 return 1;
3018 }
3019
3020 if(cb->areaName!=NULL){
3021 prErr("CarbonArea was specified before %s", actualKeyword);
3022 return 1;
3023 }
3024
3025 cb->move = CC_delete;
3026 _carbonrule=CC_AND;
3027 cb->rule&=CC_NOT;
3028
3029 /* checking area*/
3030 /* it is possible to have several groups of expressions and each of them */
3031 /* should have a carbonArea in the last expression */
3032 /* so now the area is known, the previous expressions must be checked */
3033 while(c--){
3034 cb--;
3035 if(cb->areaName!=NULL) /* carboncopy, -move, extern */
3036 break; /* this was the end of a previous set expressions */
3037 if(cb->move==CC_delete) /* delete */
3038 break;
3039 if(!(cb->rule&CC_AND)) /* OR */
3040 cb->move=CC_delete;
3041 }
3042 return 0;
3043 }
3044
parseCarbonExtern(char * token,s_fidoconfig * config)3045 int parseCarbonExtern(char *token, s_fidoconfig *config) {
3046
3047 unsigned int c=config->carbonCount-1;
3048 s_carbon *cb=&(config->carbons[c]);
3049
3050 if (token == NULL) {
3051 prErr("Parameters after %s are missing!", actualKeyword);
3052 return 1;
3053 }
3054 if(config->carbonCount == 0 || (cb->str==NULL && cb->addr.zone==0)){
3055 prErr("No carbon condition specified before %s", actualKeyword);
3056 return 1;
3057 }
3058
3059 if(cb->extspawn){
3060 prErr("CarbonExtern was already specified before %s", actualKeyword);
3061 return 1;
3062 }
3063
3064 if (cb->areaName!= NULL) {
3065 prErr("CarbonArea defined before %s!", actualKeyword);
3066 return 1;
3067 }
3068 if (cb->move==CC_delete) {
3069 prErr("CarbonDelete defined before %s!", actualKeyword);
3070 return 1;
3071 }
3072
3073 fc_copyString(token, &(cb->areaName));
3074 cb->extspawn = 1;
3075 cb->move = CC_copy;
3076 _carbonrule=CC_AND;
3077 cb->rule&=CC_NOT;
3078
3079 /* checking area*/
3080 /* it is possible to have several groups of expressions and each of them */
3081 /* should have a carbonArea in the last expression */
3082 /* so now the area is known, the previous expressions must be checked */
3083 while(c--){
3084 cb--;
3085 if(cb->areaName!=NULL) /* carboncopy, -move, extern */
3086 break; /* this was the end of a previous set expressions */
3087 if(cb->move==CC_delete) /* delete */
3088 break;
3089 if(!(cb->rule&CC_AND)){ /* OR */
3090 fc_copyString(token, &(cb->areaName));
3091 cb->extspawn=1;
3092 cb->move=CC_copy;
3093 }
3094 }
3095
3096 /* +AS+ */
3097 if (tolower(*actualKeyword) == 'n')
3098 cb->netMail = 1;
3099 else
3100 cb->netMail = 0;
3101 /* -AS- */
3102 return 0;
3103 }
3104
parseCarbonReason(char * token,s_fidoconfig * config)3105 int parseCarbonReason(char *token, s_fidoconfig *config) {
3106
3107 s_carbon *cb=&(config->carbons[config->carbonCount-1]);
3108 /* I know, when count==0 this will give strange results, but */
3109 /* in that case, cb will not be used */
3110
3111 if (token == NULL) {
3112 prErr("Parameters after %s are missing!", actualKeyword);
3113 return 1;
3114 }
3115
3116 /* if (config->carbonCount == 0) {*/
3117 if(config->carbonCount == 0 || (cb->str==NULL && cb->addr.zone==0)){
3118 prErr("No carbon condition specified before %s", actualKeyword);
3119 return 1;
3120 }
3121
3122 fc_copyString(token, &(cb->reason));
3123 return 0;
3124 }
3125
parseForwardPkts(char * token,s_link * link)3126 int parseForwardPkts(char *token, s_link *link)
3127 {
3128 if (token && stricmp(token, "secure") == 0)
3129 link->forwardPkts = fSecure;
3130 else {
3131 unsigned int bval = link->forwardPkts;
3132 return parseBool(token, &bval);
3133 }
3134
3135 return 0;
3136 }
3137
parseAllowEmptyPktPwd(char * token,s_fidoconfig * config,s_link * link)3138 int parseAllowEmptyPktPwd(char *token, s_fidoconfig *config, s_link *link)
3139 { unsigned t;
3140
3141 unused(config);
3142
3143 if (token == NULL) {
3144 prErr("Parameters after %s are missing!", actualKeyword);
3145 return 1;
3146 }
3147
3148 if (stricmp(token, "secure")==0) link->allowEmptyPktPwd = eSecure;
3149 /* else if (stricmp(token, "on")==0) link->allowEmptyPktPwd = eOn;*/
3150 /* else if (stricmp(token, "off")==0) link->allowEmptyPktPwd = eOff;*/
3151 else if( !parseBool (token, &t) ){
3152 if(t) link->allowEmptyPktPwd = eOn;
3153 else link->allowEmptyPktPwd = eOff;
3154 }else return 2;
3155
3156 return 0;
3157 }
3158
parseAllowPktAddrDiffer(char * token,s_fidoconfig * config,s_link * link)3159 int parseAllowPktAddrDiffer(char *token, s_fidoconfig *config, s_link *link)
3160 {
3161
3162 unused(config);
3163
3164 if (token == NULL) {
3165 prErr("Parameters after %s are missing!", actualKeyword);
3166 return 1;
3167 }
3168
3169 if (stricmp(token, "on")==0) link->allowPktAddrDiffer = pdOn;
3170 else if (stricmp(token, "off")==0) link->allowPktAddrDiffer = pdOff;
3171 else return 2;
3172
3173 return 0;
3174 }
3175
parseNodelistFormat(char * token,s_fidoconfig * config,s_nodelist * nodelist)3176 int parseNodelistFormat(char *token, s_fidoconfig *config, s_nodelist *nodelist)
3177 {
3178 char *iToken;
3179
3180 unused(config);
3181
3182 if (token == NULL) {
3183 prErr("Parameters after %s are missing!", actualKeyword);
3184 return 1;
3185 }
3186
3187 iToken = strLower(sstrdup(token));
3188 if ((strcmp(iToken, "fts5000") == 0) || (strcmp(iToken, "standard") == 0))
3189 nodelist->format = fts5000;
3190 else if (strcmp(iToken, "points24") == 0)
3191 nodelist->format = points24;
3192 else if (strcmp(iToken, "points4d") == 0)
3193 nodelist->format = points4d;
3194 else {
3195 nfree(iToken);
3196 return 2;
3197 }
3198
3199 nfree(iToken);
3200 return 0;
3201 }
3202
parseTypeDupes(char * line,e_typeDupeCheck * typeDupeBase,unsigned * DayAge)3203 int parseTypeDupes(char *line, e_typeDupeCheck *typeDupeBase, unsigned *DayAge)
3204 {
3205 char *iLine;
3206
3207 if (line == NULL) {
3208 prErr("A parameter after %s is missing!", actualKeyword);
3209 return 1;
3210 }
3211
3212 iLine = strLower(sstrdup(line));
3213 if (strcmp(iLine, "textdupes")==0) *typeDupeBase = textDupes;
3214 else if (strcmp(iLine, "hashdupes")==0) *typeDupeBase = hashDupes;
3215 else if (strcmp(iLine, "hashdupeswmsgid")==0) *typeDupeBase = hashDupesWmsgid;
3216 else if (strcmp(iLine, "commondupebase")==0) {
3217 *typeDupeBase = commonDupeBase;
3218 if (*DayAge==0) *DayAge=(unsigned) 5;
3219 }
3220 else {
3221 prErr("Unknown type base of dupes %s!", line);
3222 nfree(iLine);
3223 return 2;
3224 }
3225 nfree(iLine);
3226 return 0;
3227 }
3228
3229
parseSaveTic(const s_fidoconfig * config,char * token,s_savetic * savetic)3230 int parseSaveTic(const s_fidoconfig *config, char *token, s_savetic *savetic)
3231 {
3232 char *tok;
3233 int rc;
3234
3235 unused(config);
3236
3237 if (token == NULL) {
3238 prErr("Parameters after %s are missing!", actualKeyword);
3239 return 1;
3240 }
3241
3242 memset(savetic, 0, sizeof(s_savetic));
3243
3244 tok = strtok(token, " \t");
3245 if (tok == NULL) {
3246 prErr("An areaname mask after %s is missing!", actualKeyword);
3247 return 1; /* if there is no areaname mask */
3248 }
3249
3250 savetic->fileAreaNameMask = sstrdup(tok);
3251
3252 tok = strtok(NULL, " \t");
3253
3254 if (tok == NULL) {
3255 prErr("Parameters after %s are missing!", token);
3256 return 1;
3257 }
3258
3259
3260 if(*tok == '-')
3261 {
3262 if (tok[1] == 'l')
3263 savetic->fileAction = 2;
3264 else if (tok[1] == 'c')
3265 savetic->fileAction = 1;
3266 tok = strtok(NULL, " \t");
3267 }
3268
3269
3270 rc = parsePath(tok, &savetic->pathName, NULL);
3271 if(rc==0) {
3272 tok = strtok(NULL, " \t");
3273 if (tok) {
3274 parseNumber(tok, 10, &(savetic->days2save));
3275 }
3276 }
3277 return rc;
3278 }
3279
parseSaveTicStatement(char * token,s_fidoconfig * config)3280 int parseSaveTicStatement(char *token, s_fidoconfig *config)
3281 {
3282 int rc;
3283
3284 if (token == NULL) {
3285 prErr("Parameters after %s are missing!", actualKeyword);
3286 return 1;
3287 }
3288
3289 config->saveTic = srealloc(config->saveTic,sizeof(s_savetic)*(config->saveTicCount+1));
3290 rc = parseSaveTic(config, token,&(config->saveTic[config->saveTicCount]));
3291 config->saveTicCount++;
3292 return rc;
3293 }
3294
parseExecOnFile(char * line,s_fidoconfig * config)3295 int parseExecOnFile(char *line, s_fidoconfig *config) {
3296 char *a, *f, *c;
3297 s_execonfile *execonfile;
3298
3299 if (line == NULL) {
3300 prErr("A parameter after %s is missing!", actualKeyword);
3301 return 1;
3302 }
3303
3304 a = strtok(line, " \t");
3305 f = strtok(NULL, " \t");
3306 c = getRestOfLine();
3307 if ((a != NULL) && (f != NULL) && (c != NULL)) {
3308
3309 /* add new execonfile statement */
3310 config->execonfileCount++;
3311 config->execonfile = srealloc(config->execonfile, config->execonfileCount * sizeof(s_execonfile));
3312
3313 /* fill new execonfile statement */
3314 execonfile = &(config->execonfile[config->execonfileCount-1]);
3315 execonfile->filearea = (char *) smalloc(strlen(a)+1);
3316 strcpy(execonfile->filearea, a);
3317 execonfile->filename = (char *) smalloc(strlen(f)+1);
3318 strcpy(execonfile->filename, f);
3319 execonfile->command = (char *) smalloc(strlen(c)+1);
3320 strcpy(execonfile->command, c);
3321 return 0;
3322
3323 } else {
3324 prErr("A parameter after %s is missing!", actualKeyword);
3325 return 1;
3326 }
3327 }
3328
printNodelistError(void)3329 void printNodelistError(void)
3330 {
3331 prErr("You must define a nodelist first before you use %s!", actualKeyword);
3332 }
3333
parseLinkDefaults(char * token,s_fidoconfig * config)3334 int parseLinkDefaults(char *token, s_fidoconfig *config)
3335 {
3336
3337 if (token==NULL) {
3338 config->describeLinkDefaults = 1;
3339 } else {
3340
3341 if (stricmp(token, "begin")==0) config->describeLinkDefaults = 1;
3342 else if (stricmp(token, "end")==0) config->describeLinkDefaults = 0;
3343 else if (stricmp(token, "destroy")==0) {
3344 config->describeLinkDefaults = 0;
3345 freeLink(config->linkDefaults);
3346 config->linkDefaults = NULL;
3347 }
3348 else return 2;
3349 }
3350
3351 if (config->describeLinkDefaults && config->linkDefaults==NULL) {
3352
3353 config->linkDefaults = scalloc(1, sizeof(s_link));
3354
3355 /* Set defaults like in parseLink() */
3356
3357 /* set areafix default to on */
3358 config->linkDefaults->areafix.on = 1;
3359 config->linkDefaults->filefix.on = 1;
3360
3361 /* set defaults to export, import, mandatory (0), manual (0) */
3362 config->linkDefaults->aexport = 1;
3363 config->linkDefaults->import = 1;
3364 config->linkDefaults->ourAka = &(config->addr[0]);
3365
3366 /* set defaults maxUnpackedNetmail */
3367 config->linkDefaults->maxUnpackedNetmail = 100;
3368 config->linkDefaults->dailyBundles = config->dailyBundles;
3369
3370 /* set FileFixFSC87Subset default to on */
3371 config->linkDefaults->FileFixFSC87Subset = 1;
3372 }
3373
3374 memset(&linkDefined, 0, sizeof(linkDefined));
3375 return 0;
3376 }
3377
parseNamesCase(char * line,e_nameCase * value)3378 int parseNamesCase(char *line, e_nameCase *value)
3379 {
3380 if (line == NULL) {
3381 prErr("A parameter after %s is missing!", actualKeyword);
3382 return 1;
3383 }
3384
3385 if (stricmp(line, "lower") == 0) *value = eLower;
3386 else if (stricmp(line, "upper") == 0) *value = eUpper;
3387 else {
3388 prErr("Unknown case parameter %s!", line);
3389 return 2;
3390 }
3391 return 0;
3392 }
3393
parseNamesCaseConversion(char * line,e_nameCaseConvertion * value)3394 int parseNamesCaseConversion(char *line, e_nameCaseConvertion *value)
3395 {
3396 char *iLine;
3397
3398 if (line == NULL) {
3399 prErr("A parameter after %s is missing!", actualKeyword);
3400 return 1;
3401 }
3402
3403 iLine = strLower(sstrdup(line));
3404 if (strcmp(iLine, "lower") == 0) *value = cLower;
3405 else if (strcmp(iLine, "upper") == 0) *value = cUpper;
3406 else if (strcmp(iLine, "dont") == 0) *value = cDontTouch;
3407 else if (strcmp(iLine, "donttouch") == 0) *value = cDontTouch;
3408 else if (strcmp(iLine, "same") == 0) *value = cDontTouch;
3409 else {
3410 prErr("Unknown case convertion parameter %s!", line);
3411 nfree(iLine);
3412 return 2;
3413 }
3414 nfree(iLine);
3415 return 0;
3416 }
3417
parseBundleNameStyle(char * line,e_bundleFileNameStyle * value)3418 int parseBundleNameStyle(char *line, e_bundleFileNameStyle *value)
3419 {
3420 char *iLine;
3421
3422 if (line == NULL) {
3423 prErr("A parameter after %s is missing!", actualKeyword);
3424 return 1;
3425 }
3426
3427 iLine = strLower(sstrdup(line));
3428 if (strcmp(iLine, "addrdiff") == 0) *value = eAddrDiff;
3429 else if (strcmp(iLine, "addrdiffalways") == 0) *value = eAddrDiffAlways;
3430 else if (strcmp(iLine, "timestamp") == 0) *value = eTimeStamp;
3431 else if (strcmp(iLine, "amiga") == 0) *value = eAmiga;
3432 else if (strcmp(iLine, "addrscrc32") == 0) *value = eAddrsCRC32;
3433 else if (strcmp(iLine, "addrscrc32always") == 0) *value = eAddrsCRC32Always;
3434 else {
3435 prErr("Unknown bundle name style %s!", line);
3436 nfree(iLine);
3437 return 2;
3438 }
3439 nfree(iLine);
3440 return 0;
3441 }
3442
parseLinkWithILogType(char * line,e_linkWithImportLog * value)3443 int parseLinkWithILogType(char *line, e_linkWithImportLog *value)
3444 {
3445 char *iLine;
3446
3447 if (line == NULL) {
3448 prErr("A parameter after %s is missing!", actualKeyword);
3449 return 1;
3450 }
3451
3452 if (*value) {
3453 prErr("LinkWithImportLog redefinition");
3454 return 2;
3455 }
3456
3457 iLine = strLower(sstrdup(line));
3458 striptwhite(iLine);
3459 if (strcmp(iLine, "yes") == 0) *value = lwiYes;
3460 else if (strcmp(iLine, "no") == 0) *value = lwiNo;
3461 else if (strcmp(iLine, "kill") == 0) *value = lwiKill;
3462 else {
3463 prErr("Unknown LinkWithImportLog value %s!", line);
3464 nfree(iLine);
3465 return 2;
3466 }
3467 nfree(iLine);
3468 return 0;
3469 }
3470
parseKludgeAreaNetmailType(char * line,e_kludgeAreaNetmail * value)3471 int parseKludgeAreaNetmailType(char *line, e_kludgeAreaNetmail *value)
3472 {
3473 char *iLine;
3474
3475 if (line == NULL) {
3476 prErr("A parameter after %s is missing!", actualKeyword);
3477 return 1;
3478 }
3479
3480 if (*value) {
3481 prErr("kludgeAreaNetmail redefinition");
3482 return 2;
3483 }
3484
3485 iLine = strLower(sstrdup(line));
3486 if (strcmp(iLine, "kill") == 0) *value = kanKill;
3487 else if (strcmp(iLine, "ignore") == 0) *value = kanIgnore;
3488 else if (strcmp(iLine, "echomail") == 0) *value = kanEcho;
3489 else {
3490 prErr("Unknown klugdeAreaNetmail value %s!", line);
3491 nfree(iLine);
3492 return 2;
3493 }
3494 nfree(iLine);
3495 return 0;
3496 }
3497
parseSendMailCmd(char * line,char ** sendMailCmd)3498 int parseSendMailCmd( char *line, char **sendMailCmd )
3499 {
3500 if (!line)
3501 {
3502 prErr("A parameter after %s is missing!", actualKeyword);
3503 return 1;
3504 }
3505
3506 if (*sendMailCmd) {
3507 prErr("sendMailCmd redefinition!");
3508 return 2;
3509 }
3510
3511 *sendMailCmd = sstrdup(line);
3512 return 0;
3513 }
3514
parseEmailEncoding(char * line,e_emailEncoding * value)3515 int parseEmailEncoding(char *line, e_emailEncoding *value)
3516 {
3517 char *iLine;
3518
3519 if (line == NULL)
3520 {
3521 prErr("A parameter after %s is missing!", actualKeyword);
3522 return 1;
3523 }
3524
3525 iLine = strLower(sstrdup(line));
3526 if (strcmp(iLine, "uue") == 0) *value = eeUUE;
3527 else if (strcmp(iLine, "mime") == 0) *value = eeMIME;
3528 else if (strcmp(iLine, "seat") == 0) *value = eeSEAT;
3529 else
3530 {
3531 prErr("Unknown email encoding parameter %s!", line);
3532 nfree(iLine);
3533 return 2;
3534 }
3535 nfree(iLine);
3536 return 0;
3537 }
3538
3539 /* options: <flType> <destFile> <dirHdrTpl> <dirEntryTpl> <dirFtrTpl> [<globHdrTpl> <globFtrTpl>] */
parseFilelist(char * line,s_fidoconfig * config)3540 int parseFilelist(char *line, s_fidoconfig *config)
3541 {
3542 char *lineTmp;
3543 s_filelist *curFl;
3544 char *flType = NULL;
3545 unsigned int numCopied;
3546
3547 if (line == NULL) {
3548 prErr("Parameters after %s are missing!", actualKeyword);
3549 return 1;
3550 }
3551
3552 /* add new template */
3553 config->filelistCount++;
3554 config->filelists = realloc(config->filelists, config->filelistCount * sizeof(s_filelist));
3555 curFl = &config->filelists[config->filelistCount - 1];
3556 memset(curFl, 0, sizeof(s_filelist));
3557
3558 /* parse type */
3559 numCopied = copyStringUntilSep(line, " ", &flType);
3560 if (!numCopied) return 1;
3561 strLower(flType);
3562
3563 if (!strcmp(flType, "dir")) curFl->flType = flDir;
3564 else if (!strcmp(flType, "global")) curFl->flType = flGlobal;
3565 else if (!strcmp(flType, "dirlist")) curFl->flType = flDirList;
3566 else
3567 {
3568 prErr("Unknown filelist type %s!", flType);
3569 nfree(flType);
3570 return 2;
3571 }
3572 nfree(flType);
3573
3574 /* parse destFile */
3575 lineTmp = line + numCopied;
3576 if (*lineTmp) lineTmp++;
3577 numCopied = copyStringUntilSep(lineTmp, " ", &(curFl->destFile));
3578 if (!numCopied) return 1;
3579
3580 if ((curFl->flType == flDir) || (curFl->flType == flGlobal))
3581 {
3582 /* parse dirHdrTpl */
3583 lineTmp += numCopied;
3584 if (*lineTmp) lineTmp++;
3585 numCopied = copyStringUntilSep(lineTmp, " ", &(curFl->dirHdrTpl));
3586 if (!numCopied) return 1;
3587
3588 /* parse dirEntryTpl */
3589 lineTmp += numCopied;
3590 if (*lineTmp) lineTmp++;
3591 numCopied = copyStringUntilSep(lineTmp, " ", &(curFl->dirEntryTpl));
3592 if (!numCopied) return 1;
3593
3594 /* parse dirFtrTpl */
3595 lineTmp += numCopied;
3596 if (*lineTmp) lineTmp++;
3597 numCopied = copyStringUntilSep(lineTmp, " ", &(curFl->dirFtrTpl));
3598 if (!numCopied) return 1;
3599 }
3600
3601 switch (curFl->flType)
3602 {
3603 case flGlobal:
3604 /* parse globHdrTpl */
3605 lineTmp += numCopied;
3606 if (*lineTmp) lineTmp++;
3607 numCopied = copyStringUntilSep(lineTmp, " ", &(curFl->globHdrTpl));
3608 if (!numCopied) return 1;
3609
3610 /* parse globFtrTpl */
3611 lineTmp += numCopied;
3612 if (*lineTmp) lineTmp++;
3613 numCopied = copyStringUntilSep(lineTmp, " ", &(curFl->globFtrTpl));
3614 if (!numCopied) return 1;
3615 break;
3616
3617 case flDirList:
3618 /* parse dirListHdrTpl */
3619 lineTmp += numCopied;
3620 if (*lineTmp) lineTmp++;
3621 numCopied = copyStringUntilSep(lineTmp, " ", &(curFl->dirListHdrTpl));
3622 if (!numCopied) return 1;
3623
3624 /* parse dirListEntryTpl */
3625 lineTmp += numCopied;
3626 if (*lineTmp) lineTmp++;
3627 numCopied = copyStringUntilSep(lineTmp, " ", &(curFl->dirListEntryTpl));
3628 if (!numCopied) return 1;
3629
3630 /* parse dirListFtrTpl */
3631 lineTmp += numCopied;
3632 if (*lineTmp) lineTmp++;
3633 numCopied = copyStringUntilSep(lineTmp, " ", &(curFl->dirListFtrTpl));
3634 if (!numCopied) return 1;
3635 break;
3636
3637 case flDir:
3638 default:
3639 /* just avoid a warning */
3640 break;
3641 }
3642
3643 return 0;
3644 }
3645
parseSyslog(char * line,int * value)3646 int parseSyslog(char *line, int *value)
3647 {
3648 int rv=0;
3649
3650 #ifndef HAVE_SYSLOG
3651 prErr("%s: Syslogging is not supported on your platform!", actualKeyword);
3652 rv=1;
3653 unused(line);
3654 unused(value);
3655
3656 #else
3657 # include <huskylib/syslogp.h>
3658 int i;
3659
3660 if (line == NULL || line[0] == '\0') {
3661 prErr("A parameter after %s is missing!", actualKeyword);
3662 return 1;
3663 }
3664
3665 if (isdigit(line[0]))
3666 {
3667 *value = atoi(line);
3668 }
3669 else
3670 {
3671
3672 /* | if you get an error about undefined symbol "facilitynames"
3673 | add your operating system after "sun" to the ifdef line
3674 | in syslogp.h which comes below the
3675 | "unix systems that have syslog, but not facilitynames"
3676 | comment
3677 V */
3678 for (i = 0; facilitynames[i].c_name != NULL; i++)
3679 {
3680 if (!strcmp(line, facilitynames[i].c_name))
3681 {
3682 *value = facilitynames[i].c_val;
3683 break;
3684 }
3685 }
3686
3687 if (facilitynames[i].c_name == NULL)
3688 {
3689 prErr("%s: %s is an unknown syslog facility on this system.",
3690 actualKeyword, line);
3691 rv=1;
3692 }
3693 }
3694 #endif
3695 return rv;
3696 }
3697
3698
3699 /* Parse additional option tokens like ReadOnly/WriteOnly */
3700
parsePermissions(char * line,s_permissions ** perm,unsigned int * permCount)3701 int parsePermissions (char *line, s_permissions **perm, unsigned int *permCount)
3702 {
3703 char *ptr;
3704
3705 if (line == NULL) {
3706 prErr("A parameter after %s is missing!", actualKeyword);
3707 return 1;
3708 }
3709
3710 *perm = srealloc (*perm, (*permCount + 1) * sizeof(s_permissions));
3711
3712 if ((ptr = strtok(line, " \t")) == NULL) {
3713 prErr("An AddressMask in %s is missing!", actualKeyword);
3714 return 1;
3715 }
3716
3717 (*perm)[*permCount].addrMask = strdup (ptr);
3718
3719 if ((ptr = strtok(NULL, " \t")) == NULL) {
3720 prErr("An AreaMask in %s is missing!", actualKeyword);
3721 return 1;
3722 }
3723
3724 (*perm)[*permCount].areaMask = strdup (ptr);
3725
3726 (*permCount)++;
3727
3728 if (strtok(NULL, " \t") != NULL) {
3729 prErr("Extra parameters in %s", actualLine);
3730 return 1;
3731 }
3732
3733 return 0;
3734 }
3735
parseSeqOutrun(char * line,unsigned long * seqoutrun)3736 int parseSeqOutrun(char *line, unsigned long *seqoutrun)
3737 {
3738 char *p;
3739
3740 if (line == NULL) {
3741 prErr("Parameters after %s are missing!", actualKeyword);
3742 return 1;
3743 }
3744
3745 while (isspace(*line)) line++;
3746 if (!isdigit(*line)) {
3747 prErr("Bad SeqOutrun value %s", line);
3748 return 1;
3749 }
3750 *seqoutrun = (unsigned long)atol(line);
3751 p = line;
3752 while (isdigit(*p)) p++;
3753 if (*p == '\0') return 0;
3754 if (p[1]) {
3755 prErr("Bad SeqOutrun value %s", line);
3756 return 1;
3757 }
3758 switch (tolower(*p)) {
3759 case 'y': *seqoutrun *= 365;
3760 case 'd': *seqoutrun *= 24;
3761 case 'h': *seqoutrun *= 60*60;
3762 break;
3763 case 'w': *seqoutrun *= 7l*24*60*60;
3764 break;
3765 case 'm': *seqoutrun *= 31l*24*60*60;
3766 break;
3767 default: prErr("Bad SeqOutrun value %s", line);
3768 return 1;
3769 }
3770 return 0;
3771 }
3772
3773
3774 /* Parse the 'AvailList' token value
3775 */
parseAvailList(char * line,eAvailList * availlist)3776 int parseAvailList(char *line, eAvailList *availlist)
3777 {
3778 char *iLine;
3779
3780 if (line == NULL)
3781 {
3782 prErr("A parameter after %s is missing!", actualKeyword);
3783 return 1;
3784 }
3785
3786 iLine = strLower(sstrdup(line));
3787 if (stricmp(iLine, "full") == 0) *availlist = AVAILLIST_FULL;
3788 else if (stricmp(iLine, "unique") == 0) *availlist = AVAILLIST_UNIQUE;
3789 else if (stricmp(iLine, "uniqueone") == 0) *availlist = AVAILLIST_UNIQUEONE;
3790 else
3791 {
3792 prErr("Unknown AvailList value %s!", line);
3793 nfree(iLine);
3794 return 1;
3795 }
3796 nfree(iLine);
3797 return 0;
3798 }
3799
3800 /* parse group description */
parseGroupDesc(s_fidoconfig * config,char * line)3801 int parseGroupDesc(s_fidoconfig *config, char *line) {
3802 char *n, *d;
3803 register char *s = line;
3804 register short l;
3805 register unsigned short i;
3806 /* parse line */
3807 while (*s && (*s == ' ' || *s == '\t')) s++;
3808 if (*s == '\0') { prErr("Missing group name, line %d!", actualLineNr); return 1; }
3809 n = s;
3810 while (*s && (*s != ' ' && *s != '\t')) s++;
3811 if (*n == '"' && *(s-1) == '"') { n++; *(s-1) = '\0'; }
3812 if (*s) { *s = '\0'; s++; }
3813 while (*s && (*s == ' ' || *s == '\t')) s++;
3814 if (*s == '\0') { prErr("Missing group description, line %d!", actualLineNr); return 1; }
3815 l = strlen(s) - 1;
3816 while (l > 0 && (s[l] == ' ' || s[l] == '\t')) l--;
3817 if (l <= 0) { prErr("Missing group description, line %d!", actualLineNr); return 1; }
3818 s[l+1] = '\0';
3819 /* create a new group record */
3820 for (i = 0; i <= config->groupCount; i++) {
3821 if (i == config->groupCount) {
3822 config->groupCount++;
3823 config->group = srealloc(config->group, sizeof(s_group)*config->groupCount);
3824 config->group[i].name = sstrdup(n);
3825 break;
3826 }
3827 else if ( strcmp(config->group[i].name, n) == 0 ) {
3828 nfree(config->group[i].desc);
3829 break;
3830 }
3831 }
3832 /* make group desc */
3833 if (*s != '"') { config->group[i].desc = sstrdup(s); return 0; }
3834 else {
3835 d = smalloc(l); s++; l = 0;
3836 for (;;)
3837 {
3838 if (*s == '"') { d[l++] = '\0'; break; }
3839 if (*s != '\\' || (*s == '\\' && *(s+1) == '\0')) d[l++] = *s;
3840 else switch (*(++s)) {
3841 case '"': d[l++] = '"'; break;
3842 case 'n': d[l++] = '\n'; break;
3843 case 'r': d[l++] = '\r'; break;
3844 case 't': d[l++] = '\t'; break;
3845 default : d[l++] = *s;
3846 }
3847 if (*s == '\0') break; else s++;
3848 };
3849 config->group[i].desc = d;
3850 }
3851 return 0;
3852 }
3853
3854 /* parse SoftEchoList <none|name|group|group,name> */
parseListEcho(char * line,e_listEchoMode * value)3855 int parseListEcho(char *line, e_listEchoMode *value) {
3856 char *iLine;
3857
3858 if (line == NULL) {
3859 prErr("A parameter after %s is missing!", actualKeyword);
3860 return 1;
3861 }
3862
3863 if (*value) {
3864 prErr("%s redefinition", actualKeyword);
3865 return 2;
3866 }
3867
3868 iLine = strLower(sstrdup(line));
3869 if (strcmp(iLine, "none") == 0) *value = lemUnsorted;
3870 else if (strcmp(iLine, "name") == 0) *value = lemName;
3871 else if (strcmp(iLine, "group") == 0) *value = lemGroup;
3872 else if (strcmp(iLine, "group,name") == 0) *value = lemGroupName;
3873 else {
3874 prErr("Unknown %s value %s!", actualKeyword, line);
3875 nfree(iLine);
3876 return 2;
3877 }
3878 nfree(iLine);
3879 return 0;
3880 }
3881
3882
3883 /* Parse fidoconfig line
3884 * Return 0 if success.
3885 */
parseLine(char * line,s_fidoconfig * config)3886 int parseLine(char *line, s_fidoconfig *config)
3887 {
3888 char *token, *temp, *s;
3889 char *iToken;
3890 int rc = 0, id;
3891 s_link *clink = NULL;
3892 int link_robot = -1;
3893 static token_list_t tl;
3894 static token_list_t *ptl = NULL;
3895
3896 temp = (char *) smalloc(strlen(line)+1);
3897 strcpy(temp, line);
3898 actualLine = temp = vars_expand(temp);
3899
3900 if (ptl == NULL)
3901 {
3902 ptl = &tl;
3903 make_token_list(ptl, parseline_tokens);
3904 }
3905
3906 actualKeyword = token = strtok(temp, " \t");
3907
3908 /* printf("Parsing: %s\n", line);
3909 printf("token: %s - %s\n", line, strtok(NULL, "\0")); */
3910
3911 if (token)
3912 {
3913 iToken = strLower(sstrdup(token));
3914
3915 id = find_token(ptl, iToken);
3916 /* val: handle ^(area|file)fix.* */
3917 if (id == -1) {
3918 link_robot = (!strnicmp(iToken, "areafix", 7) << 0)
3919 | (!strnicmp(iToken, "filefix", 7) << 1);
3920 if (link_robot) id = find_token(ptl, iToken + 7);
3921 }
3922
3923 switch (id)
3924 {
3925 case ID_VERSION:
3926 rc = parseVersion(getRestOfLine(), config);
3927 break;
3928 case ID_NAME:
3929 if (link_robot == 1 || link_robot == 2) {
3930 clink = getDescrLink(config);
3931 if (clink) {
3932 if (link_robot == 1)
3933 fc_copyString(getRestOfLine(), &(clink->areafix.name));
3934 else
3935 fc_copyString(getRestOfLine(), &(clink->filefix.name));
3936 }
3937 }
3938 else
3939 rc = fc_copyString(getRestOfLine(), &(config->name));
3940 break;
3941 case ID_LOCATION:
3942 rc = fc_copyString(getRestOfLine(), &(config->location));
3943 break;
3944 case ID_SYSOP:
3945 rc = fc_copyString(getRestOfLine(), &(config->sysop));
3946 break;
3947 case ID_ADDRESS:
3948 rc = parseAddress(getRestOfLine(), config);
3949 break;
3950 case ID_INBOUND:
3951 rc = parsePath(getRestOfLine(), &(config->inbound), NULL);
3952 break;
3953 case ID_PROTINBOUND:
3954 rc = parsePath(getRestOfLine(), &(config->protInbound), NULL);
3955 break;
3956 case ID_LISTINBOUND:
3957 rc = parsePath(getRestOfLine(), &(config->listInbound), NULL);
3958 break;
3959 case ID_LOCALINBOUND:
3960 rc= parsePath(getRestOfLine(), &(config->localInbound), NULL);
3961 break;
3962 case ID_TEMPINBOUND:
3963 rc= parsePath(getRestOfLine(), &(config->tempInbound), NULL);
3964 break;
3965 case ID_OUTBOUND:
3966 rc = parsePath(getRestOfLine(), &(config->outbound), NULL);
3967 break;
3968 case ID_TICOUTBOUND:
3969 rc = parsePath(getRestOfLine(), &(config->ticOutbound), NULL);
3970 break;
3971 case ID_PUBLIC:
3972 rc = parsePublic(getRestOfLine(), config);
3973 break;
3974 case ID_LOGFILEDIR:
3975 rc = parsePath(getRestOfLine(), &(config->logFileDir), NULL);
3976 break;
3977 case ID_DUPEHISTORYDIR:
3978 rc = parsePath(getRestOfLine(), &(config->dupeHistoryDir), NULL);
3979 break;
3980 case ID_NODELISTDIR:
3981 rc = parsePath(getRestOfLine(), &(config->nodelistDir), NULL);
3982 break;
3983 case ID_FILEAREABASEDIR:
3984 rc = parseAreaPath(getRestOfLine(), &(config->fileAreaBaseDir), NULL);
3985 break;
3986 case ID_PASSFILEAREADIR:
3987 rc = parseAreaPath(getRestOfLine(), &(config->passFileAreaDir), NULL);
3988 break;
3989 case ID_BUSYFILEDIR:
3990 rc = parsePath(getRestOfLine(), &(config->busyFileDir), NULL);
3991 break;
3992 case ID_MSGBASEDIR:
3993 rc = parseAreaPathExpand(getRestOfLine(), &(config->msgBaseDir), NULL);
3994 break;
3995 case ID_LINKMSGBASEDIR:
3996 rc = parseAreaPathExpand(getRestOfLine(),
3997 &(getDescrLink(config)->areafix.baseDir),
3998 &(linkDefined.areafix.baseDir));
3999 break;
4000 case ID_LINKFILEBASEDIR:
4001 rc = parseAreaPath(getRestOfLine(),
4002 &(getDescrLink(config)->filefix.baseDir),
4003 &(linkDefined.filefix.baseDir));
4004 break;
4005
4006 case ID_MAGIC:
4007 rc = parsePath(getRestOfLine(), &(config->magic), NULL);
4008 break;
4009 case ID_SEMADIR:
4010 rc = parsePath(getRestOfLine(), &(config->semaDir), NULL);
4011 break;
4012 case ID_BADFILESDIR:
4013 rc = parsePath(getRestOfLine(), &(config->badFilesDir), NULL);
4014 break;
4015 case ID_NETMAILAREA:
4016 case ID_NETAREA:
4017 rc = parseNetMailArea(getRestOfLine(), config);
4018 break;
4019 case ID_DUPEAREA:
4020 rc = parseArea(config, getRestOfLine(), &(config->dupeArea), 1);
4021 break;
4022 case ID_BADAREA:
4023 rc = parseArea(config, getRestOfLine(), &(config->badArea), 1);
4024 break;
4025 case ID_ECHOAREADEFAULT:
4026 rc = parseAreaDefault(config, getRestOfLine(), &(config->EchoAreaDefault), 1);
4027 break;
4028 case ID_FILEAREADEFAULT:
4029 rc = parseAreaDefault(config, getRestOfLine(), &(config->FileAreaDefault),1);
4030 break;
4031 case ID_ECHOAREA:
4032 rc = parseEchoArea(getRestOfLine(), config);
4033 break;
4034 case ID_FILEAREA:
4035 rc = parseFileArea(getRestOfLine(), config);
4036 break;
4037 case ID_BBSAREA:
4038 rc = parseBbsAreaStatement(getRestOfLine(), config);
4039 break;
4040 case ID_LOCALAREA:
4041 rc = parseLocalArea(getRestOfLine(), config);
4042 break;
4043 case ID_REMAP:
4044 rc = parseRemap(getRestOfLine(),config);
4045 break;
4046 case ID_LINK:
4047 rc = parseLink(getRestOfLine(), config);
4048 if (rc)
4049 {
4050 exit(EX_CONFIG); /* 'cause of parsing aka and overriding prev. aka */
4051 }
4052 break;
4053 case ID_PASSWORD:
4054 if( (clink = getDescrLink(config)) != NULL ) {
4055 rc = parsePWD(getRestOfLine(), &clink->defaultPwd);
4056 /* this way used because of redefinition */
4057 /* defaultPwd from linkdefaults (if exist) */
4058 clink->pktPwd = clink->defaultPwd;
4059 clink->ticPwd = clink->defaultPwd;
4060 clink->areafix.pwd = clink->defaultPwd;
4061 clink->filefix.pwd = clink->defaultPwd;
4062 clink->bbsPwd = clink->defaultPwd;
4063 clink->sessionPwd = clink->defaultPwd;
4064 } else {
4065 rc = 1;
4066 }
4067 break;
4068 case ID_AKA:
4069 if ((clink = getDescrLink(config)) != NULL ) {
4070 parseFtnAddrZS(getRestOfLine(), &clink->hisAka);
4071 }
4072 else {
4073 rc = 1;
4074 }
4075 break;
4076 case ID_OURAKA:
4077 rc = 0;
4078 if( (clink = getDescrLink(config)) != NULL ) {
4079 char *l = getRestOfLine();
4080 clink->ourAka = getAddr(config, l);
4081 if (clink->ourAka == NULL) {
4082 prErr( "Address %s is not our aka!", l );
4083 rc = 2;
4084 }
4085 } else {
4086 rc = 1;
4087 }
4088 break;
4089 case ID_PACKAKA:
4090 rc = 0;
4091 if((clink = getDescrLink(config)) != NULL)
4092 {
4093 parseFtnAddrZS(getRestOfLine(), &clink->hisPackAka);
4094 }
4095 else
4096 rc = 1;
4097 break;
4098 case ID_AUTOCREATE:
4099 if( (clink = getDescrLink(config)) != NULL ) {
4100 s = getRestOfLine();
4101 if (link_robot & 1)
4102 rc |= parseBool (s, &clink->areafix.autoCreate);
4103 if (link_robot & 2)
4104 rc |= parseBool (s, &clink->filefix.autoCreate);
4105 } else {
4106 rc = 1;
4107 }
4108 break;
4109 case ID_FILEFIXFSC87SUBSET:
4110 if( (clink = getDescrLink(config)) != NULL ) {
4111 rc = parseBool (getRestOfLine(), &clink->FileFixFSC87Subset);
4112 } else {
4113 rc = 1;
4114 }
4115 break;
4116 case ID_FORWARDREQUESTS:
4117 if( (clink = getDescrLink(config)) != NULL ) {
4118 s = getRestOfLine();
4119 if (link_robot & 1)
4120 rc = parseBool (s, &clink->areafix.forwardRequests);
4121 if (link_robot & 2)
4122 rc = parseBool (s, &clink->filefix.forwardRequests);
4123 } else {
4124 rc = 1;
4125 }
4126 break;
4127 case ID_AUTOSUBSCRIBE:
4128 if( (clink = getDescrLink(config)) != NULL ) {
4129 s = getRestOfLine();
4130 if (link_robot & 1)
4131 rc = parseBool (s, &clink->areafix.autoSubscribe);
4132 if (link_robot & 2)
4133 rc = parseBool (s, &clink->filefix.autoSubscribe);
4134 } else {
4135 rc = 1;
4136 }
4137 break;
4138 case ID_DENYFWDREQACCESS:
4139 if( (clink = getDescrLink(config)) != NULL ) {
4140 s = getRestOfLine();
4141 if (link_robot & 1)
4142 rc = parseBool (s, &clink->areafix.denyFRA);
4143 if (link_robot & 2)
4144 rc = parseBool (s, &clink->filefix.denyFRA);
4145 } else rc = 1;
4146 break;
4147 case ID_FORWARDPKTS:
4148 if( (clink = getDescrLink(config)) != NULL ) {
4149 rc = parseForwardPkts(getRestOfLine(), clink);
4150 }
4151 else {
4152 rc = 1;
4153 }
4154 break;
4155 case ID_ALLOWEMPTYPKTPWD:
4156 if( (clink = getDescrLink(config)) != NULL ) {
4157 rc = parseAllowEmptyPktPwd(getRestOfLine(), config, clink);
4158 }
4159 else {
4160 rc = 1;
4161 }
4162 break;
4163 case ID_PACKNETMAIL:
4164 if( (clink = getDescrLink(config)) != NULL ) {
4165 rc = parseBool(getRestOfLine(), &clink->packNetmail);
4166 }
4167 else rc = 1;
4168 break;
4169 case ID_SENDNOTIFYMESSAGES:
4170 if( (clink = getDescrLink(config)) != NULL ) {
4171 rc = parseBool(getRestOfLine(), &clink->sendNotifyMessages);
4172 }
4173 else rc = 1;
4174 break;
4175 case ID_ALLOWREMOTECONTROL:
4176 if( (clink = getDescrLink(config)) != NULL ) {
4177 rc = parseBool(getRestOfLine(), &clink->allowRemoteControl);
4178 }
4179 else rc = 1;
4180 break;
4181 case ID_UNSUBSCRIBEONAREADELETE:
4182 if( (clink = getDescrLink(config)) != NULL ) {
4183 rc = parseBool(getRestOfLine(), &clink->unsubscribeOnAreaDelete);
4184 }
4185 else rc = 1;
4186 break;
4187 case ID_ALLOWPKTADDRDIFFER:
4188 if( (clink = getDescrLink(config)) != NULL ) {
4189 rc = parseAllowPktAddrDiffer(getRestOfLine(), config, clink);
4190 }
4191 else {
4192 rc = 1;
4193 }
4194 break;
4195 case ID_AUTOCREATEDEFAULTS:
4196 s = getRestOfLine();
4197 if( (clink = getDescrLink(config)) != NULL ) {
4198 if (link_robot & 1)
4199 rc = fc_copyStringWOstrip(s, &clink->areafix.autoCreateDefaults);
4200 if (link_robot & 2)
4201 rc = fc_copyStringWOstrip(s, &clink->filefix.autoCreateDefaults);
4202 }
4203 else {
4204 rc = 1;
4205 }
4206 break;
4207 case ID_AREAFIX:
4208 if( (clink = getDescrLink(config)) != NULL ) {
4209 rc = parseBool (getRestOfLine(), &clink->areafix.on);
4210 } else {
4211 rc = 1;
4212 }
4213 break;
4214 case ID_FILEFIX:
4215 if( (clink = getDescrLink(config)) != NULL ) {
4216 rc = parseBool (getRestOfLine(), &clink->filefix.on);
4217 } else {
4218 rc = 1;
4219 }
4220 break;
4221 case ID_PAUSE:
4222 if( (clink = getDescrLink(config)) != NULL ) {
4223 rc = parsePause (getRestOfLine(), &clink->Pause);
4224 } else {
4225 rc = 1;
4226 }
4227 break;
4228 case ID_NOTIC:
4229 if( (clink = getDescrLink(config)) != NULL ) {
4230 rc = parseBool (getRestOfLine(), &clink->noTIC);
4231 } else {
4232 rc = 1;
4233 }
4234 break;
4235 case ID_DELNOTRECEIVEDTIC:
4236 if( (clink = getDescrLink(config)) != NULL ) {
4237 rc = parseBool (getRestOfLine(), &clink->delNotReceivedTIC);
4238 } else {
4239 rc = 1;
4240 }
4241 break;
4242 case ID_ADVANCEDAREAFIX:
4243 if( (clink = getDescrLink(config)) != NULL ) {
4244 rc = parseBool (getRestOfLine(), &clink->advancedAreafix);
4245 } else {
4246 rc = 1;
4247 }
4248 break;
4249 case ID_AUTOPAUSE:
4250 rc = parseAutoPause(getRestOfLine(),
4251 &(getDescrLink(config)->autoPause));
4252 break;
4253 case ID_FWDPRIORITY:
4254 s = getRestOfLine();
4255 if (link_robot & 1)
4256 rc = parseUInt(s,
4257 &(getDescrLink(config)->areafix.forwardPriority));
4258 if (link_robot & 2)
4259 rc = parseUInt(s,
4260 &(getDescrLink(config)->filefix.forwardPriority));
4261 break;
4262 case ID_FORWARDREQUESTTIMEOUT:
4263 checkRobot();
4264 rc = parseUInt(getRestOfLine(), &(curRobot->forwardRequestTimeout));
4265 break;
4266 case ID_IDLEPASSTHRUTIMEOUT:
4267 checkRobot();
4268 rc = parseUInt(getRestOfLine(), &(curRobot->idlePassthruTimeout));
4269 break;
4270 case ID_KILLEDREQUESTTIMEOUT:
4271 checkRobot();
4272 rc = parseUInt(getRestOfLine(), &(curRobot->killedRequestTimeout));
4273 break;
4274
4275 case ID_DENYUNCONDFWDREQACCESS:
4276 if( (clink = getDescrLink(config)) != NULL ) {
4277 s = getRestOfLine();
4278 if (link_robot & 1)
4279 rc |= parseBool(s, &(clink->areafix.denyUFRA));
4280 if (link_robot & 2)
4281 rc |= parseBool(s, &(clink->filefix.denyUFRA));
4282 } else {
4283 rc = 1;
4284 }
4285 break;
4286 case ID_REDUCEDSEENBY:
4287 rc = parseBool(getRestOfLine(), &(getDescrLink(config)->reducedSeenBy));
4288 break;
4289 case ID_EXPORT:
4290 if( (clink = getDescrLink(config)) != NULL ) {
4291 rc = parseBool (getRestOfLine(), &clink->aexport);
4292 } else {
4293 rc = 1;
4294 }
4295 break;
4296 case ID_IMPORT:
4297 if( (clink = getDescrLink(config)) != NULL ) {
4298 rc = parseBool (getRestOfLine(), &clink->import);
4299 } else {
4300 rc = 1;
4301 }
4302 break;
4303 case ID_MANDATORY:
4304 if( (clink = getDescrLink(config)) != NULL ) {
4305 rc = parseBool (getRestOfLine(), &clink->mandatory);
4306 } else {
4307 rc = 1;
4308 }
4309 break;
4310 case ID_MANUAL:
4311 if( (clink = getDescrLink(config)) != NULL ) {
4312 rc = parseBool (getRestOfLine(), &clink->manual);
4313 } else {
4314 rc = 1;
4315 }
4316 break;
4317 case ID_OPTGRP:
4318 rc = parseGroup(getRestOfLine(), config, 3);
4319 break;
4320 case ID_FWDMASK:
4321 s = getRestOfLine();
4322 if (link_robot & 1) rc = parseGroup(s, config, 4);
4323 if (link_robot & 2) rc = parseGroup(s, config, 14);
4324 break;
4325 case ID_FWDDENYMASK:
4326 s = getRestOfLine();
4327 if (link_robot & 1) rc = parseGroup(s, config, 5);
4328 if (link_robot & 2) rc = parseGroup(s, config, 15);
4329 break;
4330 case ID_LEVEL:
4331 rc = parseNumber(getRestOfLine(), 10,
4332 &(getDescrLink(config)->level));
4333 break;
4334 case ID_ECHOLIMIT:
4335 {
4336 s_link *link = getDescrLink(config);
4337 s = getRestOfLine();
4338 if (link_robot & 1) rc |= parseNumber(s, 10, &(link->areafix.echoLimit));
4339 if (link_robot & 2) rc |= parseNumber(s, 10, &(link->filefix.echoLimit));
4340 break;
4341 }
4342 case ID_ARCMAILSIZE:
4343 rc = parseNumber(getRestOfLine(), 10,
4344 &(getDescrLink(config)->arcmailSize));
4345 break;
4346 case ID_DAILYBUNDLES:
4347 if( (clink = getDescrLink(config)) != NULL ) {
4348 rc = parseBool (getRestOfLine(), &clink->dailyBundles);
4349 } else {
4350 rc = parseBool (getRestOfLine(), &config->dailyBundles);
4351 }
4352 break;
4353 case ID_PKTSIZE:
4354 rc = parseNumber(getRestOfLine(), 10,
4355 &(getDescrLink(config)->pktSize));
4356 break;
4357 case ID_MAXUNPACKEDNETMAIL:
4358 rc = parseNumber(getRestOfLine(), 10,
4359 &(getDescrLink(config)->maxUnpackedNetmail));
4360 break;
4361 case ID_PKTPWD:
4362 rc = parsePWD(getRestOfLine(), &(getDescrLink(config)->pktPwd));
4363 break;
4364 case ID_TICPWD:
4365 rc = parsePWD(getRestOfLine(), &(getDescrLink(config)->ticPwd));
4366 break;
4367 case ID_AREAFIXPWD:
4368 rc = parsePWD(getRestOfLine(),
4369 &(getDescrLink(config)->areafix.pwd));
4370 break;
4371 case ID_FILEFIXPWD:
4372 rc = parsePWD(getRestOfLine(),
4373 &(getDescrLink(config)->filefix.pwd));
4374 break;
4375 case ID_BBSPWD:
4376 rc = parsePWD(getRestOfLine(), &(getDescrLink(config)->bbsPwd));
4377 break;
4378 case ID_SESSIONPWD:
4379 rc = parsePWD(getRestOfLine(),
4380 &(getDescrLink(config)->sessionPwd));
4381 break;
4382 case ID_HANDLE:
4383 rc = parseHandle(getRestOfLine(), config);
4384 break;
4385 case ID_EMAIL:
4386 if (config->linkCount) { /* email of link */
4387 rc = fc_copyString(getRestOfLine(), &(getDescrLink(config)->email));
4388 }else{ /* email of self */
4389 rc = fc_copyString(getRestOfLine(), &config->email );
4390 }
4391 break;
4392 case ID_EMAILFROM:
4393 rc = fc_copyString(getRestOfLine(),
4394 &(getDescrLink(config)->emailFrom));
4395 break;
4396 case ID_EMAILSUBJ:
4397 rc = fc_copyString(getRestOfLine(),
4398 &(getDescrLink(config)->emailSubj));
4399 break;
4400 case ID_EMAILENCODING:
4401 rc = parseEmailEncoding(getRestOfLine(),
4402 &(getDescrLink(config)->emailEncoding));
4403 break;
4404 case ID_FLAVOUR:
4405 rc = parseFlavour(getRestOfLine(),
4406 &(getDescrLink(config)->netMailFlavour));
4407 if (rc == 0) getDescrLink(config)->echoMailFlavour =
4408 getDescrLink(config)->fileEchoFlavour =
4409 getDescrLink(config)->netMailFlavour;
4410 break;
4411 case ID_NETMAILFLAVOUR:
4412 rc = parseFlavour(getRestOfLine(),
4413 &(getDescrLink(config)->netMailFlavour));
4414 break;
4415 case ID_ECHOMAILFLAVOUR:
4416 rc = parseFlavour(getRestOfLine(),
4417 &(getDescrLink(config)->echoMailFlavour));
4418 break;
4419 case ID_FILEECHOFLAVOUR:
4420 rc = parseFlavour(getRestOfLine(),
4421 &(getDescrLink(config)->fileEchoFlavour));
4422 break;
4423 case ID_ROBOT:
4424 if (config->describeLinkDefaults || config->linkCount) {
4425 prErr( "Any robots should be described before any link or linkdefaults!");
4426 rc = 1;
4427 }
4428 curRobot = getRobot(config, getRestOfLine(), 1);
4429 break;
4430 case ID_ROUTE:
4431 rc = parseRoute(getRestOfLine(), config, &(config->route),
4432 &(config->routeCount), id_route);
4433 break;
4434 case ID_ROUTEFILE:
4435 rc = parseRoute(getRestOfLine(), config, &(config->route),
4436 &(config->routeCount), id_routeFile);
4437 break;
4438 case ID_ROUTEMAIL:
4439 rc = parseRoute(getRestOfLine(), config, &(config->route),
4440 &(config->routeCount), id_routeMail);
4441 break;
4442 case ID_PACK:
4443 rc = parsePack(getRestOfLine(), config);
4444 break;
4445 case ID_UNPACK:
4446 rc = parseUnpack(getRestOfLine(), config);
4447 break;
4448 case ID_PACKER:
4449 rc = parsePackerDef(getRestOfLine(), config,
4450 &(getDescrLink(config)->packerDef));
4451 break;
4452 case ID_INTAB:
4453 rc = parseFileName(getRestOfLine(), &(config->intab), NULL);
4454 break;
4455 case ID_OUTTAB:
4456 rc = parseFileName(getRestOfLine(), &(config->outtab), NULL);
4457 break;
4458 case ID_RECODEMSGBASE:
4459 rc = parseBool (getRestOfLine(), &config->recodeMsgBase);
4460 break;
4461 case ID_HELPFILE:
4462 checkRobot();
4463 rc = parseFileName(getRestOfLine(), &(curRobot->helpFile), NULL);
4464 break;
4465 case ID_FWDFILE:
4466 s = getRestOfLine();
4467 if (link_robot & 1)
4468 rc = parseFileName(s,
4469 &(getDescrLink(config)->areafix.fwdFile),
4470 &(linkDefined.areafix.fwdFile));
4471 if (link_robot & 2)
4472 rc = parseFileName(s,
4473 &(getDescrLink(config)->filefix.fwdFile),
4474 &(linkDefined.filefix.fwdFile));
4475 break;
4476 case ID_FWDDENYFILE:
4477 s = getRestOfLine();
4478 if (link_robot & 1)
4479 rc = parseFileName(s,
4480 &(getDescrLink(config)->areafix.denyFwdFile),
4481 &(linkDefined.areafix.denyFwdFile));
4482 if (link_robot & 2)
4483 rc = parseFileName(s,
4484 &(getDescrLink(config)->filefix.denyFwdFile),
4485 &(linkDefined.filefix.denyFwdFile));
4486 break;
4487 case ID_AUTOCREATEFILE:
4488 s = getRestOfLine();
4489 if (link_robot & 1)
4490 rc = parseFileName(s,
4491 &(getDescrLink(config)->areafix.autoCreateFile),
4492 &(linkDefined.areafix.autoCreateFile));
4493 if (link_robot & 2)
4494 rc = parseFileName(s,
4495 &(getDescrLink(config)->filefix.autoCreateFile),
4496 &(linkDefined.filefix.autoCreateFile));
4497 break;
4498 case ID_LINKBUNDLENAMESTYLE:
4499 rc = parseBundleNameStyle(getRestOfLine(),
4500 &(getDescrLink(config)->linkBundleNameStyle));
4501 break;
4502 case ID_ECHOTOSSLOG:
4503 rc = fc_copyString(getRestOfLine(), &(config->echotosslog));
4504 break;
4505 case ID_STATLOG:
4506 rc = fc_copyString(getRestOfLine(), &(config->statlog));
4507 break;
4508 case ID_IMPORTLOG:
4509 rc = fc_copyString(getRestOfLine(), &(config->importlog));
4510 break;
4511 case ID_LINKWITHIMPORTLOG:
4512 rc = parseLinkWithILogType(getRestOfLine(),
4513 &(config->LinkWithImportlog));
4514 break;
4515 case ID_KLUDGEAREANETMAIL:
4516 rc = parseKludgeAreaNetmailType(getRestOfLine(),
4517 &(config->kludgeAreaNetmail));
4518 break;
4519 /* not used
4520 case ID_FILEAREASLOG:
4521 rc = parseFileName(getRestOfLine(), &(config->fileAreasLog), NULL);
4522 break;
4523 case ID_FILENEWAREASLOG:
4524 rc = parseFileName(getRestOfLine(), &(config->fileNewAreasLog), NULL);
4525 break;
4526 case ID_LONGNAMELIST:
4527 rc = parseFileName(getRestOfLine(), &(config->longNameList), NULL);
4528 break;
4529 case ID_FILEARCLIST:
4530 rc = parseFileName(getRestOfLine(), &(config->fileArcList), NULL);
4531 break;
4532 case ID_FILEPASSLIST:
4533 rc = parseFileName(getRestOfLine(), &(config->filePassList), NULL);
4534 break;
4535 case ID_FILEDUPELIST:
4536 rc = parseFileName(getRestOfLine(), &(config->fileDupeList), NULL);
4537 break;
4538 */
4539 case ID_LOGLEVELS:
4540 rc = parseLoglevels(getRestOfLine(), &(config->loglevels));
4541 break;
4542 case ID_SCREENLOGLEVELS:
4543 rc = parseLoglevels(getRestOfLine(), &(config->screenloglevels));
4544 break;
4545 case ID_LOGDATEFORMAT:
4546 rc = fc_copyString(getRestOfLine(), &(config->logDateFormat));
4547 break;
4548 case ID_ACCESSGRP:
4549 rc = parseGroup(getRestOfLine(), config, 0);
4550 break;
4551 case ID_LINKGRP:
4552 rc = parseGroup(getRestOfLine(), config, 1);
4553 break;
4554 case ID_CARBONTO:
4555 rc = parseCarbon(getRestOfLine(),config, ct_to);
4556 break;
4557 case ID_CARBONFROM:
4558 rc = parseCarbon(getRestOfLine(), config, ct_from);
4559 break;
4560 case ID_CARBONADDR:
4561 rc = parseCarbon(getRestOfLine(), config, ct_addr);
4562 break;
4563 case ID_CARBONKLUDGE:
4564 rc = parseCarbon(getRestOfLine(), config, ct_kludge);
4565 break;
4566 case ID_CARBONSUBJ:
4567 rc = parseCarbon(getRestOfLine(), config, ct_subject);
4568 break;
4569 case ID_CARBONTEXT:
4570 rc = parseCarbon(getRestOfLine(), config, ct_msgtext);
4571 break;
4572 case ID_CARBONFROMAREA:
4573 rc = parseCarbon(getRestOfLine(), config, ct_fromarea);
4574 break;
4575 case ID_CARBONGROUPS:
4576 rc = parseCarbon(getRestOfLine(), config, ct_group);
4577 break;
4578 case ID_CARBONCOPY:
4579 rc = parseCarbonArea(getRestOfLine(), config, 0);
4580 break;
4581 case ID_CARBONMOVE:
4582 rc = parseCarbonArea(getRestOfLine(), config, 1);
4583 break;
4584 case ID_CARBONEXTERN:
4585 rc = parseCarbonExtern(getRestOfLine(), config);
4586 break;
4587 case ID_NETMAILEXTERN:
4588 rc = parseCarbonExtern(getRestOfLine(), config);
4589 break;
4590 case ID_CARBONDELETE:
4591 rc = parseCarbonDelete(getRestOfLine(), config);
4592 break;
4593 case ID_CARBONREASON:
4594 rc = parseCarbonReason(getRestOfLine(), config);
4595 break;
4596 case ID_CARBONRULE:
4597 rc = parseCarbonRule(getRestOfLine(), config);
4598 break;
4599 case ID_EXCLUDEPASSTHROUGHCARBON:
4600 rc = parseBool(getRestOfLine(), &(config->exclPassCC));
4601 break;
4602 case ID_LOCKFILE:
4603 rc = fc_copyString(getRestOfLine(), &(config->lockfile));
4604 break;
4605 case ID_TEMPOUTBOUND:
4606 rc = parsePath(getRestOfLine(), &(config->tempOutbound), NULL);
4607 break;
4608 case ID_AUTOAREAPAUSE:
4609 checkRobot();
4610 rc = parseBool(getRestOfLine(), &(curRobot->autoAreaPause));
4611 break;
4612 case ID_AREAFIXFROMPKT:
4613 rc = parseBool(getRestOfLine(), &(config->areafixFromPkt));
4614 break;
4615 case ID_QUEUEFILE:
4616 checkRobot();
4617 rc = parseFileName(getRestOfLine(), &(curRobot->queueFile), NULL);
4618 break;
4619 case ID_REPORTSATTR:
4620 if (config->describeLinkDefaults || config->linkCount) {
4621 s_link *link = getDescrLink(config);
4622 s = getRestOfLine();
4623 if (link_robot & 1) rc |= parseAttr(s, &(link->areafix.reportsFlags), &(link->areafix.reportsAttr));
4624 if (link_robot & 2) rc |= parseAttr(s, &(link->filefix.reportsFlags), &(link->filefix.reportsAttr));
4625 }
4626 else {
4627 checkRobot();
4628 rc = parseAttr(getRestOfLine(), &(curRobot->reportsFlags), &(curRobot->reportsAttr));
4629 }
4630 break;
4631 case ID_KILLREQUESTS:
4632 checkRobot();
4633 rc = parseBool(getRestOfLine(), &(curRobot->killRequests));
4634 break;
4635 case ID_QUERYREPORTS:
4636 checkRobot();
4637 rc = parseBool(getRestOfLine(), &(curRobot->queryReports));
4638 break;
4639 case ID_CREATEDIRS:
4640 rc = parseBool(getRestOfLine(), &(config->createDirs));
4641 break;
4642 case ID_LONGDIRNAMES:
4643 rc = parseBool(getRestOfLine(), &(config->longDirNames));
4644 break;
4645 case ID_SPLITDIRS:
4646 rc = parseBool(getRestOfLine(), &(config->splitDirs));
4647 break;
4648 case ID_ADDDLC:
4649 rc = parseBool(getRestOfLine(), &(config->addDLC));
4650 break;
4651 case ID_FILESINGLEDESCLINE:
4652 rc = parseBool(getRestOfLine(), &(config->fileSingleDescLine));
4653 break;
4654 case ID_FILECHECKDEST:
4655 rc = parseBool(getRestOfLine(), &(config->fileCheckDest));
4656 break;
4657 case ID_PUBLICGROUP:
4658 rc = parseGroup(getRestOfLine(), config, 2);
4659 break;
4660 case ID_LOGECHOTOSCREEN:
4661 rc = parseBool(getRestOfLine(), &(config->logEchoToScreen));
4662 break;
4663 case ID_SEPARATEBUNDLES:
4664 rc = parseBool(getRestOfLine(), &(config->separateBundles));
4665 break;
4666 case ID_CARBONANDQUIT:
4667 rc = parseBool(getRestOfLine(), &(config->carbonAndQuit));
4668 break;
4669 case ID_CARBONKEEPSB:
4670 rc = parseBool(getRestOfLine(), &(config->carbonKeepSb));
4671 break;
4672 case ID_CARBONOUT:
4673 rc = parseBool(getRestOfLine(), &(config->carbonOut));
4674 break;
4675 case ID_IGNORECAPWORD:
4676 rc = parseBool(getRestOfLine(), &(config->ignoreCapWord));
4677 break;
4678 case ID_NOPROCESSBUNDLES:
4679 rc = parseBool(getRestOfLine(), &(config->noProcessBundles));
4680 break;
4681 case ID_NOTVALIDFILENAMECHARS:
4682 rc = fc_copyString(getRestOfLine(), &(config->notValidFNChars));
4683 break;
4684 case ID_REPORTTO:
4685 rc = fc_copyString(getRestOfLine(), &(config->ReportTo));
4686 break;
4687 case ID_REPORTREQUESTER:
4688 rc = parseBool(getRestOfLine(), (unsigned int*)&(config->reportRequester));
4689 break;
4690 case ID_EXECONFILE:
4691 rc = parseExecOnFile(getRestOfLine(), config);
4692 break;
4693 case ID_DEFARCMAILSIZE:
4694 rc = parseNumber(getRestOfLine(), 10, &(config->defarcmailSize));
4695 break;
4696 case ID_MSGSIZE:
4697 checkRobot();
4698 rc = parseNumber(getRestOfLine(), 10, &(curRobot->msgSize));
4699 break;
4700 case ID_AFTERUNPACK:
4701 rc = fc_copyString(getRestOfLine(), &(config->afterUnpack));
4702 break;
4703 case ID_BEFOREPACK:
4704 rc = fc_copyString(getRestOfLine(), &(config->beforePack));
4705 break;
4706 case ID_PROCESSPKT:
4707 rc = fc_copyString(getRestOfLine(), &(config->processPkt));
4708 break;
4709 case ID_SPLITSTR:
4710 checkRobot();
4711 rc = fc_copyString(getRestOfLine(), &(curRobot->splitStr));
4712 break;
4713 case ID_ROBOTORIGIN:
4714 checkRobot();
4715 temp = getRestOfLine();
4716 if( temp[0] == '"' && temp[strlen(temp)-1] =='"' ) {
4717 temp++; temp[strlen(temp)-1]='\0';
4718 }
4719 rc = fc_copyString(temp, &(curRobot->origin));
4720 break;
4721 case ID_ROBOTSAREA:
4722 rc = fc_copyString(getRestOfLine(), &(config->robotsArea));
4723 break;
4724 case ID_FILEDESCNAME:
4725 rc = parseUUEechoAreas(getRestOfLine(),&(config->fileDescNames),&(config->fDescNameCount));
4726 break;
4727 case ID_FILEDESCRIPTION:
4728 rc = fc_copyString(getRestOfLine(), &(config->fileDescription));
4729 break;
4730 case ID_FILEDESCPOS:
4731 rc = parseUInt(getRestOfLine(), &(config->fileDescPos));
4732 break;
4733 case ID_DLCDIGITS:
4734 rc = parseUInt(getRestOfLine(), &(config->DLCDigits));
4735 break;
4736 /* not used
4737 case ID_FILEMAXDUPEAGE:
4738 rc = parseUInt(getRestOfLine(), &(config->fileMaxDupeAge));
4739 break;
4740 case ID_FILEFILEUMASK:
4741 rc = parseOctal(getRestOfLine(), &(config->fileFileUMask));
4742 break;
4743 case ID_FILEDIRUMASK:
4744 rc = parseOctal(getRestOfLine(), &(config->fileDirUMask));
4745 break;
4746 case ID_FILELOCALPWD:
4747 rc = fc_copyString(getRestOfLine(), &(config->fileLocalPwd));
4748 break;
4749
4750 */
4751 case ID_ORIGININANNOUNCE:
4752 rc = parseBool(getRestOfLine(), &(config->originInAnnounce));
4753 break;
4754 case ID_MAXTICLINELENGTH:
4755 rc = parseUInt(getRestOfLine(), &(config->MaxTicLineLength));
4756 break;
4757 case ID_FILELDESCSTRING:
4758 rc = fc_copyString(getRestOfLine(), &(config->fileLDescString));
4759 break;
4760 case ID_SAVETIC:
4761 rc = parseSaveTicStatement(getRestOfLine(), config);
4762 break;
4763 case ID_AREASMAXDUPEAGE:
4764 rc = parseNumber(getRestOfLine(), 10, &(config->areasMaxDupeAge));
4765 break;
4766 case ID_DUPEBASETYPE:
4767 rc = parseTypeDupes(getRestOfLine(), &(config->typeDupeBase),
4768 &(config->areasMaxDupeAge));
4769 break;
4770 case ID_FIDOUSERLIST:
4771 rc = fc_copyString(getRestOfLine(), &(config->fidoUserList));
4772 break;
4773 case ID_NODELIST:
4774 rc = parseNodelist(getRestOfLine(), config);
4775 break;
4776 case ID_DIFFUPDATE:
4777 rc = 0;
4778 if (config->nodelistCount > 0) {
4779 rc = fc_copyString(getRestOfLine(),
4780 &(config->nodelists[config->nodelistCount-1].diffUpdateStem));
4781 }
4782 else {
4783 printNodelistError();
4784 rc = 1;
4785 }
4786 break;
4787 case ID_DELAPPLIEDDIFF:
4788 rc = parseBool(getRestOfLine(),
4789 (unsigned int*)&(config->nodelists[config->nodelistCount-1].delAppliedDiff));
4790 break;
4791 case ID_FULLUPDATE:
4792 rc = 0;
4793 if (config->nodelistCount > 0) {
4794 rc = fc_copyString(getRestOfLine(),
4795 &(config->nodelists[config->nodelistCount-1].fullUpdateStem));
4796 }
4797 else {
4798 printNodelistError();
4799 rc = 1;
4800 }
4801 break;
4802 case ID_DEFAULTZONE:
4803 rc = 0;
4804 if (config->nodelistCount > 0) {
4805 rc = parseUInt(getRestOfLine(),
4806 &(config->nodelists[config->nodelistCount-1].defaultZone));
4807 }
4808 else {
4809 printNodelistError();
4810 rc = 1;
4811 }
4812 break;
4813 case ID_NODELISTFORMAT:
4814 if (config->nodelistCount > 0) {
4815 rc = parseNodelistFormat(getRestOfLine(), config,
4816 &(config->nodelists[config->nodelistCount-1]));
4817 }
4818 else {
4819 printNodelistError();
4820 rc = 1;
4821 }
4822 break;
4823 case ID_LOGOWNER:
4824 rc = parseOwner(getRestOfLine(), &(config->loguid),
4825 &(config->loggid));
4826 break;
4827 case ID_LOGPERM:
4828 rc = parseNumber(getRestOfLine(), 8, &(config->logperm));
4829 break;
4830 case ID_LINKDEFAULTS:
4831 rc = parseLinkDefaults(getRestOfLine(), config);
4832 break;
4833 case ID_CREATEAREASCASE:
4834 rc = parseNamesCase(getRestOfLine(), &(config->createAreasCase));
4835 break;
4836 case ID_AREASFILENAMECASE:
4837 rc = parseNamesCase(getRestOfLine(), &(config->areasFileNameCase));
4838 break;
4839 case ID_CONVERTLONGNAMES:
4840 rc = parseNamesCaseConversion(getRestOfLine(),
4841 &(config->convertLongNames));
4842 break;
4843 case ID_CONVERTSHORTNAMES:
4844 rc = parseNamesCaseConversion(getRestOfLine(),
4845 &(config->convertShortNames));
4846 break;
4847 case ID_DISABLEKLUDGERESCANNED:
4848 rc = parseBool(getRestOfLine(), &(config->disableKludgeRescanned));
4849 break;
4850 case ID_DISABLETID:
4851 rc = parseBool(getRestOfLine(), &(config->disableTID));
4852 break;
4853 case ID_DISABLEPID:
4854 rc = parseBool(getRestOfLine(), &(config->disablePID));
4855 break;
4856 case ID_TOSSINGEXT:
4857 if ((temp=getRestOfLine()) != NULL)
4858 rc = fc_copyString(temp, &(config->tossingExt));
4859 else
4860 config->tossingExt = NULL;
4861 break;
4862 #if defined ( __NT__ )
4863 case ID_SETCONSOLETITLE:
4864 rc = parseBool(getRestOfLine(), &(config->setConsoleTitle));
4865 break;
4866 #endif
4867 case ID_ADDTOSEEN:
4868 rc = parseSeenBy2D(getRestOfLine(),&(config->addToSeen),
4869 &(config->addToSeenCount));
4870 break;
4871 case ID_IGNORESEEN:
4872 rc = parseSeenBy2D(getRestOfLine(),&(config->ignoreSeen),
4873 &(config->ignoreSeenCount));
4874 break;
4875 case ID_TEARLINE:
4876 rc = fc_copyString(getRestOfLine(), &(config->tearline));
4877 break;
4878 case ID_ORIGIN:
4879 temp = getRestOfLine();
4880 if (temp) {
4881 if( temp[0] == '"' && temp[strlen(temp)-1] =='"' ) {
4882 temp++; temp[strlen(temp)-1]='\0';
4883 }
4884 }
4885 rc = fc_copyString(temp, &(config->origin));
4886 break;
4887 case ID_BUNDLENAMESTYLE:
4888 rc = parseBundleNameStyle(getRestOfLine(),
4889 &(config->bundleNameStyle));
4890 break;
4891 case ID_KEEPTRSMAIL:
4892 rc = parseBool(getRestOfLine(), &(config->keepTrsMail));
4893 break;
4894 case ID_KEEPTRSFILES:
4895 rc = parseBool(getRestOfLine(), &(config->keepTrsFiles));
4896 break;
4897 case ID_FILELIST:
4898 rc = parseFilelist(getRestOfLine(), config);
4899 break;
4900 case ID_CREATEFWDNONPASS:
4901 rc = parseBool(getRestOfLine(), &(config->createFwdNonPass));
4902 break;
4903 case ID_AUTOPASSIVE:
4904 rc = parseBool(getRestOfLine(), &(config->autoPassive));
4905 break;
4906 case ID_NETMAILFLAG:
4907 rc = fc_copyString(getRestOfLine(), &(config->netmailFlag));
4908 break;
4909 case ID_AUTOCREATEFLAG:
4910 checkRobot();
4911 rc = fc_copyString(getRestOfLine(), &(curRobot->autoCreateFlag));
4912 break;
4913 case ID_MINDISKFREESPACE:
4914 rc = parseNumber(getRestOfLine(), 10, &(config->minDiskFreeSpace));
4915 break;
4916 case ID_AUTOAREACREATESUBDIRS:
4917 rc = parseBool(getRestOfLine(), &(getDescrLink(config)->autoAreaCreateSubdirs));
4918 break;
4919 case ID_AUTOFILECREATESUBDIRS:
4920 rc = parseBool(getRestOfLine(), &(getDescrLink(config)->autoFileCreateSubdirs));
4921 break;
4922 case ID_TICKERPACKTOBOX:
4923 rc = parseBool(getRestOfLine(), &(getDescrLink(config)->tickerPackToBox));
4924 break;
4925 case ID_ADVISORYLOCK:
4926 rc = parseUInt(getRestOfLine(), &(config->advisoryLock));
4927 break;
4928 case ID_NAMES:
4929 checkRobot();
4930 rc = parseStringList(getRestOfLine(), &(curRobot->names));
4931 break;
4932 case ID_REQIDXDIR:
4933 rc = parsePath(getRestOfLine(), &(config->reqidxDir), NULL);
4934 break;
4935 case ID_SYSLOG_FACILITY:
4936 rc = parseSyslog(getRestOfLine(), &(config->syslogFacility));
4937 break;
4938 case ID_FILEBOX:
4939 rc = parsePathNoCheck(getRestOfLine(),
4940 &(getDescrLink(config)->fileBox),
4941 &(linkDefined.fileBox));
4942 break;
4943 case ID_FILEBOXESDIR:
4944 rc = parsePath(getRestOfLine(), &(config->fileBoxesDir), NULL);
4945 break;
4946 case ID_FILEBOXALWAYS:
4947 rc = parseBool(getRestOfLine(), &(getDescrLink(config)->fileBoxAlways));
4948 break;
4949 case ID_CARBONEXCLUDEFWDFROM:
4950 rc = parseBool(getRestOfLine(), &(config->carbonExcludeFwdFrom));
4951 break;
4952 case ID_HPTPERLFILE:
4953 rc = parseFileName(getRestOfLine(), &(config->hptPerlFile), NULL);
4954 break;
4955 case ID_ADVSTATISTICSFILE:
4956 rc = fc_copyString(getRestOfLine(), &(config->advStatisticsFile));
4957 break;
4958 case ID_READONLY:
4959 rc = parsePermissions (getRestOfLine(), &(config->readOnly), &(config->readOnlyCount));
4960 break;
4961 case ID_WRITEONLY:
4962 rc = parsePermissions (getRestOfLine(), &(config->writeOnly), &(config->writeOnlyCount));
4963 break;
4964 case ID_ARCNETMAIL:
4965 if( (clink = getDescrLink(config)) != NULL ) {
4966 rc = parseBool (getRestOfLine(), &clink->arcNetmail);
4967 } else {
4968 rc = 1;
4969 }
4970 break;
4971 case ID_RULESDIR:
4972 checkRobot();
4973 rc = parsePath(getRestOfLine(), &(curRobot->rulesDir), NULL);
4974 break;
4975 case ID_NORULES:
4976 s = getRestOfLine();
4977 if (link_robot & 1)
4978 rc = parseBool(s, &(getDescrLink(config)->areafix.noRules));
4979 if (link_robot & 2)
4980 rc = parseBool(s, &(getDescrLink(config)->filefix.noRules));
4981 break;
4982 case ID_PACKNETMAILONSCAN:
4983 rc = parseBool(getRestOfLine(), &(config->packNetMailOnScan));
4984 break;
4985 case ID_UUEECHOGROUP:
4986 rc = parseUUEechoAreas(getRestOfLine(), &(config->uuEGrp), &(config->numuuEGrp));
4987 break;
4988 case ID_SENDMAILCMD:
4989 rc = parseSendMailCmd( getRestOfLine(), &(config->sendmailcmd) );
4990 break;
4991
4992 case ID_TEMPDIR:
4993 rc = parsePath(getRestOfLine(), &(config->tempDir), NULL);
4994 break;
4995
4996 /* htick announcer */
4997 case ID_ANNOUNCESPOOL:
4998 rc = parsePath(getRestOfLine(), &(config->announceSpool), NULL);
4999 break;
5000 case ID_ANNAREATAG:
5001 rc = parseAnnDef(getRestOfLine(), config);
5002 break;
5003 case ID_ANNINCLUDE:
5004 rc = parseGroup(getRestOfLine(), config, 6);
5005 break;
5006 case ID_ANNEXCLUDE:
5007 rc = parseGroup(getRestOfLine(), config, 7);
5008 break;
5009 case ID_ANNTO:
5010 rc = fc_copyString(getRestOfLine(), &(getDescrAnnDef(config)->annto));
5011 break;
5012 case ID_ANNFROM:
5013 rc = fc_copyString(getRestOfLine(), &(getDescrAnnDef(config)->annfrom));
5014 break;
5015 case ID_ANNSUBJ:
5016 rc = fc_copyString(getRestOfLine(), &(getDescrAnnDef(config)->annsubj));
5017 break;
5018 case ID_ANNORIGIN:
5019 rc = fc_copyString(getRestOfLine(), &(getDescrAnnDef(config)->annorigin));
5020 break;
5021 case ID_ANNMESSFLAGS:
5022 rc = fc_copyString(getRestOfLine(), &(getDescrAnnDef(config)->annmessflags));
5023 break;
5024 case ID_ANNFILEORIGIN:
5025 rc = parseBool(getRestOfLine(), &(getDescrAnnDef(config)->annforigin));
5026 break;
5027 case ID_ANNFILERFROM:
5028 rc = parseBool(getRestOfLine(), &(getDescrAnnDef(config)->annfrfrom));
5029 break;
5030 case ID_ANNADDRTO:
5031 rc = parseAnnDefAddres(getRestOfLine(), config, 1);
5032 break;
5033 case ID_ANNADDRFROM:
5034 rc = parseAnnDefAddres(getRestOfLine(), config, 2);
5035 break;
5036 case ID_FILEAREACREATEPERMS:
5037 rc = parseNumber(getRestOfLine(), 10, &(config->fileAreaCreatePerms));
5038 config->fileAreaCreatePerms = dec2oct(config->fileAreaCreatePerms);
5039 break;
5040 case ID_NEWAREAREFUSEFILE:
5041 checkRobot();
5042 rc = fc_copyString(getRestOfLine(), &(curRobot->newAreaRefuseFile));
5043 break;
5044 case ID_FROMNAME:
5045 checkRobot();
5046 rc = fc_copyString(getRestOfLine(), &(curRobot->fromName));
5047 break;
5048 case ID_SEQDIR:
5049 rc = parsePath(getRestOfLine(), &(config->seqDir), NULL);
5050 break;
5051 case ID_SEQOUTRUN:
5052 rc = parseSeqOutrun(getRestOfLine(), &(config->seqOutrun));
5053 break;
5054 case ID_AVAILLIST:
5055 if( (clink = getDescrLink(config)) != NULL ) {
5056 rc = parseAvailList(getRestOfLine(), &(clink->availlist));
5057 } else {
5058 rc = 1;
5059 }
5060 break;
5061 case ID_AREAGROUP:
5062 rc = parseAreaGroup(getRestOfLine());
5063 break;
5064 case ID_AREAGROUPDEFAULTS:
5065 rc = parseAreaGroupDefaults(config, getRestOfLine());
5066 break;
5067 case ID_GRPDESC:
5068 rc = parseGroupDesc(config, getRestOfLine());
5069 break;
5070 case ID_LISTECHO:
5071 rc = parseListEcho( getRestOfLine(), &(config->listEcho) );
5072 break;
5073 case ID_CREATEADDUPLINK:
5074 rc = parseBool(getRestOfLine(), &(config->createAddUplink));
5075 break;
5076 case ID_DENYRESCAN:
5077 rc = parseBool(getRestOfLine(), &(getDescrLink(config)->denyRescan));
5078 break;
5079 case ID_RESCANGRP:
5080 rc = parseGroup(getRestOfLine(), config, 8);
5081 break;
5082 case ID_RESCANLIMIT:
5083 rc = parseNumber(getRestOfLine(), 10, (unsigned int*)&(getDescrLink(config)->rescanLimit));
5084 break;
5085
5086 default:
5087 prErr( "unrecognized: %s", line);
5088 wasError = 1;
5089 nfree(iToken);
5090 nfree(actualLine);
5091 return 1;
5092 }
5093
5094 nfree(iToken);
5095 }
5096 if (rc != 0) {
5097 prErr( "error %d in: %s", rc, line);
5098 wasError = 1;
5099 }
5100
5101 nfree(actualLine);
5102 return rc;
5103 }
5104