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 * read_setup_ge
52 *
53 * reads a SETUP_GE structure.
54 *
55 */
56
read_fe_config(CONFIG * c,FILE * fp)57 int read_fe_config(CONFIG *c, FILE *fp)
58 {
59 unsigned char *buffer = (unsigned char *) malloc(FE_CONFIG_SIZE);
60 unsigned char *pbuf;
61 int i;
62
63 pbuf = buffer;
64
65 if (buffer == NULL)
66 {
67 return -1;
68 }
69
70 if (fread(buffer, FE_CONFIG_SIZE, 1, fp) != 1)
71 {
72 free(buffer);
73 return -1;
74 }
75
76 c->revision = get_word(pbuf); pbuf += 2;
77 c->flags = get_dword(pbuf); pbuf += 4;
78 c->NodeCnt = get_word(pbuf); pbuf += 2;
79 c->AreaCnt = get_word(pbuf); pbuf += 2;
80 c->unused1 = get_word(pbuf); pbuf += 2;
81
82 memcpy(c->NetMPath, pbuf, _MAXPATH); pbuf += _MAXPATH;
83 memcpy(c->MsgBase, pbuf, _MAXPATH); pbuf += _MAXPATH;
84 memcpy(c->InBound, pbuf, _MAXPATH); pbuf += _MAXPATH;
85 memcpy(c->OutBound, pbuf, _MAXPATH); pbuf += _MAXPATH;
86 memcpy(c->Unpacker, pbuf, _MAXPATH); pbuf += _MAXPATH;
87 memcpy(c->LogFile, pbuf, _MAXPATH); pbuf += _MAXPATH;
88 memcpy(c->unused2, pbuf, 280); pbuf += 280;
89 memcpy(c->RulesDir, pbuf, _MAXPATH); pbuf += _MAXPATH;
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.manual = (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 /* Possible here need bits parsing (n->afixflags is union: bit structure and short) */
367 n->afixflags.afixflags = get_word(pbuf); pbuf+=2;
368
369 n->resv2 = get_word(pbuf); pbuf+=2;
370 memcpy(n->password, pbuf, 9); pbuf+=9;
371 memcpy(n->areafixpw, pbuf, 9); pbuf+=9;
372
373 n->sec_level = get_word(pbuf); pbuf+=2;
374 n->groups = get_dword(pbuf); pbuf+=4;
375 n->resv3 = get_dword(pbuf); pbuf+=4;
376 n->resv4 = get_word(pbuf); pbuf+=2;
377 n->maxarcsize = get_word(pbuf); pbuf+=2;
378
379 memcpy(n->name, pbuf, 36); pbuf+=36;
380
381 assert(pbuf - buffer == FE_NODE_SIZE);
382
383 /* Now read the variable length part */
384
385 if (length <= FE_NODE_SIZE ||
386 (n->areas = malloc(length - FE_NODE_SIZE)) == NULL ||
387 fread(n->areas, length - FE_NODE_SIZE, 1, fp) != 1)
388 {
389 return -1;
390 }
391
392 return 0;
393 }
394
free_fe_node(Node * n)395 void free_fe_node(Node *n)
396 {
397 if (n != NULL && n->areas != NULL)
398 free(n->areas);
399 }
400
read_fe_packers(Packers * p,FILE * fp)401 int read_fe_packers(Packers *p, FILE *fp)
402 {
403 unsigned char buffer[FE_PACKERS_SIZE];
404 unsigned char *pbuf = buffer;
405
406 if (fread(buffer, FE_PACKERS_SIZE, 1, fp) != 1)
407 return -1;
408
409 memcpy(p->tag, pbuf, 6); pbuf+=6;
410 memcpy(p->command, pbuf, _MAXPATH); pbuf+=_MAXPATH;
411 memcpy(p->list, pbuf, 4); pbuf+=4;
412 p->ratio = *pbuf++;
413 memcpy(p->resv, pbuf, 7); pbuf+=7;
414
415 assert(pbuf - buffer == FE_PACKERS_SIZE);
416
417 return 0;
418 }
419
read_fe_unpackers(Unpackers * p,FILE * fp)420 int read_fe_unpackers(Unpackers *p, FILE *fp)
421 {
422 unsigned char buffer[FE_UNPACKERS_SIZE];
423 unsigned char *pbuf = buffer;
424
425 if (fread(buffer, FE_UNPACKERS_SIZE, 1, fp) != 1)
426 return -1;
427
428 memcpy(p->command, pbuf, _MAXPATH); pbuf+=_MAXPATH;
429 p->callingconvention = *pbuf; pbuf++;
430 memcpy(p->resv, pbuf, 7); pbuf+=7;
431
432 assert(pbuf - buffer == FE_UNPACKERS_SIZE);
433
434 return 0;
435 }
436
read_fe_groupdefaults(GroupDefaults * g,FILE * fp,size_t length)437 int read_fe_groupdefaults(GroupDefaults *g, FILE *fp, size_t length)
438 {
439 unsigned char buffer[FE_GROUPDEFAULTS_SIZE - FE_AREA_SIZE];
440 unsigned char *pbuf = buffer;
441
442 if (fread(buffer, FE_GROUPDEFAULTS_SIZE - FE_AREA_SIZE, 1, fp) != 1)
443 {
444 return -1;
445 }
446
447 g->group = *pbuf++;
448 memcpy(g->resv, pbuf, 15); pbuf+=15;
449
450 if (read_fe_area(&(g->area), fp))
451 return -1;
452
453 assert(pbuf - buffer == FE_GROUPDEFAULTS_SIZE - FE_AREA_SIZE);
454
455 if (length <= FE_GROUPDEFAULTS_SIZE ||
456 (g->nodes = malloc(length - FE_GROUPDEFAULTS_SIZE)) == NULL ||
457 fread(g->nodes, length - FE_GROUPDEFAULTS_SIZE, 1, fp) != 1)
458 {
459 return -1;
460 }
461
462 return 0;
463 }
464
free_fe_groupdefaults(GroupDefaults * g)465 void free_fe_groupdefaults(GroupDefaults *g)
466 {
467 if (g != NULL && g->nodes != NULL)
468 free(g->nodes);
469 }
470
read_fe_frequest(ForwardAreaFix * f,FILE * fp)471 int read_fe_frequest(ForwardAreaFix *f, FILE *fp)
472 {
473 unsigned char buffer[FE_FORWARD_AREAFIX_SIZE];
474 unsigned char *pbuf = buffer;
475
476 if (fread(buffer, FE_FORWARD_AREAFIX_SIZE, 1, fp) != 1)
477 {
478 return -1;
479 }
480
481 f->nodenr = get_word(pbuf); pbuf+=2;
482 f->flags.flags = get_word(pbuf); pbuf+=2;
483
484 memcpy(f->file, pbuf, _MAXPATH); pbuf+=_MAXPATH;
485 memcpy(f->resv0, pbuf, 56); pbuf+=56;
486
487 f->sec_level = get_word(pbuf); pbuf+=2;
488 f->resv1 = get_word(pbuf); pbuf+=2;
489
490 memcpy(f->resv3, pbuf, 3); pbuf+=3;
491
492 f->groups = get_dword(pbuf); pbuf+=4;
493
494 memcpy(f->resv2, pbuf, 33); pbuf+=33;
495
496 assert(pbuf - buffer == FE_FORWARD_AREAFIX_SIZE);
497
498 return 0;
499 }
500