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 "types.hpp"
19 #include "outblk.hpp"
20 #include "misc.hpp"
21 #include "cfgdata.hpp"
22 #include "data.hpp"
23 #include "export.hpp"
24 #include "inmem.hpp"
25 #include <stdlib.h>
26 #include <string.h>
27 #if !defined(__FreeBSD__)
28   #include <malloc.h>
29 #endif
30 #include <unistd.h>
31 
32 
OutLoc(void)33 OutLoc::OutLoc (void)
34 {
35     memset (this, 0, sizeof (*this));
36 }
37 
38 
NLname(byte nltype)39 char *OutLoc::NLname (byte nltype)
40 {
41     char *p = filename[filename_i++];
42     filename_i %= MaxNL;
43 
44     switch (nltype & 0x7F) {
45 
46         case NL_DAT:
47             sprintf (p, "%s.dat", v7data.nodex);
48             break;
49 
50         case NL_NDX:
51             sprintf (p, "%s.ndx", v7data.nodex);
52             break;
53 
54         case NL_SDX:
55             if (!v7data.sysopndx)
56                 return NULL;
57             strcpy (p, v7data.sysopndx);
58             break;
59 
60         case NL_DTP:
61             if (!(v7data.flags & V7DTP_F))
62                 return NULL;
63             sprintf (p, "%s.dtp", v7data.nodex);
64             break;
65 
66         case NL_PDX:
67             if (!(v7data.flags & V7PDX_F))
68                 return NULL;
69             sprintf (p, "%s.pdx", v7data.nodex);
70             break;
71     }
72 
73 
74     if (killafter && (nltype & 0x80))
75         p[strlen(p)-1] = '$';
76 
77     return p;
78 }
79 
80 
81 
82 
OutSave(void)83 OutSave::OutSave (void)
84 {
85     memset (this, 0, sizeof (*this));
86 }
87 
88 
OutncBlk(InpAll * ia)89 OutncBlk::OutncBlk (InpAll *ia)
90 {
91     a = new InpAll (ia);
92     InpBlk = NULL;
93 }
94 
95 
InpSavInit(void)96 void OutncBlk::InpSavInit (void)
97 {
98     InpncBlk *cib = InpBlk;
99     while (cib) {
100         cib->savinit ();
101         cib = cib->next;
102     }
103 }
104 
105 
OUTBLK(InpAll * ia,InpNnc * in,SegAll * isa)106 OUTBLK::OUTBLK (InpAll *ia, InpNnc *in, SegAll *isa)
107 {
108     a->Init (ia);
109     n = new InpNnc (in);
110     o = new InpOut;
111     sa = new SegAll (isa);
112     l = new OutLoc;
113     s = new OutSave;
114     next = NULL;
115 }
116 
117 
SizeReport(const OUTCUR * ocp,_RSP * rsp)118 static void SizeReport (const OUTCUR *ocp, _RSP *rsp)
119 {
120    printf ("\n");
121    vprintlogrsp (rsp, "+-----------------------------------+\n");
122    vprintlogrsp (rsp, "|Total Systems              = %6lu|\n", ocp->nnodes + ocp->npoints + ocp->ndown + ocp->nunknown);
123    vprintlogrsp (rsp, "+-----------------------------------+\n");
124    vprintlogrsp (rsp, "|Zone Coordinators          = %6lu|\n", ocp->nzones);
125    vprintlogrsp (rsp, "|Regional Coordinators      = %6lu|\n", ocp->nregions);
126    vprintlogrsp (rsp, "|Network Coordinators       = %6lu|\n", ocp->nnets);
127    vprintlogrsp (rsp, "|Hub Coordinators           = %6lu|\n", ocp->nhubs);
128    vprintlogrsp (rsp, "+-----------------------------------+\n");
129    vprintlogrsp (rsp, "|Total Nodes                = %6lu|\n", ocp->nnodes);
130    vprintlogrsp (rsp, "|Total Points               = %6lu|\n", ocp->npoints);
131    vprintlogrsp (rsp, "|Total Down Systems         = %6lu|\n", ocp->ndown);
132  if (ocp->nunknown)
133    vprintlogrsp (rsp, "|Total Unknown Systems      = %6lu|\n", ocp->nunknown);
134    vprintlogrsp (rsp, "+-----------------------------------+\n");
135  if (ocp->nexcluded)
136    vprintlogrsp (rsp, "|Excluded Systems           = %6lu|\n", ocp->nexcluded);
137    vprintlogrsp (rsp, "|Total Compiled Systems     = %6lu|\n", ocp->nnodes + ocp->npoints - ocp->nexcluded);
138    vprintlogrsp (rsp, "+-----------------------------------+\n");
139  if (!NoRedir)
140    vprintlogrsp (rsp, "|ReDirected Systems         = %6lu|\n", ocp->nredirect);
141    vprintlogrsp (rsp, "|Null Phone Systems         = %6lu|\n", ocp->nnullphone);
142    vprintlogrsp (rsp, "+-----------------------------------+\n");
143    vprintlogrsp (rsp, "|Unique Addresses           = %6lu|\n", ocp->naddr);
144  if (ocp->nphones)
145    vprintlogrsp (rsp, "|Unique Phone Numbers       = %6lu|\n", ocp->nphones);
146  if (ocp->nsysops)
147    vprintlogrsp (rsp, "|Unique SysOp Names         = %6lu|\n", ocp->nsysops);
148    vprintlogrsp (rsp, "+-----------------------------------+\n");
149 }
150 
151 
renameoutfile(const char * tmpname,const char * newname)152 static int renameoutfile (const char *tmpname, const char *newname)
153 {
154     if (access (newname, 0) == 0)       // erase existing file
155         EraseFile (newname, 30);
156 
157     if (rename (tmpname, newname)) {    // rename temp -> new
158         vprintlog ("Cannot rename \"%s\" to \"%s\"\n", tmpname, newname);
159         errorlevel = NO_NEW;
160         return -1;
161     }
162 
163     return 0;           // All Ok
164 }
165 
166 
renameout(OutLoc * l)167 static void renameout (OutLoc *l)
168 {
169     if (renameoutfile (l->NLname (NL_DAs), l->NLname (NL_DAT)))
170         return;
171 
172     renameoutfile (l->NLname (NL_NDs), l->NLname (NL_NDX));
173 
174     if (l->v7data.sysopndx)
175         renameoutfile (l->NLname (NL_SDs), l->NLname (NL_SDX));
176 
177     if (l->v7data.flags & V7DTP_F)
178         renameoutfile (l->NLname (NL_DTs), l->NLname (NL_DTP));
179 
180     if (l->v7data.flags & V7PDX_F)
181         renameoutfile (l->NLname (NL_PDs), l->NLname (NL_PDX));
182 }
183 
184 
Process(void)185 BOOL OUTBLK::Process (void)         // public
186 {
187     BOOL SomeNeeded = FALSE;        // True if some exported lists are NeededBeforeKill
188 
189     OUTCUR outcur (o);
190 
191     Busy *bsy = new Busy (l->v7data.nodex);     // Name for .bsy flag
192 
193     if (!killafter)                 // Make the .bsy
194         if (bsy->Wait (60)) {
195             vprintlogrsp (MsgLogRsp, "\nTimeOut on \"%s.bsy\"\n\n", l->v7data.nodex);
196             errorlevel = ERR_TIMEOUT;
197             delete bsy;
198             return SomeNeeded;
199         }
200 
201     Open (&outcur); /* Open output files for current OUTBLK */
202 
203     vprintlogrsp (MsgLogRsp, "\nCompiling to \"%s\"\n\n", l->v7data.nodex);
204 
205     BOOL Ok = TRUE;
206 
207     INPBLK *cib = (INPBLK *)InpBlk;
208     while (cib) {
209         if (!cib->Process (&outcur, this, &SomeNeeded)) {
210             Ok = FALSE;
211             break;
212         }
213         cib = (INPBLK *)cib->next;
214     }
215 
216     outcur.FreeTab ();
217 
218     printf ("%15s\n", "");
219 
220     vprintlog ("Nodelist Input Completed.\n\n");
221 
222     Close (&outcur, Ok);           /* Close output files for current OUTBLK */
223 
224     if (!Ok) {
225         vprintlog ("Processing of \"%s\" aborted\n\n", l->v7data.nodex);
226         delete bsy;
227         return SomeNeeded;
228     }
229 
230     if (killafter) {
231         if (bsy->Wait (60)) {
232             vprintlogrsp (MsgLogRsp, "\nTimeOut on \"%s.bsy\"\n\n", l->v7data.nodex);
233             errorlevel = ERR_TIMEOUT;
234             delete bsy;
235             return SomeNeeded;
236         }
237         renameout (l);
238     }
239 
240     delete bsy;
241 
242     if (!noreport)
243         SizeReport (&outcur, l->v7data.flags & Stats_F ? MsgLogRsp : NULL);
244 
245     vprintlogrsp (MsgLogRsp, "\nCompilation of \"%s\" Completed.\n\n", l->v7data.nodex);
246 
247     return SomeNeeded;
248 }
249 
250 
WriteDtpHead(FILE * f)251 static dword WriteDtpHead (FILE *f)
252 {
253     const _DTPHead DTPHead = {
254         {
255           sizeof (_DTPCtl),
256           V7PLUS_VERSION,
257           sizeof (_DTPAllLnk),
258           sizeof (_DTPNodeLnk)
259         },{
260           0,            // ndowns (top level nodes)
261           OfsNoLink     // pointer to first downlink (first top node)
262         }
263     };
264 
265     if (fwrite (&DTPHead, sizeof (DTPHead), 1, f) != 1)
266         DiskFull (f);
267 
268     return sizeof (DTPHead);
269 }
270 
271 
Open(OUTCUR * ocp)272 void OUTBLK::Open (OUTCUR *ocp)  // open out files for current OUTBLK
273 {
274                                         // Open DAT/DA$
275     if ((ocp->nodex_dat = fopen (l->NLname (NL_DAs), "wb")) == NULL) {
276     	vprintlog ("Could not open V7 Nodelist Index File \"%s\"\n", l->NLname (NL_DAs));
277     	myexit(ERR_WRITE_V7);
278     }
279     if (l->v7data.flags & V7DTP_F) {        // Open DTP/DT$
280         ocp->nodex_dtp = fopen (l->NLname (NL_DTs), "wb");
281         ocp->dtpofs = WriteDtpHead (ocp->nodex_dtp);
282     }
283 
284     ocp->heap->Open ();
285 }
286 
287 
MyClose(FILE * f)288 static void MyClose (FILE *f)
289 {
290     if (fclose (f) == EOF)
291         DiskFull (f);
292 }
293 
294 
Close(OUTCUR * ocp,BOOL Ok)295 void OUTBLK::Close (OUTCUR *ocp, BOOL Ok)
296 {
297     if (Ok)
298         ocp->heap->Close ();        // build unique block of pointers
299 
300     MyClose (ocp->nodex_dat);       // close DAT/DA$
301 
302     if (l->v7data.flags & V7DTP_F)             // close DTP/DT$
303         MyClose (ocp->nodex_dtp);
304 
305     if (!Ok) {
306         unlink (l->NLname (NL_DAs));
307         if (l->v7data.flags & V7DTP_F)
308             unlink (l->NLname (NL_DTs));
309         return;
310     }
311 
312     printflush ("Creating Address Index\n");
313     ocp->naddr = ocp->heap->MkNodeNdx (l->NLname (NL_NDs));
314 
315     if (l->v7data.flags & V7DTP_F) {
316         ocp->heap->DTPLnkOpen ();
317 
318         printflush ("Linking Fido Hierarchy\n");
319         ocp->heap->FidoLnk ();
320     }
321 
322     if (l->v7data.flags & V7PDX_F) {
323         printflush ("Creating Phone Index\n");
324         ocp->nphones = ocp->heap->MkPhLst (l->NLname (NL_PDs));
325     }
326 
327     if (l->v7data.sysopndx || l->FidoUserLst) {
328         printflush ("Creating SysOp Index\n");
329         ocp->nsysops = ocp->heap->MkSysLst (l->NLname (NL_SDs), l->FidoUserLst);
330     }
331 
332     if (l->v7data.flags & V7DTP_F) {
333         printflush ("Linking DTP file");
334         ocp->heap->DTPLnkClose (l->NLname (NL_DTs), l->v7data.flags & V7Dsk_F);
335         printflush ("\n");
336     }
337 
338 }
339 
340 
ChkNew(void)341 BOOL OutncBlk::ChkNew (void)
342 {
343     BOOL New = FALSE;
344     InpncBlk *cib = InpBlk;
345     while (cib && !New) {
346         New = cib->ChkNew ();
347         cib = cib->next;
348     }
349     return New;
350 }
351 
352 
PrepareExportNeeded(void)353 void OUTBLK::PrepareExportNeeded (void)
354 {
355     INPBLK *cib = (INPBLK *)InpBlk;
356     while (cib) {
357         SEGEXPORT::PrepareAllNeeded (cib->SegExpHead);
358         cib = (INPBLK *)cib->next;
359     }
360 }
361 
362 
Prepare(int Action,BOOL * SomeNew)363 BOOL OUTBLK::Prepare (int Action, BOOL *SomeNew)
364 {
365     BOOL SomeNeededBeforeKill = OutncBlk::Prepare (Action, SomeNew);
366     if (Action == OB_NeededOnly)
367         PrepareExportNeeded ();
368     return SomeNeededBeforeKill;
369 }
370 
371 
Prepare(int Action,BOOL * SomeNew)372 BOOL OutncBlk::Prepare (int Action, BOOL *SomeNew)
373 {
374     BOOL SomeNeededBeforeKill = FALSE;
375 
376     InpncBlk *cib = InpBlk;
377     while (cib) {
378         if (Action == OB_NewOnly)
379             if (!cib->ChkNew ()) {
380                 cib = cib->next;
381                 continue;
382             }
383         if (cib->Prepare (Action == OB_NeededOnly, SomeNew))
384             SomeNeededBeforeKill = TRUE;
385         cib = cib->next;
386     }
387     return SomeNeededBeforeKill;
388 }
389 
390 
KillSource(void)391 void OUTBLK::KillSource (void)
392 {
393     INPBLK *cib = (INPBLK *)InpBlk;
394     while (cib) {
395         cib->KillSource ();
396         cib = (INPBLK *)cib->next;
397     }
398 }
399 
400 
KillSource(void)401 void OutncBlk::KillSource (void)
402 {
403     InpncBlk *cib = InpBlk;
404     while (cib) {
405         cib->KillSource ();
406         cib = cib->next;
407     }
408 }
409 
410