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