1 /*****************************************************************************/
2 /*                                                                           */
3 /*                 (C) Copyright 1992-1997  Alberto Pasquale                 */
4 /*                                                                           */
5 /*                   A L L   R I G H T S   R E S E R V E D                   */
6 /*                                                                           */
7 /*****************************************************************************/
8 /*                                                                           */
9 /* This source code is NOT in the public domain and it CANNOT be used or     */
10 /* distributed without written permission from the author.                   */
11 /*                                                                           */
12 /*****************************************************************************/
13 /*                                                                           */
14 /* How to contact the author:  Alberto Pasquale of 2:332/504@fidonet         */
15 /*                             Viale Verdi 106                               */
16 /*                             41100 Modena                                  */
17 /*                             Italy                                         */
18 /*                                                                           */
19 /*****************************************************************************/
20 
21 // Export.Cpp
22 
23 #include <string.h>
24 #include <apgenlib.hpp>
25 #include <bbsgenlb.hpp>
26 #include <unistd.h>
27 #include "data.hpp"
28 #include "misc.hpp"
29 #include "export.hpp"
30 #include "parsetyp.hpp"
31 #include "filesbbs.hpp"
32 
33 
SegAll(SegAll * isa)34 SegAll::SegAll (SegAll *isa)
35 {
36     if (!isa)
37         memset (this, 0, sizeof (*this));
38     else {
39         *this = *isa;
40         ArcMethHead = CopyArcMethod (isa->ArcMethHead);
41     }
42 }
43 
44 
SegLoc(void)45 SegLoc::SegLoc (void)
46 {
47     memset (this, 0, sizeof (*this));
48 }
49 
50 
SegVar(void)51 SegVar::SegVar (void)
52 {
53     memset (this, 0, sizeof (*this));
54 }
55 
56 
SEGEXPORT(SegAll * isa)57 SEGEXPORT::SEGEXPORT (SegAll *isa)
58 {
59     a = new SegAll (isa);
60     l = new SegLoc;
61     v = new SegVar;
62     next = NULL;
63 }
64 
65 
PrepareAllNeeded(SEGEXPORT * Head)66 void SEGEXPORT::PrepareAllNeeded (SEGEXPORT *Head)
67 {
68     DAYDIR *dd;
69     BOOL exist;
70 
71     SEGEXPORT *s = Head;
72     while (s) {
73         if ((!s->a->NeededBeforeKill) || (s->v->f) || (!s->l->ArcName)) {
74             s = s->next;  // not necessary or just created or not archived
75             continue;
76         }
77 
78         if (s->l->Varname) {        // does the requested list already exist ?
79             dd = new DAYDIR (NODELIST, s->l->name);
80             exist = (dd->LatestDay () != -1);
81             delete dd;
82         } else {
83             exist = fexist (s->l->name);
84         }
85         if (exist) {
86             s = s->next;
87             continue;
88         }                    // if not, decompress it
89 
90         dd = new DAYDIR (ARCLIST, s->l->ArcName);
91         if (dd->NewAvail ())
92             ExecUnarc (dd->LatestName (), s->l->name);
93         delete dd;
94 
95         s = s->next;
96     }
97 }
98 
99 
ArcOk(char * ArcTpl,ARCMETHOD * amh,time_t NodeTime,int NodeDay=-1)100 static BOOL ArcOk (char *ArcTpl, ARCMETHOD *amh, time_t NodeTime, int NodeDay = -1)
101 {
102     char ArcName[PATH_MAX];
103 
104     strcpy (ArcName, ArcTpl);
105     BOOL Var = (NodeDay > 0);
106 
107     char *p = ArcName + strlen (ArcName) - 3;   // pointer to extension
108     if (Var)                               // day name
109         sprintf (p+1, "%02d", NodeDay % 100);
110 
111     ARCMETHOD *am = amh;
112     while (am) {
113         if (Var) {
114             *p = am->first;
115             if (!fexist (ArcName))
116                 return FALSE;
117         } else {
118             strcpy (p, am->archiver->ext);
119             if (arcfiletime (ArcName) != NodeTime)   // ArcName missing or not up to date
120                 return FALSE;
121         }
122 
123         am = am->next;
124     }
125 
126     return TRUE;
127 }
128 
129 
OpenAll(SEGEXPORT * SegExpHead,time_t NodeTime,int NodeDay,char * NodeList)130 BOOL SEGEXPORT::OpenAll (SEGEXPORT *SegExpHead, time_t NodeTime, int NodeDay, char *NodeList)
131 {
132     BOOL SomeNeeded = FALSE;        // Varname not accepted in cfg if NodeList is not variable
133 
134     SEGEXPORT *s = SegExpHead;
135     while (s) {
136         s->v->FTime = NodeTime;
137         s->v->FDay  = s->l->Varname ? NodeDay : -1;
138         if (s->l->Varname) {
139             s->l->sname = newcpy (s->l->name);
140             SetDay3 (s->l->sname, NodeDay);
141         } else
142             s->l->sname = s->l->name;
143         time_t oldt = DosFileTime (s->l->sname);
144 
145         if (!IgnoreDat && !s->l->Append) {
146             if (oldt == s->v->FTime)
147                 goto OAc;           // export file already existing, equal date
148             if (s->l->Varname)
149                 if (oldt != 0)
150                     goto OAc;       // export file already existing, equal day
151             if (oldt == 0)      // export file not existing
152                 if (s->l->ArcName)
153                     if (ArcOk (s->l->ArcName, s->a->ArcMethHead, NodeTime, s->v->FDay))
154                         goto OAc;       // arced export file already existing
155         }
156 
157         if (s->l->Varname) {
158             DAYDIR *dd = new DAYDIR (NODELIST, s->l->name);
159             dd->KillAll ();
160             delete dd;
161         }
162 
163         if (s->l->Append)
164             s->v->f = SmartOpen (s->l->sname, ";\n; Start of New Export Segment\n;\n");
165         else
166             s->v->f = fopen (s->l->sname, "wt");
167 
168         if (s->v->f == NULL)
169             vprintlogrsp (MsgLogRsp, "Cannot open \"%s\"\n", s->l->sname);
170         else {
171             SomeNeeded = SomeNeeded || s->a->NeededBeforeKill;
172             vprintlogrsp (MsgLogRsp, "Exporting to \"%s\"\n", s->l->sname);
173             if (fprintf (s->v->f, "; Exported from \"%s\"\n;\n", NodeList) < 0) {
174                 vprintlogrsp (MsgLogRsp, "Error writing to \"%s\"\n", s->l->sname);
175                 myexit (DISK_FULL);
176             }
177         }
178   OAc:  s = s->next;
179     }
180 
181     return SomeNeeded;
182 }
183 
184 
WriteAll(SEGEXPORT * SegExpHead,const EXTADR * adr,char * buff)185 void SEGEXPORT::WriteAll (SEGEXPORT *SegExpHead, const EXTADR *adr, char *buff)
186 {
187     SEGEXPORT *s = SegExpHead;
188     while (s) {
189         if (s->v->f) {
190             if ((s->l->Seg == NULL) || InPartAdrLst (adr, s->l->Seg))
191                 if (fprintf (s->v->f, "%s\n", buff) < 0) {
192                     vprintlogrsp (MsgLogRsp, "Error writing to \"%s\"\n", s->l->sname);
193                     myexit (DISK_FULL);
194                 }
195         }
196         s = s->next;
197     }
198 }
199 
200 
CloseAll(SEGEXPORT * SegExpHead)201 void SEGEXPORT::CloseAll (SEGEXPORT *SegExpHead)
202 {
203     SEGEXPORT *s = SegExpHead;
204     while (s) {
205         if (s->v->f) {
206             if (fclose (s->v->f)) {
207                 vprintlogrsp (MsgLogRsp, "Cannot close \"%s\"\n", s->l->sname);
208                 myexit (DISK_FULL);
209             }
210             if (!s->l->Append)
211                 if (!touchf (s->l->sname, s->v->FTime))
212                     vprintlogrsp (MsgLogRsp, "Cannot set datime of \"%s\"\n", s->l->sname);
213             if (s->l->ArcName) {
214                 DAYDIR *dd = new DAYDIR (ARCLIST, s->l->ArcName, s->l->ArcKeep - 1);
215                 dd->KillOld ();
216                 delete dd;
217                 ExecArc (s->l->ArcName, s->l->sname, s->v->FDay,
218                          s->a->ArcMethHead, s->a->BeforeArc, s->a->AfterArc,
219                          s->l->ArcDesc);
220             }
221         }
222         if (s->l->Varname)
223             delete[] s->l->sname;
224         s = s->next;
225     }
226 }
227 
228 
ExecArc(char * ArcName,char * name,int NodeDay,ARCMETHOD * ArcMethHead,char * BeforeArc,char * AfterArc,char * ArcDesc)229 time_t ExecArc (char *ArcName, char *name, int NodeDay, ARCMETHOD *ArcMethHead, char *BeforeArc, char *AfterArc, char *ArcDesc)
230 {
231     char *prm_a = new char[PATH_MAX];
232     char *prm_f = new char[PATH_MAX];
233     char *e_dir = new char[PATH_MAX];
234     char *c_dir = new char[PATH_MAX];
235 
236     BOOL Var = (NodeDay > 0);
237 
238     strcpy (prm_a, ArcName);
239     char *p = prm_a + strlen (prm_a) - 3;   // pointer to extension
240     if (Var)                               // day name
241         sprintf (p+1, "%02d", NodeDay % 100);
242 
243     strcpy (e_dir, name);        // already resolved
244     MoveName (e_dir, prm_f);
245     if (Var)                        // make sure there is correct extension
246         SetDay3 (prm_f, NodeDay);
247 
248     mkdirpath (e_dir);          // make sure extract dir exists
249     getcwd (c_dir, PATH_MAX);    // save current dir
250     cdd (e_dir);                // change to extract dir
251 
252     time_t ftime = DosFileTime (prm_f);
253 
254     ARCMETHOD *am = ArcMethHead;
255     while (am) {
256         if (Var) {
257             *p = am->first;
258             if (fexist (prm_a)) {
259                 if (!toucharcfile (prm_a, ftime))
260                     vprintlog ("Error setting date and time of \"%s\"\n", prm_a);
261                 am = am->next;
262                 continue;
263             }
264         } else {
265             strcpy (p, am->archiver->ext);
266             time_t arctime = arcfiletime (prm_a);
267             if (arctime == ftime) {
268                 am = am->next;
269                 continue;
270             }
271             if (arctime > 0)
272                 DeleteFile (prm_a);
273         }
274 
275         if (BeforeArc) {
276             RunCmd (BeforeArc, RCf, "af", prm_a, prm_f);
277             if (DosFileTime (prm_f) != ftime)
278                 if (!touchf (prm_f, ftime))
279                     vprintlog ("Error re-setting date and time of \"%s\"\n", prm_f);
280         }
281 
282         Compr->Arc (am->archiver, prm_a, prm_f);
283 
284         if (!toucharcfile (prm_a, ftime))
285             vprintlog ("Error setting date and time of \"%s\"\n", prm_a);
286 
287         if (ArcDesc)
288             SetDesc (prm_a, ArcDesc, NodeDay, am->archiver->name);
289 
290         if (AfterArc)
291             RunCmd (AfterArc, RCf, "af", prm_a, prm_f);
292 
293         am = am->next;
294     }
295 
296     cdd (c_dir);                // restore dir
297 
298     delete[] c_dir;
299     delete[] e_dir;
300     delete[] prm_f;
301     delete[] prm_a;
302 
303     return ftime;
304 }
305 
306 
ExecUnarc(char * ArcFile,char * file,char * BeforeUnArc,char * AfterUnarc)307 void ExecUnarc (char *ArcFile, char *file, char *BeforeUnArc, char *AfterUnarc)
308 {
309     char *prm_f = new char[PATH_MAX];
310     char *e_dir = new char[PATH_MAX];
311     char *c_dir = new char[PATH_MAX];
312 
313     strcpy (e_dir, file);
314     MoveName (e_dir, prm_f);
315 
316     BOOL FFix = (strpbrk (prm_f, "?*") == NULL);  // no wildcards: prm_f fixed
317 
318     mkdirpath (e_dir);          // make sure extract dir exists
319     getcwd (c_dir, PATH_MAX);    // save current dir
320     cdd (e_dir);                // change to extract dir
321 
322     if (BeforeUnArc)
323         RunCmd (BeforeUnArc, RCf, "af", ArcFile, prm_f);
324 
325     if (FFix)                           // If prm_f fixed -> delete
326         if (Exist (prm_f))
327             if (tunlink (prm_f, 60))
328                 myexit (ERR_UNARCHIVE);
329 
330     Compr->UnArc (ArcFile, prm_f);
331 
332     if (FFix) {                         // If prm_f fixed -> touch ArcFile
333         time_t nodetime = DosFileTime (prm_f);
334         if (nodetime == 0)
335             myexit (ERR_UNARCHIVE);
336         if (!toucharcfile (ArcFile, nodetime))
337             vprintlog ("Error setting date and time of \"%s\"\n", ArcFile);
338     }
339 
340     if (AfterUnarc)
341         RunCmd (AfterUnarc, RCf, "af", ArcFile, prm_f);
342 
343     cdd (c_dir);                // restore dir
344 
345     delete[] c_dir;
346     delete[] e_dir;
347     delete[] prm_f;
348 }
349 
350 
KillSource(SEGEXPORT * SegExpHead)351 void SEGEXPORT::KillSource (SEGEXPORT *SegExpHead)
352 {
353     SEGEXPORT *s = SegExpHead;
354     while (s) {
355         if (s->l->ArcName && s->a->ArcMethHead) {
356             if (!s->l->Varname)
357                 DeleteFile (s->l->name, CHK_EXIST);
358             else {
359                 DAYDIR *dd = new DAYDIR (NODELIST, s->l->name);
360                 dd->KillAll ();
361                 delete dd;
362             }
363         }
364         s = s->next;
365     }
366 }
367 
368 
369