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