1 /******************************************************************************
2  * FIDOCONFIG --- library for fidonet configs
3  ******************************************************************************
4  * Copyright (C) 1998-1999
5  *
6  * Matthias Tichy
7  *
8  * Fido:     2:2433/1245 2:2433/1247 2:2432/605.14
9  * Internet: mtt@tichy.de
10  *
11  * Grimmestr. 12         Buchholzer Weg 4
12  * 33098 Paderborn       40472 Duesseldorf
13  * Germany               Germany
14  *
15  * This file is part of FIDOCONFIG.
16  *
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Library General Public
19  * License as published by the Free Software Foundation; either
20  * version 2 of the License, or (at your option) any later version.
21  *
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Library General Public License for more details.
26  *
27  * You should have received a copy of the GNU Library General Public
28  * License along with this library; see file COPYING. If not, write to the Free
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
30  *****************************************************************************/
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 
37 #include <huskylib/huskylib.h>
38 
39 #ifdef HAS_SYS_SYSEXITS_H
40 #include <sys/sysexits.h>
41 #elif defined(HAS_SYSEXITS_H)
42 #include <sysexits.h>
43 #endif
44 
45 #ifdef HAS_STRINGS_H
46 #include <strings.h>
47 #endif /* HAS_STRINGS_H */
48 
49 /* export functions from DLL */
50 #define DLLEXPORT
51 #include <huskylib/huskyext.h>
52 
53 /* smapi */
54 #include <smapi/msgapi.h>
55 
56 /* fidoconfig */
57 #include "fidoconf.h"
58 #include "common.h"
59 #include "areatree.h"
60 #include "grptree.h"
61 
62 /* Global for fidoconfig, do not export from DLL, please! */
63 /*s_fidoconfig *config;*/
64 
65 /* End of line: CR+LF (wasCR==1) or LF only (wasCR==0) */
66 static int wasCR=0;
67 
68 sApp theApp = { 0, NULL };
69 
cfgEol()70 const char *cfgEol()
71 {
72     return wasCR ? "\r\n" : "\n";
73 }
74 
readLine(FILE * f)75 char *readLine(FILE *f)
76 {
77     char *line=NULL;
78     int len=0, i=0, stop=0;
79     int ch;
80 
81     if (get_hcfg()) wasCR = 0;
82     do {
83 	ch = getc (f);
84         /*  not fgets() 'cause it concatenates lines without \r on Watcom C / WinDos */
85 	if (ch < 0) { /*  EOF */
86 	    if (i==0) {
87 		return NULL;
88 	    } else { /*  EOF without EOL */
89 		if (i >= len) {
90 		    len += 128;
91 		    line = srealloc (line, len);
92 		}
93 		line[i] = '\0';
94 		stop++;
95 	    }
96 	} else {
97 	    if (i >= len) {
98 		len += 128;
99 		line = srealloc (line, len);
100 	    }
101 
102 	    if (ch=='\n') { /*  EOL */
103 		line[i] = '\0';
104 		stop++;
105 	    } else if (ch=='\r') { /*  CR (must be before LF), ignore */
106 		if (get_hcfg()) wasCR = 1;
107 	    } else { /*  other characters */
108 		line[i] = ch;
109 		i++;
110 	    }
111 	}
112     } while (!stop);
113 
114     line = srealloc (line, strlen(line)+1);
115 
116     return line;
117 }
118 
trimLine(char * line)119 char *trimLine(char *line)
120 {
121    char *start = line;
122 
123    while ((*start == ' ') || (*start == '\t') /*|| (*start == '\xFE')*/ ) start++; /* whats is 0xFE? */
124    striptwhite(start);
125    if(start != line)
126       memmove(line, start, strlen(start)+1);
127    return line;
128 }
129 
130 /* Strips trailing spaces from a string. */
131 
striptwhite(char * str)132 char *striptwhite(char *str)
133 {
134     char *p;
135 
136     if (str == NULL)
137     {
138         return str;
139     }
140     if (*str == 0)
141     {
142         return str;   /*  strend is undefined for zero-length string! */
143     }
144     p = strend(str);
145     while (p >= str && *p && isspace((unsigned char)*p))
146     {
147         *p = '\0';
148         p--;
149     }
150     return str;
151 }
152 
stripComment(char * line)153 char *stripComment(char *line)
154 {
155   char *aux;
156 
157   if (line == NULL || *line == 0) return line;
158 
159   if (line[0]==CommentChar) {
160     line[0]='\0';
161     return line;
162   }
163 
164   aux = line;
165   while ((aux=strchr(aux+1,CommentChar)) != NULL) {
166     if ((*(aux-1)==' ' || *(aux-1)=='\t' ) && (isspace(aux[1]) || aux[1]=='\0'))
167     {
168       *(aux-1)='\0';
169       break;
170     }
171   }
172 
173   striptwhite(line);
174 
175   return line;
176 }
177 
initConfig(s_fidoconfig * config)178 void initConfig(s_fidoconfig *config)
179 {
180    /* set all to 0 */
181    memset(config, 0, sizeof(s_fidoconfig));
182 
183    /* set defaults */
184    config -> loguid = config -> loggid = config -> logperm = (UINT)-1;
185    config -> tossingExt = strdup("tos");
186    config -> convertLongNames = config -> convertShortNames = cDontTouch;
187    config -> typeDupeBase = hashDupesWmsgid;
188    config -> packNetMailOnScan = 1;
189    config -> recodeMsgBase = 1;
190    config -> reportRequester = 1;
191    config -> minDiskFreeSpace = 10;
192 
193    config->dupeArea.areaType = ECHOAREA;
194    config->badArea.areaType = ECHOAREA;
195    config->EchoAreaDefault.areaType = ECHOAREA;
196    config->FileAreaDefault.areaType = FILEAREA;
197 
198    initGroupTree();
199 }
200 
getConfigFileNameForProgram(char * envVar,char * configName)201 char *getConfigFileNameForProgram(char *envVar, char *configName)
202 {
203    char *envFidoConfig = getenv(envVar);
204    char *osSpecificName;
205    int i;
206 
207    FILE *f = NULL;
208    char *ret;
209 
210 #ifdef CFGDIR
211    char *osSpecificPrefix = CFGDIR;
212 #elif defined(__linux__)
213    char *osSpecificPrefix = "/etc/fido/";
214 #elif defined(__FreeBSD__)
215    char *osSpecificPrefix = "/usr/local/etc/fido/";
216 #elif defined(__QNXNTO__)
217    char *osSpecificPrefix = "/etc/fido/";
218 #elif defined(__UNIX__)
219    char *osSpecificPrefix = "./";
220 #else
221    char *osSpecificPrefix = "";
222 #endif
223 
224    /* try env-var fidoconfig */
225    if (envFidoConfig != NULL) f = fopen(envFidoConfig, "r");
226 
227    if (f == NULL) {
228       if (configName == NULL) return NULL;
229 
230       /* try osSpecificName */
231       osSpecificName = (char *) smalloc(strlen(osSpecificPrefix)+strlen(configName)+2); /*  +1 - for training delimiter */
232       strcpy(osSpecificName, osSpecificPrefix);
233 
234       i = strlen(osSpecificName);
235       if (i && osSpecificName[i - 1] != '/' && osSpecificName[i - 1] != '\\') {
236          osSpecificName[i] = PATH_DELIM;
237          osSpecificName[i+1] = '\0';
238       }
239 
240       strcat(osSpecificName, configName);
241 
242       f = fopen(osSpecificName, "r");
243       if (f==NULL) {
244          if (NULL != (envFidoConfig = getenv("FIDOCONFIG"))) {
245             if (strrchr(envFidoConfig, PATH_DELIM) != NULL) {
246                nfree (osSpecificName);
247                i = strlen(envFidoConfig) - strlen(strrchr(envFidoConfig,PATH_DELIM)) + strlen(configName)+1;
248                osSpecificName = smalloc (i+1);
249                strncpy (osSpecificName,envFidoConfig,i);
250                strcpy (strrchr(osSpecificName,PATH_DELIM)+1,configName);
251                f = fopen (osSpecificName, "r");
252                if (f==NULL) return NULL; else ret = osSpecificName;
253             } else return NULL;
254          } else return NULL;
255       } else ret =  osSpecificName;
256    } else ret = envFidoConfig;
257 
258    fclose(f);
259 
260    return ret;
261 }
262 
getConfigFileName(void)263 char *getConfigFileName(void) {
264 #ifndef CFGNAME
265 #define CFGNAME "config"
266 #endif
267    return getConfigFileNameForProgram("FIDOCONFIG", CFGNAME);
268 }
269 
carbonNames2Addr(s_fidoconfig * config)270 int carbonNames2Addr(s_fidoconfig *config)
271 {
272    unsigned int i, found, narea;
273    s_carbon *cb;
274    ps_area aptr;
275    char *cbaName=NULL;
276    int rc=0;
277 
278    if(!config->carbonCount) return 0;
279 
280    cb = &(config->carbons[0]);
281 
282    for (i=0; i<config->carbonCount; i++, cb++) {
283        /* Can't use getArea() - it doesn't say about export and
284 	  doesn't look at localAreas */
285        /* now getArea can found local areas */
286        if(cb->rule&CC_AND) /* area is not used with AND */
287 	   continue;
288        found=0;
289        if(cb->areaName!=NULL){
290 	   cbaName=cb->areaName;
291 	   if (cbaName[0]=='*') cbaName++;
292 
293 	   if (!(cb -> extspawn)) {
294 	       aptr=config->echoAreas;
295 	       for (narea=0; narea<config->echoAreaCount && !found; narea++,aptr++) {
296 		   if (stricmp(cbaName, aptr->areaName)==0) {
297 		       found++;
298 		       cb->area = aptr;
299 		       cb->aexport = 1;
300 		       cb->netMail = 0;
301 		   }
302 	       }
303 	       aptr=config->localAreas;
304 	       for (narea=0; narea<config->localAreaCount && !found; narea++,aptr++) {
305 		   if (stricmp(cbaName, aptr->areaName)==0) {
306 		       found++;
307 		       cb->area = aptr;
308 		       cb->aexport = 0;
309 		       cb->netMail = 0;
310 		   }
311 	       }
312 	       aptr=config->netMailAreas;
313 	       for (narea=0; narea<config->netMailAreaCount && !found; narea++,aptr++){
314 		   if (stricmp(cbaName, aptr->areaName)==0) {
315 		       found++;
316 		       cb->area = aptr;
317 		       cb->aexport = 0;
318 		       cb->netMail = 1;
319 		   }
320 	       }
321 	   }
322        }
323 
324        if (!found && (cb->move != 2) && !cb->extspawn) { /*  move==2 - delete */
325          if (config->badArea.areaName) {
326 	   printf("Could not find area \"%s\" for carbon copy. Use BadArea\n",
327 		  (cb->areaName) ? cb->areaName : "");
328 	   cb->area = &(config->badArea);
329 	   if (cb->areaName!=NULL) {
330 	       i = (*cb->areaName=='*') ? 1 : 0;
331 	       nfree(cb->areaName);
332 	   }
333 	   else i = 0;
334 	   cb->areaName = (char *) smalloc(sstrlen(config->badArea.areaName)+i+1);
335 	   if (i) *cb->areaName='*';
336 	   strcpy(cb->areaName+i,config->badArea.areaName);
337 	   cb->aexport = 0;
338 	 } else {
339 	   printf("Could not find area \"%s\" for carbon copy and BadArea not defined. Can't use this area for carbon copy\n", cb->areaName);
340            cb->area = NULL;
341            rc++;
342 	 }
343        }
344    }
345    return rc;
346 }
347 
processAreaPermissions(s_fidoconfig * config,ps_area areas,unsigned areaCount)348 void processAreaPermissions(s_fidoconfig *config, ps_area areas, unsigned areaCount)
349 {
350     unsigned i,narea, nalink;
351     ps_area aptr;
352     ps_arealink *dlink;
353     char *ExclMask;
354 
355 
356     if (config->readOnlyCount) {
357         for (i=0; i < config->readOnlyCount; i++) {
358             if(config->readOnly[i].areaMask[0] != '!') {
359                 for (aptr=areas, narea=0; narea < areaCount; narea++, aptr++) {
360                     if (patimat (aptr->areaName, config->readOnly[i].areaMask)) {
361                         for (nalink=0, dlink=aptr->downlinks; nalink < aptr->downlinkCount; nalink++, dlink++) {
362                             if (patmat (aka2str((*dlink)->link->hisAka),
363                                 config->readOnly[i].addrMask)) {
364                                 (*dlink)->import = 0;
365                             }
366                         }
367                     }
368                 }
369             } else {
370                 ExclMask = config->readOnly[i].areaMask;
371                 ExclMask++;
372                 for (aptr=areas, narea=0; narea < areaCount; narea++, aptr++) {
373                     if (patimat (aptr->areaName, ExclMask)) {
374                         for (nalink=0, dlink=aptr->downlinks; nalink < aptr->downlinkCount; nalink++, dlink++) {
375                             if (patmat (aka2str((*dlink)->link->hisAka),
376                                 config->readOnly[i].addrMask)) {
377                                 (*dlink)->import = 1;
378                             }
379                         }
380                     }
381                 }
382             }
383         }
384     }
385 
386     if (config->writeOnlyCount) {
387         for (i=0; i < config->writeOnlyCount; i++) {
388             if(config->writeOnly[i].areaMask[0] != '!') {
389                 for (aptr=areas, narea=0; narea < areaCount; narea++, aptr++) {
390                     if (patimat (aptr->areaName, config->writeOnly[i].areaMask)) {
391                         for (nalink=0, dlink=aptr->downlinks; nalink < aptr->downlinkCount; nalink++, dlink++) {
392                             if (patmat (aka2str((*dlink)->link->hisAka),
393                                 config->writeOnly[i].addrMask)) {
394                                 (*dlink)->aexport = 0;
395                             }
396                         }
397                     }
398                 }
399             } else {
400                 ExclMask = config->writeOnly[i].areaMask;
401                 ExclMask++;
402                 for (aptr=areas, narea=0; narea < areaCount; narea++, aptr++) {
403                     if (patimat (aptr->areaName, ExclMask)) {
404                         for (nalink=0, dlink=aptr->downlinks; nalink < aptr->downlinkCount; nalink++, dlink++) {
405                             if (patmat (aka2str((*dlink)->link->hisAka),
406                                 config->writeOnly[i].addrMask)) {
407                                 (*dlink)->aexport = 1;
408                             }
409                         }
410                     }
411                 }
412             }
413         }
414     }
415 }
416 
417 /* set link-area permissions stored in readOnly[], writeOnly[] */
processPermissions(s_fidoconfig * config)418 void processPermissions(s_fidoconfig *config)
419 {
420     if      (theApp.module == M_HPT || theApp.module == M_TPARSER)
421         processAreaPermissions(config, config->echoAreas, config->echoAreaCount);
422     if (theApp.module == M_HTICK || theApp.module == M_TPARSER)
423         processAreaPermissions(config, config->fileAreas, config->fileAreaCount);
424 }
425 
fixRoute(s_fidoconfig * config)426 void fixRoute(s_fidoconfig *config)
427 {
428     unsigned int i;
429 
430     for (i = 0; i < config->routeCount; i++) {
431         if (config->route[i].viaStr != NULL)
432             config->route[i].target = getLink(config, config->route[i].viaStr);
433         nfree(config->route[i].viaStr);
434     }
435 }
436 
stripPktPwd(s_fidoconfig * config)437 void stripPktPwd(s_fidoconfig *config)
438 {
439    unsigned int i;
440    for (i = 0; i < config->linkCount; i++) {
441       if (config->links[i]->pktPwd && strlen(config->links[i]->pktPwd) > 8) {
442          if (config->links[i]->pktPwd == config->links[i]->defaultPwd) {
443             config->links[i]->pktPwd = (char *) smalloc(9);
444             memcpy(config->links[i]->pktPwd, config->links[i]->defaultPwd, 8);
445          }
446          config->links[i]->pktPwd[8] = '\0';
447 /*         printf("WARNING: pktPwd too long! Truncated to 8 chars (%s)\n",aka2str(config->links[i]->hisAka));
448          fprintf(stderr,"pktPwd too long! Truncated to 8 chars (%s)\n",aka2str(config->links[i]->hisAka));
449 */
450       }
451    }
452 }
453 
setConfigDefaults(s_fidoconfig * config)454 void setConfigDefaults(s_fidoconfig *config)
455 {
456    ps_robot r;
457 
458    r = getRobot(config, "areafix", 1);
459    r->areas = &(config->echoAreas);
460    r->areaCount = &(config->echoAreaCount);
461    r->strA = sstrdup("area");
462    r->strC = sstrdup("echoarea");
463    if (!r->names)
464    {
465 	   char *s =sstrdup("AreaFix AreaMgr hpt");
466 	   r->names = makeStrArray(s);
467 	   nfree(s);
468    }
469 
470    r = getRobot(config, "filefix", 1);
471    r->areas = &(config->fileAreas);
472    r->areaCount = &(config->fileAreaCount);
473    r->strA = sstrdup("filearea");
474    r->strC = sstrdup("filearea");
475    if (!r->names)
476    {
477 	   char *s =sstrdup("FileFix FileMgr AllFix FileScan htick");
478 	   r->names = makeStrArray(s);
479 	   nfree(s);
480    }
481 
482    if (config->sysop==NULL) xstrcat(&config->sysop,"SysOp");
483    if (config->advisoryLock==0)  config->advisoryLock  = 0;
484    if ( RebuildEchoAreaTree(config) == 0 || RebuildFileAreaTree(config) == 0 ) {
485       printf("Please correct above error(s) first!\n");
486       fflush(stdout);
487       exit(EX_CONFIG);
488    }
489 
490    /* defaults for htick */
491    if(config->fileDescription==NULL) xstrcat(&config->fileDescription,"files.bbs");
492 
493    if (!config->tempDir) {
494       char *p=NULL;
495       if ((p=getenv("TEMP")) != NULL ||
496           (p=getenv("TMP")) != NULL ||
497           (p=getenv("TMPDIR")) != NULL)
498          parsePath(p, &(config->tempDir), NULL);
499       else
500 #if defined(__UNIX__) && !defined (__MINGW32__)
501          parsePath("/tmp", &(config->tempDir), NULL);
502 #elif defined(WINNT) || defined (__MINGW32__)
503          if ((getenv("WINDIR")) != NULL ){
504             xstrscat( &p, getenv("WINDIR"), "\\TEMP", NULLP);
505             parsePath(p, &(config->tempDir), NULL);
506             nfree(p);
507          }
508 #else
509          parsePath("c:\\", &(config->tempDir), NULL);
510 #endif
511    }
512    { /* add all our aka to links array */
513        unsigned i;
514        s_link   *clink;
515 
516        for (i = 0; i < config->addrCount; i++) {
517            if (!getLinkFromAddr(config,config->addr[i])) {
518                config->links = srealloc(config->links, sizeof(ps_link)*(config->linkCount+1));
519                config->links[config->linkCount] = scalloc(1,sizeof(s_link));
520                clink = config->links[config->linkCount];
521                memset(clink, 0, sizeof(s_link));
522                clink->areafix.on = 1;
523                clink->filefix.on = 1;
524                clink->filefix.autoCreate = 1; /* needed for hpucode + htick */
525                clink->aexport = 0;         /* do not export anything to virtual link */
526                clink->import = 1;
527                clink->maxUnpackedNetmail = 100;
528                clink->FileFixFSC87Subset = 1;
529                memcpy ( &(clink->hisAka), &(config->addr[i]), sizeof(hs_addr));
530                clink->ourAka = &(config->addr[i]);
531                xscatprintf(&(clink->name), "Our virtual link for aka: %s",aka2str(config->addr[i]));
532                xscatprintf(&(clink->defaultPwd),"%X",strcrc32(clink->name, 0xFFFFFFFFL));
533                clink->pktPwd = clink->defaultPwd;
534                clink->ticPwd = clink->defaultPwd;
535                clink->areafix.pwd = clink->defaultPwd;
536                clink->filefix.pwd = clink->defaultPwd;
537                clink->bbsPwd = clink->defaultPwd;
538                clink->sessionPwd = clink->defaultPwd;
539                config->linkCount++;
540            }
541        }
542    }
543 }
544 
545 /* Read fidoconfig from file into memory.
546  * Parameter: filename or NULL
547  * if NULL: try to find FIDOCONFIG enviroment variable, next use hardcoded path
548  * Return NULL and print diagnostic message to stdout if error(s) found.
549  */
readConfig(const char * fileName)550 s_fidoconfig *readConfig(const char *fileName)
551 {
552    s_fidoconfig *config;  /* Use global variable ?*/
553    char *line, *tmp;
554 
555    if (fileName==NULL) fileName = getConfigFileName();
556 
557    if (fileName == NULL) {
558         printf("Could not find Config-file\n");
559         exit(EX_UNAVAILABLE);
560    }
561 
562    tmp = GetDirnameFromPathname(fileName);
563    setvar("configdir", tmp);
564    nfree(tmp);
565 
566    if (init_conf(fileName))
567       return NULL;
568 
569    config = (s_fidoconfig *) smalloc(sizeof(s_fidoconfig));
570 
571    /* initialization and setting default values */
572    initConfig(config);
573 
574    while ((line = configline()) != NULL) {
575       line = trimLine(line);
576       if (line[0] != 0) {
577          line = shell_expand(line);
578          parseLine(line, config);
579       }
580       nfree(line);
581    }
582 
583    if (wasError == 1) {
584       printf("Please correct above error(s) first!\n");
585       fflush(stdout);
586       exit(EX_CONFIG);
587    }
588    checkIncludeLogic(config);
589    close_conf();
590    if(carbonNames2Addr(config)) { /* Can't use carbon copy/move/delete */
591       printf("Please correct above error(s) first!\n");
592       fflush(stdout);
593       exit(EX_CONFIG);
594    }
595    setConfigDefaults(config);
596    processPermissions (config);
597    fixRoute(config);
598    stripPktPwd(config);
599    theApp.config = config;
600    return config;
601 }
602 
fc_freeEchoArea(s_area * area)603 void fc_freeEchoArea(s_area *area) {
604     unsigned int i;
605 	nfree(area->areaName);
606 	nfree(area->fileName);
607 	nfree(area->description);
608 	nfree(area->group);
609 	for (i=0; i < area->downlinkCount; i++) nfree(area->downlinks[i]);
610 	nfree(area->downlinks);
611 	nfree(area->sbadd);
612 	nfree(area->sbign);
613 	nfree(area->sbstrip);
614 	nfree(area->sbkeep);
615 }
616 
freeBbsArea(s_bbsarea area)617 void freeBbsArea(s_bbsarea area) {
618         nfree(area.areaName);
619         nfree(area.pathName);
620         nfree(area.description);
621 }
622 
freeSaveTic(s_savetic * savetic)623 void freeSaveTic(s_savetic *savetic) {
624         nfree(savetic->fileAreaNameMask);
625         nfree(savetic->pathName);
626 }
627 
628 /* Dispose of fidoconfig structure: free memory.
629  */
disposeConfig(s_fidoconfig * config)630 void disposeConfig(s_fidoconfig *config)
631 {
632   unsigned int i;
633 
634    nfree(config->name);
635    nfree(config->sysop);
636    nfree(config->location);
637    nfree(config->email);
638 
639    nfree(config->addr);
640 
641    for (i=0; i < config->publicCount; i++) nfree(config->publicDir[i]);
642    nfree(config->publicDir);
643 
644    for (i = 0; i< config->linkCount; i++) freeLink(config->links[i]);
645    nfree(config->links);
646 
647    freeLink(config->linkDefaults);
648 
649    nfree(config->inbound);
650    nfree(config->outbound);
651    nfree(config->ticOutbound);
652    nfree(config->protInbound);
653    nfree(config->listInbound);
654    nfree(config->localInbound);
655    nfree(config->tempInbound);
656    nfree(config->logFileDir);
657    nfree(config->tempDir);
658    nfree(config->seqDir);
659    nfree(config->dupeHistoryDir);
660    nfree(config->nodelistDir);
661    nfree(config->msgBaseDir);
662    nfree(config->magic);
663    nfree(config->semaDir);
664    nfree(config->badFilesDir);
665    nfree(config->tempOutbound);
666    nfree(config->fileAreaBaseDir);
667    nfree(config->passFileAreaDir);
668    nfree(config->busyFileDir);
669    nfree(config->hptPerlFile);
670    nfree(config->sendmailcmd);
671    nfree(config->PublicGroup);
672 
673 
674    for (i = 0; i< config->netMailAreaCount; i++)
675        fc_freeEchoArea(&(config->netMailAreas[i]));
676    nfree(config->netMailAreas);
677 
678    fc_freeEchoArea(&(config->dupeArea));
679    fc_freeEchoArea(&(config->badArea));
680 
681    for (i = 0; i< config->echoAreaCount; i++)
682        fc_freeEchoArea(&(config->echoAreas[i]));
683    nfree(config->echoAreas);
684 
685    for (i = 0; i< config->fileAreaCount; i++)
686        fc_freeEchoArea(&(config->fileAreas[i]));
687    nfree(config->fileAreas);
688 
689    for (i = 0; i< config->bbsAreaCount; i++)
690        freeBbsArea(config->bbsAreas[i]);
691    nfree(config->bbsAreas);
692    for (i = 0; i< config->localAreaCount; i++)
693        fc_freeEchoArea(&(config->localAreas[i]));
694    nfree(config->localAreas);
695 
696    FreeAreaTree();
697    freeGrpTree();
698 
699    fc_freeEchoArea(&(config->EchoAreaDefault));
700    fc_freeEchoArea(&(config->FileAreaDefault));
701 
702    nfree(config->robotsArea);
703 
704    for (i = 0; i < config->robotCount; i++) {
705      nfree(config->robot[i]->name);
706      nfree(config->robot[i]->strA);
707      nfree(config->robot[i]->strC);
708      nfree(config->robot[i]->names);
709      nfree(config->robot[i]->fromName);
710      nfree(config->robot[i]->origin);
711      nfree(config->robot[i]->helpFile);
712      nfree(config->robot[i]->rulesDir);
713      nfree(config->robot[i]->newAreaRefuseFile);
714      nfree(config->robot[i]->autoCreateFlag);
715      nfree(config->robot[i]->queueFile);
716      nfree(config->robot[i]->reportsFlags);
717      nfree(config->robot[i]->splitStr);
718 	 nfree(config->robot[i]);
719    }
720    nfree(config->robot);
721 
722    for (i = 0; i < config->routeCount; i++) nfree(config->route[i].pattern);
723    nfree(config->route);
724    for (i = 0; i < config->remapCount; i++)
725        if (config->remaps[i].toname!=NULL)
726           nfree(config->remaps[i].toname);
727    nfree(config->remaps);
728 
729    for (i = 0; i < config->groupCount; i++) {
730        nfree(config->group[i].name);
731        nfree(config->group[i].desc);
732    }
733    nfree(config->group);
734 
735    for (i = 0; i < config->nodelistCount; i++)
736      {
737        if (config->nodelists[i].nodelistName != NULL)
738          nfree(config->nodelists[i].nodelistName);
739        if (config->nodelists[i].diffUpdateStem != NULL)
740          nfree(config->nodelists[i].diffUpdateStem);
741        if (config->nodelists[i].fullUpdateStem != NULL)
742          nfree(config->nodelists[i].fullUpdateStem);
743      }
744    nfree(config->nodelists);
745    nfree(config->fidoUserList);
746 
747    for (i = 0; i < config->packCount; i++) {
748            nfree(config->pack[i].packer);
749            nfree(config->pack[i].call);
750    }
751    nfree(config->pack);
752 
753    for (i = 0; i < config->unpackCount; i++) {
754            nfree(config->unpack[i].matchCode);
755            nfree(config->unpack[i].mask);
756            nfree(config->unpack[i].call);
757    }
758    nfree(config->unpack);
759    nfree(config->intab);
760    nfree(config->outtab);
761    nfree(config->importlog);
762    nfree(config->fileAreasLog);
763    nfree(config->fileNewAreasLog);
764    nfree(config->longNameList);
765    nfree(config->fileArcList);
766    nfree(config->filePassList);
767    nfree(config->fileDupeList);
768    nfree(config->advStatisticsFile);
769    nfree(config->loglevels);
770    nfree(config->screenloglevels);
771    nfree(config->echotosslog);
772    nfree(config->statlog);
773    nfree(config->lockfile);
774    nfree(config->fileDescription);
775    nfree(config->tossingExt);
776 
777    for (i = 0; i< config->carbonCount; i++) {
778 	   nfree(config->carbons[i].str);
779 	   nfree(config->carbons[i].areaName);
780 	   nfree(config->carbons[i].reason);
781    }
782    nfree(config->carbons);
783 
784    for (i=0; i < config->readOnlyCount; i++) {
785        nfree (config->readOnly[i].areaMask);
786        nfree (config->readOnly[i].addrMask);
787    }
788    nfree (config->readOnly);
789 
790    for (i=0; i < config->writeOnlyCount; i++) {
791        nfree (config->writeOnly[i].areaMask);
792        nfree (config->writeOnly[i].addrMask);
793    }
794    nfree (config->writeOnly);
795 
796 
797    nfree(config->ReportTo);
798 
799    nfree(config->beforePack);
800    nfree(config->afterUnpack);
801    nfree(config->processPkt);
802    nfree(config->fileLocalPwd);
803    nfree(config->fileLDescString);
804 
805    for (i = 0; i< config->saveTicCount; i++)
806        freeSaveTic(&(config->saveTic[i]));
807    nfree(config->saveTic);
808 
809    for (i = 0; i < config->execonfileCount; i++) {
810 		nfree(config->execonfile[i].filearea);
811 		nfree(config->execonfile[i].filename);
812 		nfree(config->execonfile[i].command);
813    }
814    nfree(config->addToSeen);
815    nfree(config->ignoreSeen);
816    nfree(config->tearline);
817    nfree(config->origin);
818 
819    for (i = 0; i < config->filelistCount; i++)
820    {
821      nfree(config->filelists[i].destFile);
822      nfree(config->filelists[i].dirHdrTpl);
823      nfree(config->filelists[i].dirEntryTpl);
824      nfree(config->filelists[i].dirFtrTpl);
825      nfree(config->filelists[i].globHdrTpl);
826      nfree(config->filelists[i].globFtrTpl);
827      nfree(config->filelists[i].dirListHdrTpl);
828      nfree(config->filelists[i].dirListEntryTpl);
829      nfree(config->filelists[i].dirListFtrTpl);
830    }
831 
832    for (i = 0; i < config->numuuEGrp; i++)
833    {
834      nfree(config->uuEGrp[i]);
835    }
836 
837    nfree(config->netmailFlag);
838    nfree(config->notValidFNChars);
839 
840    free_vars();
841 
842    nfree(config);
843    config = NULL;
844 }
845 
getLink(s_fidoconfig * config,char * addr)846 s_link *getLink(s_fidoconfig *config, char *addr)
847 {
848    hs_addr aka;
849 
850    memset(&aka, 0, sizeof(hs_addr));
851 
852    parseFtnAddrZS(addr, &aka);
853 
854    return getLinkFromAddr(config, aka);
855 }
856 
getLinkFromAddr(s_fidoconfig * config,hs_addr aka)857 s_link *getLinkFromAddr(s_fidoconfig *config, hs_addr aka)
858 {
859    unsigned i;
860 
861    for (i = 0; i <config->linkCount; i++) {
862       if (addrComp(aka, config->links[i]->hisAka)==0) return config->links[i];
863    }
864 
865    return NULL;
866 }
867 
getLinkForArea(const s_fidoconfig * config,char * addr,s_area * area)868 s_link *getLinkForArea(const s_fidoconfig *config, char *addr, s_area *area)
869 {
870 	hs_addr aka;
871 	unsigned i;
872 
873 	memset(&aka, 0, sizeof(hs_addr));
874 
875 	parseFtnAddrZS(addr, &aka);
876 
877 	/*  we must find "right" link */
878         for (i = 0; i< config->linkCount; i++) {
879                 if (!config->links[i]->ourAka) continue;
880 		if (addrComp(aka, config->links[i]->hisAka)==0 &&
881 			addrComp(*area->useAka, *(config->links[i]->ourAka))==0)
882 			return config->links[i];
883 	}
884 
885 	/*  backward compatibility */
886 	for (i = 0; i< config->linkCount; i++) {
887 	    if (addrComp(aka, config->links[i]->hisAka)==0) return config->links[i];
888 	}
889 
890 	return NULL;
891 }
892 
getAddr(const s_fidoconfig * config,char * addr)893 hs_addr *getAddr(const s_fidoconfig *config, char *addr)
894 {
895    hs_addr aka;
896    unsigned i;
897 
898    memset(&aka, 0, sizeof(hs_addr));
899    parseFtnAddrZS(addr, &aka);
900 
901    for (i = 0; i < config->addrCount; i++) {
902       if (addrComp(aka, config->addr[i])==0) return &(config->addr[i]);
903    }
904 
905    return NULL;
906 }
907 
existAddr(s_fidoconfig * config,hs_addr aka)908 int existAddr(s_fidoconfig *config, hs_addr aka) {
909    unsigned i;
910 
911    for (i=0; i< config->addrCount; i++) {
912       if (addrComp(aka, config->addr[i])==0) return 1;
913    }
914    return 0;
915 }
916 
getEchoArea(s_fidoconfig * config,char * areaName)917 s_area *getEchoArea(s_fidoconfig *config, char *areaName)
918 {
919     return getArea(config, areaName);
920 }
921 
getArea(s_fidoconfig * config,char * areaName)922 s_area *getArea(s_fidoconfig *config, char *areaName)
923 {
924     if(areaName) {
925       ps_area ret = FindAreaInTree(areaName);
926       if(ret)
927           return ret;
928     }
929     return &(config->badArea); /*  if all else fails, return badArea :-) */
930 }
931 
getNetMailArea(s_fidoconfig * config,char * areaName)932 s_area *getNetMailArea(s_fidoconfig *config, char *areaName)
933 {
934    unsigned i;
935 
936    if (areaName==NULL) return (NULL);
937 
938    for (i=0; i < config->netMailAreaCount; i++) {
939       if (stricmp(config->netMailAreas[i].areaName, areaName)==0)
940          return &(config->netMailAreas[i]);
941    }
942    return (NULL);
943 }
944 
getRobotsArea(s_fidoconfig * config)945 s_area *getRobotsArea(s_fidoconfig *config)
946 {
947     s_area *area = NULL;
948 
949     if (config->robotsArea)
950         area = getNetMailArea(config, config->robotsArea);
951     if (area == NULL)
952         area = &(config->netMailAreas[0]);
953     return area;
954 }
955 
getFileArea(char * areaName)956 s_area *getFileArea(char *areaName)
957 {
958    return FindFileAreaInTree(areaName);
959 }
960 
isLinkOfArea(s_link * link,s_area * area)961 int isLinkOfArea(s_link *link, s_area *area)
962 {
963    unsigned int i;
964 
965    for (i = 0; i < area->downlinkCount; i++)
966    {
967       if (link == area->downlinks[i]->link) return 1;
968    }
969    return 0;
970 }
971 
972 
isOurAka(ps_fidoconfig config,hs_addr link)973 int isOurAka(ps_fidoconfig config, hs_addr link)
974 {
975     unsigned int i;
976     for (i = 0; i < config->addrCount; i++) {
977         if (addrComp(link, config->addr[i])==0) return 1;
978     }
979     return 0;
980 }
981 
isAreaLink(hs_addr link,s_area * area)982 int isAreaLink(hs_addr link, s_area *area)
983 {
984     unsigned int i;
985     for (i = 0; i < area->downlinkCount; i++) {
986         if (addrComp(link, area->downlinks[i]->link->hisAka)==0) {
987             return i; /*  return index of link */
988         }
989     }
990     return -1;
991 }
992 
993 
grpInArray(char * group,char ** strarray,unsigned int len)994 int grpInArray(char *group, char **strarray, unsigned int len)
995 {
996 	unsigned int i;
997 
998 	if (group==NULL) return 0;
999 
1000 	for (i=0; i < len; i++) {
1001 		if (strarray[i] && strcmp(group, strarray[i])==0) return 1;
1002 	}
1003 
1004 	return 0;
1005 }
1006 
SetAppModule(e_known_moduls mod)1007 void SetAppModule(e_known_moduls mod) { theApp.module = mod; }
1008