1 
2 /*****************************************************************************/
3 /*                                                                           */
4 /*                 (C) Copyright 1992-1997  Alberto Pasquale                 */
5 /*                 Portions (C) Copyright 1999 Per Lundberg                  */
6 /*                                                                           */
7 /*                   A L L   R I G H T S   R E S E R V E D                   */
8 /*                                                                           */
9 /*****************************************************************************/
10 /*                                                                           */
11 /* How to contact the author:  Alberto Pasquale of 2:332/504@fidonet         */
12 /*                             Viale Verdi 106                               */
13 /*                             41100 Modena                                  */
14 /*                             Italy                                         */
15 /*                                                                           */
16 /*****************************************************************************/
17 
18 #include <signal.h>
19 #define __USE_GNU
20 #define _GNU_SOURCE
21 #ifndef __GNUC__
22 #  include <libio.h>
23 #endif
24 #include <stdio.h>
25 #include <ctype.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #if __GNUC__ < 3
29 #  include <new.h>
30 #endif
31 #include <fcntl.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <limits.h>
35 #include <unistd.h>
36 #include <stdio.h>
37 #include "apgenlib.hpp"
38 #include "types.hpp"
39 #include "defines.hpp"
40 #include "msgapier.hpp"
41 #include "misc.hpp"
42 #include "outblk.hpp"
43 #include "cfgdata.hpp"
44 #include "data.hpp"
45 #include "flstdat.hpp"
46 #include "parsetyp.hpp"
47 #include "parsecfg.hpp"
48 
49 static OUTBLK  *cob;
50 static BOOL SomeNewNeeded;      // needed for RunBeforeKillSource
51 
KillSourceFiles(void)52 void KillSourceFiles (void)
53 {
54     if (nocomp)
55         nocomp->KillSource ();
56 
57     OUTBLK *ob = outblk;        // compiled blocks
58     while (ob) {
59         ob->KillSource ();
60         ob = ob->next;
61     }
62 }
63 
PrepareAllNeeded(void)64 void PrepareAllNeeded (void)
65 {
66     if (nocomp)
67         nocomp->Prepare (IB_NeededOnly);
68 
69     OUTBLK *ob = outblk;        // compiled blocks
70     while (ob) {
71         ob->Prepare (IB_NeededOnly);
72         ob = ob->next;
73     }
74 }
75 
exitfunc(void)76 void exitfunc (void)
77 {
78     if (BeforeKillSource)
79         if (SomeNewNeeded) {
80             PrepareAllNeeded ();
81             RunCmd (BeforeKillSource, RCf);
82         }
83 
84     if (killsource)
85         KillSourceFiles ();
86 
87     switch (errorlevel) {
88     	case OK:
89 	    vprintlogrsp (MsgLogRsp, "\nEverything went ok!\n");
90             break;
91 	case OPEN_ERR:
92 	    vprintlogrsp (MsgLogRsp, "\nFile Open Error!\n");
93 	    break;
94         case DISK_FULL:
95             vprintlogrsp (MsgLogRsp, "\nError: Disk Full !\n");
96             break;
97         case NOTHING_COMPILED:
98             vprintlog ("\nNothing new to compile.\n");
99             break;
100         case OUT_OF_MEMORY:
101             vprintlogrsp (MsgLogRsp, "\nError: Out Of Memory !\n");
102             break;
103         case USER_BREAK:
104             vprintlogrsp (MsgLogRsp, "\n!!! User Break !!!\n");
105             break;
106     }
107 
108     vprintlogrsp (MsgLogRsp, "\nTerminating with Errorlevel %d.\n", errorlevel);
109 
110     if (ApiOpened) {
111         if (MsgLogRsp)
112             closersp (MsgLogRsp, (errorlevel == NOTHING_COMPILED));
113         if (MsgLog)
114             if (MsgCloseArea (MsgLog))
115                 wr_mapi_err ();
116 
117         if (MsgRemRsp)
118             closersp (MsgRemRsp, (errorlevel == NOTHING_COMPILED));
119         if (MsgRem)
120             if (MsgCloseArea (MsgRem))
121                 wr_mapi_err ();
122 
123         if (MsgCloseApi ())
124             vprintlog ("Error closing MsgApi !\n");
125     }
126 
127     vwritelog ("End, FastLst "VER);
128 #if defined(__FreeBSD__) || defined(__CYGWIN__)
129     fclose(logfile);
130 #else
131     fcloseall ();
132 #endif
133 
134     if ((cob) && (killafter)) {     /* Erase temporary files if existing (aborted) */
135 
136         unlink (cob->l->NLname(NL_DAs));
137         unlink (cob->l->NLname(NL_NDs));
138 
139         if (cob->l->v7data.sysopndx)
140             unlink (cob->l->NLname(NL_SDs));
141 
142         if (cob->l->v7data.flags & V7DTP_F)
143             unlink (cob->l->NLname(NL_DTs));
144 
145         if (cob->l->v7data.flags & V7PDX_F)
146             unlink (cob->l->NLname(NL_PDs));
147 
148     }
149 }
150 
151 #ifndef __GNUC__
152 #pragma off (unreferenced)
153 #endif
154 
BreakHandler(int sign)155 void BreakHandler (int sign)
156 {
157     Break = TRUE;
158 }
159 
160 #ifndef __GNUC__
161 #pragma on (unreferenced)
162 #endif
163 
main(short argc,char * argv[])164 int main (short argc, char *argv[])
165 {
166     char    *s;
167     #ifndef __QNXNTO__
168        char    *config_file = "fastlst.cfg";
169     #else
170        char    *config_file = "/etc/fido/fastlst.cfg";
171     #endif // __QNXNTO__
172     BOOL    PrepOnly;
173     short   i;
174 
175     StartTime = time (NULL);        // record start time
176 
177     fprintf (stderr,
178 	     "\n"
179 	     "FastLst ver. " VER "\n"
180 	     "See the file AUTHORS for copyright infos.\n"
181 	     "\n");
182 
183 //    set_new_handler (new_handler);      // abort on out of memory
184 
185     PrepOnly = FALSE;
186 
187     if (argc > 1) {
188         for (i=1;i<argc;i++) {
189             s=argv[i];
190             if ((s[0] == '/') || (s[0] == '-')) {
191                 switch(tolower(s[1])) {
192                     case 'h' :
193                     case '?' :  printf ("\nAvailable options:\n\n");
194                                 printf ("-c<config>     Use <config> configuration file\n");
195                                 printf ("-f             Force compilation even if nothing new\n");
196                                 printf ("-i             Ignore <FastLst>.DAT (run as 1st time)\n");
197                                 printf ("-p             Prepare: Unarc and Apply diffs only\n");
198                                 printf ("-r             Continue Processing on CRC error\n");
199                                 printf ("-h or -?       This help\n\n");
200                                 myexit (HELP_REQ);
201 
202                     case 'c' :  config_file=s+2;
203                                 break;
204 
205                     case 'f' :  ForceComp = TRUE;
206                                 break;
207 
208                     case 'i' :  IgnoreDat = TRUE;
209                                 break;
210 
211                     case 'p' :  PrepOnly = TRUE;
212                                 break;
213 
214                     case 'r' :  nocrcexit = TRUE;
215                                 break;
216 
217                       default:  vprintlog("Can't understand \"%s\"\n\n", s);
218                                 break;
219                 }
220             }
221         }
222     }
223 
224 
225     /* Parse configuration file */
226     Config *cfg = new Config;
227     time_t cfgtime = cfg->parse (config_file);
228     delete cfg;
229 
230     if (!IgnoreDat)
231         read_data (DatFile, cfgtime);
232 
233 
234     if (MsgLogAreaPath || MsgRemAreaPath) {
235         struct _minf minf;
236         minf.req_version = 0;
237         minf.def_zone = 0;
238         if (MsgOpenApi (&minf)) {           /* MSGAPI init */
239            vprintlog ("Error initializing MSGAPI !\n");
240            myexit (MsgApiInitErr);
241         }
242         ApiOpened = TRUE;
243 
244         if (MsgLogAreaPath) {
245             vprintlog ("Reporting to \"%s\"\n", MsgLogAreaPath);
246             MsgLog = MsgSOpenArea ((byte *)MsgLogAreaPath, MSGAREA_NORMAL, MsgLogAreaType);
247             if (MsgLog == NULL) {
248                vprintlog ("Cannot open message area \"%s\"\n", MsgLogAreaPath);
249                wr_mapi_err ();
250                myexit (AreaOpenErr);
251             }
252             MsgLogRsp = writerspheader (MsgLog, "FastLst "VER, &MsgFromNode,
253                 MsgTo, &MsgToNode, "Nodelist Compilation Report",
254                 (word) MsgAttr, NULL);
255         }
256 
257         if (MsgRemAreaPath) {
258             vprintlog ("Sending Nodelist Comments to \"%s\"\n", MsgRemAreaPath);
259             MsgRem = MsgSOpenArea ((byte *)MsgRemAreaPath, MSGAREA_NORMAL, MsgRemAreaType);
260             if (MsgRem == NULL) {
261                vprintlog ("Cannot open message area \"%s\"\n", MsgRemAreaPath);
262                wr_mapi_err ();
263                myexit (AreaOpenErr);
264             }
265             MsgRemRsp = writerspheader (MsgRem, "FastLst "VER, &MsgFromNode,
266                 MsgTo, &MsgToNode, "Nodelist Comments",
267                 (word) MsgAttr, NULL);
268         }
269     }
270 
271     atexit (exitfunc);
272     signal (SIGINT, BreakHandler);
273 
274     SomeNewNeeded = FALSE;      // initialized false
275 
276     if (nocomp)
277         if (nocomp->Prepare (OB_NewOnly))
278             SomeNewNeeded = TRUE;
279 
280     BOOL SomethingCompiled = FALSE;
281     cob = outblk;
282     while (cob) {
283         BOOL SomeNew = FALSE;
284         if (ForceComp || cob->ChkNew ()) {
285             if (cob->Prepare (OB_All, &SomeNew))    // Prepare (Extract) for compilation
286                 SomeNewNeeded = TRUE;
287             if (!PrepOnly) {
288                 if (SomeNew || ForceComp) {
289                     if (cob->Process ())    // Compile
290                         SomeNewNeeded = TRUE;
291                     SomethingCompiled = TRUE;
292                 }
293             }
294         }
295         cob = cob->next;
296     }
297 
298     if ((errorlevel != NO_NEW) && (errorlevel != ERR_TIMEOUT))
299         save_data (DatFile, cfgtime);
300 
301     if ((errorlevel == OK) && (!SomethingCompiled))
302         errorlevel = NOTHING_COMPILED;
303 
304     exit (errorlevel);
305 }
306