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