1 /*
2 * SMAPI; Modified Squish MSGAPI
3 *
4 * Squish MSGAPI0 is copyright 1991 by Scott J. Dudley. All rights reserved.
5 * Modifications released to the public domain.
6 *
7 * Use of this file is subject to the restrictions contain in the Squish
8 * MSGAPI0 licence agreement. Please refer to licence.txt for complete
9 * details of the licencing restrictions. If you do not find the text
10 * of this agreement in licence.txt, or if you do not have this file,
11 * you should contact Scott Dudley at FidoNet node 1:249/106 or Internet
12 * e-mail Scott.Dudley@f106.n249.z1.fidonet.org.
13 *
14 * In no event should you proceed to use any of the source files in this
15 * archive without having accepted the terms of the MSGAPI0 licensing
16 * agreement, or such other agreement as you are able to reach with the
17 * author.
18 */
19 /* STRUCTRW.C written 1998 by Tobias Ernst
20 *
21 * This file contains routines read and write packed structures like the
22 * struct XMSG in an platform-independent manner.
23 *
24 * Background information: You should never ever read or write any
25 * structure directly from disk with something like
26 * fread(&structure, sizeof(structure), 1, f)
27 * This will fail on some compliers that can't be told to pack structures
28 * in exactly the way that they are supposed to be. It will also fail
29 * when trying to read a file that is supposed to be used by a little-
30 * endian machine (like Intel) on a big endian machine (like PPC).
31 *
32 * So the conclusion: Never use fread, fwrite, farread, farwrite on
33 * structures - use the routines from this module instead, or if you are
34 * introducing a new structure, add a routine for it to this file.
35 *
36 * If you have any questions on this topic, feel free to contact me
37 * at 2:2476/418 or tobi@bland.fido.de.
38 */
39
40 #include <stdlib.h>
41 #include <string.h>
42 #include <assert.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <fcntl.h>
46 #include <errno.h>
47
48
49 #define MSGAPI_HANDLERS
50 #define _SMAPI_EXT
51 #include "compiler.h"
52
53 #ifdef HAS_UNISTD_H
54 #include <unistd.h>
55 #endif
56 #ifdef HAS_IO_H
57 #include <io.h>
58 #endif
59
60 #include "memory.h"
61 #include "ftnaddr.h"
62 #include "locking.h"
63 /* Swith for build DLL */
64 #define DLLEXPORT
65
66 #include "msgapi.h"
67 #include "api_sq.h"
68 #include "old_msg.h"
69 #include "api_jam.h"
70
71 #define MAXHDRINCORE (1024l * 1024 * 10) /* Maximum jam hdr size for incore, 10M */
72
73 #ifdef NEED_trivial_farread
74 #ifdef HAS_dos_read
75 /* "Text mode" not implemented !!! */
trivial_farread(int handle,void far * buffer,unsigned len)76 int trivial_farread(int handle, void far * buffer, unsigned len)
77 {
78 unsigned r_len = 0;
79
80 if(dos_read(handle, buffer, len, &r_len))
81 {
82 return 0;
83 }
84
85 return r_len;
86 }
87
88 #else
89 #error "Can't implement trivial_farread() without dos_read()"
90 #endif
91 #endif
92
93 #ifdef NEED_trivial_farwrite
94 #ifdef HAS_dos_write
95 /* "Text mode" not implemented !!! */
trivial_farwrite(int handle,void far * buffer,unsigned len)96 int trivial_farwrite(int handle, void far * buffer, unsigned len)
97 {
98 unsigned r_len = 0;
99
100 if(dos_write(handle, buffer, len, &r_len))
101 {
102 return 0;
103 }
104
105 return r_len;
106 }
107
108 #else
109 #error "Can't implement trivial_farwrite() without dos_write()"
110 #endif
111 #endif
112
113
read_xmsg(int handle,XMSG * pxmsg)114 int read_xmsg(int handle, XMSG * pxmsg)
115 {
116 byte buf[XMSG_SIZE], * pbuf = buf;
117 word rawdate, rawtime;
118 int i;
119
120 if(farread(handle, (byte far *)buf, XMSG_SIZE) != XMSG_SIZE)
121 {
122 return 0;
123 }
124
125 /* 04 bytes "attr" */
126 pxmsg->attr = get_dword(pbuf);
127 pbuf += 4;
128 /* 36 bytes "from" */
129 memmove(pxmsg->from, pbuf, XMSG_FROM_SIZE);
130 pbuf += XMSG_FROM_SIZE;
131 /* 36 bytes "to" */
132 memmove(pxmsg->to, pbuf, XMSG_TO_SIZE);
133 pbuf += XMSG_TO_SIZE;
134 /* 72 bytes "subj" */
135 memmove(pxmsg->subj, pbuf, XMSG_SUBJ_SIZE);
136 pbuf += XMSG_SUBJ_SIZE;
137 /* 8 bytes "orig" */
138 pxmsg->orig.zone = get_word(pbuf);
139 pbuf += 2;
140 pxmsg->orig.net = get_word(pbuf);
141 pbuf += 2;
142 pxmsg->orig.node = get_word(pbuf);
143 pbuf += 2;
144 pxmsg->orig.point = get_word(pbuf);
145 pbuf += 2;
146 /* 8 bytes "dest" */
147 pxmsg->dest.zone = get_word(pbuf);
148 pbuf += 2;
149 pxmsg->dest.net = get_word(pbuf);
150 pbuf += 2;
151 pxmsg->dest.node = get_word(pbuf);
152 pbuf += 2;
153 pxmsg->dest.point = get_word(pbuf);
154 pbuf += 2;
155 /* 4 bytes "date_written" */
156 rawdate = get_word(pbuf);
157 pbuf += 2;
158 rawtime = get_word(pbuf);
159 pbuf += 2;
160 pxmsg->date_written.date.da = rawdate & 31;
161 pxmsg->date_written.date.mo = (rawdate >> 5) & 15;
162 pxmsg->date_written.date.yr = (rawdate >> 9) & 127;
163 pxmsg->date_written.time.ss = rawtime & 31;
164 pxmsg->date_written.time.mm = (rawtime >> 5) & 63;
165 pxmsg->date_written.time.hh = (rawtime >> 11) & 31;
166 /* 4 bytes "date_arrived" */
167 rawdate = get_word(pbuf);
168 pbuf += 2;
169 rawtime = get_word(pbuf);
170 pbuf += 2;
171 pxmsg->date_arrived.date.da = rawdate & 31;
172 pxmsg->date_arrived.date.mo = (rawdate >> 5) & 15;
173 pxmsg->date_arrived.date.yr = (rawdate >> 9) & 127;
174 pxmsg->date_arrived.time.ss = rawtime & 31;
175 pxmsg->date_arrived.time.mm = (rawtime >> 5) & 63;
176 pxmsg->date_arrived.time.hh = (rawtime >> 11) & 31;
177 /* 2 byte "utc_ofs" */
178 pxmsg->utc_ofs = get_word(pbuf);
179 pbuf += 2;
180 /* 4 bytes "replyto" */
181 pxmsg->replyto = get_dword(pbuf);
182 pbuf += 4;
183
184 /* 10 times 4 bytes "replies" */
185 for(i = 0; i < MAX_REPLY; i++)
186 {
187 pxmsg->replies[i] = get_dword(pbuf);
188 pbuf += 4;
189 }
190 /* 4 bytes "umsgid" */
191 pxmsg->umsgid = get_dword(pbuf);
192 pbuf += 4;
193 /* 20 times FTSC date stamp */
194 memmove(pxmsg->__ftsc_date, pbuf, 20);
195 pbuf += 20;
196 assert(pbuf - buf == XMSG_SIZE);
197 return 1;
198 } /* read_xmsg */
199
write_xmsg(int handle,XMSG * pxmsg)200 int write_xmsg(int handle, XMSG * pxmsg)
201 {
202 byte buf[XMSG_SIZE], * pbuf = buf;
203 word rawdate, rawtime;
204 int i;
205
206 /* 04 bytes "attr" */
207 put_dword(pbuf, pxmsg->attr);
208 pbuf += 4;
209 /* 36 bytes "from" */
210 memmove(pbuf, pxmsg->from, XMSG_FROM_SIZE);
211 pbuf += XMSG_FROM_SIZE;
212 /* 36 bytes "to" */
213 memmove(pbuf, pxmsg->to, XMSG_TO_SIZE);
214 pbuf += XMSG_TO_SIZE;
215 /* 72 bytes "subj" */
216 memmove(pbuf, pxmsg->subj, XMSG_SUBJ_SIZE);
217 pbuf += XMSG_SUBJ_SIZE;
218 /* 8 bytes "orig" */
219 put_word(pbuf, pxmsg->orig.zone);
220 pbuf += 2;
221 put_word(pbuf, pxmsg->orig.net);
222 pbuf += 2;
223 put_word(pbuf, pxmsg->orig.node);
224 pbuf += 2;
225 put_word(pbuf, pxmsg->orig.point);
226 pbuf += 2;
227 /* 8 bytes "dest" */
228 put_word(pbuf, pxmsg->dest.zone);
229 pbuf += 2;
230 put_word(pbuf, pxmsg->dest.net);
231 pbuf += 2;
232 put_word(pbuf, pxmsg->dest.node);
233 pbuf += 2;
234 put_word(pbuf, pxmsg->dest.point);
235 pbuf += 2;
236 /* 4 bytes "date_written" */
237 rawdate = rawtime = 0;
238 rawdate |= (((word)pxmsg->date_written.date.da) & 31);
239 rawdate |= (((word)pxmsg->date_written.date.mo) & 15) << 5;
240 rawdate |= (((word)pxmsg->date_written.date.yr) & 127) << 9;
241 rawtime |= (((word)pxmsg->date_written.time.ss) & 31);
242 rawtime |= (((word)pxmsg->date_written.time.mm) & 63) << 5;
243 rawtime |= (((word)pxmsg->date_written.time.hh) & 31) << 11;
244 put_word(pbuf, rawdate);
245 pbuf += 2;
246 put_word(pbuf, rawtime);
247 pbuf += 2;
248 /* 4 bytes "date_arrvied" */
249 rawdate = rawtime = 0;
250 rawdate |= (((word)pxmsg->date_arrived.date.da) & 31);
251 rawdate |= (((word)pxmsg->date_arrived.date.mo) & 15) << 5;
252 rawdate |= (((word)pxmsg->date_arrived.date.yr) & 127) << 9;
253 rawtime |= (((word)pxmsg->date_arrived.time.ss) & 31);
254 rawtime |= (((word)pxmsg->date_arrived.time.mm) & 63) << 5;
255 rawtime |= (((word)pxmsg->date_arrived.time.hh) & 31) << 11;
256 put_word(pbuf, rawdate);
257 pbuf += 2;
258 put_word(pbuf, rawtime);
259 pbuf += 2;
260 /* 2 byte "utc_ofs" */
261 put_word(pbuf, pxmsg->utc_ofs);
262 pbuf += 2;
263 /* 4 bytes "replyto" */
264 put_dword(pbuf, pxmsg->replyto);
265 pbuf += 4;
266
267 /* 10 times 4 bytes "replies" */
268 for(i = 0; i < MAX_REPLY; i++)
269 {
270 put_dword(pbuf, pxmsg->replies[i]);
271 pbuf += 4;
272 }
273 /* 4 bytes "umsgid" */
274 put_dword(pbuf, pxmsg->umsgid);
275 pbuf += 4;
276 /* 20 times FTSC date stamp */
277 memmove(pbuf, pxmsg->__ftsc_date, 20);
278 pbuf += 20;
279 assert(pbuf - buf == XMSG_SIZE);
280 return farwrite(handle, (byte far *)buf, XMSG_SIZE) == XMSG_SIZE;
281 } /* write_xmsg */
282
read_sqhdr(int handle,SQHDR * psqhdr)283 int read_sqhdr(int handle, SQHDR * psqhdr)
284 {
285 byte buf[SQHDR_SIZE], * pbuf = buf;
286
287 if(farread(handle, (byte far *)buf, SQHDR_SIZE) != SQHDR_SIZE)
288 {
289 return 0;
290 }
291
292 /* 4 bytes "id" */
293 psqhdr->id = get_dword(pbuf);
294 pbuf += 4;
295 /* 4 bytes "next_frame" */
296 psqhdr->next_frame = get_dword(pbuf);
297 pbuf += 4;
298 /* 4 bytes "prev_frame" */
299 psqhdr->prev_frame = get_dword(pbuf);
300 pbuf += 4;
301 /* 4 bytes "frame_length" */
302 psqhdr->frame_length = get_dword(pbuf);
303 pbuf += 4;
304 /* 4 bytes "msg_length" */
305 psqhdr->msg_length = get_dword(pbuf);
306 pbuf += 4;
307 /* 4 bytes "clen" */
308 psqhdr->clen = get_dword(pbuf);
309 pbuf += 4;
310 /* 2 bytes "frame_type" */
311 psqhdr->frame_type = get_word(pbuf);
312 pbuf += 2;
313 /* 4 bytes "rsvd" */
314 psqhdr->rsvd = get_word(pbuf);
315 pbuf += 2;
316 assert(pbuf - buf == SQHDR_SIZE);
317 return 1;
318 } /* read_sqhdr */
319
write_sqhdr(int handle,SQHDR * psqhdr)320 int write_sqhdr(int handle, SQHDR * psqhdr)
321 {
322 byte buf[SQHDR_SIZE], * pbuf = buf;
323
324 /* 4 bytes "id" */
325 put_dword(pbuf, psqhdr->id);
326 pbuf += 4;
327 /* 4 bytes "next_frame" */
328 put_dword(pbuf, psqhdr->next_frame);
329 pbuf += 4;
330 /* 4 bytes "prev_frame" */
331 put_dword(pbuf, psqhdr->prev_frame);
332 pbuf += 4;
333 /* 4 bytes "frame_length" */
334 put_dword(pbuf, psqhdr->frame_length);
335 pbuf += 4;
336 /* 4 bytes "msg_length" */
337 put_dword(pbuf, psqhdr->msg_length);
338 pbuf += 4;
339 /* 4 bytes "clen" */
340 put_dword(pbuf, psqhdr->clen);
341 pbuf += 4;
342 /* 2 bytes "frame_type" */
343 put_word(pbuf, psqhdr->frame_type);
344 pbuf += 2;
345 /* 4 bytes "rsvd" */
346 put_word(pbuf, psqhdr->rsvd);
347 pbuf += 2;
348 assert(pbuf - buf == SQHDR_SIZE);
349 return farwrite(handle, (byte far *)buf, SQHDR_SIZE) == SQHDR_SIZE;
350 } /* write_sqhdr */
351
352 /*
353 * read_sqidx
354 *
355 * This function needs a little explanation. Just like the other functions,
356 * it reads in a special structure, the SQIDX structure. The problem is
357 * that this is done very often: It is not uncommon that 5000 SQIDXs are
358 * being read in seqeuence. Therefore, I had to do a little performance
359 * tuning here. I try to read in as much SQIDX structures as possible
360 * at once, while at the same time being able to cope with the fact that
361 * the OS might not be able to provide me with enough temporrary storage.
362 *
363 * Normally, you will not have to care about the buffering thing. Only
364 * the code between "begin reading in a single structre" and "end reading
365 * in a single structure" must be change if the structure layout changes.
366 */
read_sqidx(int handle,SQIDX * psqidx,dword n)367 int read_sqidx(int handle, SQIDX * psqidx, dword n)
368 {
369 byte buf[SQIDX_SIZE], * pbuf = NULL;
370 byte * accel_buffer = NULL;
371 dword i, maxbuf = 0, rd;
372
373 if(n > 1)
374 {
375 maxbuf = n;
376
377 if((dword)SQIDX_SIZE * (dword)n >= 32768L)
378 {
379 maxbuf = (dword)32768L / SQIDX_SIZE;
380 }
381
382 accel_buffer = (byte *)malloc(SQIDX_SIZE * maxbuf);
383 }
384
385 for(i = 0; i < n; i++)
386 {
387 if(accel_buffer == NULL)
388 {
389 if(farread(handle, buf, SQIDX_SIZE) != SQIDX_SIZE)
390 {
391 return 0;
392 }
393
394 pbuf = buf;
395 }
396 else
397 {
398 if(!(i % maxbuf))
399 {
400 rd = (i + maxbuf > n) ? (n - i) : maxbuf;
401
402 if(farread(handle, accel_buffer, rd * SQIDX_SIZE) != (int)(rd * SQIDX_SIZE))
403 {
404 free(accel_buffer);
405 return 0;
406 }
407
408 pbuf = accel_buffer;
409 }
410 }
411
412 /* Begin reading in a single structure */
413 /* 4 bytes "ofs" */
414 psqidx[i].ofs = get_dword(pbuf);
415 pbuf += 4;
416 /* 4 bytes "umsgid" */
417 psqidx[i].umsgid = get_dword(pbuf);
418 pbuf += 4;
419 /* 4 bytes "hash" */
420 psqidx[i].hash = get_dword(pbuf);
421 pbuf += 4;
422 /* Stop reading in a single structure */
423 }
424
425 if(accel_buffer != NULL)
426 {
427 free(accel_buffer);
428 }
429
430 return 1;
431 } /* read_sqidx */
432
write_sqidx(int handle,SQIDX * psqidx,dword n)433 int write_sqidx(int handle, SQIDX * psqidx, dword n)
434 {
435 byte buf[SQIDX_SIZE], * pbuf = NULL;
436 byte * accel_buffer = NULL;
437 dword i, maxbuf = 0;
438 int wr;
439
440 if(n > 1)
441 {
442 maxbuf = n;
443
444 if((dword)SQIDX_SIZE * (dword)n >= 32768L)
445 {
446 maxbuf = (dword)32768L / SQIDX_SIZE;
447 }
448
449 accel_buffer = (byte *)malloc(SQIDX_SIZE * maxbuf);
450 pbuf = accel_buffer;
451 }
452
453 for(i = 0; i < n; i++)
454 {
455 if(accel_buffer == NULL)
456 {
457 pbuf = buf;
458 }
459
460 /* 4 bytes "ofs" */
461 put_dword(pbuf, psqidx[i].ofs);
462 pbuf += 4;
463 /* 4 bytes "umsgid" */
464 put_dword(pbuf, psqidx[i].umsgid);
465 pbuf += 4;
466 /* 4 bytes "hash" */
467 put_dword(pbuf, psqidx[i].hash);
468 pbuf += 4;
469
470 if(accel_buffer == NULL)
471 {
472 if(farwrite(handle, buf, SQIDX_SIZE) != SQIDX_SIZE)
473 {
474 return 0;
475 }
476 }
477 else
478 {
479 if(i == n - 1 || (!((i + 1) % maxbuf)))
480 {
481 wr = (!((i + 1) % maxbuf)) ? maxbuf : (n % maxbuf);
482
483 if(farwrite(handle, accel_buffer, wr * SQIDX_SIZE) != (wr * SQIDX_SIZE))
484 {
485 free(accel_buffer);
486 return 0;
487 }
488
489 pbuf = accel_buffer;
490 }
491 }
492 }
493
494 if(accel_buffer != NULL)
495 {
496 free(accel_buffer);
497 }
498
499 return 1;
500 } /* write_sqidx */
501
read_sqbase(int handle,struct _sqbase * psqbase)502 int read_sqbase(int handle, struct _sqbase * psqbase)
503 {
504 byte buf[SQBASE_SIZE], * pbuf = buf;
505
506 if(farread(handle, (byte far *)buf, SQBASE_SIZE) != SQBASE_SIZE)
507 {
508 return 0;
509 }
510
511 psqbase->len = get_word(pbuf);
512 pbuf += 2;
513 psqbase->rsvd1 = get_word(pbuf);
514 pbuf += 2;
515 psqbase->num_msg = get_dword(pbuf);
516 pbuf += 4;
517 psqbase->high_msg = get_dword(pbuf);
518 pbuf += 4;
519 psqbase->skip_msg = get_dword(pbuf);
520 pbuf += 4;
521 psqbase->high_water = get_dword(pbuf);
522 pbuf += 4;
523 psqbase->uid = get_dword(pbuf);
524 pbuf += 4;
525 memmove(psqbase->base, pbuf, 80);
526 pbuf += 80;
527 psqbase->begin_frame = get_dword(pbuf);
528 pbuf += 4;
529 psqbase->last_frame = get_dword(pbuf);
530 pbuf += 4;
531 psqbase->free_frame = get_dword(pbuf);
532 pbuf += 4;
533 psqbase->last_free_frame = get_dword(pbuf);
534 pbuf += 4;
535 psqbase->end_frame = get_dword(pbuf);
536 pbuf += 4;
537 psqbase->max_msg = get_dword(pbuf);
538 pbuf += 4;
539 psqbase->keep_days = get_word(pbuf);
540 pbuf += 2;
541 psqbase->sz_sqhdr = get_word(pbuf);
542 pbuf += 2;
543 memmove(psqbase->rsvd2, pbuf, 124);
544 pbuf += 124;
545 assert(pbuf - buf == SQBASE_SIZE);
546 return 1;
547 } /* read_sqbase */
548
write_sqbase(int handle,struct _sqbase * psqbase)549 int write_sqbase(int handle, struct _sqbase * psqbase)
550 {
551 byte buf[SQBASE_SIZE], * pbuf = buf;
552
553 put_word(pbuf, psqbase->len);
554 pbuf += 2;
555 put_word(pbuf, psqbase->rsvd1);
556 pbuf += 2;
557 put_dword(pbuf, psqbase->num_msg);
558 pbuf += 4;
559 put_dword(pbuf, psqbase->high_msg);
560 pbuf += 4;
561 put_dword(pbuf, psqbase->skip_msg);
562 pbuf += 4;
563 put_dword(pbuf, psqbase->high_water);
564 pbuf += 4;
565 put_dword(pbuf, psqbase->uid);
566 pbuf += 4;
567 memmove(pbuf, psqbase->base, 80);
568 pbuf += 80;
569 put_dword(pbuf, psqbase->begin_frame);
570 pbuf += 4;
571 put_dword(pbuf, psqbase->last_frame);
572 pbuf += 4;
573 put_dword(pbuf, psqbase->free_frame);
574 pbuf += 4;
575 put_dword(pbuf, psqbase->last_free_frame);
576 pbuf += 4;
577 put_dword(pbuf, psqbase->end_frame);
578 pbuf += 4;
579 put_dword(pbuf, psqbase->max_msg);
580 pbuf += 4;
581 put_word(pbuf, psqbase->keep_days);
582 pbuf += 2;
583 put_word(pbuf, psqbase->sz_sqhdr);
584 pbuf += 2;
585 memmove(pbuf, psqbase->rsvd2, 124);
586 pbuf += 124;
587 assert(pbuf - buf == SQBASE_SIZE);
588 return farwrite(handle, (byte far *)buf, SQBASE_SIZE) == SQBASE_SIZE;
589 } /* write_sqbase */
590
read_omsg(int handle,struct _omsg * pomsg)591 int read_omsg(int handle, struct _omsg * pomsg)
592 {
593 byte buf[OMSG_SIZE], * pbuf = buf;
594 word rawdate, rawtime;
595
596 if(farread(handle, (byte far *)buf, OMSG_SIZE) != OMSG_SIZE)
597 {
598 return 0;
599 }
600
601 memmove(pomsg->from, pbuf, 36);
602 pbuf += 36;
603 memmove(pomsg->to, pbuf, 36);
604 pbuf += 36;
605 memmove(pomsg->subj, pbuf, 72);
606 pbuf += 72;
607 memmove(pomsg->date, pbuf, 20);
608 pbuf += 20;
609 pomsg->times = get_word(pbuf);
610 pbuf += 2;
611 pomsg->dest = get_word(pbuf);
612 pbuf += 2;
613 pomsg->orig = get_word(pbuf);
614 pbuf += 2;
615 pomsg->cost = get_word(pbuf);
616 pbuf += 2;
617 pomsg->orig_net = get_word(pbuf);
618 pbuf += 2;
619 pomsg->dest_net = get_word(pbuf);
620 pbuf += 2;
621
622 /* 4 bytes "date_written" */
623 rawdate = get_word(pbuf);
624 pbuf += 2;
625 rawtime = get_word(pbuf);
626 pbuf += 2;
627 pomsg->date_written.date.da = rawdate & 31;
628 pomsg->date_written.date.mo = (rawdate >> 5) & 15;
629 pomsg->date_written.date.yr = (rawdate >> 9) & 127;
630 pomsg->date_written.time.ss = rawtime & 31;
631 pomsg->date_written.time.mm = (rawtime >> 5) & 63;
632 pomsg->date_written.time.hh = (rawtime >> 11) & 31;
633 /* 4 bytes "date_arrived" */
634 rawdate = get_word(pbuf);
635 pbuf += 2;
636 rawtime = get_word(pbuf);
637 pbuf += 2;
638 pomsg->date_arrived.date.da = rawdate & 31;
639 pomsg->date_arrived.date.mo = (rawdate >> 5) & 15;
640 pomsg->date_arrived.date.yr = (rawdate >> 9) & 127;
641 pomsg->date_arrived.time.ss = rawtime & 31;
642 pomsg->date_arrived.time.mm = (rawtime >> 5) & 63;
643 pomsg->date_arrived.time.hh = (rawtime >> 11) & 31;
644 pomsg->reply = get_word(pbuf);
645 pbuf += 2;
646 pomsg->attr = get_word(pbuf);
647 pbuf += 2;
648 pomsg->up = get_word(pbuf);
649 pbuf += 2;
650 assert(pbuf - buf == OMSG_SIZE);
651 return 1;
652 } /* read_omsg */
653
write_omsg(int handle,struct _omsg * pomsg)654 int write_omsg(int handle, struct _omsg * pomsg)
655 {
656 byte buf[OMSG_SIZE], * pbuf = buf;
657 word rawdate, rawtime;
658
659 memmove(pbuf, pomsg->from, 36);
660 pbuf += 36;
661 memmove(pbuf, pomsg->to, 36);
662 pbuf += 36;
663 memmove(pbuf, pomsg->subj, 72);
664 pbuf += 72;
665 memmove(pbuf, pomsg->date, 20);
666 pbuf += 20;
667 put_word(pbuf, pomsg->times);
668 pbuf += 2;
669 put_word(pbuf, pomsg->dest);
670 pbuf += 2;
671 put_word(pbuf, pomsg->orig);
672 pbuf += 2;
673 put_word(pbuf, pomsg->cost);
674 pbuf += 2;
675 put_word(pbuf, pomsg->orig_net);
676 pbuf += 2;
677 put_word(pbuf, pomsg->dest_net);
678 pbuf += 2;
679
680 /* 4 bytes "date_written" */
681 rawdate = rawtime = 0;
682 rawdate |= (((word)pomsg->date_written.date.da) & 31);
683 rawdate |= (((word)pomsg->date_written.date.mo) & 15) << 5;
684 rawdate |= (((word)pomsg->date_written.date.yr) & 127) << 9;
685 rawtime |= (((word)pomsg->date_written.time.ss) & 31);
686 rawtime |= (((word)pomsg->date_written.time.mm) & 63) << 5;
687 rawtime |= (((word)pomsg->date_written.time.hh) & 31) << 11;
688 put_word(pbuf, rawdate);
689 pbuf += 2;
690 put_word(pbuf, rawtime);
691 pbuf += 2;
692 /* 4 bytes "date_arrvied" */
693 rawdate = rawtime = 0;
694 rawdate |= (((word)pomsg->date_arrived.date.da) & 31);
695 rawdate |= (((word)pomsg->date_arrived.date.mo) & 15) << 5;
696 rawdate |= (((word)pomsg->date_arrived.date.yr) & 127) << 9;
697 rawtime |= (((word)pomsg->date_arrived.time.ss) & 31);
698 rawtime |= (((word)pomsg->date_arrived.time.mm) & 63) << 5;
699 rawtime |= (((word)pomsg->date_arrived.time.hh) & 31) << 11;
700 put_word(pbuf, rawdate);
701 pbuf += 2;
702 put_word(pbuf, rawtime);
703 pbuf += 2;
704 put_word(pbuf, pomsg->reply);
705 pbuf += 2;
706 put_word(pbuf, pomsg->attr);
707 pbuf += 2;
708 put_word(pbuf, pomsg->up);
709 pbuf += 2;
710 assert(pbuf - buf == OMSG_SIZE);
711 return farwrite(handle, (byte far *)buf, OMSG_SIZE) == OMSG_SIZE;
712 } /* write_omsg */
713
read_hdrinfo(int handle,JAMHDRINFO * HdrInfo)714 int read_hdrinfo(int handle, JAMHDRINFO * HdrInfo)
715 {
716 byte buf[HDRINFO_SIZE], * pbuf = buf;
717
718 if(farread(handle, (byte far *)buf, HDRINFO_SIZE) != HDRINFO_SIZE)
719 {
720 return 0;
721 } /* endif */
722
723 /* 04 bytes Signature */
724 memmove(HdrInfo->Signature, pbuf, (size_t)4);
725 pbuf += 4;
726 /* 04 bytes DateCreated */
727 HdrInfo->DateCreated = get_dword(pbuf);
728 pbuf += 4;
729 /* 04 bytes ModCounter */
730 HdrInfo->ModCounter = get_dword(pbuf);
731 pbuf += 4;
732 /* 04 bytes ActiveMsgs */
733 HdrInfo->ActiveMsgs = get_dword(pbuf);
734 pbuf += 4;
735 /* 04 bytes PasswordCRC */
736 HdrInfo->PasswordCRC = get_dword(pbuf);
737 pbuf += 4;
738 /* 04 bytes BaseMsgNum */
739 HdrInfo->BaseMsgNum = get_dword(pbuf);
740 pbuf += 4;
741 /* 04 bytes highwater */
742 HdrInfo->highwater = get_dword(pbuf);
743 pbuf += 4;
744 /* 996 bytes RSRVD */
745 memmove(HdrInfo->RSRVD, pbuf, (size_t)996);
746 pbuf += 996;
747 assert(pbuf - buf == HDRINFO_SIZE);
748 return 1;
749 } /* read_hdrinfo */
750
read_idx(int handle,JAMIDXREC * Idx)751 int read_idx(int handle, JAMIDXREC * Idx)
752 {
753 byte buf[IDX_SIZE], * pbuf = buf;
754
755 if(farread(handle, (byte far *)buf, IDX_SIZE) != IDX_SIZE)
756 {
757 return 0;
758 } /* endif */
759
760 /* 04 bytes UserCRC */
761 Idx->UserCRC = get_dword(pbuf);
762 pbuf += 4;
763 /* 04 bytes HdrOffset */
764 Idx->HdrOffset = get_dword(pbuf);
765 pbuf += 4;
766 assert(pbuf - buf == IDX_SIZE);
767 return 1;
768 }
769
decode_hdr(byte * pbuf,JAMHDR * Hdr)770 static void decode_hdr(byte * pbuf, JAMHDR * Hdr)
771 {
772 /* 04 bytes Signature */
773 memmove(Hdr->Signature, pbuf, (size_t)4);
774 pbuf += 4;
775 /* 02 bytes Revision */
776 Hdr->Revision = get_word(pbuf);
777 pbuf += 2;
778 /* 02 bytes ReservedWord */
779 Hdr->ReservedWord = get_word(pbuf);
780 pbuf += 2;
781 /* 04 bytes SubfieldLen */
782 Hdr->SubfieldLen = get_dword(pbuf);
783 pbuf += 4;
784 /* 04 bytes TimesRead */
785 Hdr->TimesRead = get_dword(pbuf);
786 pbuf += 4;
787 /* 04 bytes MsgIdCRC */
788 Hdr->MsgIdCRC = get_dword(pbuf);
789 pbuf += 4;
790 /* 04 bytes ReplyCRC */
791 Hdr->ReplyCRC = get_dword(pbuf);
792 pbuf += 4;
793 /* 04 bytes ReplyTo */
794 Hdr->ReplyTo = get_dword(pbuf);
795 pbuf += 4;
796 /* 04 bytes Reply1st */
797 Hdr->Reply1st = get_dword(pbuf);
798 pbuf += 4;
799 /* 04 bytes ReplyNext */
800 Hdr->ReplyNext = get_dword(pbuf);
801 pbuf += 4;
802 /* 04 bytes DateWritten */
803 Hdr->DateWritten = get_dword(pbuf);
804 pbuf += 4;
805 /* 04 bytes DateReceived */
806 Hdr->DateReceived = get_dword(pbuf);
807 pbuf += 4;
808 /* 04 bytes DateProcessed */
809 Hdr->DateProcessed = get_dword(pbuf);
810 pbuf += 4;
811 /* 04 bytes MsgNum */
812 Hdr->MsgNum = get_dword(pbuf);
813 pbuf += 4;
814 /* 04 bytes Attribute */
815 Hdr->Attribute = get_dword(pbuf);
816 pbuf += 4;
817 /* 04 bytes Attribute2 */
818 Hdr->Attribute2 = get_dword(pbuf);
819 pbuf += 4;
820 /* 04 bytes TxtOffset */
821 Hdr->TxtOffset = get_dword(pbuf);
822 pbuf += 4;
823 /* 04 bytes TxtLen */
824 Hdr->TxtLen = get_dword(pbuf);
825 pbuf += 4;
826 /* 04 bytes PasswordCRC */
827 Hdr->PasswordCRC = get_dword(pbuf);
828 pbuf += 4;
829 /* 04 bytes Cost */
830 Hdr->Cost = get_dword(pbuf);
831 } /* decode_hdr */
832
read_hdr(int handle,JAMHDR * Hdr)833 int read_hdr(int handle, JAMHDR * Hdr)
834 {
835 byte buf[HDR_SIZE];
836
837 if(farread(handle, (byte far *)buf, HDR_SIZE) != HDR_SIZE)
838 {
839 return 0;
840 } /* endif */
841
842 decode_hdr(buf, Hdr);
843 return 1;
844 }
845
copy_subfield(JAMSUBFIELD2LISTptr * to,JAMSUBFIELD2LISTptr from)846 int copy_subfield(JAMSUBFIELD2LISTptr * to, JAMSUBFIELD2LISTptr from)
847 {
848 dword i;
849
850 *to = (JAMSUBFIELD2LISTptr)palloc(from->arraySize);
851
852 if(*to == NULL)
853 {
854 return 1;
855 }
856
857 memcpy(*to, from, from->arraySize);
858
859 for(i = 0; i < from->subfieldCount; i++)
860 {
861 to[0]->subfield[i].Buffer += ((char *)*to - (char *)from);
862 }
863 return 0;
864 }
865
866 /* Define DEBUG to catch more weirdness in databases */
decode_subfield(byte * buf,JAMSUBFIELD2LISTptr * subfield,dword * SubfieldLen)867 static void decode_subfield(byte * buf, JAMSUBFIELD2LISTptr * subfield, dword * SubfieldLen)
868 {
869 JAMSUBFIELD2ptr subfieldNext;
870 dword datlen;
871 unsigned int count, len;
872 byte * pbuf, * limit;
873
874 pbuf = buf;
875 limit = buf + *SubfieldLen;
876 assert(limit >= buf);
877 count = 0;
878
879 while(pbuf + JAM_SF_HEADER_SIZE <= limit)
880 {
881 dword size;
882 #ifdef DEBUG
883 word loID, hiID;
884 loID = get_word(pbuf);
885 hiID = get_word(pbuf + 2);
886
887 if(!(loID <= JAMSFLD_ENCLINDFILE || loID == JAMSFLD_EMBINDAT ||
888 loID >= JAMSFLD_FTSKLUDGE && loID <= JAMSFLD_TZUTCINFO))
889 {
890 /* This subfield type is not supported and is most
891 probably sign of error in messagebase */
892 printf("SMAPI ERROR: weird subfield type! (%X)\n", (unsigned int)loID);
893 /* Keep going, these fields won't hurt unless they have improper size too */
894 }
895
896 #endif
897 size = get_dword(pbuf + 4);
898 #ifdef DEBUG
899
900 if(size == 0 && loID != JAMSFLD_SUBJECT) /* While possible, it isn't normal value */
901 {
902 printf("SMAPI ERROR: subfield of 0 size! (%X)\n", (unsigned int)loID);
903 }
904
905 #endif
906
907 if(pbuf + JAM_SF_HEADER_SIZE + size > limit)
908 /* it means that subfield claims to be longer
909 than header says. can't be. */
910 {
911 /* just break, ideally there shall be a setting for lax treatment of messagebase */
912 printf("SMAPI ERROR: wrongly sized subfield occured!\n");
913 break;
914 }
915
916 if(size >= 0xFFFF) /* realistic check: single subfield
917 longer than 64k is not realistic */
918 {
919 printf("SMAPI ERROR: subfield is suspiciously large! (%lu bytes)\n",
920 (unsigned long)size);
921 break;
922 }
923
924 ++count;
925 pbuf += JAM_SF_HEADER_SIZE + size;
926 }
927 len = sizeof(JAMSUBFIELD2LIST) + count *
928 (sizeof(JAMSUBFIELD2) - JAM_SF_HEADER_SIZE + 1) + *SubfieldLen;
929 *subfield = (JAMSUBFIELD2LISTptr)palloc(len);
930 subfield[0]->arraySize = len;
931 subfield[0]->subfieldCount = 0;
932 /* reserve memory for (real count + 1)*JAMSUBFIELD2 */
933 subfield[0]->subfield[0].Buffer = (byte *)&(subfield[0]->subfield[count + 1]);
934 subfieldNext = subfield[0]->subfield;
935 pbuf = buf;
936
937 while(subfield[0]->subfieldCount < count && pbuf + JAM_SF_HEADER_SIZE <= limit)
938 {
939 /* 02 bytes LoID */
940 subfieldNext->LoID = get_word(pbuf);
941 pbuf += 2;
942 /* 02 bytes HiID */
943 subfieldNext->HiID = get_word(pbuf);
944 pbuf += 2;
945 /* 04 bytes DatLen */
946 subfieldNext->DatLen = 0;
947 subfieldNext->Buffer[0] = '\0';
948 datlen = get_dword(pbuf);
949 pbuf += 4;
950 subfield[0]->subfieldCount++;
951
952 if(*SubfieldLen - (pbuf - buf) < datlen)
953 {
954 break;
955 }
956
957 /* DatLen bytes Buffer */
958 subfieldNext->DatLen = datlen;
959 memmove(subfieldNext->Buffer, pbuf, datlen);
960 /* Set up next element */
961 assert((byte *)(subfieldNext + 1) < subfield[0]->subfield[0].Buffer);
962 subfieldNext[1].Buffer = subfieldNext->Buffer + subfieldNext->DatLen + 1;
963 subfieldNext++;
964 assert(subfieldNext->Buffer <= (byte *)*subfield + subfield[0]->arraySize);
965 pbuf += datlen;
966 } /* endwhile */
967 *SubfieldLen = (dword)(pbuf - buf);
968 } /* decode_subfield */
969
read_subfield(int handle,JAMSUBFIELD2LISTptr * subfield,dword * SubfieldLen)970 int read_subfield(int handle, JAMSUBFIELD2LISTptr * subfield, dword * SubfieldLen)
971 {
972 byte * buf;
973
974 buf = (byte *)palloc(*SubfieldLen);
975
976 if((dword)farread(handle, (byte far *)buf, *SubfieldLen) != *SubfieldLen)
977 {
978 pfree(buf);
979 return 0;
980 } /* endif */
981
982 decode_subfield(buf, subfield, SubfieldLen);
983 pfree(buf);
984 return 1;
985 }
986
read_allidx(JAMBASEptr jmb)987 int read_allidx(JAMBASEptr jmb)
988 {
989 byte * buf, * pbuf, * hdrbuf = NULL;
990 JAMACTMSGptr newptr;
991 JAMHDR hbuf;
992 int len;
993 dword i, allocated, hlen;
994 dword offset;
995
996 lseek(jmb->IdxHandle, 0, SEEK_END);
997 len = tell(jmb->IdxHandle);
998 lseek(jmb->IdxHandle, 0, SEEK_SET);
999 buf = (byte *)palloc(len);
1000 pbuf = buf;
1001
1002 if(farread(jmb->IdxHandle, (byte far *)buf, len) != len)
1003 {
1004 pfree(buf);
1005 return 0;
1006 } /* endif */
1007
1008 lseek(jmb->HdrHandle, 0, SEEK_END);
1009 hlen = tell(jmb->HdrHandle);
1010 lseek(jmb->HdrHandle, 0, SEEK_SET);
1011
1012 if(hlen < MAXHDRINCORE)
1013 {
1014 /* read all headers in core */
1015 hdrbuf = (byte *)palloc(hlen);
1016
1017 if((dword)farread(jmb->HdrHandle, (byte far *)hdrbuf, hlen) != hlen)
1018 {
1019 pfree(hdrbuf);
1020 pfree(buf);
1021 return 0;
1022 } /* endif */
1023
1024 jmb->actmsg_read = 1;
1025 }
1026 else
1027 {
1028 jmb->actmsg_read = 2;
1029 }
1030
1031 allocated = jmb->HdrInfo.ActiveMsgs;
1032
1033 if(allocated > (dword)len / IDX_SIZE)
1034 {
1035 allocated = (dword)len / IDX_SIZE;
1036 }
1037
1038 if(allocated)
1039 {
1040 jmb->actmsg = (JAMACTMSGptr)farmalloc(allocated * sizeof(JAMACTMSG));
1041
1042 if(jmb->actmsg == NULL)
1043 {
1044 if(hdrbuf)
1045 {
1046 pfree(hdrbuf);
1047 }
1048
1049 pfree(buf);
1050 return 0;
1051 }
1052 }
1053
1054 for(i = 0; (pbuf - buf) < len; )
1055 {
1056 offset = get_dword(pbuf + 4);
1057
1058 if(offset != 0xFFFFFFFFUL)
1059 {
1060 if(offset + HDR_SIZE <= hlen)
1061 {
1062 if(hdrbuf)
1063 {
1064 decode_hdr(hdrbuf + offset, &hbuf);
1065 }
1066 else
1067 {
1068 lseek(jmb->HdrHandle, offset, SEEK_SET);
1069 read_hdr(jmb->HdrHandle, &hbuf);
1070 }
1071
1072 if(!(hbuf.Attribute & JMSG_DELETED))
1073 {
1074 if(i >= allocated)
1075 {
1076 newptr =
1077 (JAMACTMSGptr)farrealloc(jmb->actmsg,
1078 sizeof(JAMACTMSG) * (allocated += 16));
1079
1080 if(newptr == NULL)
1081 {
1082 pfree(jmb->actmsg);
1083
1084 if(hdrbuf)
1085 {
1086 pfree(hdrbuf);
1087 }
1088
1089 pfree(buf);
1090 return 0;
1091 }
1092
1093 jmb->actmsg = newptr;
1094 }
1095
1096 jmb->actmsg[i].IdxOffset = (dword)(pbuf - buf);
1097 jmb->actmsg[i].TrueMsg = offset;
1098 jmb->actmsg[i].UserCRC = get_dword(pbuf);
1099 memcpy(&(jmb->actmsg[i].hdr), &hbuf, sizeof(hbuf));
1100
1101 if(hdrbuf && offset + HDR_SIZE + jmb->actmsg[i].hdr.SubfieldLen <= hlen)
1102 {
1103 decode_subfield(hdrbuf + offset + HDR_SIZE, &(jmb->actmsg[i].subfield),
1104 &(jmb->actmsg[i].hdr.SubfieldLen));
1105 i++;
1106 }
1107 else
1108 {
1109 jmb->actmsg[i++].subfield = NULL;
1110 }
1111 } /* endif */
1112 } /* endif */
1113 } /* endif */
1114
1115 pbuf += 8;
1116 } /* endfor */
1117 pfree(buf);
1118
1119 if(hdrbuf)
1120 {
1121 pfree(hdrbuf);
1122 }
1123
1124 if(i != jmb->HdrInfo.ActiveMsgs)
1125 {
1126 /* warning: database corrupted! */
1127 jmb->HdrInfo.ActiveMsgs = i;
1128 jmb->modified = 1;
1129
1130 if(i == 0)
1131 {
1132 if(jmb->actmsg)
1133 {
1134 pfree(jmb->actmsg);
1135 jmb->actmsg = NULL;
1136 }
1137 }
1138 else if(i != allocated)
1139 {
1140 newptr = (JAMACTMSGptr)farrealloc(jmb->actmsg, sizeof(JAMACTMSG) * i);
1141
1142 if(newptr)
1143 {
1144 jmb->actmsg = newptr;
1145 }
1146 }
1147 } /* endif */
1148
1149 return 1;
1150 } /* read_allidx */
1151
write_hdrinfo(int handle,JAMHDRINFO * HdrInfo)1152 int write_hdrinfo(int handle, JAMHDRINFO * HdrInfo)
1153 {
1154 byte buf[HDRINFO_SIZE], * pbuf = buf;
1155
1156 /* 04 bytes Signature */
1157 memmove(pbuf, HdrInfo->Signature, (size_t)4);
1158 pbuf += 4;
1159 /* 04 bytes DateCreated */
1160 put_dword(pbuf, HdrInfo->DateCreated);
1161 pbuf += 4;
1162 /* 04 bytes ModCounter */
1163 put_dword(pbuf, HdrInfo->ModCounter);
1164 pbuf += 4;
1165 /* 04 bytes ActiveMsgs */
1166 put_dword(pbuf, HdrInfo->ActiveMsgs);
1167 pbuf += 4;
1168 /* 04 bytes PasswordCRC */
1169 put_dword(pbuf, HdrInfo->PasswordCRC);
1170 pbuf += 4;
1171 /* 04 bytes BaseMsgNum */
1172 put_dword(pbuf, HdrInfo->BaseMsgNum);
1173 pbuf += 4;
1174 /* 04 bytes highwater */
1175 put_dword(pbuf, HdrInfo->highwater);
1176 pbuf += 4;
1177 /* 996 bytes RSRVD */
1178 memmove(pbuf, HdrInfo->RSRVD, (size_t)996);
1179 pbuf += 996;
1180 assert(pbuf - buf == HDRINFO_SIZE);
1181 return farwrite(handle, (byte far *)buf, HDRINFO_SIZE) == HDRINFO_SIZE;
1182 } /* write_hdrinfo */
1183
write_idx(int handle,JAMIDXREC * Idx)1184 int write_idx(int handle, JAMIDXREC * Idx)
1185 {
1186 byte buf[IDX_SIZE], * pbuf = buf;
1187
1188 /* 04 bytes UserCRC */
1189 put_dword(pbuf, Idx->UserCRC);
1190 pbuf += 4;
1191 /* 04 bytes HdrOffset */
1192 put_dword(pbuf, Idx->HdrOffset);
1193 pbuf += 4;
1194 assert(pbuf - buf == IDX_SIZE);
1195 return farwrite(handle, (byte far *)buf, IDX_SIZE) == IDX_SIZE;
1196 }
1197
write_hdr(int handle,JAMHDR * Hdr)1198 int write_hdr(int handle, JAMHDR * Hdr)
1199 {
1200 byte buf[HDR_SIZE], * pbuf = buf;
1201
1202 /* 04 bytes Signature */
1203 memmove(pbuf, Hdr->Signature, (size_t)4);
1204 pbuf += 4;
1205 /* 02 bytes Revision */
1206 put_word(pbuf, Hdr->Revision);
1207 pbuf += 2;
1208 /* 02 bytes ReservedWord */
1209 put_word(pbuf, Hdr->ReservedWord);
1210 pbuf += 2;
1211 /* 04 bytes SubfieldLen */
1212 put_dword(pbuf, Hdr->SubfieldLen);
1213 pbuf += 4;
1214 /* 04 bytes TimesRead */
1215 put_dword(pbuf, Hdr->TimesRead);
1216 pbuf += 4;
1217 /* 04 bytes MsgIdCRC */
1218 put_dword(pbuf, Hdr->MsgIdCRC);
1219 pbuf += 4;
1220 /* 04 bytes ReplyCRC */
1221 put_dword(pbuf, Hdr->ReplyCRC);
1222 pbuf += 4;
1223 /* 04 bytes ReplyTo */
1224 put_dword(pbuf, Hdr->ReplyTo);
1225 pbuf += 4;
1226 /* 04 bytes Reply1st */
1227 put_dword(pbuf, Hdr->Reply1st);
1228 pbuf += 4;
1229 /* 04 bytes ReplyNext */
1230 put_dword(pbuf, Hdr->ReplyNext);
1231 pbuf += 4;
1232 /* 04 bytes DateWritten */
1233 put_dword(pbuf, Hdr->DateWritten);
1234 pbuf += 4;
1235 /* 04 bytes DateReceived */
1236 put_dword(pbuf, Hdr->DateReceived);
1237 pbuf += 4;
1238 /* 04 bytes DateProcessed */
1239 put_dword(pbuf, Hdr->DateProcessed);
1240 pbuf += 4;
1241 /* 04 bytes MsgNum */
1242 put_dword(pbuf, Hdr->MsgNum);
1243 pbuf += 4;
1244 /* 04 bytes Attribute */
1245 put_dword(pbuf, Hdr->Attribute);
1246 pbuf += 4;
1247 /* 04 bytes Attribute2 */
1248 put_dword(pbuf, Hdr->Attribute2);
1249 pbuf += 4;
1250 /* 04 bytes TxtOffset */
1251 put_dword(pbuf, Hdr->TxtOffset);
1252 pbuf += 4;
1253 /* 04 bytes TxtLen */
1254 put_dword(pbuf, Hdr->TxtLen);
1255 pbuf += 4;
1256 /* 04 bytes PasswordCRC */
1257 put_dword(pbuf, Hdr->PasswordCRC);
1258 pbuf += 4;
1259 /* 04 bytes Cost */
1260 put_dword(pbuf, Hdr->Cost);
1261 pbuf += 4;
1262 assert(pbuf - buf == HDR_SIZE);
1263 return farwrite(handle, (byte far *)buf, HDR_SIZE) == HDR_SIZE;
1264 } /* write_hdr */
1265
write_subfield(int handle,JAMSUBFIELD2LISTptr * subfield,dword SubfieldLen)1266 int write_subfield(int handle, JAMSUBFIELD2LISTptr * subfield, dword SubfieldLen)
1267 {
1268 unsigned char * buf, * pbuf;
1269 dword datlen;
1270 int rc;
1271 dword i;
1272 JAMSUBFIELD2ptr subfieldNext;
1273
1274 buf = (unsigned char *)palloc(SubfieldLen);
1275 pbuf = buf;
1276 subfieldNext = &(subfield[0]->subfield[0]);
1277
1278 for(i = 0; i < subfield[0]->subfieldCount; i++, subfieldNext++)
1279 {
1280 /* 02 bytes LoID */
1281 put_word(pbuf, subfieldNext->LoID);
1282 pbuf += 2;
1283 /* 02 bytes HiID */
1284 put_word(pbuf, subfieldNext->HiID);
1285 pbuf += 2;
1286 /* 04 bytes DatLen */
1287 put_dword(pbuf, subfieldNext->DatLen);
1288 datlen = subfieldNext->DatLen;
1289 pbuf += 4;
1290 /* DatLen bytes Buffer */
1291 memmove(pbuf, subfieldNext->Buffer, datlen);
1292 pbuf += datlen;
1293 } /* endwhile */
1294 rc = ((dword)farwrite(handle, (byte far *)buf, SubfieldLen) == SubfieldLen);
1295 pfree(buf);
1296 return rc;
1297 } /* write_subfield */
1298