1 
2 /*
3  * fecfg146.c
4  *
5  * This module contains routines that read in structures from
6  * FASTEECHO configuration files in a portable way, i.E. they will even
7  * work in cases where a fread(&structure, sizeof(structure), 1, stream)
8  * would fail because of structure packing or big endian problems.
9  *
10  * Only those structures that are of importance to MsgEd have been
11  * implemented.
12  *
13  * Written 04-Oct-98 by Tobias Ernst and donated to the Public Domain.
14  *
15  */
16 
17 #include <assert.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21 
22 #include "fecfg146.h"
23 
24 /*
25  *  get_dword
26  *
27  *  Reads in a 4 byte word that is stored in little endian (Intel) notation
28  *  and converts it to the local representation n an architecture-
29  *  independent manner
30  */
31 
32 #define get_dword(ptr)            \
33    ((unsigned long)((ptr)[0]) |           \
34     (((unsigned long)((ptr)[1])) << 8)  | \
35     (((unsigned long)((ptr)[2])) << 16) | \
36     (((unsigned long)((ptr)[3])) << 24))  \
37 
38 /*
39  *  get_word
40  *
41  *  Reads in a 2 byte word that is stored in little endian (Intel) notation
42  *  and converts it to the local representation in an architecture-
43  *  independent manner
44  */
45 
46 #define get_word(ptr)         \
47     ((unsigned short)(ptr)[0] |         \
48      (((unsigned short)(ptr)[1]) << 8 ))
49 
50 
51 /*
52  * read_setup_ge
53  *
54  * reads a SETUP_GE structure.
55  *
56  */
57 
read_fe_config(CONFIG * c,FILE * fp)58 int read_fe_config(CONFIG *c, FILE *fp)
59 {
60     unsigned char *buffer = (unsigned char *) malloc(FE_CONFIG_SIZE);
61     unsigned char *pbuf;
62     int i;
63 
64     pbuf = buffer;
65 
66     if (buffer == NULL)
67     {
68         return -1;
69     }
70 
71     if (fread(buffer, FE_CONFIG_SIZE, 1, fp) != 1)
72     {
73         free(buffer);
74         return -1;
75     }
76 
77     c->revision = get_word(pbuf); pbuf += 2;
78     c->flags    = get_dword(pbuf); pbuf += 4;
79     c->NodeCnt  = get_word(pbuf); pbuf += 2;
80     c->AreaCnt  = get_word(pbuf); pbuf += 2;
81     c->unused1  = get_word(pbuf); pbuf += 2;
82 
83     memcpy(c->NetMPath, pbuf, _MAXPATH); pbuf += _MAXPATH;
84     memcpy(c->MsgBase, pbuf, _MAXPATH); pbuf += _MAXPATH;
85     memcpy(c->InBound, pbuf, _MAXPATH); pbuf += _MAXPATH;
86     memcpy(c->OutBound, pbuf, _MAXPATH); pbuf += _MAXPATH;
87     memcpy(c->Unpacker, pbuf, _MAXPATH); pbuf += _MAXPATH;
88     memcpy(c->LogFile, pbuf, _MAXPATH); pbuf += _MAXPATH;
89     memcpy(c->unused2, pbuf, 336); pbuf += 336;
90     memcpy(c->Unpacker2, pbuf, _MAXPATH); pbuf += _MAXPATH;
91     memcpy(c->UnprotInBound, pbuf, _MAXPATH); pbuf += _MAXPATH;
92     memcpy(c->StatFile, pbuf, _MAXPATH); pbuf += _MAXPATH;
93     memcpy(c->SwapPath, pbuf, _MAXPATH); pbuf += _MAXPATH;
94     memcpy(c->SemaphorePath, pbuf, _MAXPATH); pbuf += _MAXPATH;
95     memcpy(c->BBSConfigPath, pbuf, _MAXPATH); pbuf += _MAXPATH;
96     memcpy(c->QueuePath, pbuf, _MAXPATH); pbuf += _MAXPATH;
97     memcpy(c->RulesPrefix, pbuf, 32); pbuf += 32;
98     memcpy(c->RetearTo, pbuf, 40); pbuf += 40;
99     memcpy(c->LocalInBound, pbuf, _MAXPATH); pbuf += _MAXPATH;
100     memcpy(c->ExtAfter, pbuf, _MAXPATH - 4); pbuf += _MAXPATH - 4;
101     memcpy(c->ExtBefore, pbuf, _MAXPATH - 4); pbuf += _MAXPATH - 4;
102     memcpy(c->unused3, pbuf, 480); pbuf += 480;
103 
104     for (i = 0; i < 10; i++)
105     {
106         c->CC[i].what = *pbuf++;
107         memcpy(c->CC[i].object, pbuf, 31); pbuf += 31;
108         c->CC[i].conference = get_word(pbuf); pbuf += 2;
109     }
110 
111     c->security = *pbuf++;
112     c->loglevel = *pbuf++;
113     c->def_days = get_word(pbuf); pbuf += 2;
114     c->def_messages = get_word(pbuf); pbuf += 2;
115     memcpy(c->unused4, pbuf, 462); pbuf += 462;
116     c->autorenum = get_word(pbuf); pbuf += 2;
117     c->def_recvdays = get_word(pbuf); pbuf += 2;
118     c->openQQQs = *pbuf++;
119     c->Swapping = *pbuf++;
120     c->compressafter = get_word(pbuf); pbuf += 2;
121     c->afixmaxmsglen = get_word(pbuf); pbuf += 2;
122     c->compressfree = get_word(pbuf); pbuf += 2;
123 
124     memcpy(c->TempPath, pbuf, _MAXPATH); pbuf += _MAXPATH;
125 
126     c->graphics = *pbuf++;
127     c->BBSSoftware = *pbuf++;
128 
129     memcpy(c->AreaFixHelp, pbuf, _MAXPATH); pbuf += _MAXPATH;
130     memcpy(c->unused5, pbuf, 504); pbuf += 504;
131 
132     c->AreaFixFlags = get_word(pbuf); pbuf += 2;
133     c->QuietLevel = *pbuf++;
134     c->Buffers = *pbuf++;
135     c->FWACnt = *pbuf++;
136     c->GDCnt = *pbuf++;
137 
138     c->rescan_def.flags = get_word(pbuf); pbuf += 2;
139     c->rescan_def.days[0] = get_word(pbuf); pbuf += 2;
140     c->rescan_def.days[1] = get_word(pbuf); pbuf += 2;
141     c->rescan_def.msgs[0] = get_word(pbuf); pbuf += 2;
142     c->rescan_def.msgs[1] = get_word(pbuf); pbuf += 2;
143 
144     c->duperecords = get_dword(pbuf); pbuf += 4;
145 
146     c->arcext.inb = *pbuf++;
147     c->arcext.outb = *pbuf++;
148 
149     c->AFixRcptLen = get_word(pbuf); pbuf += 2;
150     c->AkaCnt = *pbuf++;
151     c->resv = *pbuf++;
152     c->maxPKT = get_word(pbuf); pbuf += 2;
153     c->sharing = *pbuf++;
154     c->sorting = *pbuf++;
155 
156     for (i=0; i < 11; i++)
157     {
158         memcpy(c->sysops[i].name, pbuf, 36); pbuf += 36;
159         c->sysops[i].resv = get_dword(pbuf); pbuf += 4;
160     }
161 
162     memcpy(c->AreaFixLog, pbuf, _MAXPATH); pbuf += _MAXPATH;
163     memcpy(c->TempInBound, pbuf, _MAXPATH); pbuf += _MAXPATH;
164 
165     c->maxPKTmsgs = get_word(pbuf); pbuf += 2;
166     c->RouteCnt = get_word(pbuf); pbuf += 2;
167     c->maxPACKratio = *pbuf++;
168     c->SemaphoreTimer = *pbuf++;
169     c->PackerCnt = *pbuf++;
170     c->UnpackerCnt = *pbuf++;
171     c->GroupCnt = *pbuf++;
172     c->OriginCnt = *pbuf++;
173     c->mailer = get_word(pbuf); pbuf += 2;
174     c->maxarcsize = get_word(pbuf); pbuf += 2;
175     c->maxarcdays = get_word(pbuf); pbuf += 2;
176     c->minInbPKTSize = get_word(pbuf); pbuf += 2;
177 
178     memcpy(c->reserved, pbuf, 804); pbuf += 804;
179 
180     c->AreaRecSize = get_word(pbuf); pbuf += 2;
181     c->GrpDefRecSize = get_word(pbuf); pbuf += 2;
182     c->MaxAreas = get_word(pbuf); pbuf += 2;
183     c->MaxNodes = get_word(pbuf); pbuf += 2;
184     c->NodeRecSize = get_word(pbuf); pbuf += 2;
185     c->offset = get_dword(pbuf); pbuf += 4;
186 
187     assert(pbuf - buffer == FE_CONFIG_SIZE);
188 
189     free(buffer);
190     return 0;
191 }
192 
read_fe_extension_header(ExtensionHeader * h,FILE * fp)193 int read_fe_extension_header(ExtensionHeader *h, FILE *fp)
194 {
195     unsigned char buffer[FE_EXTHEADER_SIZE];
196     unsigned char *pbuf;
197 
198     pbuf = buffer;
199 
200     if (fread(buffer, FE_EXTHEADER_SIZE, 1, fp) != 1)
201     {
202         return -1;
203     }
204 
205     h->type   = get_word(pbuf);  pbuf += 2;
206     h->offset = get_dword(pbuf); pbuf += 4;
207 
208     assert(pbuf - buffer == FE_EXTHEADER_SIZE);
209 
210     return 0;
211 }
212 
read_fe_address(FEAddress * a,FILE * fp)213 int read_fe_address(FEAddress *a, FILE *fp)
214 {
215     unsigned char buffer[FE_ADDRESS_SIZE];
216     unsigned char *pbuf;
217 
218     pbuf = buffer;
219 
220     if (fread(buffer, FE_ADDRESS_SIZE, 1, fp) != 1)
221     {
222         return -1;
223     }
224 
225     a->zone = get_word(pbuf); pbuf += 2;
226     a->net = get_word(pbuf); pbuf += 2;
227     a->node = get_word(pbuf); pbuf += 2;
228     a->point = get_word(pbuf); pbuf += 2;
229 
230     assert(pbuf - buffer == FE_ADDRESS_SIZE);
231 
232     return 0;
233 }
234 
235 
read_fe_sysaddress(SysAddress * a,FILE * fp)236 int read_fe_sysaddress(SysAddress *a, FILE *fp)
237 {
238     unsigned char buffer[FE_SYS_ADDRESS_SIZE];
239     unsigned char *pbuf;
240 
241     pbuf = buffer + FE_ADDRESS_SIZE;;
242 
243     if (read_fe_address(&(a->main), fp) == -1)
244     {
245         return -1;
246     }
247 
248     if (fread(pbuf, FE_SYS_ADDRESS_SIZE - FE_ADDRESS_SIZE, 1, fp) != 1)
249     {
250         return -1;
251     }
252 
253     memcpy(a->domain, pbuf, 28); pbuf += 28;
254 
255     a->pointnet = get_word(pbuf); pbuf += 2;
256     a->flags = get_dword(pbuf); pbuf += 4;
257 
258     assert(pbuf - buffer == FE_SYS_ADDRESS_SIZE);
259 
260     return 0;
261 }
262 
read_fe_area(Area * a,FILE * fp)263 int read_fe_area(Area *a, FILE *fp)
264 {
265     unsigned char buffer[FE_AREA_SIZE];
266     unsigned char *pbuf;
267     unsigned short temp;
268 
269     pbuf = buffer;
270 
271     if (fread(buffer, FE_AREA_SIZE, 1, fp) != 1)
272     {
273         return -1;
274     }
275 
276     memcpy(a->name, pbuf, 52); pbuf += 52;
277     a->board = get_word(pbuf); pbuf += 2;
278     a->conference = get_word(pbuf); pbuf += 2;
279     a->read_sec = get_word(pbuf); pbuf += 2;
280     a->write_sec = get_word(pbuf); pbuf += 2;
281 
282     temp = get_word(pbuf); pbuf += 2;
283     a->info.aka = temp & 0x00FF;
284     a->info.group = (temp >> 8) & 0x00FF;
285 
286     temp = get_word(pbuf); pbuf += 2;
287     a->flags.storage = temp & 0x000F;
288     a->flags.atype   = (temp >> 4) & 0x000F;
289     a->flags.origin  = (temp >> 8) & 0x001F;
290     a->flags.resv    = (temp >> 13) & 0x0007;
291 
292     temp = get_word(pbuf); pbuf += 2;
293     a->advflags.autoadded  = temp & 1;
294     a->advflags.tinyseen   = (temp >> 1) & 1;
295     a->advflags.cpd        = (temp >> 2) & 1;
296     a->advflags.passive    = (temp >> 3) & 1;
297     a->advflags.keepseen   = (temp >> 4) & 1;
298     a->advflags.mandatory  = (temp >> 5) & 1;
299     a->advflags.keepsysop  = (temp >> 6) & 1;
300     a->advflags.killread   = (temp >> 7) & 1;
301     a->advflags.disablepsv = (temp >> 8) & 1;
302     a->advflags.keepmails  = (temp >> 9) & 1;
303     a->advflags.hide       = (temp >> 10) & 1;
304     a->advflags.nomanual   = (temp >> 11) & 1;
305     a->advflags.umlaut     = (temp >> 12) & 1;
306     a->advflags.resv       = (temp >> 13) & 7;
307 
308     a->resv1 = get_word(pbuf); pbuf += 2;
309     a->seenbys = get_dword(pbuf); pbuf += 4;
310     a->resv2 = get_dword(pbuf); pbuf += 4;
311     a->days = get_word(pbuf); pbuf += 2;
312     a->messages = get_word(pbuf); pbuf += 2;
313     a->recvdays = get_word(pbuf); pbuf += 2;
314     memcpy(a->path, pbuf, _MAXPATH); pbuf += _MAXPATH;
315     memcpy(a->desc, pbuf, 52); pbuf += 52;
316 
317     assert(pbuf - buffer == FE_AREA_SIZE);
318 
319     return 0;
320 }
321 
read_fe_node(Node * n,FILE * fp,size_t length)322 int read_fe_node(Node *n, FILE *fp, size_t length)
323 {
324     unsigned char buffer[FE_NODE_SIZE];
325     unsigned char *pbuf;
326     unsigned long temp;
327 
328     if (read_fe_address(&(n->addr), fp) == -1) return -1;
329     if (read_fe_address(&(n->arcdest), fp) == -1) return -1;
330 
331     pbuf = buffer + (2 * FE_ADDRESS_SIZE);
332 
333     if (fread(buffer + 2 * FE_ADDRESS_SIZE, (FE_NODE_SIZE - (2 * FE_ADDRESS_SIZE)), 1, fp) != 1)
334     {
335         return -1;
336     }
337 
338     n->aka = *pbuf++;
339     n->autopassive = *pbuf++;
340     n->newgroup = *pbuf++;
341     n->resv1 = *pbuf++;
342                                 /* because pbuf is little endian, we can read a
343                                    whole dword even if it only contains a 24
344                                    bit value. */
345     temp = get_dword(pbuf) & 0x00FFFFFFUL; pbuf+=3;
346 
347     n->flags.passive          =temp & 1; temp>>=1;
348     n->flags.dddd             =temp & 1; temp>>=1;
349     n->flags.arcmail060       =temp & 1; temp>>=1;
350     n->flags.tosscan          =temp & 1; temp>>=1;
351     n->flags.umlautnet        =temp & 1; temp>>=1;
352     n->flags.exportbyname     =temp & 1; temp>>=1;
353     n->flags.allowareacreate  =temp & 1; temp>>=1;
354     n->flags.disablerescan    =temp & 1; temp>>=1;
355     n->flags.arc_status       =temp & 3; temp>>=2;
356     n->flags.arc_direct       =temp & 1; temp>>=1;
357     n->flags.noattach         =temp & 1; temp>>=1;
358     n->flags.mgr_status       =temp & 3; temp>>=2;
359     n->flags.mgr_direct       =temp & 1; temp>>=1;
360     n->flags.not_help         =temp & 1; temp>>=1;
361     n->flags.not_notify       =temp & 1; temp>>=1;
362     n->flags.packer           =temp & 15; temp>>=4;
363     n->flags.packpriority     =temp & 1; temp>>=1;
364     n->flags.resv             =temp & 3; temp>>=2;
365 
366     n->afixflags.afixflags = get_word(pbuf); pbuf+=2;
367 
368     n->resv2 = get_word(pbuf); pbuf+=2;
369     memcpy(n->password, pbuf, 9); pbuf+=9;
370     memcpy(n->areafixpw, pbuf, 9); pbuf+=9;
371 
372     n->sec_level  = get_word(pbuf);  pbuf+=2;
373     n->groups     = get_dword(pbuf); pbuf+=4;
374     n->resv3      = get_dword(pbuf); pbuf+=4;
375     n->resv4      = get_word(pbuf);  pbuf+=2;
376     n->maxarcsize = get_word(pbuf);  pbuf+=2;
377 
378     memcpy(n->name, pbuf, 36); pbuf+=36;
379 
380     assert(pbuf - buffer == FE_NODE_SIZE);
381 
382                                 /* Now read the variable length part */
383 
384     if (length <= FE_NODE_SIZE ||
385         (n->areas = malloc(length - FE_NODE_SIZE)) == NULL ||
386         fread(n->areas, length - FE_NODE_SIZE, 1, fp) != 1)
387     {
388         return -1;
389     }
390 
391     return 0;
392 }
393 
free_fe_node(Node * n)394 void free_fe_node(Node *n)
395 {
396     if (n != NULL && n->areas != NULL)
397         free(n->areas);
398 }
399 
read_fe_packers(Packers * p,FILE * fp)400 int read_fe_packers(Packers *p, FILE *fp)
401 {
402     unsigned char buffer[FE_PACKERS_SIZE];
403     unsigned char *pbuf = buffer;
404 
405     if (fread(buffer, FE_PACKERS_SIZE, 1, fp) != 1)
406         return -1;
407 
408     memcpy(p->tag, pbuf, 6); pbuf+=6;
409     memcpy(p->command, pbuf, _MAXPATH); pbuf+=_MAXPATH;
410     memcpy(p->list, pbuf, 4); pbuf+=4;
411     p->ratio = *pbuf++;
412     memcpy(p->resv, pbuf, 7); pbuf+=7;
413 
414     assert(pbuf - buffer == FE_PACKERS_SIZE);
415 
416     return 0;
417 }
418 
read_fe_groupdefaults(GroupDefaults * g,FILE * fp,size_t length)419 int read_fe_groupdefaults(GroupDefaults *g, FILE *fp, size_t length)
420 {
421     unsigned char buffer[FE_GROUPDEFAULTS_SIZE - FE_AREA_SIZE];
422     unsigned char *pbuf = buffer;
423 
424     if (fread(buffer, FE_GROUPDEFAULTS_SIZE - FE_AREA_SIZE, 1, fp) != 1)
425     {
426         return -1;
427     }
428 
429     g->group = *pbuf++;
430     memcpy(g->resv, pbuf, 15); pbuf+=15;
431 
432     if (read_fe_area(&(g->area), fp))
433         return -1;
434 
435     assert(pbuf - buffer == FE_GROUPDEFAULTS_SIZE - FE_AREA_SIZE);
436 
437     if (length <= FE_GROUPDEFAULTS_SIZE ||
438         (g->nodes = malloc(length - FE_GROUPDEFAULTS_SIZE)) == NULL ||
439         fread(g->nodes, length - FE_GROUPDEFAULTS_SIZE, 1, fp) != 1)
440     {
441         return -1;
442     }
443 
444     return 0;
445 }
446 
free_fe_groupdefaults(GroupDefaults * g)447 void free_fe_groupdefaults(GroupDefaults *g)
448 {
449     if (g != NULL && g->nodes != NULL)
450         free(g->nodes);
451 }
452 
read_fe_frequest(ForwardAreaFix * f,FILE * fp)453 int read_fe_frequest(ForwardAreaFix *f, FILE *fp)
454 {
455     unsigned char buffer[FE_FORWARD_AREAFIX_SIZE];
456     unsigned char *pbuf = buffer;
457 
458     if (fread(buffer, FE_FORWARD_AREAFIX_SIZE, 1, fp) != 1)
459     {
460         return -1;
461     }
462 
463     f->nodenr = get_word(pbuf); pbuf+=2;
464     f->flags.flags = get_word(pbuf); pbuf+=2;
465 
466     memcpy(f->file, pbuf, _MAXPATH); pbuf+=_MAXPATH;
467     memcpy(f->resv0, pbuf, 56); pbuf+=56;
468 
469     f->sec_level = get_word(pbuf); pbuf+=2;
470     f->resv1     = get_word(pbuf); pbuf+=2;
471 
472     memcpy(f->resv3, pbuf, 3); pbuf+=3;
473 
474     f->groups = get_dword(pbuf); pbuf+=4;
475 
476     memcpy(f->resv2, pbuf, 33); pbuf+=33;
477 
478     assert(pbuf - buffer == FE_FORWARD_AREAFIX_SIZE);
479 
480     return 0;
481 }
482