1 /*****************************************************************************/
2 /*                                                                           */
3 /*                 (C) Copyright 1992-1997  Alberto Pasquale                 */
4 /*                 Portions (C) Copyright 1999 Per Lundberg                  */
5 /*                                                                           */
6 /*                   A L L   R I G H T S   R E S E R V E D                   */
7 /*                                                                           */
8 /*****************************************************************************/
9 /*                                                                           */
10 /* How to contact the author:  Alberto Pasquale of 2:332/504@fidonet         */
11 /*                             Viale Verdi 106                               */
12 /*                             41100 Modena                                  */
13 /*                             Italy                                         */
14 /*                                                                           */
15 /*****************************************************************************/
16 
17 #include <ctype.h>
18 
19 #include <limits.h>
20 #include <string.h>
21 
22 #ifdef __QNXNTO__
23    #include <strings.h>
24 #endif // __QNXNTO__
25 
26 #include <apgenlib.hpp>
27 #include <bbsgenlb.hpp>
28 #include "misc.hpp"
29 #include "data.hpp"
30 #include "parsecfg.hpp"
31 #include "parseglb.hpp"
32 
GetCostData(CfgFile & f,CO * tco)33 void GetCostData (CfgFile &f, CO *tco)
34 {
35     pcsz tok;
36 
37     tok = f.GetToken ();      // cost
38     if (tok)
39         tco->cost = (word) atoi (tok);
40     else
41         tco->cost = USHRT_MAX;
42 
43     tok = f.GetToken ();      // ucost
44     if (tok)
45         tco->ucost = (word) atoi (tok);
46     else
47         tco->ucost = tco->cost;
48                                            // cost/ucost assigned
49 
50     tok = f.GetToken ();      // costdig
51     if (!tok) {
52         tco->costdig  = tco->cost;
53         tco->ucostdig = tco->ucost;
54         return;
55     }
56 
57     tco->costdig = (word) atoi (tok);
58 
59     tok = f.GetToken ();      // ucostdig
60     if (tok)
61         tco->ucostdig = (word) atoi (tok);
62     else
63         tco->ucostdig = tco->costdig;
64 }
65 
66 
GetCostTable(CfgFile & f,CO ** co_head)67 void GetCostTable (CfgFile &f, CO **co_head)
68 {
69     CO **co; CO *tco;
70 
71     co = co_head;
72     tco = NULL;
73 
74     while (f.GetLn ()) {
75 
76         pcsz tok = f.GetToken ();
77 
78         if (strcasecmp (tok, "end") == 0)
79             break;
80         tco = *co = new CO;
81 
82         if (strcmp (tok, "-") == 0)
83             tok = NullStr;
84 
85         tco->mstr = newcpy (tok);       /* string to be substituted */
86 
87         GetCostData (f, tco);
88 
89         tco->next = NULL;
90         co = &(tco->next);
91     }
92 
93     if (!tco) {
94         vprintlog ("Cost table MUST NOT be empty !\n");
95         myexit (CFG_ERROR);
96     }
97 
98     if (*tco->mstr != '\0') {
99         vprintlog ("Last entry in Cost Table must have a single dash '-' as the first field !\n");
100         myexit (CFG_ERROR);
101     }
102 }
103 
104 
105 
GetDialPrePost(CfgFile & f,DL * tdl)106 void GetDialPrePost (CfgFile &f, DL *tdl)
107 {
108     pcsz tok2;
109     int itmp;
110 
111     pcsz tok = f.GetToken ();    // get prefix/suffix
112     if (!tok)
113         tok = NullStr;
114     itmp = strcspn (tok, "/");   /* find length of prefix */
115     tdl->pre = new char[itmp + 1];
116     strncpy (tdl->pre, tok, itmp);
117     *(tdl->pre+itmp) = '\0';
118 
119     tok2 = tok + itmp;
120     if (*tok2 == '/')     /* point to suffix */
121         tok2++;
122     tdl->post = newcpy (tok2);
123 }
124 
125 
GetDialTable(CfgFile & f,DL ** dl_head,BOOL GetCost)126 void GetDialTable (CfgFile &f, DL **dl_head, BOOL GetCost)
127 {
128     DL **dl = dl_head;
129     DL *tdl = NULL;
130     StrChain **pple = NULL;
131 
132     while (f.GetLn ()) { /* dial lines */
133 
134         pcsz tok = f.GetToken ();
135 
136         if (strcasecmp (tok, "LocalExchanges") == 0) {
137             if (!pple) {
138                 vprintlog ("LocalExchanges must follow some Dial translation entry !\n");
139                 CfgError (f);
140             }
141             while ((tok = f.GetToken ()) != NULL) {
142                 *pple = new StrChain;
143                 (*pple)->text = newcpy (tok);
144                 pple = &(*pple)->next;
145             }
146             *pple = NULL;     // close the list
147             continue;
148         }
149 
150         if (strcasecmp (tok, "LocalValues") == 0) {
151             tok = f.GetToken ();               // Ignore "LocalValues"
152             if (!tok)
153                 continue;
154         }
155 
156         if (strcasecmp (tok, "end") == 0)
157             break;
158 
159         tdl = *dl = new DL;
160         tdl->Exchange_head = NULL;
161         pple = &tdl->Exchange_head;
162 
163         if (strcmp (tok, "-") == 0)
164             tok = NullStr;
165 
166         tdl->mstr = newcpy (tok);       /* string to be substituted */
167 
168         GetDialPrePost (f, tdl);
169 
170         if (GetCost) {
171             tdl->co = new CO;
172             GetCostData (f, tdl->co);
173         } else {
174             tdl->co = NULL;
175             if (f.TokenPtr ()) {
176                 vprintlog ("Cannot define costs in the Dial table when a Cost table exists !\n");
177                 CfgError (f);
178             }
179         }
180 
181         tdl->next = NULL;
182         dl = &(tdl->next);
183     }
184 
185     if (!tdl) {
186         vprintlog ("Dial table MUST NOT be empty !\n");
187         myexit (CFG_ERROR);
188     }
189 
190     if (*tdl->mstr != '\0') {
191         vprintlog ("Last entry in Dial Table must have a single dash '-' as the first field !\n");
192         myexit (CFG_ERROR);
193     }
194 }
195 
196 
GetTypeDef(CfgFile & f,TD ** td_head)197 int GetTypeDef (CfgFile &f, TD **td_head)
198 {
199                             // all Flags are stored as uppercase !
200     TD **td; TD *ttd;
201 
202     td = td_head;
203 
204     while (f.GetLn ()) {
205 
206         pcsz tok = f.GetToken ();
207 
208         if (strcasecmp (tok, "end") == 0)
209             break;
210         ttd = *td = new TD;
211         strzcpy (ttd->flag, tok, sizeof (ttd->flag));
212         fl_strupr (ttd->flag);
213         tok = f.GetToken ();
214         if (tok)
215             ttd->type = (byte) atoi (tok);
216         else
217             ttd->type = 0;
218 
219         ttd->info = 0;
220         ttd->pt   = NULL;
221 
222         pcsz tkp = f.TokenPtr ();
223 
224         if (tkp) {         // something after modem type
225           if (isdigit (*tkp)) {   // PhoneTrans
226             ttd->pt = new PT;
227             if (ttd->pt->Get (tkp))
228                 return -1;
229           } else {
230             tok = f.GetToken ();
231             if (strcasecmp (tok, "DIGITAL") == 0)
232                 ttd->info |= TD_DIGITAL;
233             else if (strcasecmp (tok, "ANALOG") == 0)
234                 ;
235             else
236                 return -1;
237           }
238         }
239 
240         ttd->next = NULL;
241         td = &(ttd->next);
242     }
243 
244     return 0;
245 }
246 
247 
GetFlagDef(CfgFile & f,FD ** fd_head)248 void GetFlagDef (CfgFile &f, FD **fd_head)
249 {
250                             // all Flags are stored as uppercase !
251     FD **fd; FD *tfd;
252 
253     fd = fd_head;
254 
255     while (f.GetLn ()) { /* FlagDef lines */
256 
257         pcsz tok = f.GetToken ();
258 
259         if (strcasecmp (tok, "end") == 0)
260             break;
261         tfd = *fd = new FD;
262         strzcpy (tfd->flag, tok, sizeof (tfd->flag));
263         fl_strupr (tfd->flag);
264         tok = f.GetToken ();
265         tfd->flag_w = 0;
266         if (tok)
267             if (GetUserFlags (tok, &tfd->flag_w)) {
268                 vprintlog ("Invalid flags !\n");
269                 CfgError (f);
270             }
271         tfd->next = NULL;
272         fd = &(tfd->next);
273     }
274 }
275 
ParseGlb(CfgFile & f1)276 BOOL ParseGlb (CfgFile &f1)
277 {
278     pcsz tok = f1.ReGetToken ();
279 
280     static BOOL CostNeeded = TRUE;  // Cost table not acquired yet.
281 
282     if (strcasecmp (tok, "MultiLineDesc") == 0) {  // MultiLineDesc
283         pcsz tkp = f1.RestOfLine ();
284         if (sscanf (tkp, "%d %c", &fb_cpos, &fb_cont) < 1)
285             CfgError (f1);
286         if (fb_cpos != -1)
287             vwritelog ("Using MultiLineDesc %d '%c'", fb_cpos, fb_cont);
288         return TRUE;
289     }
290 
291     if (strcasecmp (tok, "CompressCfg") == 0) {
292         char path[PATH_MAX];
293         tok = f1.GetToken ();
294         if (!tok)
295             CfgError (f1);
296         getpath (tok, path, Build);
297         Compr = new AH_ComprCfg (path, vpwlog);
298         return TRUE;
299     }
300 
301     if (strcasecmp (tok, "statuslog") == 0) {
302         tok = f1.GetToken ();
303         if (!tok)
304             CfgError (f1);
305         char logname[PATH_MAX];
306         getpath (tok, logname, Build);
307         if ((logfile = fopen (logname, "at")) == NULL) {
308             fprintf(stderr, "\nError opening log file \"%s\" !\n\n", logname);
309             myexit(OPEN_ERR);
310         } else {
311             fprintf (logfile, "\n");
312             vwritelog ("Begin, FastLst "VER);
313         }
314         return TRUE;
315     }
316 
317     if (strcasecmp (tok, "InputPath") == 0) {
318         tok = f1.GetToken ();
319         if (!tok)
320             CfgError (f1);
321         getallocpath (tok, &InputPath, Slash | MkDir | Build);
322         return TRUE;
323     }
324 
325     if (strcasecmp (tok, "DatFile") == 0) {
326         tok = f1.GetToken ();
327         if (!tok)
328             CfgError (f1);
329         getallocpath (tok, &DatFile);
330         return TRUE;
331     }
332 
333     if (strcasecmp (tok, "ArcPath") == 0) {
334         tok = f1.GetToken ();
335         if (!tok)
336             CfgError (f1);
337         getallocpath (tok, &ArcPath, Slash | Build);
338         return TRUE;
339     }
340 
341     if (strcasecmp (tok, "ArcDate") == 0) {      /* ArcDate */
342         tok = f1.GetToken ();
343         if (tok) {
344             if (strcasecmp (tok, "Write") == 0)
345                 ArcDate = _ArcDateWrite_;
346             else if (strcasecmp (tok, "Creation") == 0)
347                 ArcDate = _ArcDateCreation_;
348             else
349                 CfgError (f1);
350         } else
351             ArcDate = _ArcDateCreation_;
352         return TRUE;
353     }
354 
355     if (strcasecmp (tok, "killafter") == 0) {
356         killafter = TRUE;
357         return TRUE;
358     }
359 
360     if (strcasecmp (tok, "KillSource") == 0) {
361         killsource = TRUE;
362         return TRUE;
363     }
364 
365     if (strcasecmp (tok, "BeforeKillSource") == 0) {
366         BeforeKillSource = getallocline (f1.RestOfLine ());
367         return TRUE;
368     }
369 
370     if (strcasecmp (tok, "dash2comma") == 0) {
371         dash2comma = TRUE;
372         return TRUE;
373     }
374 
375     if (strcasecmp (tok, "noreport") == 0) {
376         noreport = TRUE;
377         return TRUE;
378     }
379 
380     if (strcasecmp (tok, "V7BugFix") == 0) {
381         V7BugFix = TRUE;
382         return TRUE;
383     }
384 
385     if (strcasecmp (tok, "cost") == 0) {
386         if (!CostNeeded) {
387             vprintlog ("Error: The Cost table must precede the Dial table !\n");
388             CfgError (f1);
389         }
390         GetCostTable (f1, &co_head);
391         CostNeeded = FALSE;
392         return TRUE;
393     }
394 
395     if (strcasecmp (tok, "dial") == 0) {
396         if (dl_head) {
397             vprintlog ("Error: The Dial table must be unique !\n");
398             CfgError (f1);
399         }
400         GetDialTable (f1, &dl_head, CostNeeded);
401         CostNeeded = FALSE;
402         return TRUE;
403     }
404 
405     if (strcasecmp (tok, "NoRedir") == 0) {
406         NoRedir = TRUE;
407         return TRUE;
408     }
409 
410     if (strcasecmp (tok, "TypeDef") == 0) {
411         if (GetTypeDef (f1, &td_head)) {
412             vprintlog ("Error in TypeDef !\n");
413             CfgError (f1);
414         }
415         return TRUE;
416     }
417 
418     if (strcasecmp (tok, "BitType") == 0) {
419         BitType = TRUE;
420         return TRUE;
421     }
422 
423     if (strcasecmp (tok, "FlagDef") == 0) {
424         GetFlagDef (f1, &fd_head);
425         return TRUE;
426     }
427 
428     if (strcasecmp (tok, "MsgLogArea") == 0) {
429         tok = f1.GetToken ();
430         if (!tok)
431             return TRUE;
432         MsgLogAreaPath = GetAllocName (tok, GN_BSlash);
433         MsgLogAreaType = MSGTYPE_SDM;
434         if ((tok = f1.GetToken ()) != NULL)
435             if (strcmp (tok, "-$") == 0) {
436                 MsgLogAreaType = MSGTYPE_SQUISH;
437                 strubslash (MsgLogAreaPath);
438             }
439         return TRUE;
440     }
441 
442     if (strcasecmp (tok, "MsgRemArea") == 0) {
443         tok = f1.GetToken ();
444         if (!tok)
445             return TRUE;
446         MsgRemAreaPath = GetAllocName (tok, GN_BSlash);
447         MsgRemAreaType = MSGTYPE_SDM;
448         if ((tok = f1.GetToken ()) != NULL)
449             if (strcmp (tok, "-$") == 0) {
450                 MsgRemAreaType = MSGTYPE_SQUISH;
451                 strubslash (MsgRemAreaPath);
452             }
453         return TRUE;
454     }
455 
456     if (strcasecmp (tok, "MsgSize") == 0) {
457         tok = f1.GetToken ();
458         if (!tok)
459             CfgError (f1);
460         if (str2uint (tok, &MsgSize))
461             CfgError (f1);
462         MsgSize = __min (MsgSize, UINT_MAX - 256 - 160);
463         return TRUE;
464     }
465 
466     if (strcasecmp (tok, "MsgFromNode") == 0) {
467         if ((tok = f1.GetToken ()) == NULL) {
468             CfgError (f1);
469             return TRUE;
470         }
471         strto4Dadr (tok, &MsgFromNode);
472         return TRUE;
473     }
474 
475     if (strcasecmp (tok, "MsgToNode") == 0) {
476         if ((tok = f1.GetToken ()) == NULL) {
477             CfgError (f1);
478             return TRUE;
479         }
480         strto4Dadr (tok, &MsgToNode);
481         return TRUE;
482     }
483 
484     if (strcasecmp (tok, "MsgTo") == 0) {
485         MsgTo = GetAllocLn (f1.RestOfLine ());
486         return TRUE;
487     }
488 
489     if (strcasecmp (tok, "MsgAttr") == 0) {
490         MsgAttr = 0;
491         tok = f1.RestOfLine ();
492         if (strpbrk (tok, "Pp"))
493             MsgAttr |= MSGPRIVATE;
494         if (strpbrk (tok, "Kk"))
495             MsgAttr |= MSGKILL;
496         if (strpbrk (tok, "Cc"))
497             MsgAttr |= MSGCRASH;
498         if (strpbrk (tok, "Hh"))
499             MsgAttr |= MSGHOLD;
500         if (strpbrk (tok, "Dd"))
501             MsgAttr |= (MSGCRASH|MSGHOLD);
502         // no special action necessary for 'N' and 'O' //
503         return TRUE;
504     }
505 
506     if (strcasecmp (tok, "CostNullPhone") == 0) {
507         tok = f1.GetToken ();      // cost
508         if (tok) {
509             CostNullPhone.cost = (word) atoi (tok);
510             tok = f1.GetToken ();      // ucost
511             if (tok)
512                 CostNullPhone.ucost = (word) atoi (tok);
513             else
514                 CostNullPhone.ucost = CostNullPhone.cost;
515         }
516         return TRUE;
517     }
518 
519     if (strcasecmp (tok, "CostVerbatimPhone") == 0) {
520         tok = f1.GetToken ();      // cost
521         if (tok) {
522             CostVerbatimPhone.cost = (word) atoi (tok);
523             tok = f1.GetToken ();      // ucost
524             if (tok)
525                 CostVerbatimPhone.ucost = (word) atoi (tok);
526             else
527                 CostVerbatimPhone.ucost = CostVerbatimPhone.cost;
528         }
529         return TRUE;
530     }
531 
532     return FALSE;
533 }
534