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  * or download licence from http://www.gnu.org.
31  *****************************************************************************
32  *   $Id$
33  */
34 
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <errno.h>
39 #include <sys/types.h>
40 #include <fcntl.h>
41 #include <ctype.h>
42 
43 #include <huskylib/huskylib.h>
44 
45 #ifdef HAS_STRINGS_H
46 # include <strings.h>
47 #endif /* HAS_STRINGS_H */
48 
49 #define DLLIMPORT
50 #include <huskylib/huskyext.h>
51 #include <huskylib/strext.h>
52 #include <smapi/msgapi.h>
53 
54 
55 #ifdef HAS_UNISTD_H
56 # include <unistd.h>
57 #endif
58 
59 #ifdef HAS_IO_H
60 # include <io.h>
61 #endif
62 
63 #include "version.h"
64 #include "../cvsdate.h"
65 #include "fidoconf.h"
66 #include "common.h"
67 #include "grptree.h"
68 
69 #ifndef VERSION_H
70 # define VERSION_H
71 
72 #endif
73 
74 static s_fidoconfig *config;
75 
76 /*******************************************************/
77 /* Every config error increases tparser exit code by 1 */
78 /* Warnings do not influence the exit code             */
79 /*******************************************************/
80 
81 /* Test for required tokens */
testConfig(s_fidoconfig * config)82 int testConfig(s_fidoconfig * config)
83 {
84   int rc = 0;
85 
86   printf("\n");
87 
88   if(!config->tempDir)
89   {
90     printf("Warning:  TempDir not defined!\n");
91   }
92   if(!config->protInbound)
93   {
94     printf("Warning:  ProtInbound not defined!\n");
95   }
96   if(!config->inbound)
97   {
98     printf("Warning:  Inbound not defined!\n");
99   }
100   if(!config->localInbound)
101   {
102     printf("Warning:  localInbound not defined. The statement \"localInbound\" is not required but recommended.\n");
103   }
104   if(!config->tempInbound)
105   {
106     printf("Warning:  TempInbound not defined!\n");
107   }
108   if(!config->outbound)
109   {
110     printf("Warning:  Outbound not defined!\n");
111   }
112   if(!config->tempOutbound)
113   {
114     printf("Warning:  TempOutbound not defined!\n");
115   }
116   if(!config->nodelistDir)
117   {
118     printf("Warning:  NodelistDir not defined!\n");
119   }
120 
121 
122   if(config->netMailAreaCount == 0)
123   {
124     printf("You must define at least one NetmailArea!\n");
125     rc = 1;
126   }
127   if(config->dupeArea.areaName == NULL)
128   {
129     printf("You must define DupeArea!\n");
130     rc = 1;
131   }
132   else if(config->dupeArea.fileName == NULL)
133   {
134     printf("DupeArea cannot be passthrough!\n");
135     rc = 1;
136   }
137   if(config->badArea.areaName == NULL)
138   {
139     printf("You must define BadArea!\n");
140     rc = 1;
141   }
142   else if(config->badArea.fileName == NULL)
143   {
144     printf("BadArea cannot be passthrough!\n");
145     rc = 1;
146   }
147 
148   if(rc)
149     putchar('\n');
150 
151   return rc;
152 }
153 
154 /* check to path accuracy */
testpath(const char * s,const char * t1,const char * t2,const char * t3)155 int testpath(const char *s, const char *t1, const char *t2, const char *t3)
156 {
157   unsigned c;
158   int rc = 0;
159 
160   /* list of invalid substrings */
161   static char *invalids[] = { "/../",
162     "\\..\\",
163     ">",
164     "<",
165     "|",
166     NULL
167   };
168   /* list of reasons corresponding to the previous list */
169   static char *reasons[] = { "relative path",
170     "relative path",
171     "'redirect to' symbol is not allowed in a path name",
172     "'redirect from' symbol is not allowed in a path name",
173     "pipe symbol is not allowed in a path name",
174     NULL
175   };
176 
177   if(s)
178   {
179     for(c = 0; invalids[c]; c++)
180       if(strstr(s, invalids[c]))
181       {
182         printf("ERROR: mistake in %s%s%s%s%s value: %s\n", (t1 ? t1 : ""),
183                (t2 ? " " : ""), (t2 ? t2 : ""), (t3 ? " " : ""),
184                (t3 ? t3 : ""), reasons[c]);
185         rc++;
186       }
187     if(!
188        (strncmp(s, "./", 2) && strncmp(s, "../", 3) && strncmp(s, ".\\", 2)
189         && strncmp(s, "..\\", 3)))
190     {
191       printf("WARNING: mistake in %s%s%s%s%s value: relative path\n",
192              (t1 ? t1 : ""), (t2 ? " " : ""), (t2 ? t2 : ""), (t3 ? " " : ""),
193              (t3 ? t3 : ""));
194     }
195   }
196 
197   return rc;
198 }
199 
200 /* check for correctness of a plain file name */
testplainfile(const char * s,const char * t1,const char * t2,const char * t3)201 int testplainfile(const char *s, const char *t1, const char *t2,
202                   const char *t3)
203 {
204   static char invalidc[] = ":/\\><|";
205   register char *p;
206 
207   if(s && (p = strpbrk(s, invalidc)) != NULL)
208   {
209     printf("ERROR: %s%s%s%s%s can't contain %c\n", t1, (t2 ? " " : ""),
210            t2, (t3 ? " " : ""), t3, *p);
211     return -1;
212   }
213   return 0;
214 }
215 
216 /* check for correctness of file names and paths. Return zero if success. */
testPathsAndFiles()217 int testPathsAndFiles()
218 {
219   int rc = 0;
220   register unsigned int i;
221 
222   rc += testpath(config->inbound, "inbound", NULL, NULL);
223   rc += testpath(config->outbound, "outbound", NULL, NULL);
224   rc += testpath(config->protInbound, "protInbound", NULL, NULL);
225   rc += testpath(config->listInbound, "listInbound", NULL, NULL);
226   rc += testpath(config->localInbound, "localInbound", NULL, NULL);
227   rc += testpath(config->tempInbound, "tempInbound", NULL, NULL);
228   rc += testpath(config->logFileDir, "logFileDir", NULL, NULL);
229   rc += testpath(config->dupeHistoryDir, "dupeHistoryDir", NULL, NULL);
230   rc += testpath(config->nodelistDir, "nodelistDir", NULL, NULL);
231   rc += testpath(config->msgBaseDir, "msgBaseDir", NULL, NULL);
232   rc += testpath(config->magic, "magic", NULL, NULL);
233   rc += testpath(config->tempOutbound, "tempOutbound", NULL, NULL);
234   rc += testpath(config->ticOutbound, "ticOutbound", NULL, NULL);
235   rc += testpath(config->tempDir, "tempDir", NULL, NULL);
236   rc += testpath(config->fileAreaBaseDir, "fileAreaBaseDir", NULL, NULL);
237   rc += testpath(config->passFileAreaDir, "passFileAreaDir", NULL, NULL);
238   rc += testpath(config->busyFileDir, "busyFileDir", NULL, NULL);
239   rc += testpath(config->semaDir, "semaDir", NULL, NULL);
240   rc += testpath(config->badFilesDir, "badFilesDir", NULL, NULL);
241   rc += testpath(config->hptPerlFile, "hptPerlFile", NULL, NULL);
242   rc += testpath(config->advStatisticsFile, "advStatisticsFile", NULL, NULL);
243   rc += testpath(config->intab, "intab", NULL, NULL);
244   rc += testpath(config->outtab, "outtab", NULL, NULL);
245   rc += testpath(config->echotosslog, "echotosslog", NULL, NULL);
246   rc += testpath(config->statlog, "statlog", NULL, NULL);
247   rc += testpath(config->importlog, "importlog", NULL, NULL);
248   rc += testpath(config->lockfile, "lockfile", NULL, NULL);
249   rc += testpath(config->fileAreasLog, "fileAreasLog", NULL, NULL);
250   rc += testpath(config->fileNewAreasLog, "fileNewAreasLog", NULL, NULL);
251   rc += testpath(config->longNameList, "longNameList", NULL, NULL);
252   rc += testpath(config->fileArcList, "fileArcList", NULL, NULL);
253   rc += testpath(config->filePassList, "filePassList", NULL, NULL);
254   rc += testpath(config->fileDupeList, "fileDupeList", NULL, NULL);
255   rc += testpath(config->netmailFlag, "netmailFlag", NULL, NULL);
256   rc += testpath(config->reqidxDir, "reqidxDir", NULL, NULL);
257   rc += testpath(config->seqDir, "seqDir", NULL, NULL);
258 
259   rc += testplainfile(config->fidoUserList, "fidoUserList", NULL, NULL);
260   /* extension = file name suffix test as file name */
261   rc += testplainfile(config->tossingExt, "tossingExt", NULL, NULL);
262 
263   /* checks area paths */
264   rc += testpath(config->dupeArea.fileName, "Dupearea filename", NULL, NULL);
265   rc += testpath(config->badArea.fileName, "Badarea filename", NULL, NULL);
266 
267   for(i = 0; i < config->netMailAreaCount; i++)
268     rc +=
269         testpath(config->netMailAreas[i].fileName, "Netmailarea",
270                  config->netMailAreas[i].areaName,
271                  config->netMailAreas[i].msgbType ==
272                  MSGTYPE_SDM ? "pathname" : "filename");
273 
274   for(i = 0; i < config->echoAreaCount; i++)
275     rc +=
276         testpath(config->echoAreas[i].fileName, "Echoarea",
277                  config->echoAreas[i].areaName,
278                  config->echoAreas[i].msgbType ==
279                  MSGTYPE_SDM ? "pathname" : "filename");
280 
281   for(i = 0; i < config->localAreaCount; i++)
282     rc +=
283         testpath(config->localAreas[i].fileName, "Localarea",
284                  config->localAreas[i].areaName,
285                  config->localAreas[i].msgbType ==
286                  MSGTYPE_SDM ? "pathname" : "filename");
287 
288   for(i = 0; i < config->fileAreaCount; i++)
289     rc += testpath(config->fileAreas[i].fileName, "Filearea",
290                    config->fileAreas[i].areaName, "pathname");
291 
292   for(i = 0; i < config->bbsAreaCount; i++)
293     rc += testpath(config->bbsAreas[i].pathName, "BBSarea",
294                    config->bbsAreas[i].areaName, "pathname");
295 
296   for(i = 0; i < config->nodelistCount; i++)
297   {
298     rc += testplainfile(config->nodelists[i].nodelistName, "Nodelist",
299                         config->nodelists[i].nodelistName, NULL);
300     rc += testpath(config->nodelists[i].diffUpdateStem, "Nodelist's",
301                    config->nodelists[i].nodelistName, "diffUpdateStem");
302     rc += testpath(config->nodelists[i].fullUpdateStem, "Nodelist's",
303                    config->nodelists[i].nodelistName, "fullUpdateStem");
304   }
305 
306   for(i = 0; i < config->filelistCount; i++)
307   {
308     rc += testplainfile(config->filelists[i].destFile, "Filelist",
309                         config->filelists[i].destFile, NULL);
310     rc += testpath(config->filelists[i].dirHdrTpl, "Filelist's",
311                    config->filelists[i].destFile, "dirHdrTpl");
312     rc += testpath(config->filelists[i].dirEntryTpl, "Filelist's",
313                    config->filelists[i].destFile, "dirEntryTpl");
314     rc += testpath(config->filelists[i].dirFtrTpl, "Filelist's",
315                    config->filelists[i].destFile, "dirFtrTpl");
316     rc += testpath(config->filelists[i].globHdrTpl, "Filelist's",
317                    config->filelists[i].destFile, "globHdrTpl");
318     rc += testpath(config->filelists[i].globFtrTpl, "Filelist's",
319                    config->filelists[i].destFile, "globFtrTpl");
320     rc += testpath(config->filelists[i].dirListHdrTpl, "Filelist's",
321                    config->filelists[i].destFile, "dirListHdrTpl");
322     rc += testpath(config->filelists[i].dirListEntryTpl, "Filelist's",
323                    config->filelists[i].destFile, "dirListEntryTpl");
324     rc += testpath(config->filelists[i].dirListFtrTpl, "Filelist's",
325                    config->filelists[i].destFile, "dirListFtrTpl");
326   }
327 
328   /* robots */
329   for(i = 0; i < config->robotCount; i++)
330   {
331     rc += testpath(config->robot[i]->helpFile, "helpFile", NULL, NULL);
332     rc += testpath(config->robot[i]->rulesDir, "rulesDir", NULL, NULL);
333     rc +=
334         testpath(config->robot[i]->newAreaRefuseFile, "newAreaRefuseFile",
335                  NULL, NULL);
336     rc +=
337         testpath(config->robot[i]->autoCreateFlag, "autoCreateFlag", NULL,
338                  NULL);
339     rc += testpath(config->robot[i]->queueFile, "queueFile", NULL, NULL);
340   }
341 
342   /* test links */
343 
344   for(i = 0; i < config->linkCount; i++)
345   {
346     rc += testpath(config->links[i]->areafix.autoCreateFile, "Link",
347                    config->links[i]->name, "areafixAutoCreateFile");
348     rc += testpath(config->links[i]->filefix.autoCreateFile, "Link",
349                    config->links[i]->name, "filefixAutoCreateFile");
350     rc += testpath(config->links[i]->areafix.fwdFile, "Link",
351                    config->links[i]->name, "areafixFwdFile");
352     rc += testpath(config->links[i]->areafix.denyFwdFile, "Link",
353                    config->links[i]->name, "areafixFwdDenyFile");
354     rc += testpath(config->links[i]->filefix.fwdFile, "Link",
355                    config->links[i]->name, "filefixFwdFile");
356     rc += testpath(config->links[i]->filefix.denyFwdFile, "Link",
357                    config->links[i]->name, "filefixFwdDenyFile");
358     rc += testpath(config->links[i]->areafix.baseDir, "Link",
359                    config->links[i]->name, "areafixBaseDir");
360     rc += testpath(config->links[i]->filefix.baseDir, "Link",
361                    config->links[i]->name, "filefixBaseDir");
362     rc +=
363         testpath(config->links[i]->fileBox, "Link", config->links[i]->name,
364                  "fileBox");
365   }
366 
367 /*
368   rc+=testplainfile(config->,"");
369   rc+=testplainfile(config->,"");
370   rc+=testpath(config->,"");
371   rc+=testpath(config->,"");
372 */
373   return rc;
374 }
375 
testAddr(ps_addr addr)376 const char *testAddr(ps_addr addr)
377 {
378   char *c;
379 
380   if(!addr->zone && !addr->net && !addr->node)
381   {
382     return "Error: Invalid (zero) address\n";
383   }
384   if(!addr->zone || addr->zone < -1 /*|| addr->zone > 32767 */ )
385   {
386     return "Error: FTN zone must be 16-bit positive number (32767 max) or -1";
387   }
388   if(!addr->net || addr->net < -1 /*|| addr->net > 32767 */ )
389   {
390     return
391         "Error: FTN network number must be 16-bit positive number (32767 max) or -1";
392   }
393   if(addr->node < -1 /*|| addr->node > 32767 */ )
394   {
395     return
396         "Error: FTN node number must be 16-bit positive number (32767 max), zero or -1";
397   }
398   if(addr->point < -1 /*|| addr->point > 32767 */ )
399   {
400     return
401         "Error: FTN point number must be 16-bit positive number (32767 max), zero or -1";
402   }
403   if((addr->net == -1) || (addr->node == -1) || (addr->point == -1))
404   {
405     if((addr->net != -1) || (addr->node != -1)
406        || (addr->point && (addr->point != -1)))
407     {
408       static char s[] =
409           "Error: -1 in address may only be used for node or point requests and should be       :-1/-1 or       :-1/-1.-1";
410       sprintf(s + 78, "%i:-1/1 or ", addr->zone);
411       sprintf(s + strlen(s), "%i:-1/-1.-1", addr->zone);
412       return s;
413     }
414   }
415   if(!addr->node && addr->point)
416   {
417     return "Warning: network host can't have points";
418   }
419 
420   if(addr->domain)
421   {
422     for(c = addr->domain; *c; c++)
423     {
424       if(!isalnum(*c))
425       {
426         if(*c == '.')
427           return "Warning: FTN domain should not contain '.' char";
428         else
429         {
430           char *msg =
431               "Warning: FTN domain should contain alphanumeric characters only but ' ' is not";
432           char *p = strchr(msg, '\'') + 1;
433 
434           if(p)
435             *p = *c;
436           return msg;
437         }
438       }
439     }
440   }
441   return NULL;
442 }
443 
printAddr(ps_addr addr)444 void printAddr(ps_addr addr)
445 {
446   if(addr)
447   {
448 
449     if(addr->domain[0])
450     {
451       if(addr->point)
452         printf(" %d:%d/%d.%d@%s ", addr->zone, addr->net, addr->node,
453                addr->point, addr->domain);
454       else
455         printf(" %d:%d/%d@%s ", addr->zone, addr->net, addr->node,
456                addr->domain);
457     }
458     else
459     {
460       if(addr->point)
461         printf(" %d:%d/%d.%d ", addr->zone, addr->net, addr->node,
462                addr->point);
463       else
464         printf(" %d:%d/%d ", addr->zone, addr->net, addr->node);
465     }
466   }
467 }
468 
printArea(s_area area)469 void printArea(s_area area)
470 {
471   unsigned i;
472 
473   printf("%s \n", area.areaName ? area.areaName : "");
474   printf("Description: ");
475   if(area.description != NULL)
476     printf("%s", area.description);
477   printf("\n-> %s\t", area.fileName ? area.fileName : "");
478   if(area.msgbType == MSGTYPE_SDM)
479     printf("SDM");
480   else if(area.msgbType == MSGTYPE_SQUISH)
481     printf("Squish");
482   else if(area.msgbType == MSGTYPE_JAM)
483     printf("Jam");
484   else
485     printf("Passthrough");
486 
487   printf("\t Use AKA: ");
488   if(area.useAka == NULL)
489     printf("(not configured)");
490   else
491     printAddr(area.useAka);
492   printf("\n");
493   if(area.paused)
494     printf("Area is paused\n");
495   printf("DOS Style File (8+3) %s\n",
496          (area.DOSFile) ? "on (-dosfile)" : "off (-nodosfile)");
497   printf("Level read  (-lr): %d\n", area.levelread);
498   printf("Level write (-lw): %d\n", area.levelwrite);
499   if(area.group)
500     printf("Group       - %s\n", area.group);
501   if(area.nopack)
502   {
503     printf
504         ("Never purge (option \"-nopack\") (ignoring: max (-$m): %u msgs\tpurge (-p): %u days)\tdupeHistory %u\n",
505          area.max, area.purge, area.dupeHistory);
506   }
507   else
508   {
509     printf
510         ("Purging enabled (option \"-pack\") max (-$m): %u msgs\tpurge (-p): %u days\tdupeHistory %u\n",
511          area.max, area.purge, area.dupeHistory);
512   }
513   printf("Options: ");
514   if(area.tinySB)
515     printf("tinySB ");
516   else
517     printf("noTinySB ");
518   if(area.killSB)
519     printf("killSB ");
520   else
521     printf("noKillSB ");
522   if(area.keepUnread)
523     printf("keepUnread ");
524   else
525     printf("noKeepUnread ");
526   if(area.killRead)
527     printf("killRead ");
528   else
529     printf("noKillRead ");
530   if(area.hide)
531     printf("hide ");
532   else
533     printf("noHide ");
534   if(area.killMsgBase)
535     printf("kill ");
536   else
537     printf("noKill ");
538   if(area.manual)
539     printf("manual ");
540   else
541     printf("noManual ");
542   if(area.noPause)
543     printf("noPause ");
544   else
545     printf("pause ");
546   if(area.nolink)
547     printf("nolink ");
548   else
549     printf("link ");
550   if(area.mandatory)
551     printf("mandatory ");
552   else
553     printf("noMandatory ");
554   if(area.debug)
555     printf("debug ");
556   else
557     printf("noDebug ");
558   if(area.DOSFile)
559     printf("DOSFile ");
560   else
561     printf("noDOSFile ");
562   if(area.nopack)
563     printf("noPack ");
564   else
565     printf("pack ");
566   if(area.ccoff)
567     printf("ccoff ");
568   else
569     printf("noCCoff ");
570   if(area.keepsb)
571     printf("keepSB ");
572   else
573     printf("noKeepSB ");
574   if(area.noautoareapause)
575     printf("noAutoAreaPause ");
576   else
577     printf("autoAreaPause ");
578   if(area.sbkeep_all)
579     printf("SBkeepAll ");
580   else
581     printf("noSBkeepAll ");
582   printf("\n");
583   printf("Default subscribing option:");
584   if(area.def_subscribing == RO)
585     printf(" read-only");
586   if(area.def_subscribing == WO)
587     printf(" write-only");
588   printf("\n");
589   printf("DupeCheck: ");
590   if(area.dupeCheck == dcOff)
591     printf("off");
592   if(area.dupeCheck == dcMove)
593     printf("move");
594   if(area.dupeCheck == dcDel)
595     printf("delete");
596   printf("\n");
597   /* tooOld */
598   printf("tooOld: %u days", area.tooOld);
599   if(area.tooOld == 0)
600     printf(" (disabled)");
601   printf("\n");
602   /* tooOld */
603   printf("tooNew: %u days", area.tooNew);
604   if(area.tooNew == 0)
605     printf(" (disabled)");
606   printf("\n");
607 /* val: scan */
608   printf("ScanMode: ");
609   if(area.scanMode == smNever)
610     printf("never");
611   else if(area.scanMode == smManual)
612     printf("manual");
613   else if(area.scanMode == smListed)
614     printf("listed");
615   else
616     printf("normal");
617   printf("\n");
618   if(area.downlinkCount)
619     printf("Links:\n");
620   else
621     printf("No links\n");
622   for(i = 0; i < area.downlinkCount; i++)
623   {
624     printf("\t");
625     printAddr(&(area.downlinks[i]->link->hisAka));
626     printf(" level %d,", area.downlinks[i]->link->level);
627 /*       printf(" exp. %s,", (area.downlinks[i]->export) ? "on" : "off");
628        printf(" imp. %s,", (area.downlinks[i]->import) ? "on" : "off");*/
629     if(area.downlinks[i]->aexport || area.downlinks[i]->import)
630       printf(" ");
631     else
632       printf(" no access");
633     if(area.downlinks[i]->aexport)
634       printf("read");
635     if(area.downlinks[i]->aexport && area.downlinks[i]->import)
636       printf("/");
637     if(area.downlinks[i]->import)
638       printf("write");
639     if(area.downlinks[i]->aexport && area.downlinks[i]->rescan)
640       printf("/rescan");
641     if((area.downlinks[i]->aexport + area.downlinks[i]->import) == 1)
642       printf(" only");
643     printf(",");
644     printf(" defLink %s,", (area.downlinks[i]->defLink) ? "on" : "off");
645     printf(" mand. %s.\n", (area.downlinks[i]->mandatory) ? "on" : "off");
646   }
647   if(area.sbaddCount)
648   {
649     printf("addSeenBys: ");
650     for(i = 0; i < area.sbaddCount; i++)
651       printf("%u/%u ", area.sbadd[i].net, area.sbadd[i].node);
652     printf("\n");
653   }
654   if(area.sbignCount)
655   {
656     printf("IgnoreSeenBys: ");
657     for(i = 0; i < area.sbignCount; i++)
658       printf("%u/%u ", area.sbign[i].net, area.sbign[i].node);
659     printf("\n");
660   }
661   if(area.sbstripCount)
662   {
663     printf("StripSeenBys: ");
664     for(i = 0; i < area.sbstripCount; i++)
665       printf("%u/%u ", area.sbstrip[i].net, area.sbstrip[i].node);
666     printf("\n");
667   }
668   if(area.sbkeepCount)
669   {
670     printf("KeepSeenBys: ");
671     for(i = 0; i < area.sbkeepCount; i++)
672       printf("%u/%u ", area.sbkeep[i].net, area.sbkeep[i].node);
673     printf("\n");
674   }
675   printf("-------\n");
676 }
677 
printAreaGroup(char * group)678 int printAreaGroup(char *group)
679 {
680   grp_t *g = (grp_t *) group;
681 
682   if(!g)
683     return 1;
684   printf("AreaGroup: %s -> %s \n", g->name, g->patternList);
685   printArea(*(g->area));
686   return 1;
687 }
688 
printFileArea(s_area area)689 void printFileArea(s_area area)
690 {
691   unsigned i;
692 
693   printf("%s \n", area.areaName);
694   printf("Description: %s\n", (area.description) ? area.description : "");
695   if(area.msgbType != MSGTYPE_PASSTHROUGH)
696     printf("Path: %s\t", area.fileName);
697   else
698     printf("Passthrough filearea");
699 
700   printf("\t Use AKA: ");
701   if(area.useAka == NULL)
702     printf("(not configured)");
703   else
704     printAddr(area.useAka);
705   printf("\n");
706   printf("Level read  (-lr): %d\n", area.levelread);
707   printf("Level write (-lw): %d\n", area.levelwrite);
708   if(area.purge > 0)
709     printf("Purge (-p): %u days\n", area.purge);
710   else
711     printf("Purging disabled (-p 0)\n");
712   printf("Options: ");
713   if(area.hide)
714     printf("hide ");
715   else
716     printf("noHide ");
717   if(area.manual)
718     printf("manual ");
719   else
720     printf("noManual ");
721   if(area.mandatory)
722     printf("mandatory ");
723   else
724     printf("noMandatory ");
725   if(area.sendorig)
726     printf("sendorig ");
727   else
728     printf("noSendOrig ");
729   if(area.noPause)
730     printf("noPause ");
731   else
732     printf("pause ");
733   if(area.noCRC)
734     printf("noCRC ");
735   else
736     printf("crc ");
737   if(area.noreplace)
738     printf("noReplace ");
739   else
740     printf("replace ");
741   if(area.rename)
742     printf("rename ");
743   else
744     printf("noRename ");
745   if(area.nodiz)
746     printf("noDiz ");
747   else
748     printf("diz ");
749   printf("\n");
750   if(area.group)
751     printf("Group (-g): %s\n", area.group);
752   if(area.downlinkCount)
753     printf("Links:\n");
754   else
755     printf("No links\n");
756   for(i = 0; i < area.downlinkCount; i++)
757   {
758     printf("\t");
759     printAddr(&(area.downlinks[i]->link->hisAka));
760     printf(" level %d,", area.downlinks[i]->link->level);
761     if(area.downlinks[i]->aexport || area.downlinks[i]->import)
762       printf(" ");
763     else
764       printf(" no access");
765     if(area.downlinks[i]->aexport)
766       printf("receive");
767     if(area.downlinks[i]->aexport && area.downlinks[i]->import)
768       printf("/");
769     if(area.downlinks[i]->import)
770       printf("send");
771     if((area.downlinks[i]->aexport + area.downlinks[i]->import) == 1)
772       printf(" only");
773     printf(",");
774 /*       printf(" export %s,", (area.downlinks[i]->export) ? "on" : "off");
775        printf(" import %s,", (area.downlinks[i]->import) ? "on" : "off");    */
776     printf(" mandatory %s", (area.downlinks[i]->mandatory) ? "on" : "off");
777     if(area.downlinks[i]->defLink)
778       printf("; this is (default) uplink.\n");
779     else
780       printf(".\n");
781   }
782 
783   printf("-------\n");
784 }
785 
printBbsArea(s_bbsarea area)786 void printBbsArea(s_bbsarea area)
787 {
788 
789   printf("%s \n", area.areaName);
790   printf("Description: %s\n", area.description);
791   printf("Path: %s\t", area.pathName);
792 
793   printf("\n");
794   printf("-------\n");
795 }
796 
printFilelist(s_filelist * fl)797 void printFilelist(s_filelist * fl)
798 {
799   switch (fl->flType)
800   {
801     case flDir:
802       printf("type: directory\n");
803       break;
804 
805     case flGlobal:
806       printf("type: global\n");
807       break;
808 
809     case flDirList:
810       printf("type: dirlist\n");
811       break;
812 
813     default:
814       printf("internal error: unknown flType!\n");
815       break;
816   }
817 
818   printf("destination file: %s\n", fl->destFile);
819   if((fl->flType == flGlobal) || (fl->flType == flDir))
820   {
821     printf("directory header template: %s\n", fl->dirHdrTpl);
822     printf("directory entry template: %s\n", fl->dirEntryTpl);
823     printf("directory footer template: %s\n", fl->dirFtrTpl);
824   }
825 
826   switch (fl->flType)
827   {
828     case flGlobal:
829       printf("global header template: %s\n", fl->globHdrTpl);
830       printf("global footer template: %s\n", fl->globFtrTpl);
831       break;
832 
833     case flDirList:
834       printf("dirlist header template: %s\n", fl->dirListHdrTpl);
835       printf("dirlist entry template: %s\n", fl->dirListEntryTpl);
836       printf("dirlist footer template: %s\n", fl->dirListFtrTpl);
837       break;
838 
839     case flDir:
840     default:
841       /*  just avoid a warning */
842       break;
843   }
844   printf("-------\n");
845 }
846 
cvtFlavour(e_flavour flavour)847 static char *cvtFlavour(e_flavour flavour)
848 {
849   switch (flavour)
850   {
851     case flHold:
852       return "hold";
853     case flNormal:
854       return "normal";
855     case flDirect:
856       return "direct";
857     case flCrash:
858       return "crash";
859     case flImmediate:
860       return "immediate";
861     case flUndef:
862       return "unknown!";
863     default:
864       fprintf(stderr, "Unknown flavour, update tparser!\n");
865       return "";
866   }
867 }
868 
printLink(ps_link link)869 int printLink(ps_link link)
870 {
871   unsigned int i, rc = 0;
872 
873   printf("Link: ");
874   printAddr(&(link->hisAka));
875   printf(" (ourAka ");
876   printAddr(link->ourAka);
877   printf(")\n");
878   if(link->hisPackAka.zone != 0)
879   {
880     printf("PackAka: ");
881     printAddr(&(link->hisPackAka));
882     printf("\n");
883   }
884 
885   printf("Name: %s\n", link->name);
886   if(link->defaultPwd)
887     printf("defaultPwd: %s\n", link->defaultPwd);
888   if(link->pktPwd)
889     printf("pktPwd:     %s\n", link->pktPwd);
890   if(link->ticPwd)
891     printf("ticPwd:     %s\n", link->ticPwd);
892   if(link->areafix.pwd)
893     printf("areafixPwd: %s\n", link->areafix.pwd);
894   if(link->filefix.pwd)
895     printf("filefixPwd: %s\n", link->filefix.pwd);
896   if(link->bbsPwd)
897     printf("bbsPwd:     %s\n", link->bbsPwd);
898   if(link->sessionPwd)
899   {
900     printf("sessionPwd: %s\n", link->sessionPwd);
901     if(strlen(link->sessionPwd) > 8)
902     {
903       printf
904           ("WARNING: sessionPwd is too long, should not be longer than 8 chars usually.\nA longer password may cause an error in some mailers.\n");
905       fprintf(stderr,
906               "WARNING: sessionPwd is too long, should not be longer than 8 chars usually.\n");
907     }
908   }
909   if(link->handle != link->name)
910     printf("handle:     %s\n", link->handle);
911   if(link->email)
912   {
913     printf("email:      %s\n", link->email);
914 
915     switch (link->emailEncoding)
916     {
917       case eeMIME:
918         printf("emailEncoding: MIME\n");
919         break;
920 
921       case eeSEAT:
922         printf("emailEncoding: SEAT\n");
923         break;
924 
925       case eeUUE:
926         printf("emailEncoding: UUE\n");
927         break;
928 
929       default:
930         printf("Internal error: Unknown encoding #%d!\n",
931                link->emailEncoding);
932     }
933   }
934   if(link->emailFrom)
935     printf("emailFrom:  %s\n", link->emailFrom);
936   if(link->emailSubj)
937     printf("emailSubj:  %s\n", link->emailSubj);
938   printf("Level:      %u\n", link->level);
939   printf("Export:     %s\n", (link->aexport) ? "on" : "off");
940   printf("Import:     %s\n", (link->import) ? "on" : "off");
941   printf("Mandatory:  %s\n", (link->mandatory) ? "on" : "off");
942 
943   printf("AvailList: ");
944   switch (link->availlist)
945   {
946     case AVAILLIST_FULL:
947       printf("Full\n");
948       break;
949     case AVAILLIST_UNIQUE:
950       printf("Unique\n");
951       break;
952     case AVAILLIST_UNIQUEONE:
953       printf("UniqueOne\n");
954       break;
955     default:
956       printf("Unknown (m.b. fidoconf <--> tparser incompatible?)");
957       break;
958   }
959 
960   if((link->Pause & ECHOAREA) == ECHOAREA)
961     printf("Link is paused for echoes, no export\n");
962 
963   if((link->Pause & FILEAREA) == FILEAREA)
964     printf("Link is paused for fileEchoes, no export\n");
965 
966   if(link->autoPause)
967     printf("AutoPause after %u days\n", link->autoPause);
968   if(link->numOptGrp > 0)
969   {
970     printf("OptGrp       ");
971     for(i = 0; i < link->numOptGrp; i++)
972     {
973       if(i > 0)
974         printf(",");
975       printf("%s", link->optGrp[i]);
976     }
977     printf("\n");
978   }
979   printf("areafixAutoCreate %s\n", (link->areafix.autoCreate) ? "on" : "off");
980   printf("AutoAreaCreateSubdirs %s\n",
981          (link->autoAreaCreateSubdirs) ? "on" : "off");
982   if(link->areafix.autoCreateFile)
983     printf("areafixAutoCreateFile: %s\n", link->areafix.autoCreateFile);
984   if(link->areafix.numFrMask > 0)
985   {
986     printf("areafixFwdMask: ");
987     for(i = 0; i < link->areafix.numFrMask; i++)
988     {
989       if(i > 0)
990         printf(",");
991       printf("%s", link->areafix.frMask[i]);
992     }
993     printf("\n");
994   }
995   if(link->areafix.numDfMask > 0)
996   {
997     printf("areafixFwdDenyMask: ");
998     for(i = 0; i < link->areafix.numDfMask; i++)
999     {
1000       if(i > 0)
1001         printf(",");
1002       printf("%s", link->areafix.dfMask[i]);
1003     }
1004     printf("\n");
1005   }
1006   if(link->areafix.autoCreateDefaults)
1007     printf("areafixAutoCreateDefaults: %s\n",
1008            link->areafix.autoCreateDefaults);
1009   printf("Automatically subscribing this link to an autocreated echo is %s\n",
1010          (link->areafix.autoSubscribe) ? "on" : "off");
1011   printf("Automatically subscribing this link to an autocreated fileecho is %s\n",
1012          (link->filefix.autoSubscribe) ? "on" : "off");
1013 
1014   printf("delNotReceivedTIC: %s\n", link->delNotReceivedTIC ? "on" : "off");
1015   printf("FileFixFSC87Subset %s\n",
1016          (link->FileFixFSC87Subset) ? "on" : "off");
1017 
1018   printf("filefixAutoCreate %s\n", (link->filefix.autoCreate) ? "on" : "off");
1019   printf("AutoFileCreateSubdirs %s\n",
1020          (link->autoFileCreateSubdirs) ? "on" : "off");
1021   if(link->filefix.autoCreateFile)
1022     printf("filefixAutoCreateFile: %s\n", link->filefix.autoCreateFile);
1023   if(link->filefix.numFrMask > 0)
1024   {
1025     printf("filefixFwdMask: ");
1026     for(i = 0; i < link->filefix.numFrMask; i++)
1027     {
1028       if(i > 0)
1029         printf(",");
1030       printf("%s", link->filefix.frMask[i]);
1031     }
1032     printf("\n");
1033   }
1034   if(link->filefix.numDfMask > 0)
1035   {
1036     printf("filefixFwdDenyMask: ");
1037     for(i = 0; i < link->filefix.numDfMask; i++)
1038     {
1039       if(i > 0)
1040         printf(",");
1041       printf("%s", link->filefix.dfMask[i]);
1042     }
1043     printf("\n");
1044   }
1045   if(link->filefix.autoCreateDefaults)
1046     printf("filefixAutoCreateDefaults: %s\n",
1047            link->filefix.autoCreateDefaults);
1048 
1049   if(link->LinkGrp)
1050     printf("LinkGrp %s\n", link->LinkGrp);
1051   if(link->numAccessGrp)
1052   {
1053     unsigned int i;
1054 
1055     printf("AccessGrp ");
1056     for(i = 0; i < link->numAccessGrp; i++)
1057     {
1058       if(i > 0)
1059         printf(", %s", link->AccessGrp[i]);
1060       else
1061         printf("%s", link->AccessGrp[0]);
1062     }
1063     printf("\n");
1064   }
1065   printf("AreaFix %s\n", (link->areafix.on) ? "on" : "off");
1066   if(link->areafix.echoLimit)
1067     printf("areafixEchoLimit %u\n", link->areafix.echoLimit);
1068   if(link->areafix.reportsAttr || link->areafix.reportsFlags)
1069   {
1070     char *attrs = attr2str(link->areafix.reportsAttr);
1071 
1072     printf("areafixReportsAttr: %s%s%s\n", attrs ? strUpper(attrs) : "",
1073            attrs ? " " : "",
1074            link->areafix.reportsFlags ? link->areafix.reportsFlags : "");
1075     nfree(attrs);
1076   }
1077   printf("FileFix %s\n", (link->filefix.on) ? "on" : "off");
1078   if(link->filefix.echoLimit)
1079     printf("filefixEchoLimit %u\n", link->filefix.echoLimit);
1080   if(link->filefix.reportsAttr || link->filefix.reportsFlags)
1081   {
1082     char *attrs = attr2str(link->filefix.reportsAttr);
1083 
1084     printf("filefixReportsAttr: %s%s%s\n", attrs ? strUpper(attrs) : "",
1085            attrs ? " " : "",
1086            link->filefix.reportsFlags ? link->filefix.reportsFlags : "");
1087     nfree(attrs);
1088   }
1089   printf("Forwarding Areafix Requests to this link is %s\n",
1090          (link->areafix.forwardRequests) ? "on" : "off");
1091   printf("Forwarding Filefix Requests to this link is %s\n",
1092          (link->filefix.forwardRequests) ? "on" : "off");
1093   if(link->areafix.forwardPriority)
1094     printf("areafixFwdPriority: %u\n", link->areafix.forwardPriority);
1095   if(link->filefix.forwardPriority)
1096     printf("filefixFwdPriority: %u\n", link->filefix.forwardPriority);
1097   printf("Areafix Forward Requests Access: %s\n",
1098          (link->areafix.denyFRA) ? "off" : "on");
1099   printf("Filefix Forward Requests Access: %s\n",
1100          (link->filefix.denyFRA) ? "off" : "on");
1101   printf("Areafix Unconditional Forward Requests Access: %s\n",
1102          (link->areafix.denyUFRA) ? "off" : "on");
1103   printf("Filefix Unconditional Forward Requests Access: %s\n",
1104          (link->filefix.denyUFRA) ? "off" : "on");
1105   printf("areafixName %s\n",
1106          link->areafix.name ? link->areafix.name : "areafix");
1107   printf("filefixName %s\n",
1108          link->filefix.name ? link->filefix.name : "filefix");
1109   if(link->areafix.fwdFile)
1110     printf("areafixFwdFile %s\n", link->areafix.fwdFile);
1111   if(link->filefix.fwdFile)
1112     printf("filefixFwdFile %s\n", link->filefix.fwdFile);
1113   if(link->areafix.denyFwdFile)
1114     printf("areafixFwdDenyFile %s\n", link->areafix.denyFwdFile);
1115   if(link->filefix.denyFwdFile)
1116     printf("filefixFwdDenyFile %s\n", link->filefix.denyFwdFile);
1117   if(link->areafix.baseDir)
1118     printf("MsgBaseDir %s\n", link->areafix.baseDir);
1119   if(link->filefix.baseDir)
1120     printf("LinkFileBaseDir %s\n", link->filefix.baseDir);
1121   if(link->packerDef)
1122     printf("PackerDefault %s\n", link->packerDef->packer);
1123   else
1124     printf("PackerDefault none\n");
1125   if(link->fileBox)
1126   {
1127     printf("fileBox %s\n", link->fileBox);
1128     printf("fileBoxAlways: %s\n", link->fileBoxAlways ? "on" : "off");
1129   }
1130   printf("TickerPackToBox %s\n", (link->tickerPackToBox) ? "on" : "off");
1131   if(link->pktSize != 0)
1132     printf("pktSize - %u kb\n", link->pktSize);
1133   if(link->arcmailSize != 0)
1134     printf("arcmailSize - %u kb\n", link->arcmailSize);
1135   printf("dailyBundles %s\n", link->dailyBundles ? "on" : "off");
1136 
1137   if(link->packerDef)
1138   {
1139     printf("packNetmail: %s\n", (link->packNetmail) ? "on" : "off");
1140     if(link->packNetmail)
1141       printf("maxUnpackedNetmail: %d kb\n", link->maxUnpackedNetmail);
1142   }
1143   else if(link->packNetmail)
1144     printf("Packer not defined but packNetmail is on\n");
1145 
1146   printf("TIC files %s\n", (link->noTIC == 0) ? "on" : "off");
1147   printf("forwardPkts ");
1148   switch (link->forwardPkts)
1149   {
1150     case fOff:
1151       printf("off\n");
1152       break;
1153     case fSecure:
1154       printf("secure\n");
1155       break;
1156     case fOn:
1157       printf("on\n");
1158       break;
1159     default:
1160       break;
1161   }
1162   printf("allowEmptyPktPwd ");
1163   switch (link->allowEmptyPktPwd)
1164   {
1165     case eOff:
1166       printf("off\n");
1167       break;
1168     case eSecure:
1169       printf("secure\n");
1170       break;
1171     case eOn:
1172       printf("on\n");
1173       break;
1174     default:
1175       break;
1176   }
1177   printf("allowPktAddrDiffer ");
1178   switch (link->allowPktAddrDiffer)
1179   {
1180     case pdOff:
1181       printf("off\n");
1182       break;
1183     case pdOn:
1184       printf("on\n");
1185       break;
1186     default:
1187       fprintf(stderr, "Error in keyword allowPktAddrDiffer\n");
1188       break;
1189   }
1190   printf("AdvancedAreaFix %s\n", (link->advancedAreafix) ? "on" : "off");
1191 
1192   switch (link->linkBundleNameStyle)
1193   {
1194     case eUndef:
1195       /* Don't print senseless information... printf("linkBundleNameStyle: undefined (like BundleNameStyle)\n"); */
1196       break;
1197     case eAddrDiff:
1198       printf("linkBundleNameStyle: addrDiff\n");
1199       break;
1200     case eAddrDiffAlways:
1201       printf("linkBundleNameStyle: addrDiffAlways\n");
1202       break;
1203     case eTimeStamp:
1204       printf("linkBundleNameStyle: timeStamp\n");
1205       break;
1206     case eAmiga:
1207       printf("linkBundleNameStyle: Amiga\n");
1208       break;
1209     case eAddrsCRC32:
1210       printf("linkBundleNameStyle: AddrsCRC32\n");
1211       break;
1212     case eAddrsCRC32Always:
1213       printf("linkBundleNameStyle: AddrsCRC32Always\n");
1214       break;
1215     default:
1216       printf
1217           ("Warning: linkBundleNameStyle is UNKNOWN! Update tparser, please!\n");
1218       break;
1219   }
1220   printf("arcNetmail %s\n", (link->arcNetmail) ? "on" : "off");
1221   printf("netMailFlavour %s\n", cvtFlavour(link->netMailFlavour));
1222   printf("echoMailFlavour %s\n", cvtFlavour(link->echoMailFlavour));
1223   printf("fileEchoFlavour %s\n", cvtFlavour(link->fileEchoFlavour));
1224   printf("areafixNoRules %s\n", (link->areafix.noRules) ? "on" : "off");
1225   printf("filefixNoRules %s\n", (link->filefix.noRules) ? "on" : "off");
1226   printf("reducedSeenBy %s\n", (link->reducedSeenBy) ? "on" : "off");
1227   printf("sendNotifyMessages %s\n",
1228          (link->sendNotifyMessages) ? "on" : "off");
1229   printf("allowRemoteControl %s\n",
1230          (link->allowRemoteControl) ? "on" : "off");
1231   printf("unsubscribeOnAreaDelete %s\n",
1232          (link->unsubscribeOnAreaDelete) ? "on" : "off");
1233 
1234   if(link->numRescanGrp)
1235   {
1236     printf("RescanGrp    ");
1237     for(i = 0; i < link->numRescanGrp; i++)
1238     {
1239       if(i > 0)
1240         printf(",");
1241       printf("%s", link->RescanGrp[i]);
1242     }
1243     printf("\n");
1244   }
1245   printf("denyRescan %s%s\n", (link->denyRescan) ? "on" : "off",
1246          (link->numRescanGrp) ? " (applies to areas on RescanGrp list)" : "");
1247   if(link->rescanLimit)
1248     printf("rescanLimit %d\n", link->rescanLimit);
1249 
1250   printf("-------\n");
1251   return rc;
1252 }
1253 
1254 
printRobot(ps_robot robot)1255 int printRobot(ps_robot robot)
1256 {
1257   printf("Robot %s\n", robot->name);
1258   if(robot->names)
1259   {
1260     int i;
1261     printf("  robotNames");
1262     for(i = 0; i < robot->names->count; ++i)
1263       printf(" %s", STR_N(robot->names, i));
1264     printf("\n");
1265   }
1266   if(robot->fromName)
1267     printf("  fromName %s\n", robot->fromName);
1268   if(robot->origin)
1269     printf("  robotOrigin %s\n", robot->origin);
1270   if(robot->helpFile)
1271     printf("  helpFile %s\n", robot->helpFile);
1272   if(robot->rulesDir)
1273     printf("  rulesDir %s\n", robot->rulesDir);
1274   if(robot->newAreaRefuseFile)
1275     printf("  newAreaRefuseFile %s\n", robot->newAreaRefuseFile);
1276   if(robot->autoCreateFlag)
1277     printf("  autoCreateFlag %s\n", robot->autoCreateFlag);
1278   if(robot->queueFile)
1279     printf("  queueFile %s\n", robot->queueFile);
1280   if(robot->reportsAttr || robot->reportsFlags)
1281   {
1282     char *attrs = attr2str(robot->reportsAttr);
1283 
1284     printf("  reportsAttr %s%s%s\n", attrs ? strUpper(attrs) : "",
1285            attrs ? " " : "", robot->reportsFlags ? robot->reportsFlags : "");
1286     nfree(attrs);
1287   }
1288   printf("  killRequests %s\n", robot->killRequests ? "on" : "off");
1289   printf("  queryReports %s\n", robot->queryReports ? "on" : "off");
1290   if(robot->msgSize)
1291     printf(" msgSize %u\n", robot->msgSize);
1292   if(robot->splitStr)
1293     printf(" splitStr \"%s\"\n", robot->splitStr);
1294   printf("  autoAreaPause %s\n", robot->autoAreaPause ? "on" : "off");
1295   printf("  forwardRequestTimeout %u\n", robot->forwardRequestTimeout);
1296   printf("  idlePassthruTimeout   %u\n", robot->idlePassthruTimeout);
1297   printf("  killedRequestTimeout  %u\n", robot->killedRequestTimeout);
1298   printf("-------\n");
1299   return 0;
1300 }
1301 
1302 /* Attention! Return value is static string */
routeViaStr(e_routing routeVia)1303 const char *routeViaStr(e_routing routeVia)
1304 {
1305   switch (routeVia)
1306   {
1307     case route_zero:
1308       return "zero";
1309     case noroute:
1310       return "direct";
1311     case nopack:
1312       return "nopack";
1313     case host:
1314       return "host (Z:N/0.0@domain)";
1315     case hub:
1316       return "\"hub\" (Z:N/ff00.0@domain)";
1317     case boss:
1318       return "boss (Z:N/F.0@domain)";
1319     case route_extern: /* internal only */
1320       return "";
1321   }
1322   return "UNKNOWN(error?)";
1323 }
1324 
printRouteTarget(s_route aroute)1325 void printRouteTarget(s_route aroute)
1326 {
1327   if (aroute.target) printAddr(&(aroute.target->hisAka));
1328   else printf(" %s ", routeViaStr(aroute.routeVia));
1329 }
1330 
1331 /*  Some dumb checks ;-) */
checkLogic(s_fidoconfig * config)1332 int checkLogic(s_fidoconfig * config)
1333 {
1334   register unsigned i, j, m;
1335   register int k, rc = 0;
1336   int robotsarea_ok;
1337   s_link *link;
1338   s_area *area;
1339   register char *areaName;
1340   char * passthrough = "passthrough";
1341 
1342   robotsarea_ok = config->robotsArea ? 0 : 1;
1343 
1344   /* Robots should not access same queueFile */
1345   for(i = 0; i < config->robotCount; i++)
1346   {
1347     if(config->robot[i]->queueFile == NULL)
1348       continue;
1349     for(j = i+1; j < config->robotCount; j++)
1350     {
1351       if(config->robot[j]->queueFile != NULL &&
1352          stricmp(config->robot[i]->queueFile, config->robot[j]->queueFile) == 0)
1353       {
1354         printf("Error: robots %s and %s use the same queueFile %s, but they should not!\n",
1355            config->robot[i]->name, config->robot[j]->name, config->robot[i]->queueFile);
1356         rc++;
1357       }
1358     }
1359   }
1360 
1361   for(i = 0; i + 1 < config->linkCount; i++)
1362   {
1363     /* Check link address */
1364     const char *addrerror = testAddr(&(config->links[i]->hisAka));
1365 
1366     if(addrerror)
1367     {
1368       printf("Link %s", config->links[i]->name);
1369       printAddr(&(config->links[i]->hisAka));
1370       printf(":\n %s\n", addrerror);
1371       rc++;
1372     }
1373 
1374     /* Check links duplication */
1375     for(j = i + 1; j < config->linkCount; j++)
1376     {
1377       if(addrComp(config->links[i]->hisAka, config->links[j]->hisAka) == 0)
1378       {
1379 
1380         if(strcmp(config->links[i]->name, config->links[j]->name) != 0)
1381         {
1382           printf("Warning: duplicate definition of link %s ",
1383                  config->links[i]->name);
1384           printAddr(&(config->links[i]->hisAka));
1385           printf("\n");
1386           continue;
1387         }
1388 
1389         printf("ERROR: duplication of link ");
1390         printAddr(&(config->links[i]->hisAka));
1391         printf("\n");
1392         printf("remove it, or change the name!\n");
1393         exit(-1);
1394       }
1395     }
1396     /* Check file permissions */
1397     if(config->links[i]->areafix.autoCreateFile)
1398     {
1399       k = open(config->links[i]->areafix.autoCreateFile, O_RDWR | O_APPEND);
1400       if(k < 0)
1401       {
1402         printf("ERROR: link ");
1403         printAddr(&(config->links[i]->hisAka));
1404         printf(" areafixAutoCreateFile '%s': %s\n",
1405                config->links[i]->areafix.autoCreateFile, strerror(errno));
1406         exit(-1);
1407       }
1408       else
1409         close(k);
1410     }
1411     if(config->links[i]->filefix.autoCreateFile)
1412     {
1413       k = open(config->links[i]->filefix.autoCreateFile, O_RDWR | O_APPEND);
1414       if(k < 0)
1415       {
1416         printf("ERROR: link ");
1417         printAddr((&config->links[i]->hisAka));
1418         printf(" filefixAutoCreateFile '%s': %s\n",
1419                config->links[i]->filefix.autoCreateFile, strerror(errno));
1420         exit(-1);
1421       }
1422       else
1423         close(k);
1424     }
1425     /* Check for absence of passthrough token in autoCreateDefaults */
1426     if(config->links[i]->areafix.autoCreateDefaults)
1427     {
1428       if(strstr(strLower(config->links[i]->areafix.autoCreateDefaults), passthrough))
1429       {
1430         printf("ERROR: areafixAutoCreateDefaults for");
1431         printAddr((&config->links[i]->hisAka));
1432         printf("contains 'passthrough' keyword\n");
1433         rc++;
1434       }
1435     }
1436     if(config->links[i]->filefix.autoCreateDefaults)
1437     {
1438       if(strstr(strLower(config->links[i]->filefix.autoCreateDefaults), passthrough))
1439       {
1440         printf("ERROR: filefixAutoCreateDefaults for");
1441         printAddr((&config->links[i]->hisAka));
1442         printf("contains 'passthrough' keyword\n");
1443         rc++;
1444       }
1445     }
1446   }
1447 
1448   for(i = 0; i < config->echoAreaCount; i++)
1449   {
1450 
1451     area = &(config->echoAreas[i]);
1452     areaName = area->areaName;
1453 
1454     if(config->robotsArea && sstricmp(config->robotsArea, areaName) == 0)
1455       robotsarea_ok = 1;
1456 
1457     /*    j=i+1 */
1458     for(j = i + 1; j < config->echoAreaCount; j++)
1459     {
1460       if(stricmp(config->echoAreas[j].areaName, areaName) == 0)
1461       {
1462         printf("ERROR: duplication of echoarea %s\n", areaName);
1463         exit(-1);
1464       }
1465     }
1466 
1467     for(j = 0; j < config->localAreaCount; j++)
1468     {
1469       if(stricmp(config->localAreas[j].areaName, areaName) == 0)
1470       {
1471         printf("ERROR: duplication of echoarea %s\n", areaName);
1472         exit(-1);
1473       }
1474     }
1475 
1476     for(j = 0; j < config->netMailAreaCount; j++)
1477     {
1478       if(stricmp(config->netMailAreas[j].areaName, areaName) == 0)
1479       {
1480         printf("ERROR: duplication of echoarea %s\n", areaName);
1481         exit(-1);
1482       }
1483     }
1484 
1485     /*  Check for area link duplication */
1486     for(j = 0; j + 1 < area->downlinkCount; j++)
1487     {
1488       link = area->downlinks[j]->link;
1489       for(m = j + 1; m < area->downlinkCount; m++)
1490       {
1491         if(link == area->downlinks[m]->link)
1492         {
1493           printf("ERROR: duplication of link ");
1494           printAddr(&(link->hisAka));
1495           printf(" in echoarea %s\n", areaName);
1496           exit(-1);
1497         }
1498       }
1499     }
1500     /* Check for echoloop */
1501     if(area->useAka->point)
1502     {
1503       hs_addr areaboss = *area->useAka;
1504 
1505       areaboss.point = 0;
1506       for(j = 0; j < area->downlinkCount; j++)
1507       {
1508         ps_link link = area->downlinks[j]->link;
1509 
1510         if((link->hisAka.point == 0) && addrComp(link->hisAka, areaboss))
1511         {
1512           printf("WARNING: echoarea %s is subscribed to ", areaName);
1513           printAddr(&(link->hisAka));
1514           printf(". This node is not boss-node of your AKA ");
1515           printAddr(area->useAka);
1516           printf
1517               (" used in this echo! Echo loop or seen-by lock is possible.\n");
1518         }
1519       }
1520     }
1521   }
1522 
1523   for(i = 0; i < config->localAreaCount; i++)
1524   {
1525 
1526     area = &(config->localAreas[i]);
1527     areaName = config->localAreas[i].areaName;
1528 
1529     if(config->robotsArea && sstricmp(config->robotsArea, areaName) == 0)
1530       robotsarea_ok = 1;
1531 
1532     for(j = 0; j < config->echoAreaCount; j++)
1533     {
1534       if(stricmp(config->echoAreas[j].areaName, areaName) == 0)
1535       {
1536         printf("ERROR: duplication of local area %s\n", areaName);
1537         exit(-1);
1538       }
1539     }
1540 
1541     /*    j=i+1 */
1542     for(j = i + 1; j < config->localAreaCount; j++)
1543     {
1544       if(stricmp(config->localAreas[j].areaName, areaName) == 0)
1545       {
1546         printf("ERROR: duplication of local area %s\n", areaName);
1547         exit(-1);
1548       }
1549     }
1550 
1551     for(j = 0; j < config->netMailAreaCount; j++)
1552     {
1553       if(stricmp(config->netMailAreas[j].areaName, areaName) == 0)
1554       {
1555         printf("ERROR: duplication of local area %s\n", areaName);
1556         exit(-1);
1557       }
1558     }
1559 
1560     /*  Check for area link duplication */
1561     for(j = 0; j + 1 < area->downlinkCount; j++)
1562     {
1563       link = area->downlinks[j]->link;
1564       for(m = j + 1; m < area->downlinkCount; m++)
1565       {
1566         if(link == area->downlinks[m]->link)
1567         {
1568           printf("ERROR: duplication of link ");
1569           printAddr(&(link->hisAka));
1570           printf(" in local area %s\n", areaName);
1571           exit(-1);
1572         }
1573       }
1574     }
1575   }
1576 
1577   for(i = 0; i < config->netMailAreaCount; i++)
1578   {
1579 
1580     area = &(config->netMailAreas[i]);
1581     areaName = config->netMailAreas[i].areaName;
1582 
1583     if(config->robotsArea && sstricmp(config->robotsArea, areaName) == 0)
1584       robotsarea_ok = 1;
1585 
1586     for(j = 0; j < config->echoAreaCount; j++)
1587     {
1588       if(stricmp(config->echoAreas[j].areaName, areaName) == 0)
1589       {
1590         printf("ERROR: duplication of netmail area %s\n", areaName);
1591         exit(-1);
1592       }
1593     }
1594 
1595     for(j = 0; j < config->localAreaCount; j++)
1596     {
1597       if(stricmp(config->localAreas[j].areaName, areaName) == 0)
1598       {
1599         printf("ERROR: duplication of netmail area %s\n", areaName);
1600         exit(-1);
1601       }
1602     }
1603 
1604     /*    j=i+1 */
1605     for(j = i + 1; j < config->netMailAreaCount; j++)
1606     {
1607       if(stricmp(config->netMailAreas[j].areaName, areaName) == 0)
1608       {
1609         printf("ERROR: duplication of netmail area %s\n", areaName);
1610         exit(-1);
1611       }
1612     }
1613 
1614     /*  Check for area link duplication */
1615     for(j = 0; j + 1 < area->downlinkCount; j++)
1616     {
1617       link = area->downlinks[j]->link;
1618       for(m = j + 1; m < area->downlinkCount; m++)
1619       {
1620         if(link == area->downlinks[m]->link)
1621         {
1622           printf("ERROR: duplication of link");
1623           printAddr(&(link->hisAka));
1624           printf("in netmail area %s\n", areaName);
1625           exit(-1);
1626         }
1627       }
1628     }
1629   }
1630   if(!robotsarea_ok)
1631   {
1632     printf("ERROR: robotsarea value is not an existing area\n");
1633     exit(-1);
1634   }
1635 
1636   {/* Check Remap rules */
1637     int c;
1638     for (c=0;c<config->remapCount;c++) {
1639       const char *testresult = NULL;
1640       if (config->remaps[c].oldaddr.zone>0)
1641         testresult = testAddr(&(config->remaps[c].oldaddr));
1642       if (testresult) {
1643         printf("Remap rule %i, old destination address %s\n", c+1, testresult);
1644         rc++;
1645       }
1646       testresult = testAddr(&(config->remaps[c].newaddr));
1647       if (testresult) {
1648         printf("Remap rule %i, new destination address %s\n", c+1, testresult);
1649         rc++;
1650       }
1651     }
1652   }
1653 
1654   /* Check Routing rules */
1655   {
1656     ps_route aroute;
1657     int c,i;
1658     for (c=0; c<config->routeCount; c++) {
1659       aroute = &(config->route[c]);
1660       for (i=c+1;i<config->routeCount; i++) {
1661         if ( (aroute->id==id_route || config->route[i].id==id_route || aroute->id==config->route[i].id)
1662            && (stricmp(aroute->pattern,config->route[i].pattern)==0) ) {
1663           if (aroute->id==config->route[i].id) {
1664             printf( "Warning! Duplicate route%s%s %s via ",
1665                     aroute->id==id_routeMail?"mail":"",
1666                     aroute->id==id_routeFile?"file":"", aroute->pattern);
1667           } else {
1668             printf( "Warning! Duplicate route%s%s and route%s%s %s via ",
1669                     aroute->id==id_routeMail?"mail":"",
1670                     aroute->id==id_routeFile?"file":"",
1671                     config->route[i].id==id_routeMail?"mail":"",
1672                     config->route[i].id==id_routeFile?"file":"",
1673                     aroute->pattern);
1674           }
1675           if ( config->route[i].target!=aroute->target &&
1676                ( !config->route[i].target || !aroute->target ||
1677                  addrComp(config->route[i].target->hisAka, aroute->target->hisAka)
1678              ) ) {
1679             printf("different links (targets): ");
1680             printRouteTarget(*aroute);
1681             printf(" and ");
1682             printRouteTarget(config->route[i]);
1683           } else {
1684             printRouteTarget(*aroute);
1685           }
1686           printf("\n");
1687         }
1688       }
1689     }
1690   }
1691 
1692   return rc;
1693 }
1694 
printCarbons(s_fidoconfig * config)1695 void printCarbons(s_fidoconfig * config)
1696 {
1697 
1698   unsigned i;
1699   s_carbon *cb;
1700   char *crbKey = "", *nspc, *cbaName, *tempc = NULL;
1701 
1702   printf("\n=== CarbonCopy ===\n");
1703   printf("CarbonAndQuit %s\n", (config->carbonAndQuit) ? "on" : "off");
1704   printf("CarbonKeepSb %s\n", (config->carbonKeepSb) ? "on" : "off");
1705   printf("CarbonOut %s\n", (config->carbonOut) ? "on" : "off");
1706   printf("ExcludePassthroughCarbon %s\n",
1707          (config->exclPassCC) ? "on" : "off");
1708   printf("Exclude \" * Forward from area \" string: %s\n\n",
1709          (config->carbonExcludeFwdFrom) ? "on" : "off");
1710 
1711   for(i = 0, cb = &(config->carbons[0]); i < config->carbonCount; i++, cb++)
1712   {
1713 
1714     if(cb->rule & CC_NOT)
1715     {
1716       nspc = "";
1717       printf("|NOT ");
1718     }
1719     else
1720       nspc = "|    ";
1721 
1722     switch (cb->ctype)
1723     {
1724       case ct_to:
1725         crbKey = "To:       ";
1726         break;
1727       case ct_from:
1728         crbKey = "From:     ";
1729         break;
1730       case ct_kludge:
1731         crbKey = "Kludge:   ";
1732         break;
1733       case ct_subject:
1734         crbKey = "Subj:     ";
1735         break;
1736       case ct_msgtext:
1737         crbKey = "Text:     ";
1738         break;
1739       case ct_fromarea:
1740         crbKey = "FromArea: ";
1741         break;
1742       case ct_group:
1743         crbKey = "Groups:   ";
1744         break;
1745       case ct_addr:
1746         crbKey = "Addr:     ";
1747         break;
1748       default:
1749         break;
1750     }
1751 
1752     printf("%sCarbon%s\"%s\"\n", nspc, crbKey,
1753            (cb->ctype == ct_addr) ? (tempc = aka2str5d(cb->addr)) : cb->str);
1754     nfree(tempc);
1755     if(cb->rule & CC_AND)
1756       continue;
1757 
1758     if(cb->areaName != NULL)
1759     {
1760       cbaName = cb->areaName;
1761       if(*cbaName == '*')
1762         ++cbaName;
1763     }
1764     else
1765       cbaName = "UNKNOWN";
1766     if(cb->extspawn)
1767       printf("CarbonExtern: \"%s\"", cbaName);
1768     else
1769     {
1770 
1771       switch (cb->move)
1772       {
1773         case 0:
1774           printf("CarbonCopy:          ");
1775           break;
1776         case 2:
1777           printf("CarbonDelete");
1778           break;
1779         case 1:
1780         default:
1781           printf("CarbonMove:          ");
1782           break;
1783       }
1784       if(cb->areaName)
1785       {
1786         if(stricmp(cbaName, cb->area->areaName))
1787         {
1788           printf(" !!! \"%s\" wanted !!! using \"%s\"", cbaName,
1789                  cb->area->areaName);
1790         }
1791         else
1792         {
1793           printf("\"%s\"", cb->area->areaName);
1794         }
1795       }
1796       else if(cb->move != 2)
1797         printf(" !!! No area specified !!!");
1798     }
1799     putchar('\n');
1800     if(cb->reason)
1801       printf("CarbonReason:   %s\n", cb->reason);
1802     if(cb->aexport)
1803       printf("Copied messages will be exported.\n");
1804     if(cb->netMail)
1805       printf("Active on netMail\n");
1806     if(cb->areaName != NULL)
1807       if(*cb->areaName == '*')
1808         printf("CarbonAndQuit ignored.\n");
1809     printf("-------\n");
1810   }
1811 }
1812 
printRemaps(s_fidoconfig * config)1813 void printRemaps(s_fidoconfig * config)
1814 {
1815   unsigned i;
1816 
1817   printf("\n=== Remap config ===\n");
1818   for(i = 0; i < config->remapCount; i++)
1819   {
1820     printf("ToName: \"%s\" and ToAddress:",
1821            sstrlen(config->remaps[i].toname) ? config->remaps[i].
1822            toname : "<any name>");
1823     if(config->remaps[i].oldaddr.zone == 0)
1824       printf(" <any address> ");
1825     else
1826       printAddr(&(config->remaps[i].oldaddr));
1827     printf("=>");
1828     printAddr(&(config->remaps[i].newaddr));
1829     putchar('\n');
1830   }
1831 }
1832 
printSeqOutrun(unsigned long seqOutrun)1833 void printSeqOutrun(unsigned long seqOutrun)
1834 {
1835   if(seqOutrun % (365l * 24 * 60 * 60) == 0)
1836     printf("seqOutrun: %luy\n", seqOutrun / (365l * 24 * 60 * 60));
1837   else if(seqOutrun % (31l * 24 * 60 * 60) == 0)
1838     printf("seqOutrun: %lum\n", seqOutrun / (31l * 24 * 60 * 60));
1839   else if(seqOutrun % (7l * 24 * 60 * 60) == 0)
1840     printf("seqOutrun: %luw\n", seqOutrun / (7l * 24 * 60 * 60));
1841   else if(seqOutrun % (24 * 60 * 60) == 0)
1842     printf("seqOutrun: %lud\n", seqOutrun / (24 * 60 * 60));
1843   else if(seqOutrun % (60 * 60) == 0)
1844     printf("seqOutrun: %luh\n", seqOutrun / (60 * 60));
1845   else
1846     printf("seqOutrun: %lu\n", seqOutrun);
1847 }
1848 
printListEcho(e_listEchoMode mode)1849 char *printListEcho(e_listEchoMode mode)
1850 {
1851   switch (mode)
1852   {
1853     case lemUnsorted:
1854       return "unsorted";
1855     case lemName:
1856       return "name";
1857     case lemUndef:
1858       return "name (default)";  /* default is equal to "name" */
1859     case lemGroup:
1860       return "group";
1861     case lemGroupName:
1862       return "group,name";
1863     default:
1864       return "unknown (try to update tparser)";
1865   }
1866 }
1867 
dumpcfg(char * fileName)1868 static int dumpcfg(char *fileName)
1869 {
1870   char *line;
1871 
1872   if(fileName == NULL)
1873     fileName = getConfigFileName();
1874 
1875   if(fileName == NULL)
1876   {
1877     printf("Could not find Config-file\n");
1878     return EX_UNAVAILABLE;
1879   }
1880 
1881   if(init_conf(fileName))
1882     return 0;
1883 
1884   while((line = configline()) != NULL)
1885   {
1886     line = trimLine(line);
1887     if(line[0] != 0)
1888     {
1889       line = shell_expand(line);
1890       line = vars_expand(line);
1891       puts(line);
1892     }
1893     else
1894       puts(line);
1895     nfree(line);
1896   }
1897 
1898   close_conf();
1899   /* nfree(fileName); */
1900   return 0;
1901 }
1902 
usage()1903 void usage()
1904 {
1905   printf("\tParses Fidoconfig, checks your Fidoconfig for errors and gives ");
1906   printf("you some\n\thints to solve the problems.\n\n");
1907   printf("run: tparser [-h|--help] [-Dvar=value] [-E] [-P] [/path/to/config/file]\n");
1908   printf("\tOptions:\n");
1909   printf("-h\tDisplay this help\n");
1910   printf("--help\tDisplay this help\n");
1911   printf("-Dvar=value\tSet the config variable 'var' to 'value'\n");
1912   printf("-E\tDump config to stdout\n");
1913   printf("-P\tTry to create non-existing directories\n");
1914   exit(0);
1915 }
1916 
main(int argc,char ** argv)1917 int main(int argc, char **argv)
1918 {
1919 /*   s_fidoconfig *config = NULL;  use global variable */
1920   unsigned i, j, hpt = 0, preproc = 0, rc = 0;
1921   int k;
1922   char *cfgFile = NULL, *module;
1923 
1924 #include "../cvsdate.h"
1925 
1926   SetAppModule(M_TPARSER);
1927   printf("%s\n", module = GenVersionStr("tparser", FC_VER_MAJOR, FC_VER_MINOR,
1928                                         FC_VER_PATCH, FC_VER_BRANCH,
1929                                         cvs_date));
1930   nfree(module);                /* used as a temporary variable */
1931 
1932   //if( !CheckFidoconfigVersion(1,9,0,BRANCH_CURRENT,cvs_date) ) {
1933   //  printf("Incompatible version of FIDOCONFIG library: require fidoconfig-1.9.0-current at %s\n",cvs_date);
1934   //  exit(255);
1935   //}
1936   //if( !CheckSmapiVersion(2,5,0,smapi_cvs_date()) ) {
1937   //  printf("Incompatible version of SMAPI: require smapi-2.5.0-current at %s\n",smapi_cvs_date());
1938   //  exit(255);
1939   //}
1940   //printf("using smapi-2.5.0-current at %s and fidoconfig-1.9.0-current at %s\n\n",smapi_cvs_date(),cvs_date);
1941 
1942   for(k = 1; k < argc; k++)
1943   {
1944     if(argv[k][0] != '-')
1945     {                           /* is not option */
1946       if(cfgFile)
1947         usage();
1948       else
1949         xstrcat(&cfgFile, argv[k]);
1950     }
1951     else if(argv[k][1] == 'D')
1952     {                           /* -Dvar=value */
1953       char *p = strchr(argv[k], '=');
1954 
1955       if(p)
1956       {
1957         *p = '\0';
1958         setvar(argv[k] + 2, p + 1);
1959         *p = '=';
1960       }
1961       else
1962       {
1963         setvar(argv[k] + 2, "");
1964       }
1965     }
1966     else if(argv[k][1] == 'E')
1967     {                           /* -E */
1968       preproc = 1;
1969     }
1970     else if(argv[k][1] == 'P')
1971     {                           /* -P */
1972       fc_trycreate = 1;
1973     }
1974     else if(stricmp(argv[k], "--help") == 0 || argv[k][1] == 'h'
1975             || cfgFile != NULL)
1976     {
1977       usage();
1978       return 0;
1979     }
1980   }
1981 
1982   if(cfgFile == NULL)
1983     cfgFile = getConfigFileName();
1984 
1985   if(cfgFile == NULL)
1986   {
1987     printf("Could not find Config-file\n");
1988     exit(EX_UNAVAILABLE);
1989   }
1990 
1991   module = getvar("module");
1992   printf("Test %s for ", cfgFile);
1993   if(module)
1994   {
1995     printf("module: %s\n", module);
1996     if(stricmp(module, "hpt") == 0)
1997       hpt = 1;
1998   }
1999   else
2000     printf("all modules\n");
2001 
2002   if(preproc)
2003     return dumpcfg(cfgFile);
2004 
2005   config = readConfig(cfgFile);
2006   /* nfree(cfgFile); */
2007 
2008   if(config != NULL)
2009   {
2010 
2011     rc += checkLogic(config);
2012     rc += testConfig(config);
2013     printf("=== MAIN CONFIG ===\n");
2014     printf("Version: %u.%u\n", config->cfgVersionMajor,
2015            config->cfgVersionMinor);
2016     if(config->name != NULL)
2017       printf("Name:     %s\n", config->name);
2018     if(config->sysop != NULL)
2019       printf("Sysop:    %s\n", config->sysop);
2020     if(config->location != NULL)
2021       printf("Location: %s\n", config->location);
2022     for(i = 0; i < config->addrCount; i++)
2023     {
2024       if(config->addr[i].domain[0])
2025         printf("Addr: %u:%u/%u.%u@%s\n", config->addr[i].zone,
2026                config->addr[i].net, config->addr[i].node,
2027                config->addr[i].point, config->addr[i].domain);
2028       else
2029         printf("Addr: %u:%u/%u.%u\n", config->addr[i].zone,
2030                config->addr[i].net, config->addr[i].node,
2031                config->addr[i].point);
2032     }
2033 
2034 #if defined(__UNIX__)
2035     printf("FileAreaCreatePerms: %o\n", config->fileAreaCreatePerms);
2036 #endif
2037     if(config->loglevels)
2038       printf("LogLevels %s\n", config->loglevels);
2039     printf("LogEchoToScreen %s\n", (config->logEchoToScreen) ? "on" : "off");
2040     if(config->logEchoToScreen && config->screenloglevels)
2041       printf("ScreenLogLevels %s\n", config->screenloglevels);
2042 
2043     if(config->echotosslog != NULL)
2044       printf("EchoTossLog:     %s\n", config->echotosslog);
2045     if(config->importlog != NULL)
2046       printf("ImportLog:       %s\n", config->importlog);
2047     if(config->statlog != NULL)
2048       printf("StatLog:         %s\n", config->statlog);
2049 
2050     if(config->inbound != NULL)
2051       printf("Inbound:         %s\n", config->inbound);
2052     if(config->tempInbound != NULL)
2053       printf("tempInbound:     %s\n", config->tempInbound);
2054     if(config->protInbound != NULL)
2055       printf("ProtInbound:     %s\n", config->protInbound);
2056     if(config->localInbound != NULL)
2057       printf("LocalInbound:    %s\n", config->localInbound);
2058     if(config->listInbound != NULL)
2059       printf("ListInbound:     %s\n", config->listInbound);
2060     if(config->ticOutbound != NULL)
2061       printf("TicOutbound:     %s\n", config->ticOutbound);
2062     if(config->outbound != NULL)
2063       printf("Outbound:        %s\n", config->outbound);
2064     if(config->tempOutbound != NULL)
2065       printf("tempOutbound:    %s\n", config->tempOutbound);
2066     for(i = 0; i < config->publicCount; i++)
2067       printf("Public: #%u %s\n", i + 1, config->publicDir[i]);
2068     if(config->reqidxDir)
2069       printf("ReqIdxDir:       %s\n", config->reqidxDir);
2070     if(config->dupeHistoryDir != NULL)
2071       printf("DupeHistoryDir:  %s\n", config->dupeHistoryDir);
2072     if(config->logFileDir != NULL)
2073       printf("LogFileDir:      %s\n", config->logFileDir);
2074     if(config->tempDir != NULL)
2075       printf("TempDir:      %s\n", config->tempDir);
2076     if(config->msgBaseDir != NULL)
2077       printf("MsgBaseDir:      %s\n", config->msgBaseDir);
2078     printf("RecodeMsgBase: %s\n", config->recodeMsgBase ? "on" : "off");
2079     if(config->fileAreaBaseDir)
2080       printf("FileAreaBaseDir: %s\n", config->fileAreaBaseDir);
2081     if(config->passFileAreaDir)
2082       printf("passFileAreaDir: %s\n", config->passFileAreaDir);
2083     if(config->busyFileDir)
2084       printf("busyFileDir:     %s\n", config->busyFileDir);
2085     if(config->magic)
2086       printf("Magic: %s\n", config->magic);
2087     if(config->semaDir)
2088       printf("semaDir:         %s\n", config->semaDir);
2089     if(config->badFilesDir)
2090       printf("BadFilesDir:     %s\n", config->badFilesDir);
2091     if(config->advStatisticsFile)
2092       printf("advStatisticsFile:       %s\n", config->advStatisticsFile);
2093     if(config->hptPerlFile)
2094       printf("hptPerlFile:     %s\n", config->hptPerlFile);
2095     if(config->netmailFlag)
2096       printf("NetmailFlag:     %s\n", config->netmailFlag);
2097     if(config->minDiskFreeSpace)
2098       printf("MinDiskFreeSpace: %u Mb\n", config->minDiskFreeSpace);
2099     if(config->syslogFacility)
2100       printf("SyslogFacility: %d\n", config->syslogFacility);
2101 
2102     if(config->lockfile)
2103     {
2104       printf("LockFile: %s\n", config->lockfile);
2105       if(config->advisoryLock == 0)
2106         printf("AdvisoryLock: off\n");
2107       else
2108         printf("AdvisoryLock: %u\n", config->advisoryLock);
2109     }
2110 
2111     if(hpt == 0)
2112     {
2113       printf("LongDirNames: %s\n", (config->longDirNames) ? "on" : "off");
2114       printf("SplitDirs: %s\n", (config->splitDirs) ? "on" : "off");
2115     }
2116 
2117     printf("Ignore Capability Word: %s\n",
2118            (config->ignoreCapWord) ? "on" : "off");
2119     printf("ProcessBundles %s\n", (config->noProcessBundles) ? "off" : "on");
2120     switch (config->bundleNameStyle)
2121     {
2122       case eUndef:
2123         printf("BundleNameStyle: undefined (timeStamp)\n");
2124         break;
2125       case eAddrDiff:
2126         printf("BundleNameStyle: addrDiff\n");
2127         break;
2128       case eAddrDiffAlways:
2129         printf("BundleNameStyle: addrDiffAlways\n");
2130         break;
2131       case eTimeStamp:
2132         printf("BundleNameStyle: timeStamp\n");
2133         break;
2134       case eAmiga:
2135         printf("BundleNameStyle: Amiga\n");
2136         break;
2137       case eAddrsCRC32:
2138         printf("BundleNameStyle: AddrsCRC32\n");
2139         break;
2140       case eAddrsCRC32Always:
2141         printf("BundleNameStyle: AddrsCRC32Always\n");
2142         break;
2143       default:
2144         printf
2145             ("Warning: BundleNameStyle is UNKNOWN! Please update tparser!\n");
2146         break;
2147 
2148     }
2149 
2150     if(config->fileBoxesDir)
2151       printf("fileBoxesDir: %s\n", config->fileBoxesDir);
2152     printf("DupeBaseType: ");
2153     if(config->typeDupeBase == textDupes)
2154       printf("textDupes\n");
2155     if(config->typeDupeBase == hashDupes)
2156       printf("hashDupes\n");
2157     if(config->typeDupeBase == hashDupesWmsgid)
2158       printf("hashDupesWmsgid\n");
2159     if(config->typeDupeBase == commonDupeBase)
2160     {
2161       printf("commonDupeBase\n");
2162       printf("AreasMaxDupeAge: %d\n", config->areasMaxDupeAge);
2163     }
2164 
2165     if(config->numPublicGroup > 0)
2166     {
2167       printf("PublicGroups: ");
2168       for(i = 0; i < config->numPublicGroup; i++)
2169         printf((i > 0) ? ",%s" : "%s", config->PublicGroup[i]);
2170       printf("\n");
2171     }
2172 
2173     printf("createAreasCase: %s\n",
2174            (config->createAreasCase == eLower) ? "Lower" : "Upper");
2175     printf("areasFileNameCase: %s\n",
2176            (config->areasFileNameCase == eLower) ? "Lower" : "Upper");
2177     printf("disableKludgeRescanned: %s\n",
2178            (config->disableKludgeRescanned) ? "on" : "off");
2179     printf("DisableTID: %s\n", (config->disableTID) ? "on" : "off");
2180     printf("DisablePID: %s\n", (config->disablePID) ? "on" : "off");
2181     printf("keepTrsMail: %s\n", (config->keepTrsMail) ? "on" : "off");
2182     printf("keepTrsFiles: %s\n", (config->keepTrsFiles) ? "on" : "off");
2183     printf("createFwdNonPass: %s\n", config->createFwdNonPass ? "on" : "off");
2184 #if defined ( __NT__ )
2185     printf("SetConsoleTitle: %s\n", (config->setConsoleTitle) ? "on" : "off");
2186 #endif
2187     if(config->processPkt != NULL)
2188       printf("processPkt: %s\n", config->processPkt);
2189     if(config->tossingExt != NULL)
2190       printf("tossingExt: %s\n", config->tossingExt);
2191 
2192     if(config->seqDir != NULL)
2193       printf("seqDir: %s\n", config->seqDir);
2194     if(config->seqOutrun != 0)
2195       printSeqOutrun(config->seqOutrun);
2196 
2197     if(config->addToSeenCount)
2198     {
2199       printf("AddToSeen:");
2200       for(i = 0; i < config->addToSeenCount; i++)
2201       {
2202         printf(" %u/%u", config->addToSeen[i].net, config->addToSeen[i].node);
2203       }
2204       printf("\n");
2205     }
2206     if(config->ignoreSeenCount)
2207     {
2208       printf("IgnoreSeen:");
2209       for(i = 0; i < config->ignoreSeenCount; i++)
2210       {
2211         printf(" %u/%u", config->ignoreSeen[i].net,
2212                config->ignoreSeen[i].node);
2213       }
2214       printf("\n");
2215     }
2216 
2217     if(config->tearline || config->origin)
2218       printf("\n");
2219     if(config->tearline)
2220       printf("--- %s\n", config->tearline);
2221     if(config->origin)
2222       printf("* Origin: %s (%s)\n", config->origin, aka2str(config->addr[0]));
2223     printf("AutoPassive: %s\n", config->autoPassive ? "on" : "off");
2224     printf("sortEchoList: %s\n", printListEcho(config->listEcho));
2225     printf("packNetMailOnScan: %s\n",
2226            config->packNetMailOnScan ? "on" : "off");
2227     printf("NotValidFileNameChars: %s\n",
2228            config->notValidFNChars ? config->
2229            notValidFNChars : "\"*/:;<=>?\\|%`'&+");
2230 
2231     printf("\n=== AREAFIX CONFIG ===\n");
2232     printf("areafixFromPkt: %s\n", (config->areafixFromPkt) ? "on" : "off");
2233     printf("RobotsArea: %s\n",
2234            (config->robotsArea) ? config->robotsArea : "all areas");
2235     if(config->ReportTo)
2236       printf("ReportTo: %s\n", config->ReportTo);
2237     printf("ReportRequester: %s\n", config->reportRequester ? "on" : "off");
2238 
2239 
2240     if(hpt == 0)
2241     {
2242       printf("\n=== TICKER CONFIG ===\n");
2243       printf("fileDescription: %s\n", config->fileDescription);
2244       /* not used
2245        * if (config->fileAreasLog) printf("FileAreasLog: %s\n", config->fileAreasLog);
2246        * if (config->fileNewAreasLog) printf("FileNewAreasLog: %s\n", config->fileNewAreasLog);
2247        * if (config->fileArcList) printf("FileArcList: %s\n", config->fileArcList);
2248        * if (config->filePassList) printf("FileArcList: %s\n", config->filePassList);
2249        * if (config->fileDupeList) printf("FileArcList: %s\n", config->fileDupeList);
2250        */
2251       /* not used
2252        * printf("FileSingleDescLine: %s\n",(config->fileSingleDescLine) ? "on": "off");
2253        * printf("FileCheckDest: %s\n",(config->fileCheckDest) ? "on": "off");
2254        */
2255 
2256       if(config->fDescNameCount)
2257       {
2258         for(i = 0; i < config->fDescNameCount; i++)
2259           printf("FileDescName: %s\n", config->fileDescNames[i]);
2260       }
2261       else
2262       {
2263         printf("FileDescName: off\n");
2264       }
2265 
2266       printf("AddDLC: %s\n", (config->addDLC) ? "on" : "off");
2267 
2268       printf("FileDescPos: %u\n", config->fileDescPos);
2269       if(config->fileLDescString)
2270         printf("FileLDescString: %s\n", config->fileLDescString);
2271       printf("DLCDigits: %u\n", config->DLCDigits);
2272       /* not used
2273        * printf("FileMaxDupeAge: %u\n", config->fileMaxDupeAge);
2274        * printf("FileFileUMask: %o\n", config->fileFileUMask);
2275        * printf("FileDirUMask: %o\n", config->fileDirUMask);
2276        * if (config->fileLocalPwd) printf("FileLocalPwd: %s\n", config->fileLocalPwd);
2277        */
2278       if(config->saveTicCount)
2279       {
2280         for(i = 0; i < config->saveTicCount; i++)
2281         {
2282           printf("SaveTic for %s in %s\n",
2283                  config->saveTic[i].fileAreaNameMask,
2284                  config->saveTic[i].pathName);
2285         }
2286       }
2287       printf("\n=== FILE ANNOUNCER CONFIG ===\n");
2288       if(config->announceSpool)
2289         printf("AnnounceSpool: %s\n", config->announceSpool);
2290       if(config->ADCount)
2291       {
2292         for(i = 0; i < config->ADCount; i++)
2293         {
2294           printf("\n----- announce group -----\n");
2295           if(config->AnnDefs[i].annAreaTag)
2296             printf("AnnAreaTag: %s\n", config->AnnDefs[i].annAreaTag);
2297           if(config->AnnDefs[i].annInclude == NULL)
2298             printf("AnnInclude: *\n");
2299           else
2300           {
2301             printf("AnnInclude:");
2302             for(j = 0; j < config->AnnDefs[i].numbI; j++)
2303             {
2304               printf(" %s", config->AnnDefs[i].annInclude[j]);
2305             }
2306             printf("\n");
2307           }
2308           if(config->AnnDefs[i].annExclude != NULL)
2309           {
2310             printf("AnnExclude:");
2311             for(j = 0; j < config->AnnDefs[i].numbE; j++)
2312             {
2313               printf(" %s", config->AnnDefs[i].annExclude[j]);
2314             }
2315             printf("\n");
2316           }
2317           if(config->AnnDefs[i].annto)
2318             printf("AnnTo     : %s\n", config->AnnDefs[i].annto);
2319           if(config->AnnDefs[i].annfrom)
2320             printf("AnnFrom   : %s\n", config->AnnDefs[i].annfrom);
2321           if(config->AnnDefs[i].annaddrto)
2322           {
2323             printf("AnnAddrTo : ");
2324             printAddr(config->AnnDefs[i].annaddrto);
2325             printf("\n");
2326           }
2327           if(config->AnnDefs[i].annaddrfrom)
2328           {
2329             printf("AnnAddrFrom: ");
2330             printAddr(config->AnnDefs[i].annaddrfrom);
2331             printf("\n");
2332           }
2333           if(config->AnnDefs[i].annsubj)
2334             printf("AnnSubj   : %s\n", config->AnnDefs[i].annsubj);
2335           if(config->AnnDefs[i].annorigin)
2336           {
2337             printf("AnnOrigin : %s\n          \" * Origin: %s (",
2338                    config->AnnDefs[i].annorigin,
2339                    config->AnnDefs[i].annorigin);
2340             printAddr(config->AnnDefs[i].annaddrfrom);
2341             printf(")\"\n");
2342           }
2343           if(config->AnnDefs[i].annorigin)
2344             printf("AnnMessFlags : %s\n", config->AnnDefs[i].annmessflags);
2345 
2346           printf("AnnFileOrigin: %s\n",
2347                  config->AnnDefs[i].annforigin ? "on" : "off");
2348           printf("AnnFileRFrom : %s\n",
2349                  config->AnnDefs[i].annfrfrom ? "on" : "off");
2350 
2351         }
2352       }
2353     }
2354     printf("\n=== FILELIST CONFIG ===\n");
2355     for(i = 0; i < config->filelistCount; i++)
2356       printFilelist(&(config->filelists[i]));
2357 
2358     printf("\n=== LINKER CONFIG ===\n");
2359     switch (config->LinkWithImportlog)
2360     {
2361       case lwiYes:
2362         printf("LinkWithImportlog   Yes\n");
2363         break;
2364 
2365       case lwiNo:
2366         printf("LinkWithImportlog   No\n");
2367         break;
2368 
2369       case lwiKill:
2370         printf("LinkWithImportlog   Kill\n");
2371         break;
2372 
2373       default:
2374         printf
2375             ("Internal error: Unknown value #%d for LinkWithImportLog!\n",
2376              config->LinkWithImportlog);
2377     }
2378 
2379     printf("\n=== ROBOT PARAMETERS ===\n");
2380     printf("%u robots in config\n", config->robotCount);
2381     for(i = 0; i < config->robotCount; i++)
2382       printRobot(config->robot[i]);
2383 
2384     printf("\n=== LINK CONFIG ===\n");
2385     printf("%u links in config\n", config->linkCount);
2386     for(i = 0; i < config->linkCount; i++)
2387       printLink(config->links[i]);
2388 
2389     printf("\n=== AREA GROUPS ===\n");
2390     for(i = 0; i < config->groupCount; i++)
2391       printf("  %s - %s\n", config->group[i].name, config->group[i].desc);
2392 
2393     printf("\n=== AREA CONFIG ===\n");
2394 
2395     printf("kludgeAreaNetmail ");
2396     switch (config->kludgeAreaNetmail)
2397     {
2398       case kanKill:
2399         printf("kill");
2400         break;
2401       case kanIgnore:
2402         printf("ignore");
2403         break;
2404       case kanEcho:
2405         printf("echomail");
2406         break;
2407       default:
2408         break;
2409     }
2410     printf("\n");
2411 
2412     printf("\n=== NetMailAreas ===\n");
2413     for(i = 0; i < config->netMailAreaCount; i++)
2414     {
2415       printArea(config->netMailAreas[i]);
2416     }
2417     printf("\n=== DupeMailArea ===\n");
2418     if(config->dupeArea.areaName)
2419       printArea(config->dupeArea);
2420     printf("\n=== BadMailArea ===\n");
2421     if(config->badArea.areaName)
2422       printArea(config->badArea);
2423 
2424     printf("\n=== AreaGroups ===\n");
2425     tree_trav(&groupTree, &printAreaGroup);
2426     printf("\n==================\n");
2427 
2428     printf("\n=== EchoAreas ===\n");
2429     for(i = 0; i < config->echoAreaCount; i++)
2430     {
2431       printArea(config->echoAreas[i]);
2432     }
2433     printf("\n=== LocalAreas ===\n");
2434     for(i = 0; i < config->localAreaCount; i++)
2435     {
2436       printArea(config->localAreas[i]);
2437     }
2438 
2439     if(hpt == 0)
2440     {
2441       printf("\n=== FileAreas ===\n");
2442       for(i = 0; i < config->fileAreaCount; i++)
2443       {
2444         printFileArea(config->fileAreas[i]);
2445       }
2446       printf("\n=== BbsAreas ===\n");
2447       for(i = 0; i < config->bbsAreaCount; i++)
2448       {
2449         printBbsArea(config->bbsAreas[i]);
2450       }
2451     }
2452 
2453 
2454     if(config->carbonCount)
2455       printCarbons(config);
2456 
2457     if(config->remapCount)
2458       printRemaps(config);
2459 
2460     printf("\n=== ROUTE CONFIG ===\n");
2461     for(i = 0; i < config->routeCount; i++)
2462     {
2463       if(config->route[i].routeVia == 0)
2464       {
2465         printf("Route %s via", config->route[i].pattern);
2466         printAddr(&(config->route[i].target->hisAka));
2467       }
2468       else
2469       {
2470         printf("Route");
2471         switch (config->route[i].id)
2472         {
2473           case id_route:
2474             break;
2475           case id_routeMail:
2476             printf("Mail");
2477             break;
2478           case id_routeFile:
2479             printf("File");
2480             break;
2481         }
2482         printf(" %s ", config->route[i].pattern);
2483         switch (config->route[i].routeVia)
2484         {
2485           case route_zero:
2486             printf("zero ");
2487             break;
2488           case noroute:
2489             printf("direct ");
2490             break;
2491           case nopack:
2492             printf("nopack ");
2493             break;
2494           case host:
2495             printf("via host");
2496             break;
2497           case hub:
2498             printf("via hub  ");
2499             break;
2500           case boss:
2501             printf("via boss ");
2502             break;
2503           case route_extern:   /* internal only */
2504           default:
2505             break;
2506         }
2507       }
2508       if(config->route[i].routeVia != nopack)
2509         printf("(flavour: %s)\n", cvtFlavour(config->route[i].flavour));
2510     }
2511 
2512     if(hpt == 0)
2513     {
2514       printf("\n=== NODELIST CONFIG ===\n");
2515       if(config->nodelistDir != NULL)
2516       {
2517         printf("NodelistDir: %s\n", config->nodelistDir);
2518       }
2519       if(config->fidoUserList != NULL)
2520       {
2521         printf("Fidouser List File: %s\n", config->fidoUserList);
2522       }
2523       printf("-------\n");
2524 
2525       for(i = 0; i < config->nodelistCount; i++)
2526       {
2527         printf("Nodelist %s\n", config->nodelists[i].nodelistName);
2528         if(config->nodelists[i].diffUpdateStem != NULL)
2529           printf("Nodediff Update File %s\n",
2530                  config->nodelists[i].diffUpdateStem);
2531         printf("DelAppliedDiff: %s\n",
2532                (config->nodelists[i].delAppliedDiff) ? "on" : "off");
2533         if(config->nodelists[i].fullUpdateStem != NULL)
2534           printf("Full Nodelist Update File %s\n",
2535                  config->nodelists[i].fullUpdateStem);
2536         if(config->nodelists[i].defaultZone != 0)
2537           printf("Zone Number %d\n", config->nodelists[i].defaultZone);
2538         switch (config->nodelists[i].format)
2539         {
2540           case fts5000:
2541             printf("Standard nodelist format\n");
2542             break;
2543           case points24:
2544             printf("Points24 nodelist format\n");
2545             break;
2546           case points4d:
2547             printf("Points4D nodelist format\n");
2548             break;
2549           default:
2550             printf("Unknown nodelist format???\n");
2551             break;
2552         }
2553         printf("-------\n");
2554       }
2555     }
2556     printf("\n=== PACK CONFIG ===\n");
2557     for(i = 0; i < config->packCount; i++)
2558     {
2559       printf("Packer: %s      Call: %s\n", config->pack[i].packer,
2560              config->pack[i].call);
2561     }
2562     if(config->defarcmailSize != 0)
2563       printf("\nDefault Arcmail Size - %u kb\n", config->defarcmailSize);
2564     printf("\n=== UNPACK CONFIG ===\n");
2565     for(i = 0; i < config->unpackCount; i++)
2566     {
2567       printf("UnPacker:  Call: %s Offset %d Match code ",
2568              config->unpack[i].call, config->unpack[i].offset);
2569       for(k = 0; k < config->unpack[i].codeSize; k++)
2570         printf("%02x", (int)config->unpack[i].matchCode[k]);
2571       printf(" Mask : ");
2572       for(k = 0; k < config->unpack[i].codeSize; k++)
2573         printf("%02x", (int)config->unpack[i].mask[k]);
2574       printf("\n");
2575     }
2576 
2577     if(config->beforePack)
2578       printf("Before Pack - \"%s\"\n", config->beforePack);
2579     if(config->afterUnpack)
2580       printf("After Unpack - \"%s\"\n", config->afterUnpack);
2581 
2582     if(hpt == 0)
2583     {
2584       printf("\n=== EXEC CONFIG ===\n");
2585       for(i = 0; i < config->execonfileCount; i++)
2586       {
2587         printf("ExecOnFile: Area %s File %s Call %s\n",
2588                config->execonfile[i].filearea,
2589                config->execonfile[i].filename, config->execonfile[i].command);
2590       }
2591     }
2592 
2593     printf("\n=== EMAILPKT CONFIG ===\n");
2594     if(config->sendmailcmd)
2595     {
2596       printf("sendMailCmd: %s\n", config->sendmailcmd);
2597     }
2598     else
2599       printf("sendMailCmd:\n");
2600 
2601     printf("\n");
2602     rc += testPathsAndFiles();
2603 
2604     if(rc)
2605     {
2606       puts("============================");
2607       checkLogic(config);
2608       testConfig(config);
2609       puts("============================");
2610     }
2611 
2612     disposeConfig(config);
2613 
2614     if(rc)
2615       fprintf(stderr, "Attention, %u errors found!\n", rc);
2616   }                             /* endif */
2617 
2618   return rc;
2619 }
2620