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 "apgenlib.hpp"
18 #include <limits.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <ctype.h>
22 #include "crc16.hpp"
23 #include "data.hpp"
24 #include "inpblk.hpp"
25 #include "misc.hpp"
26 #include "cfgdata.hpp"
27 #include "parse.hpp"
28 #include "field.hpp"
29 #include "parsetyp.hpp"
30 #include "export.hpp"
31 #include "inmem.hpp"
32
33 const char UnpublishedPhone[] = "-Unpublished-";
34
InpAll(InpAll * ia)35 InpAll::InpAll (InpAll *ia)
36 {
37 Init (ia);
38 }
39
Init(InpAll * ia)40 void InpAll::Init (InpAll *ia)
41 {
42 if (ia) {
43 *this = *ia;
44 ArcMethHead = CopyArcMethod (ia->ArcMethHead);
45 ArcDiffMethHead = CopyArcMethod (ia->ArcDiffMethHead);
46 } else
47 memset (this, 0, sizeof (*this));
48 }
49
50
InpNnc(InpNnc * in)51 InpNnc::InpNnc (InpNnc *in)
52 {
53 if (in)
54 *this = *in;
55 else
56 memset (this, 0, sizeof (*this));
57 }
58
59
InpOut(void)60 InpOut::InpOut (void)
61 {
62 memset (this, 0, sizeof (*this));
63 }
64
65
InpLoc(void)66 InpLoc::InpLoc (void)
67 {
68 memset (this, 0, sizeof (*this));
69 }
70
71
InpVar(void)72 InpVar::InpVar (void)
73 {
74 memset (this, 0, sizeof (*this));
75 crcchk = TRUE;
76 }
77
78
InpSave(void)79 InpSave::InpSave (void)
80 {
81 Init ();
82 }
83
84
Init()85 void InpSave::Init ()
86 {
87 memset (this, 0, sizeof (*this));
88 NodeDay = -1;
89 }
90
91
InpncBlk(InpAll * ia)92 InpncBlk::InpncBlk (InpAll *ia)
93 {
94 a = new InpAll (ia);
95 l = new InpLoc;
96 v = new InpVar;
97 s = new InpSave;
98 next = NULL;
99 }
100
101
savinit(void)102 void InpncBlk::savinit (void)
103 {
104 s->Init ();
105 }
106
107
INPBLK(InpAll * ia,InpNnc * in,SegAll * isa)108 INPBLK::INPBLK (InpAll *ia, InpNnc *in, SegAll *isa) // constructor initializer
109 {
110 a->Init (ia);
111 n = new InpNnc (in);
112 o = new InpOut;
113 sa = new SegAll (isa);
114 SegExpHead = NULL;
115 }
116
117
Process(OUTCUR * ocp,OUTBLK * cob,BOOL * SomeNeeded)118 BOOL INPBLK::Process (OUTCUR *ocp, OUTBLK *cob, BOOL *SomeNeeded)
119 {
120 INPCUR inpcur (o);
121
122 Open (&inpcur);
123
124 if (n->BeforeCompile)
125 RunCmd (n->BeforeCompile, RCf, "l", l->NodeList);
126
127 BOOL ret = ProcessFile (l->NodeList, &inpcur, ocp, cob, SomeNeeded);
128 writersp (MsgLogRsp, "\"%s\" processed%s\r\r", l->NodeList, ret ? "." : " with ERRORS.");
129
130 if (n->AfterCompile)
131 RunCmd (n->AfterCompile, RCf, "l", l->NodeList);
132
133 Close (&inpcur);
134
135 return ret;
136 }
137
138
TxtHeader(INPCUR * icp)139 static void TxtHeader (INPCUR *icp)
140 {
141 if (icp->txt_pagenum != 0) {
142 if (icp->nodelist_txt)
143 fprintf (icp->nodelist_txt, "");
144 if (icp->nodelist_prn)
145 fprintf (icp->nodelist_prn, "");
146 }
147 icp->txt_pagenum ++;
148 if (icp->nodelist_txt)
149 fprintf (icp->nodelist_txt, "%s %-4hd\n\n", icp->header, icp->txt_pagenum);
150 if (icp->nodelist_prn)
151 fprintf (icp->nodelist_prn, "%s %-4hd\n\n", icp->header, icp->txt_pagenum);
152 icp->txt_pg_lines = 2;
153 }
154
155
TxtLine(INPCUR * icp,char * text)156 static void TxtLine (INPCUR *icp, char *text)
157 {
158 icp->txt_pg_lines ++;
159 if (icp->nodelist_txt)
160 fprintf (icp->nodelist_txt, "%s\n", text);
161 if (icp->nodelist_prn)
162 fprintf (icp->nodelist_prn, "%s\n", text);
163 }
164
165
MkSysopComma(pcsz sysopname,char * sysop_comma)166 static void MkSysopComma (pcsz sysopname, char *sysop_comma)
167 {
168 int l = strlen (sysopname);
169
170 if (l > SYSOPSIZE-2) {
171 strcpy (sysop_comma, "Too_Long, Name");
172 return;
173 }
174
175 if (l == 0) {
176 strcpy (sysop_comma, "Empty, Name");
177 return;
178 }
179
180 pcsz lastname = strrchr (sysopname, '_');
181 if (lastname)
182 lastname ++;
183 else
184 lastname = sysopname;
185
186 char *d = fl_stpcpy (sysop_comma, lastname);
187
188 if (sysopname != lastname) { /* if there is a first name */
189 const char *s = sysopname;
190 lastname--; /* skip blank that precede last name */
191 *d++ = ',';
192 *d++ = ' ';
193 while (s < lastname) {
194 if (*s == '_') { // change underscore to blank
195 *d++ = ' ';
196 s++;
197 } else
198 *d++ = *s++;
199 }
200 *d = '\0';
201 }
202 }
203
204
Pack(word * outp,char * inp,byte * count)205 static void Pack (word *outp, char *inp, byte *count)
206 {
207 /* for name compression */
208 static byte unwrk[84] = {
209 28, 0, 0, 0, 0, 0, 27, 0, 0, // ' ( 39) -> / ( 47)
210 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // 0 ( 48) -> 9 ( 57)
211 0, 0, 0, 0, 0, 0, 0, // : ( 58) -> @ ( 64)
212 2, 12, 10, 13, 1, 21, 16, 11, // A ( 65) -> H ( 72)
213 8, 23, 18, 9, 14, 3, 5, 17, // I ( 73) -> P ( 80)
214 26, 4, 6, 7, 15, 22, 20, 24, // Q ( 81) -> X ( 88)
215 19, 25, 0, 0, 0, 0, 0, 28, // Y ( 89) -> ` ( 96)
216 2, 12, 10, 13, 1, 21, 16, 11, // a ( 97) -> h (104)
217 8, 23, 18, 9, 14, 3, 5, 17, // i (105) -> p (112)
218 26, 4, 6, 7, 15, 22, 20, 24, // q (113) -> x (120)
219 19, 25 }; // y (121) -> z (122)
220
221
222 char c;
223 word totcode = 0;
224 short j = 0;
225 *count = 0;
226
227 while ((c = (char) (*inp++)) != 0) {
228 word code;
229 if ((c < 39) || (c > 122))
230 code = 0;
231 else
232 code = unwrk[c-39];
233 totcode = (word)((word)(totcode * 40) + code);
234 j++;
235 if (j == 3) {
236 *outp++ = totcode;
237 (*count) += 2;
238 j = 0;
239 totcode = 0;
240 }
241 }
242
243 if (j != 0) {
244 for (; j < 3; j++)
245 totcode = (word)(totcode * 40);
246 *outp = totcode;
247 (*count) += 2;
248 }
249
250 }
251
252
Open(INPCUR * icp)253 void INPBLK::Open (INPCUR *icp)
254 {
255 if (n->FidoTxt || n->FidoPrn) {
256 if (n->FidoTxt)
257 icp->nodelist_txt = SmartOpen (n->FidoTxt, "");
258 if (n->FidoPrn)
259 icp->nodelist_prn = SmartOpen (n->FidoPrn, "");
260 }
261 }
262
263
Close(INPCUR * icp)264 void INPBLK::Close (INPCUR *icp)
265 {
266
267 if (icp->nodelist_prn)
268 fclose (icp->nodelist_prn);
269 if (icp->nodelist_txt)
270 fclose (icp->nodelist_txt);
271
272 }
273
274
InSegment(const EXTADR * adr,ADRLST * cobIncAddr,ADRLST * cobExcAddr,ADRLST * IncAddr,ADRLST * ExcAddr)275 BOOL INPBLK::InSegment (const EXTADR *adr, ADRLST *cobIncAddr, ADRLST *cobExcAddr, ADRLST *IncAddr, ADRLST *ExcAddr)
276 {
277 if (cobIncAddr)
278 if (!InPartAdrLst (adr, cobIncAddr))
279 return FALSE;
280
281 if (cobExcAddr)
282 if (InPartAdrLst (adr, cobExcAddr))
283 return FALSE;
284
285 if (IncAddr)
286 if (!InPartAdrLst (adr, IncAddr))
287 return FALSE;
288
289 if (ExcAddr)
290 if (InPartAdrLst (adr, ExcAddr))
291 return FALSE;
292
293 return TRUE;
294 }
295
296
297
WantRem(char * MsgRem,char * rem)298 static BOOL WantRem (char *MsgRem, char *rem)
299 {
300 if (!MsgRem)
301 return FALSE; // No MsgRem statement
302 if (*rem == '\0') // Empty Comment
303 return FALSE;
304 if (*MsgRem == '\0') // MsgRem with no char list: all comments
305 return TRUE;
306 if (*rem == ' ') // "; word" comment
307 return (strchr (MsgRem, ';') != NULL);
308 if (*(rem+1) != ' ') // ";word" comment
309 return (strchr (MsgRem, ';') != NULL);
310 return (strchr (MsgRem, *rem) != NULL); // ";<l>" comment
311 }
312
313
314
315 // for GetPhoneType
316
317
318 #define PT_PSTN 0x01
319 #define PT_Unpublished 0x02
320 #define PT_Verbatim 0x03
321 #define PT_FIDOIP 0x04
322
323
GetPhoneType(pcsz phone)324 static int GetPhoneType (pcsz phone)
325 {
326 if (*phone == '\0')
327 return PT_Unpublished;
328
329 int numlen = strspn (phone, "-0123456789");
330 if (phone[numlen] == '\0') {
331 if (strncmp (phone, "000-", 4) == 0)
332 return PT_FIDOIP;
333 return PT_PSTN;
334 }
335
336 if (stricmp (phone, UnpublishedPhone) == 0)
337 return PT_Unpublished;
338
339 return PT_Verbatim;
340 }
341
342
MkPhone(pcsz orig_phone,psz phone)343 CO *MkPhone (pcsz orig_phone, psz phone)
344 {
345 CO *co = NULL;
346 DL *dl = dl_head;
347 while (dl) {
348 char *pp = strdcmp (orig_phone, dl->mstr);
349 if (pp) { // first part match (area code)
350 bool match;
351
352 if (dl->Exchange_head) { // exch to match
353 match = false;
354 StrChain *ple = dl->Exchange_head;
355 do {
356 if (strdcmp (pp, ple->text)) { // is Local
357 match = true;
358 break;
359 }
360 ple = ple->next;
361 } while (ple);
362 } else // no exch to match
363 match = true;
364
365 if (match) {
366 strzcat (phone, PHONESIZE, dl->pre, pp, dl->post, NULL);
367 if (dl->co)
368 co = dl->co;
369 break;
370 }
371
372 }
373 dl = dl->next;
374 }
375
376 return co;
377 }
378
379
380
ProcessFile(char * fname,INPCUR * icp,OUTCUR * ocp,OUTBLK * cob,BOOL * SomeNeeded)381 BOOL INPBLK::ProcessFile (char *fname, INPCUR *icp, OUTCUR *ocp, OUTBLK *cob, BOOL *SomeNeeded)
382 {
383
384 char PackBuf[LINESIZE];
385 byte buffer[sizeof(_vers7) + LINESIZE];
386 _vers7 *vers7 = (_vers7 *) buffer;
387
388 word official_crc = 0, calc_crc = 0;
389 FILE *f;
390 word n_num;
391 word n_cost, u_cost;
392 byte n_modem;
393 dword n_baud;
394 int coord_lev, cur_addr_lev;
395 char def_phone[PHONESIZE];
396 byte def_modem = 0;
397 word def_cost = 0, def_ucost = 0;
398 dword def_baud = 0;
399 word def_flags = 0;
400 char buff[LINESIZE]; char verbuff[LINESIZE]; char *p, *q, *r;
401 char *modifier, *boardname, *cityname,
402 *sysopname; /* no comma */
403 char phone[PHONESIZE], phonendx[PHONESIZE];
404 char sysop_comma[SYSOPSIZE]; // SysOp Name: "LastName[, FirstName]"
405 int pnt, hold;
406 int tmplen;
407 ADRDATA *ph, *pw, *ad;
408
409 char *origline = NULL; // pointer to original nodelist line
410
411
412 if (SegExpHead) {
413 if (SEGEXPORT::OpenAll (SegExpHead, s->NodeTime, s->NodeDay, fname))
414 *SomeNeeded = TRUE;
415 origline = new char[LINESIZE];
416 }
417
418 BOOL SegmentSel = cob->o->IncAddr || cob->o->ExcAddr || o->IncAddr || o->ExcAddr;
419
420
421 // initialization for "constant" variables
422
423 char *sysop4ndx = (cob->l->v7data.sysopndx || cob->l->FidoUserLst) ?
424 sysop_comma : NullStr;
425
426 char const *phone4ndx = (cob->l->v7data.flags & V7PDX_F) ? phonendx : NullStr;
427
428
429
430 //
431
432 ADRDATA *def_pw = NULL;
433 *def_phone = '\0';
434
435 cur_addr_lev = NONE;
436 if ((f = fopen (fname, "rb")) == NULL) {
437 vprintlog ("Could not open Nodelist File \"%s\"\n", fname);
438 myexit (NO_NODELIST);
439 }
440 setvbuf (f, NULL, _IOFBF, BufSize);
441
442 if (!fgets (buff, LINESIZE, f)) {
443 vprintlog ("Could not read Nodelist File \"%s\"\n", fname);
444 fclose (f);
445 myexit (NO_NODELIST);
446 }
447
448 if (strncmp (buff, ";A ", 3) == 0)
449 p = strrchr (buff, ':');
450 else
451 p = NULL;
452
453 if (p) {
454 if (v->crcchk) {
455 official_crc = (word) atoi (p+1);
456 calc_crc = 0;
457 }
458 strzcpy (icp->header, buff + 3, HeaderSize - 8);
459 p = strrchr (icp->header, ':');
460 if (!p)
461 p = icp->header + strlen (icp->header);
462 strcpy (p, "- P");
463
464 if(!fgets (buff, LINESIZE, f)) {
465 vprintlog ("Empty Nodelist File \"%s\"\n", fname);
466 myexit (NO_NODELIST);
467 }
468 } else {
469 v->crcchk = FALSE;
470 strcpy (icp->header, "Private List - P");
471 }
472
473 TxtHeader (icp);
474
475 vprintlogrsp (MsgLogRsp, "Processing \"%s\"\n", fname);
476
477 if (n->MsgRem)
478 writersp (MsgRemRsp, "\r\rComments in \"%s\"\r\r", fname);
479
480 /* set initial defaults */
481 EXTADR adr = l->PartAddr;
482 if ((n->flags & GermanPointLst) && (adr.zone == word(-1)))
483 adr.zone = 2;
484
485 do { /* while fgets */
486 if (buff[0] == 0x1A) // ^Z
487 break;
488 if (v->crcchk)
489 calc_crc = crcstr (buff, calc_crc, &tmplen);
490 else
491 tmplen = strlen (buff);
492
493 if (tmplen < 2) // skip empty lines
494 continue;
495
496 p = buff + tmplen - 2; // remove trailing CR+LF
497 if (*p == '\r')
498 *p = '\0';
499
500 strcpy (verbuff, buff); // make verbatim copy of nodelist line
501
502 pnt = 0;
503 coord_lev = NONE;
504 hold = 0;
505
506 p = buff;
507
508 if (*p == ';') {
509 p ++;
510 if (n->MsgRem)
511 if (WantRem (n->MsgRem, p))
512 writersp (MsgRemRsp, "%s\r", p);
513 if ((*p == 'A') || (*p == 'F') || (*p == 'U'))
514 TxtLine (icp, p+1);
515 continue;
516 }
517
518 if (SegExpHead)
519 strcpy (origline, p);
520
521 /* Modifier (Host, Region, etc.) */
522 modifier = nextfield (p);
523 fl_strupr (modifier);
524
525 /* Node number (or region or zone) */
526 p = nextfield (NULL);
527 n_num = (word) atoi (p);
528
529 if (n_num == 0)
530 continue; // if empty line don't overwrite coord !
531
532 /* Did we get anything? */
533 if (*modifier) { /* Is it something we need to worry about? */
534 if (strcmp (modifier, "ZONE") == 0) {
535 ocp->nzones ++;
536 coord_lev = ZONE;
537 } else if (strcmp (modifier, "REGION") == 0) {
538 if (!(n->flags & GermanPointLst))
539 ocp->nregions ++;
540 coord_lev = REGION;
541 } else if (strcmp (modifier, "HOST") == 0) {
542 if (!(n->flags & GermanPointLst))
543 ocp->nnets ++;
544 coord_lev = HOST;
545 } else if (strcmp (modifier, "HUB") == 0) {
546 ocp->nhubs ++;
547 coord_lev = HUB;
548 } else if (strcmp (modifier, "BOSS") == 0) {
549 /* It is a PointList Boss */
550 coord_lev = BOSS;
551 } else if (strcmp (modifier, "NODE") == 0) {
552 /* It is a node address */
553 coord_lev = NODE;
554 } else if (strcmp (modifier, "POINT") == 0) {
555 pnt = 1;
556 } else if (strcmp (modifier, "PVT") == 0) {
557 /* It is just a private node */
558 *modifier = '\0';
559 } else if (strcmp (modifier, "HOLD") == 0) {
560 *modifier = '\0';
561 hold = 1;
562 } else if (strcmp (modifier, "DOWN") == 0) {
563 ocp->ndown ++;
564 continue;
565 } else {
566 ocp->nunknown ++;
567 continue;
568 }
569 }
570
571 /* Board name */
572 boardname = nextfield (NULL);
573
574
575 if (coord_lev == NONE) {
576 if (cur_addr_lev == BOSS)
577 pnt = 1;
578 if (!pnt) {
579 adr.node = n_num;
580 adr.point = 0;
581 } else
582 adr.point = n_num;
583 } else {
584 cur_addr_lev = coord_lev;
585 adr.point = 0;
586 switch (coord_lev) {
587
588 case ZONE:
589 adr.zone = n_num;
590 adr.region = 0;
591 goto HostLabel;
592
593 case REGION:
594 if (n->flags & GermanPointLst)
595 continue;
596 adr.region = n_num;
597
598 case HOST:
599 HostLabel: adr.hub = 0;
600 if (n->flags & GermanPointLst) {
601 get_addr_2d (boardname, &adr); // get net/node from system name
602 cur_addr_lev = BOSS;
603 } else {
604 adr.net = n_num;
605 adr.node = 0;
606 }
607 printflush ("%5hd:%-5hd\r", adr.zone, adr.net);
608 if (n->flags & GermanPointLst)
609 continue;
610 break;
611
612 case HUB:
613 adr.hub = adr.node = n_num;
614 break;
615
616 case BOSS:
617 case NODE:
618
619 strcpy (def_phone, "");
620 def_flags = 0;
621 def_baud = 300;
622 def_modem = 0;
623 def_cost = CostNullPhone.cost;
624 def_ucost = CostNullPhone.ucost;
625 def_pw = NULL;
626 get_addr ((const char **)&p, &adr);
627 adr.region = adr.hub = 0;
628
629 if (coord_lev == BOSS) {
630 printflush ("%5hd:%-5hd \r", adr.zone, adr.net);
631 continue; /* stop here */
632 } else { // NODE
633 sscanf (p, "%hu %hu", &adr.region, &adr.hub);
634 coord_lev = NONE;
635 break;
636 }
637 }
638 }
639
640 if (adr.point) {
641 ocp->npoints ++;
642 pnt = 1;
643 } else {
644 ocp->nnodes ++;
645 pnt = 0;
646 }
647
648 if (SegExpHead)
649 SEGEXPORT::WriteAll (SegExpHead, &adr, origline);
650
651 if (SegmentSel)
652 if (!InSegment (&adr, cob->o->IncAddr, cob->o->ExcAddr, o->IncAddr, o->ExcAddr) &&
653 (coord_lev < n->IncCoord)) {
654 ocp->nexcluded ++;
655 continue;
656 }
657
658 /* Location */
659 cityname = nextfield (NULL);
660
661 /* Sysop name */
662 sysopname = nextfield (NULL);
663
664 /* Phone number */
665 pcsz orig_phone = nextfield (NULL);
666
667 /* Baud rate */
668 p = nextfield (NULL);
669 n_baud = atol (p);
670
671 /* Flags */
672 char *flags = remainder; // remainder of current text line
673
674 /* Print out the Nodelist.Txt/Prn file */
675 if ((icp->nodelist_txt) || (icp->nodelist_prn))
676 if ((cur_addr_lev != NODE) && (cur_addr_lev != BOSS)) {
677 icp->txt_pg_lines ++;
678
679 if ((coord_lev >= HOST) && (icp->txt_pg_lines >= 40) ||
680 (icp->txt_pg_lines >= 60))
681 TxtHeader (icp);
682
683 if (icp->nodelist_txt)
684 fprintf (icp->nodelist_txt,
685 "%-7.7s%5hd %-19.19s %-20.20s %-19.19s %5lu\n",
686 modifier, n_num, boardname, orig_phone, cityname, n_baud);
687
688 if (icp->nodelist_prn)
689 fprintf (icp->nodelist_prn,
690 "%-7.7s%5hd %-19.19s %-20.20s %-19.19s %-20.20s %5lu %-30.30s\n",
691 modifier, n_num, boardname, orig_phone, cityname, sysopname,
692 n_baud, flags);
693 }
694
695
696 PackBuf[0] = '\0';
697
698 // Process Flags
699
700 // Override the Flags if necessary
701
702 ad = GetData (&adr, icp->tab->nf, o->nfn, ocp->tab->nf, cob->o->nfn);
703 if (ad)
704 flags = ad->txt;
705
706 fl_strupr (flags); // Convert FLAGS to upper case
707
708 PT *pt = NULL; // Phone translation (for Verbatim phones)
709 byte tdinfo = 0;
710 // Check Modem Type
711 n_modem = 0;
712 TD *td = td_head;
713 while (td) {
714 if (FindFlag (flags, td->flag)) {
715 n_modem |= td->type;
716 if (!BitType) {
717 pt = td->pt;
718 tdinfo = td->info;
719 break;
720 }
721 }
722 td = td->next;
723 }
724
725
726 word n_flags = 0; // node flags
727
728 switch (coord_lev) { // coord flags
729 case NONE:
730 break;
731 case ZONE:
732 n_flags |= B_zone;
733 break;
734 case REGION:
735 n_flags |= B_region;
736 break;
737 case HOST:
738 n_flags |= B_host;
739 break;
740 case HUB:
741 n_flags |= B_hub;
742 break;
743 }
744
745 if (pnt)
746 n_flags |= B_point;
747
748 if (FindFlag (flags, "CM"))
749 n_flags |= B_CM;
750
751 FD *fd = fd_head; // user flags from node flags
752 while (fd) {
753 if (FindFlag (flags, fd->flag))
754 n_flags |= fd->flag_w;
755 fd = fd->next;
756 }
757
758 // User Flags from address
759 ad = GetData (&adr, icp->tab->fl, o->fln, ocp->tab->fl, cob->o->fln);
760 if (ad)
761 n_flags |= ad->w.w1;
762
763
764 // Find out a password if present
765
766 pw = GetData (&adr, icp->tab->pw, o->pwn, ocp->tab->pw, cob->o->pwn);
767
768
769 // Process the phone number
770
771 // Override the phone number if necessary
772
773 if ((cur_addr_lev == BOSS) && (n->flags & NoPointLstPhone))
774 orig_phone = UnpublishedPhone;
775
776 ph = GetData (&adr, icp->tab->ph, o->phn, ocp->tab->ph, cob->o->phn);
777 if (ph)
778 orig_phone = ph->txt;
779
780 int phone_type = GetPhoneType (orig_phone);
781 bool undialable = (hold && !ph);
782
783 // process the number and related cost
784
785 switch (phone_type) {
786
787 case PT_FIDOIP:
788
789 strzcpy (phonendx, orig_phone+4, PHONESIZE);
790 dot_it (phonendx);
791 goto VerbPhone;
792
793 case PT_Verbatim:
794
795 strzcpy (phonendx, orig_phone, PHONESIZE);
796
797 VerbPhone:
798 if (undialable)
799 break;
800
801 if (pt)
802 pt->Apply (&n_cost, &u_cost, phone, phonendx, PHONESIZE);
803 else {
804 strzcpy (phone, phonendx, PHONESIZE);
805 n_cost = CostVerbatimPhone.cost;
806 u_cost = CostVerbatimPhone.ucost;
807 }
808
809 // cost override on address
810 ad = GetData (&adr, icp->tab->cs, o->csn, ocp->tab->cs, cob->o->csn);
811 if (ad) {
812 n_cost = ad->w.w1;
813 u_cost = ad->w.w2;
814 }
815
816 break;
817
818 case PT_Unpublished:
819
820 strcpy (phonendx, orig_phone);
821
822 break;
823
824 case PT_PSTN:
825
826 CO *co = MkPhone (orig_phone, phone);
827
828 CopyUndash (phone, phonendx);
829
830 if (undialable)
831 break;
832
833 if (dash2comma)
834 comma_it (phone);
835
836 ad = GetData (&adr, icp->tab->cs, o->csn, ocp->tab->cs, cob->o->csn);
837 if (ad) { // cost override
838 n_cost = ad->w.w1;
839 u_cost = ad->w.w2;
840 break;
841 }
842
843 if (!co) {
844 co = co_head; // separate cost table
845 while (co) {
846 if (strdcmp (orig_phone, co->mstr) != NULL)
847 break;
848 co = co->next;
849 }
850 }
851
852 if (tdinfo & TD_DIGITAL) {
853 n_cost = co->costdig;
854 u_cost = co->ucostdig;
855 } else {
856 n_cost = co->cost;
857 u_cost = co->ucost;
858 }
859
860 break; // phone_type == PT_PSTN
861
862 } // switch (phone_type)
863
864
865 if (undialable ||
866 (phone_type == PT_Unpublished)) {
867
868 phone[0] = '\0';
869
870 if (NoRedir || pnt || pw || def_pw ||
871 (*def_phone == '\0') || (coord_lev > NONE)) { // empty phone
872
873 n_flags &= B_admin;
874 n_modem = 0;
875 n_cost = CostNullPhone.cost;
876 u_cost = CostNullPhone.ucost;
877
878 if (n->MsgLog & MsgLogNullPhone)
879 if ((!pnt) || (n->MsgLog & MsgLogPoints))
880 writersp (MsgLogRsp, "%d:%d/%d.%d Null Phone\r", adr.zone, adr.net, adr.node, adr.point);
881
882 ocp->nnullphone ++;
883
884 } else { // Redirected (only simple nodes)
885
886 strcpy (PackBuf, "-R-"); // prefix the board name
887
888 // use defaults for redirected nodes
889 strcpy (phone, def_phone);
890 n_flags = def_flags; // There are no admin flags to save
891 n_baud = def_baud;
892 n_modem = def_modem;
893 n_cost = def_cost;
894 u_cost = def_ucost;
895
896 if (n->MsgLog & MsgLogRedirected)
897 writersp (MsgLogRsp, "%d:%d/%d.%d Redirected\r", adr.zone, adr.net, adr.node, adr.point);
898
899 ocp->nredirect ++;
900 }
901 }
902
903
904 if (!NoRedir) {
905
906 if (coord_lev > NONE) { // save defaults for redirected nodes
907 strcpy (def_phone, phone);
908 def_flags = n_flags & ~B_admin; // saved without coord flags !
909 def_baud = n_baud;
910 def_modem = n_modem;
911 def_cost = n_cost;
912 def_ucost = u_cost;
913 def_pw = pw;
914 }
915
916 }
917
918
919 // Put the results into the proper files
920
921 if (sysop4ndx == sysop_comma)
922 MkSysopComma (sysopname, sysop4ndx);
923
924 ocp->heap->Write (&adr, ocp->datofs, ocp->dtpofs,
925 sysop4ndx, phone4ndx);
926
927 int error = 0; /* check disk full */
928
929 /* Print out the results in NODEX.DAT format */
930
931 vers7->Zone = adr.zone;
932 vers7->Net = adr.net;
933 vers7->Node = adr.node;
934 vers7->HubNode = (pnt) ? adr.point : adr.hub;
935 vers7->CallCost = n_cost;
936 vers7->MsgFee = u_cost;
937 vers7->NodeFlags = n_flags;
938 vers7->ModemType = n_modem;
939 vers7->BaudRate = (byte) (n_baud / 300);
940
941 q = (char *) (buffer + sizeof (_vers7));
942 p = fl_stpcpy (q, phone);
943 vers7->Phone_len = (byte) (p - q);
944
945 /* Stick in a password if there is one */
946 if (pw != NULL) {
947 r = fl_stpcpy (p, pw->txt);
948 vers7->Password_len = (byte) (r - p);
949 } else {
950 r = p;
951 vers7->Password_len = 0;
952 }
953
954 p = PackBuf + strlen (PackBuf);
955 q = fl_stpcpy (p, boardname);
956 vers7->Bname_len = (byte) (q - PackBuf); /* board name */
957
958 p = fl_stpcpy (q, sysopname);
959 vers7->Sname_len = (byte) (p - q); /* SysOp name */
960
961 q = fl_stpcpy (p, cityname);
962 vers7->Cname_len = (byte) (q - p); /* City name */
963
964 if (cob->l->v7data.flags & V7DTP_F) { // DTP data
965
966 const _DTPLnk DTPFix = {
967 {
968 0x0000, // Region
969 0x0000, // Hub
970 OfsNoLink, // DAT pointer for next same-sysop entry
971 OfsNoLink, // DAT pointer for next same-phone entry
972 OfsNoLink, // DAT pointer for next same-level entry
973 0xff, // number of SysOp entry
974 0xff // number of Phone entry
975 },
976 {
977 0xffff, // systems in lower level
978 OfsNoLink // DAT pointer for lower level
979 }
980 };
981 // DTP ptr into Pack
982 sprintf (q, "%08lX", ocp->dtpofs);
983
984 byte DTPFixSize = pnt ? sizeof (_DTPAllLnk) : sizeof (_DTPLnk);
985
986 error |= (fwrite (&DTPFix, DTPFixSize, 1, ocp->nodex_dtp) != 1);
987
988 word dtpflen = (word) (1 + strlen (verbuff)); // raw nodelist line
989 error |= (fwrite (&dtpflen, sizeof (dtpflen), 1, ocp->nodex_dtp) != 1);
990 error |= (fwrite (verbuff, dtpflen, 1, ocp->nodex_dtp) != 1);
991
992 size_t dtpelen = DTPFixSize + sizeof (dtpflen) + dtpflen;
993 ocp->dtpofs += dtpelen;
994
995 }
996
997 Pack ((word *)r, PackBuf, &(vers7->pack_len));
998
999 size_t entrylen = sizeof (_vers7) + vers7->Phone_len +
1000 vers7->Password_len + vers7->pack_len;
1001 error |= (fwrite (buffer, entrylen, 1, ocp->nodex_dat) != 1);
1002
1003 ocp->datofs += entrylen;
1004
1005 if (error || Break) {
1006
1007 ftrunczero (ocp->nodex_dat);
1008
1009 if (cob->l->v7data.flags & V7DTP_F)
1010 ftrunczero (ocp->nodex_dtp);
1011
1012 if (error) {
1013 vprintlog ("\n\nDisk Full writing nodelist files !\n\n");
1014 myexit (DISK_FULL);
1015 } else
1016 myexit (USER_BREAK);
1017 }
1018
1019 } while (fgets (buff, LINESIZE, f));
1020
1021 fclose (f);
1022
1023 if (SegExpHead) {
1024 delete[] origline;
1025 SEGEXPORT::CloseAll (SegExpHead);
1026 }
1027
1028 if (v->crcchk)
1029 if (official_crc != calc_crc) {
1030 vprintlog ("\n\nCRC ERROR: actual/expected CRC: %05hu/%05hu !\n\n", calc_crc, official_crc);
1031 errorlevel = CRC_ON_LIST;
1032 if (!nocrcexit)
1033 return FALSE;
1034 }
1035
1036 return TRUE;
1037 }
1038
1039
KillSource(void)1040 void INPBLK::KillSource (void)
1041 {
1042 InpncBlk::KillSource ();
1043 SEGEXPORT::KillSource (SegExpHead);
1044 }
1045
1046
KillSource(void)1047 void InpncBlk::KillSource (void)
1048 {
1049 if (l->ArcList && (l->ArcListKeep > 0) && (!l->NodeDiff || a->ArcMethHead))
1050 DeleteFile (l->NodeList, CHK_EXIST);
1051
1052 if (l->ArcDiff && a->ArcDiffMethHead) {
1053 DAYDIR DayDir (NODEDIFF, this);
1054 DayDir.KillAll ();
1055 }
1056 }
1057
1058