/*
* SMAPI; Modified Squish MSGAPI
*
* Squish MSGAPI0 is copyright 1991 by Scott J. Dudley. All rights reserved.
* Modifications released to the public domain.
*
* Use of this file is subject to the restrictions contain in the Squish
* MSGAPI0 licence agreement. Please refer to licence.txt for complete
* details of the licencing restrictions. If you do not find the text
* of this agreement in licence.txt, or if you do not have this file,
* you should contact Scott Dudley at FidoNet node 1:249/106 or Internet
* e-mail Scott.Dudley@f106.n249.z1.fidonet.org.
*
* In no event should you proceed to use any of the source files in this
* archive without having accepted the terms of the MSGAPI0 licensing
* agreement, or such other agreement as you are able to reach with the
* author.
*/
/* STRUCTRW.C written 1998 by Tobias Ernst
*
* This file contains routines read and write packed structures like the
* struct XMSG in an platform-independent manner.
*
* Background information: You should never ever read or write any
* structure directly from disk with something like
* fread(&structure, sizeof(structure), 1, f)
* This will fail on some compliers that can't be told to pack structures
* in exactly the way that they are supposed to be. It will also fail
* when trying to read a file that is supposed to be used by a little-
* endian machine (like Intel) on a big endian machine (like PPC).
*
* So the conclusion: Never use fread, fwrite, farread, farwrite on
* structures - use the routines from this module instead, or if you are
* introducing a new structure, add a routine for it to this file.
*
* If you have any questions on this topic, feel free to contact me
* at 2:2476/418 or tobi@bland.fido.de.
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#define MSGAPI_HANDLERS
#include "compiler.h"
#ifdef HAS_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAS_IO_H
# include <io.h>
#endif
#include "prog.h"
#include "msgapi.h"
#include "api_sq.h"
#include "old_msg.h"
#include "api_jam.h"
#define MAXHDRINCORE (1024l*1024*10) /* Maximum jam hdr size for incore, 10M */
#ifndef __LITTLE_ENDIAN__
/*
* put_dword
*
* Writes a 4 byte word in little endian notation, independent of the local
* system architecture.
*/
void put_dword(byte *ptr, dword value)
{
ptr[0] = (value & 0xFF);
ptr[1] = (value >> 8) & 0xFF;
ptr[2] = (value >> 16) & 0xFF;
ptr[3] = (value >> 24) & 0xFF;
}
/*
* put_word
*
* Writes a 4 byte word in little endian notation, independent of the local
* system architecture.
*/
void put_word(byte *ptr, word value)
{
ptr[0] = (value & 0xFF);
ptr[1] = (value >> 8) & 0xFF;
}
#endif
#ifdef NEED_trivial_farread
#ifdef HAS_dos_read
/* "Text mode" not implemented !!! */
int trivial_farread( int handle, void far *buffer, unsigned len )
{ unsigned r_len=0;
if(dos_read( handle, buffer, len, &r_len ) )
return 0;
return r_len;
}
#else
#error "Can't implement trivial_farread() without dos_read()"
#endif
#endif
#ifdef NEED_trivial_farwrite
#ifdef HAS_dos_write
/* "Text mode" not implemented !!! */
int trivial_farwrite( int handle, void far *buffer, unsigned len )
{ unsigned r_len=0;
if(dos_write( handle, buffer, len, &r_len ) )
return 0;
return r_len;
}
#else
#error "Can't implement trivial_farwrite() without dos_write()"
#endif
#endif
int read_xmsg(int handle, XMSG *pxmsg)
{
byte buf[XMSG_SIZE], *pbuf = buf;
word rawdate, rawtime;
int i;
if (farread(handle, (byte far *)buf, XMSG_SIZE) != XMSG_SIZE)
{
return 0;
}
/* 04 bytes "attr" */
pxmsg->attr = get_dword(pbuf);
pbuf += 4;
/* 36 bytes "from" */
memmove(pxmsg->from, pbuf, XMSG_FROM_SIZE);
pbuf += XMSG_FROM_SIZE;
/* 36 bytes "to" */
memmove(pxmsg->to, pbuf, XMSG_TO_SIZE);
pbuf += XMSG_TO_SIZE;
/* 72 bytes "subj" */
memmove(pxmsg->subj, pbuf, XMSG_SUBJ_SIZE);
pbuf += XMSG_SUBJ_SIZE;
/* 8 bytes "orig" */
pxmsg->orig.zone = get_word(pbuf); pbuf += 2;
pxmsg->orig.net = get_word(pbuf); pbuf += 2;
pxmsg->orig.node = get_word(pbuf); pbuf += 2;
pxmsg->orig.point= get_word(pbuf); pbuf += 2;
/* 8 bytes "dest" */
pxmsg->dest.zone = get_word(pbuf); pbuf += 2;
pxmsg->dest.net = get_word(pbuf); pbuf += 2;
pxmsg->dest.node = get_word(pbuf); pbuf += 2;
pxmsg->dest.point= get_word(pbuf); pbuf += 2;
/* 4 bytes "date_written" */
rawdate = get_word(pbuf); pbuf += 2;
rawtime = get_word(pbuf); pbuf += 2;
pxmsg->date_written.date.da = rawdate & 31;
pxmsg->date_written.date.mo = (rawdate >> 5) & 15;
pxmsg->date_written.date.yr = (rawdate >> 9) & 127;
pxmsg->date_written.time.ss = rawtime & 31;
pxmsg->date_written.time.mm = (rawtime >> 5) & 63;
pxmsg->date_written.time.hh = (rawtime >> 11) & 31;
/* 4 bytes "date_arrived" */
rawdate = get_word(pbuf); pbuf += 2;
rawtime = get_word(pbuf); pbuf += 2;
pxmsg->date_arrived.date.da = rawdate & 31;
pxmsg->date_arrived.date.mo = (rawdate >> 5) & 15;
pxmsg->date_arrived.date.yr = (rawdate >> 9) & 127;
pxmsg->date_arrived.time.ss = rawtime & 31;
pxmsg->date_arrived.time.mm = (rawtime >> 5) & 63;
pxmsg->date_arrived.time.hh = (rawtime >> 11) & 31;
/* 2 byte "utc_ofs" */
pxmsg->utc_ofs = get_word(pbuf);
pbuf += 2;
/* 4 bytes "replyto" */
pxmsg->replyto = get_dword(pbuf);
pbuf += 4;
/* 10 times 4 bytes "replies" */
for (i = 0; i < MAX_REPLY; i++)
{
pxmsg->replies[i] = get_dword(pbuf);
pbuf += 4;
}
/* 4 bytes "umsgid" */
pxmsg->umsgid = get_dword(pbuf);
pbuf += 4;
/* 20 times FTSC date stamp */
memmove(pxmsg->__ftsc_date, pbuf, 20);
pbuf += 20;
assert(pbuf - buf == XMSG_SIZE);
return 1;
}
int write_xmsg(int handle, XMSG *pxmsg)
{
byte buf[XMSG_SIZE], *pbuf = buf;
word rawdate, rawtime;
int i;
/* 04 bytes "attr" */
put_dword(pbuf, pxmsg->attr);
pbuf += 4;
/* 36 bytes "from" */
memmove(pbuf, pxmsg->from, XMSG_FROM_SIZE);
pbuf += XMSG_FROM_SIZE;
/* 36 bytes "to" */
memmove(pbuf, pxmsg->to, XMSG_TO_SIZE);
pbuf += XMSG_TO_SIZE;
/* 72 bytes "subj" */
memmove(pbuf, pxmsg->subj, XMSG_SUBJ_SIZE);
pbuf += XMSG_SUBJ_SIZE;
/* 8 bytes "orig" */
put_word(pbuf, pxmsg->orig.zone); pbuf += 2;
put_word(pbuf, pxmsg->orig.net); pbuf += 2;
put_word(pbuf, pxmsg->orig.node); pbuf += 2;
put_word(pbuf, pxmsg->orig.point); pbuf += 2;
/* 8 bytes "dest" */
put_word(pbuf, pxmsg->dest.zone); pbuf += 2;
put_word(pbuf, pxmsg->dest.net); pbuf += 2;
put_word(pbuf, pxmsg->dest.node); pbuf += 2;
put_word(pbuf, pxmsg->dest.point); pbuf += 2;
/* 4 bytes "date_written" */
rawdate = rawtime = 0;
rawdate |= (((word)pxmsg->date_written.date.da) & 31);
rawdate |= (((word)pxmsg->date_written.date.mo) & 15) << 5;
rawdate |= (((word)pxmsg->date_written.date.yr) & 127) << 9;
rawtime |= (((word)pxmsg->date_written.time.ss) & 31);
rawtime |= (((word)pxmsg->date_written.time.mm) & 63) << 5;
rawtime |= (((word)pxmsg->date_written.time.hh) & 31) << 11;
put_word(pbuf, rawdate); pbuf += 2;
put_word(pbuf, rawtime); pbuf += 2;
/* 4 bytes "date_arrvied" */
rawdate = rawtime = 0;
rawdate |= (((word)pxmsg->date_arrived.date.da) & 31);
rawdate |= (((word)pxmsg->date_arrived.date.mo) & 15) << 5;
rawdate |= (((word)pxmsg->date_arrived.date.yr) & 127) << 9;
rawtime |= (((word)pxmsg->date_arrived.time.ss) & 31);
rawtime |= (((word)pxmsg->date_arrived.time.mm) & 63) << 5;
rawtime |= (((word)pxmsg->date_arrived.time.hh) & 31) << 11;
put_word(pbuf, rawdate); pbuf += 2;
put_word(pbuf, rawtime); pbuf += 2;
/* 2 byte "utc_ofs" */
put_word(pbuf, pxmsg->utc_ofs);
pbuf += 2;
/* 4 bytes "replyto" */
put_dword(pbuf, pxmsg->replyto);
pbuf += 4;
/* 10 times 4 bytes "replies" */
for (i = 0; i < MAX_REPLY; i++)
{
put_dword(pbuf, pxmsg->replies[i]);
pbuf += 4;
}
/* 4 bytes "umsgid" */
put_dword(pbuf, pxmsg->umsgid);
pbuf += 4;
/* 20 times FTSC date stamp */
memmove(pbuf, pxmsg->__ftsc_date, 20);
pbuf += 20;
assert(pbuf - buf == XMSG_SIZE);
return (farwrite(handle, (byte far *)buf, XMSG_SIZE) == XMSG_SIZE);
}
int read_sqhdr(int handle, SQHDR *psqhdr)
{
byte buf[SQHDR_SIZE], *pbuf = buf;
if (farread(handle, (byte far *)buf, SQHDR_SIZE) != SQHDR_SIZE)
{
return 0;
}
/* 4 bytes "id" */
psqhdr->id = get_dword(pbuf);
pbuf += 4;
/* 4 bytes "next_frame" */
psqhdr->next_frame = get_dword(pbuf);
pbuf += 4;
/* 4 bytes "prev_frame" */
psqhdr->prev_frame = get_dword(pbuf);
pbuf += 4;
/* 4 bytes "frame_length" */
psqhdr->frame_length = get_dword(pbuf);
pbuf += 4;
/* 4 bytes "msg_length" */
psqhdr->msg_length = get_dword(pbuf);
pbuf += 4;
/* 4 bytes "clen" */
psqhdr->clen = get_dword(pbuf);
pbuf += 4;
/* 2 bytes "frame_type" */
psqhdr->frame_type = get_word(pbuf);
pbuf += 2;
/* 4 bytes "rsvd" */
psqhdr->rsvd = get_word(pbuf);
pbuf += 2;
assert(pbuf - buf == SQHDR_SIZE);
return 1;
}
int write_sqhdr(int handle, SQHDR *psqhdr)
{
byte buf[SQHDR_SIZE], *pbuf = buf;
/* 4 bytes "id" */
put_dword(pbuf, psqhdr->id);
pbuf += 4;
/* 4 bytes "next_frame" */
put_dword(pbuf, psqhdr->next_frame);
pbuf += 4;
/* 4 bytes "prev_frame" */
put_dword(pbuf, psqhdr->prev_frame);
pbuf += 4;
/* 4 bytes "frame_length" */
put_dword(pbuf, psqhdr->frame_length);
pbuf += 4;
/* 4 bytes "msg_length" */
put_dword(pbuf, psqhdr->msg_length);
pbuf += 4;
/* 4 bytes "clen" */
put_dword(pbuf, psqhdr->clen);
pbuf += 4;
/* 2 bytes "frame_type" */
put_word(pbuf, psqhdr->frame_type);
pbuf += 2;
/* 4 bytes "rsvd" */
put_word(pbuf, psqhdr->rsvd);
pbuf += 2;
assert(pbuf - buf == SQHDR_SIZE);
return (farwrite(handle, (byte far *)buf, SQHDR_SIZE) == SQHDR_SIZE);
}
/*
* read_sqidx
*
* This function needs a little explanation. Just like the other functions,
* it reads in a special structure, the SQIDX structure. The problem is
* that this is done very often: It is not uncommon that 5000 SQIDXs are
* being read in seqeuence. Therefore, I had to do a little performance
* tuning here. I try to read in as much SQIDX structures as possible
* at once, while at the same time being able to cope with the fact that
* the OS might not be able to provide me with enough temporrary storage.
*
* Normally, you will not have to care about the buffering thing. Only
* the code between "begin reading in a single structre" and "end reading
* in a single structure" must be change if the structure layout changes.
*/
int read_sqidx(int handle, SQIDX *psqidx, dword n)
{
byte buf[SQIDX_SIZE], *pbuf = NULL;
byte *accel_buffer = NULL;
dword i, maxbuf = 0, rd;
if (n > 1)
{
maxbuf = n;
if ((dword)SQIDX_SIZE * (dword)n >= 32768L)
{
maxbuf = (dword)32768L / SQIDX_SIZE;
}
accel_buffer = malloc(SQIDX_SIZE * maxbuf);
}
for (i = 0; i < n; i++)
{
if (accel_buffer == NULL)
{
if (farread(handle, buf, SQIDX_SIZE) != SQIDX_SIZE)
{
return 0;
}
pbuf = buf;
}
else
{
if (!(i % maxbuf))
{
rd = (i + maxbuf > n) ? (n - i) : maxbuf;
if (farread(handle, accel_buffer, rd * SQIDX_SIZE) !=
(int)(rd * SQIDX_SIZE))
{
free(accel_buffer);
return 0;
}
pbuf = accel_buffer;
}
}
/* Begin reading in a single structure */
/* 4 bytes "ofs" */
psqidx[i].ofs = get_dword(pbuf);
pbuf += 4;
/* 4 bytes "umsgid" */
psqidx[i].umsgid = get_dword(pbuf);
pbuf += 4;
/* 4 bytes "hash" */
psqidx[i].hash = get_dword(pbuf);
pbuf += 4;
/* Stop reading in a single structure */
}
if (accel_buffer != NULL)
{
free(accel_buffer);
}
return 1;
}
int write_sqidx(int handle, SQIDX *psqidx, dword n)
{
byte buf[SQIDX_SIZE], *pbuf = NULL;
byte *accel_buffer = NULL;
dword i, maxbuf = 0, wr;
if (n > 1)
{
maxbuf = n;
if ((dword)SQIDX_SIZE * (dword)n >= 32768L)
{
maxbuf = (dword)32768L / SQIDX_SIZE;
}
accel_buffer = malloc(SQIDX_SIZE * maxbuf);
pbuf = accel_buffer;
}
for (i = 0; i < n; i++)
{
if (accel_buffer == NULL)
{
pbuf = buf;
}
/* 4 bytes "ofs" */
put_dword(pbuf, psqidx[i].ofs);
pbuf += 4;
/* 4 bytes "umsgid" */
put_dword(pbuf, psqidx[i].umsgid);
pbuf += 4;
/* 4 bytes "hash" */
put_dword(pbuf, psqidx[i].hash);
pbuf += 4;
if (accel_buffer == NULL)
{
if (farwrite(handle, buf, SQIDX_SIZE) != SQIDX_SIZE)
{
return 0;
}
}
else
{
if (i == n - 1 || (!((i + 1) % maxbuf)))
{
wr = (!((i + 1) % maxbuf)) ? maxbuf : (n % maxbuf);
if (farwrite(handle, accel_buffer, wr * SQIDX_SIZE) !=
(wr * SQIDX_SIZE))
{
free(accel_buffer);
return 0;
}
pbuf = accel_buffer;
}
}
}
if (accel_buffer != NULL)
{
free(accel_buffer);
}
return 1;
}
int read_sqbase(int handle, struct _sqbase *psqbase)
{
byte buf[SQBASE_SIZE], *pbuf = buf;
if (farread(handle, (byte far *)buf, SQBASE_SIZE) != SQBASE_SIZE)
{
return 0;
}
psqbase->len = get_word(pbuf);
pbuf += 2;
psqbase->rsvd1 = get_word(pbuf);
pbuf += 2;
psqbase->num_msg = get_dword(pbuf);
pbuf += 4;
psqbase->high_msg = get_dword(pbuf);
pbuf += 4;
psqbase->skip_msg = get_dword(pbuf);
pbuf += 4;
psqbase->high_water = get_dword(pbuf);
pbuf += 4;
psqbase->uid = get_dword(pbuf);
pbuf += 4;
memmove(psqbase->base, pbuf, 80);
pbuf += 80;
psqbase->begin_frame = get_dword(pbuf);
pbuf += 4;
psqbase->last_frame = get_dword(pbuf);
pbuf += 4;
psqbase->free_frame = get_dword(pbuf);
pbuf += 4;
psqbase->last_free_frame = get_dword(pbuf);
pbuf += 4;
psqbase->end_frame = get_dword(pbuf);
pbuf += 4;
psqbase->max_msg = get_dword(pbuf);
pbuf += 4;
psqbase->keep_days = get_word(pbuf);
pbuf += 2;
psqbase->sz_sqhdr = get_word(pbuf);
pbuf += 2;
memmove(psqbase->rsvd2, pbuf, 124);
pbuf += 124;
assert(pbuf-buf == SQBASE_SIZE);
return 1;
}
int write_sqbase(int handle, struct _sqbase *psqbase)
{
byte buf[SQBASE_SIZE], *pbuf = buf;
put_word(pbuf, psqbase->len);
pbuf += 2;
put_word(pbuf, psqbase->rsvd1);
pbuf += 2;
put_dword(pbuf, psqbase->num_msg);
pbuf += 4;
put_dword(pbuf, psqbase->high_msg);
pbuf += 4;
put_dword(pbuf, psqbase->skip_msg);
pbuf += 4;
put_dword(pbuf, psqbase->high_water);
pbuf += 4;
put_dword(pbuf, psqbase->uid);
pbuf += 4;
memmove(pbuf, psqbase->base, 80);
pbuf += 80;
put_dword(pbuf, psqbase->begin_frame);
pbuf += 4;
put_dword(pbuf, psqbase->last_frame);
pbuf += 4;
put_dword(pbuf, psqbase->free_frame);
pbuf += 4;
put_dword(pbuf, psqbase->last_free_frame);
pbuf += 4;
put_dword(pbuf, psqbase->end_frame);
pbuf += 4;
put_dword(pbuf, psqbase->max_msg);
pbuf += 4;
put_word(pbuf, psqbase->keep_days);
pbuf += 2;
put_word(pbuf, psqbase->sz_sqhdr);
pbuf += 2;
memmove(pbuf, psqbase->rsvd2, 124);
pbuf += 124;
assert(pbuf - buf == SQBASE_SIZE);
return (farwrite(handle, (byte far *)buf, SQBASE_SIZE) == SQBASE_SIZE);
}
int read_omsg(int handle, struct _omsg *pomsg)
{
byte buf[OMSG_SIZE], *pbuf = buf;
word rawdate, rawtime;
if (farread(handle, (byte far *)buf, OMSG_SIZE) != OMSG_SIZE)
{
return 0;
}
memmove(pomsg->from, pbuf, 36);
pbuf += 36;
memmove(pomsg->to, pbuf, 36);
pbuf += 36;
memmove(pomsg->subj, pbuf, 72);
pbuf += 72;
memmove(pomsg->date, pbuf, 20);
pbuf += 20;
pomsg->times = get_word(pbuf);
pbuf += 2;
pomsg->dest = get_word(pbuf);
pbuf += 2;
pomsg->orig = get_word(pbuf);
pbuf += 2;
pomsg->cost = get_word(pbuf);
pbuf += 2;
pomsg->orig_net = get_word(pbuf);
pbuf += 2;
pomsg->dest_net = get_word(pbuf);
pbuf += 2;
/* 4 bytes "date_written" */
rawdate = get_word(pbuf); pbuf += 2;
rawtime = get_word(pbuf); pbuf += 2;
pomsg->date_written.date.da = rawdate & 31;
pomsg->date_written.date.mo = (rawdate >> 5) & 15;
pomsg->date_written.date.yr = (rawdate >> 9) & 127;
pomsg->date_written.time.ss = rawtime & 31;
pomsg->date_written.time.mm = (rawtime >> 5) & 63;
pomsg->date_written.time.hh = (rawtime >> 11) & 31;
/* 4 bytes "date_arrived" */
rawdate = get_word(pbuf); pbuf += 2;
rawtime = get_word(pbuf); pbuf += 2;
pomsg->date_arrived.date.da = rawdate & 31;
pomsg->date_arrived.date.mo = (rawdate >> 5) & 15;
pomsg->date_arrived.date.yr = (rawdate >> 9) & 127;
pomsg->date_arrived.time.ss = rawtime & 31;
pomsg->date_arrived.time.mm = (rawtime >> 5) & 63;
pomsg->date_arrived.time.hh = (rawtime >> 11) & 31;
pomsg->reply = get_word(pbuf);
pbuf += 2;
pomsg->attr = get_word(pbuf);
pbuf += 2;
pomsg->up = get_word(pbuf);
pbuf += 2;
assert(pbuf - buf == OMSG_SIZE);
return 1;
}
int write_omsg(int handle, struct _omsg *pomsg)
{
byte buf[OMSG_SIZE], *pbuf = buf;
word rawdate, rawtime;
memmove(pbuf, pomsg->from, 36);
pbuf += 36;
memmove(pbuf, pomsg->to, 36);
pbuf += 36;
memmove(pbuf, pomsg->subj, 72);
pbuf += 72;
memmove(pbuf, pomsg->date, 20);
pbuf += 20;
put_word(pbuf, pomsg->times);
pbuf += 2;
put_word(pbuf, pomsg->dest);
pbuf += 2;
put_word(pbuf, pomsg->orig);
pbuf += 2;
put_word(pbuf, pomsg->cost);
pbuf += 2;
put_word(pbuf, pomsg->orig_net);
pbuf += 2;
put_word(pbuf, pomsg->dest_net);
pbuf += 2;
/* 4 bytes "date_written" */
rawdate = rawtime = 0;
rawdate |= (((word)pomsg->date_written.date.da) & 31);
rawdate |= (((word)pomsg->date_written.date.mo) & 15) << 5;
rawdate |= (((word)pomsg->date_written.date.yr) & 127) << 9;
rawtime |= (((word)pomsg->date_written.time.ss) & 31);
rawtime |= (((word)pomsg->date_written.time.mm) & 63) << 5;
rawtime |= (((word)pomsg->date_written.time.hh) & 31) << 11;
put_word(pbuf, rawdate); pbuf += 2;
put_word(pbuf, rawtime); pbuf += 2;
/* 4 bytes "date_arrvied" */
rawdate = rawtime = 0;
rawdate |= (((word)pomsg->date_arrived.date.da) & 31);
rawdate |= (((word)pomsg->date_arrived.date.mo) & 15) << 5;
rawdate |= (((word)pomsg->date_arrived.date.yr) & 127) << 9;
rawtime |= (((word)pomsg->date_arrived.time.ss) & 31);
rawtime |= (((word)pomsg->date_arrived.time.mm) & 63) << 5;
rawtime |= (((word)pomsg->date_arrived.time.hh) & 31) << 11;
put_word(pbuf, rawdate); pbuf += 2;
put_word(pbuf, rawtime); pbuf += 2;
put_word(pbuf, pomsg->reply);
pbuf += 2;
put_word(pbuf, pomsg->attr);
pbuf += 2;
put_word(pbuf, pomsg->up);
pbuf += 2;
assert(pbuf - buf == OMSG_SIZE);
return (farwrite(handle, (byte far *)buf, OMSG_SIZE) == OMSG_SIZE);
}
int read_hdrinfo(int handle, JAMHDRINFO *HdrInfo)
{
byte buf[HDRINFO_SIZE], *pbuf = buf;
if (farread(handle, (byte far *)buf, HDRINFO_SIZE) != HDRINFO_SIZE) {
return 0;
} /* endif */
/* 04 bytes Signature */
memmove(HdrInfo->Signature, pbuf, (size_t)4);
pbuf += 4;
/* 04 bytes DateCreated */
HdrInfo->DateCreated = get_dword(pbuf);
pbuf += 4;
/* 04 bytes ModCounter */
HdrInfo->ModCounter = get_dword(pbuf);
pbuf += 4;
/* 04 bytes ActiveMsgs */
HdrInfo->ActiveMsgs = get_dword(pbuf);
pbuf += 4;
/* 04 bytes PasswordCRC */
HdrInfo->PasswordCRC = get_dword(pbuf);
pbuf += 4;
/* 04 bytes BaseMsgNum */
HdrInfo->BaseMsgNum = get_dword(pbuf);
pbuf += 4;
/* 04 bytes highwater */
HdrInfo->highwater = get_dword(pbuf);
pbuf += 4;
/* 996 bytes RSRVD */
memmove(HdrInfo->RSRVD, pbuf, (size_t)996);
pbuf += 996;
assert(pbuf - buf == HDRINFO_SIZE);
return 1;
}
int read_idx(int handle, JAMIDXREC *Idx)
{
byte buf[IDX_SIZE], *pbuf = buf;
if (farread(handle, (byte far *)buf, IDX_SIZE) != IDX_SIZE) {
return 0;
} /* endif */
/* 04 bytes UserCRC */
Idx->UserCRC = get_dword(pbuf);
pbuf += 4;
/* 04 bytes HdrOffset */
Idx->HdrOffset = get_dword(pbuf);
pbuf += 4;
assert(pbuf - buf == IDX_SIZE);
return 1;
}
static void decode_hdr(byte *pbuf, JAMHDR *Hdr)
{
/* 04 bytes Signature */
memmove(Hdr->Signature, pbuf, (size_t)4);
pbuf += 4;
/* 02 bytes Revision */
Hdr->Revision = get_word(pbuf);
pbuf += 2;
/* 02 bytes ReservedWord */
Hdr->ReservedWord = get_word(pbuf);
pbuf += 2;
/* 04 bytes SubfieldLen */
Hdr->SubfieldLen = get_dword(pbuf);
pbuf += 4;
/* 04 bytes TimesRead */
Hdr->TimesRead = get_dword(pbuf);
pbuf += 4;
/* 04 bytes MsgIdCRC */
Hdr->MsgIdCRC = get_dword(pbuf);
pbuf += 4;
/* 04 bytes ReplyCRC */
Hdr->ReplyCRC = get_dword(pbuf);
pbuf += 4;
/* 04 bytes ReplyTo */
Hdr->ReplyTo = get_dword(pbuf);
pbuf += 4;
/* 04 bytes Reply1st */
Hdr->Reply1st = get_dword(pbuf);
pbuf += 4;
/* 04 bytes ReplyNext */
Hdr->ReplyNext = get_dword(pbuf);
pbuf += 4;
/* 04 bytes DateWritten */
Hdr->DateWritten = get_dword(pbuf);
pbuf += 4;
/* 04 bytes DateReceived */
Hdr->DateReceived = get_dword(pbuf);
pbuf += 4;
/* 04 bytes DateProcessed */
Hdr->DateProcessed = get_dword(pbuf);
pbuf += 4;
/* 04 bytes MsgNum */
Hdr->MsgNum = get_dword(pbuf);
pbuf += 4;
/* 04 bytes Attribute */
Hdr->Attribute = get_dword(pbuf);
pbuf += 4;
/* 04 bytes Attribute2 */
Hdr->Attribute2 = get_dword(pbuf);
pbuf += 4;
/* 04 bytes TxtOffset */
Hdr->TxtOffset = get_dword(pbuf);
pbuf += 4;
/* 04 bytes TxtLen */
Hdr->TxtLen = get_dword(pbuf);
pbuf += 4;
/* 04 bytes PasswordCRC */
Hdr->PasswordCRC = get_dword(pbuf);
pbuf += 4;
/* 04 bytes Cost */
Hdr->Cost = get_dword(pbuf);
}
int read_hdr(int handle, JAMHDR *Hdr)
{
byte buf[HDR_SIZE];
if (farread(handle, (byte far *)buf, HDR_SIZE) != HDR_SIZE) {
return 0;
} /* endif */
decode_hdr(buf, Hdr);
return 1;
}
int copy_subfield(JAMSUBFIELD2LISTptr *to, JAMSUBFIELD2LISTptr from)
{
dword i;
*to = palloc(from->arraySize);
if (*to == NULL) return 1;
memcpy(*to, from, from->arraySize);
for (i=0; i<from->subfieldCount; i++)
to[0]->subfield[i].Buffer+=((char *)*to-(char *)from);
return 0;
}
static void decode_subfield(byte *buf, JAMSUBFIELD2LISTptr *subfield, dword *SubfieldLen)
{
JAMSUBFIELD2ptr subfieldNext;
dword datlen;
int i, len;
byte *pbuf;
pbuf = buf;
i = 0;
while ((pbuf - buf + 8) < *SubfieldLen) {
i++;
pbuf += get_dword(pbuf+4) + sizeof(JAMBINSUBFIELD);
}
len = sizeof(JAMSUBFIELD2LIST)+i*(sizeof(JAMSUBFIELD2)-sizeof(JAMBINSUBFIELD)+1)+*SubfieldLen;
*subfield = palloc(len);
subfield[0]->arraySize = len;
subfield[0]->subfieldCount = 0;
subfield[0]->subfield[0].Buffer = (byte *)&(subfield[0]->subfield[i+1]);
subfieldNext = subfield[0]->subfield;
pbuf = buf;
while ((pbuf - buf + 8) < *SubfieldLen) {
/* 02 bytes LoID */
subfieldNext->LoID = get_word(pbuf);
pbuf += 2;
/* 02 bytes HiID */
subfieldNext->HiID = get_word(pbuf);
pbuf += 2;
/* 04 bytes DatLen */
subfieldNext->DatLen = 0;
subfieldNext->Buffer[0] = '\0';
datlen = get_dword(pbuf);
pbuf += 4;
subfield[0]->subfieldCount++;
if (pbuf - buf + datlen > *SubfieldLen)
break;
/* DatLen bytes Buffer */
if ((long)datlen >= 0 && datlen < *SubfieldLen)
{ subfieldNext->DatLen = datlen;
memmove(subfieldNext->Buffer, pbuf, datlen);
subfieldNext[1].Buffer = subfieldNext->Buffer+subfieldNext->DatLen+1;
subfieldNext++;
assert((byte *)(subfieldNext+1)<=subfield[0]->subfield[0].Buffer);
assert(subfieldNext->Buffer<=(byte *)*subfield+subfield[0]->arraySize);
}
else
break;
pbuf += datlen;
} /* endwhile */
*SubfieldLen = pbuf - buf;
}
int read_subfield(int handle, JAMSUBFIELD2LISTptr *subfield, dword *SubfieldLen)
{
byte *buf;
buf = (byte*)palloc(*SubfieldLen);
if (farread(handle, (byte far *)buf, *SubfieldLen) != *SubfieldLen) {
pfree(buf);
return 0;
} /* endif */
decode_subfield(buf, subfield, SubfieldLen);
pfree(buf);
return 1;
}
int read_allidx(JAMBASEptr jmb)
{
byte *buf, *pbuf, *hdrbuf = NULL;
JAMACTMSGptr newptr;
JAMHDR hbuf;
int len;
dword i, allocated, hlen;
dword offset;
lseek(jmb->IdxHandle, 0, SEEK_END);
len = tell(jmb->IdxHandle);
lseek(jmb->IdxHandle, 0, SEEK_SET);
buf = (byte *)palloc(len);
pbuf = buf;
if (farread(jmb->IdxHandle, (byte far *)buf, len) != len) {
pfree(buf);
return 0;
} /* endif */
lseek(jmb->HdrHandle, 0, SEEK_END);
hlen = tell(jmb->HdrHandle);
lseek(jmb->HdrHandle, 0, SEEK_SET);
if (hlen<MAXHDRINCORE) {
/* read all headers in core */
hdrbuf = (byte *)palloc(hlen);
if (farread(jmb->HdrHandle, (byte far *)hdrbuf, hlen) != hlen) {
pfree(hdrbuf);
pfree(buf);
return 0;
} /* endif */
jmb->actmsg_read = 1;
} else
jmb->actmsg_read = 2;
allocated = jmb->HdrInfo.ActiveMsgs;
if (allocated > len/IDX_SIZE) allocated = len/IDX_SIZE;
if (allocated) {
jmb->actmsg = (JAMACTMSGptr)farmalloc(allocated * sizeof(JAMACTMSG));
if (jmb->actmsg == NULL) {
if (hdrbuf) pfree(hdrbuf);
pfree(buf);
return 0;
}
}
for (i = 0; (pbuf - buf) < len;) {
offset = get_dword(pbuf+4);
if (offset != 0xFFFFFFFFUL) {
if (offset+HDR_SIZE<=hlen) {
if (hdrbuf)
decode_hdr(hdrbuf+offset, &hbuf);
else {
lseek(jmb->HdrHandle, offset, SEEK_SET);
read_hdr(jmb->HdrHandle, &hbuf);
}
if (!(hbuf.Attribute & JMSG_DELETED)) {
if (i >= allocated) {
newptr = (JAMACTMSGptr)farrealloc(jmb->actmsg, sizeof(JAMACTMSG)*(allocated += 16));
if (newptr == NULL) {
pfree(jmb->actmsg);
if (hdrbuf) pfree(hdrbuf);
pfree(buf);
return 0;
}
jmb->actmsg = newptr;
}
jmb->actmsg[i].IdxOffset = pbuf - buf;
jmb->actmsg[i].TrueMsg = offset;
jmb->actmsg[i].UserCRC = get_dword(pbuf);
memcpy(&(jmb->actmsg[i].hdr), &hbuf, sizeof(hbuf));
if (hdrbuf && offset+HDR_SIZE+jmb->actmsg[i].hdr.SubfieldLen<=hlen) {
decode_subfield(hdrbuf+offset+HDR_SIZE, &(jmb->actmsg[i].subfield), &(jmb->actmsg[i].hdr.SubfieldLen));
i++;
} else
jmb->actmsg[i++].subfield = NULL;
} /* endif */
} /* endif */
} /* endif */
pbuf += 8;
} /* endfor */
pfree(buf);
if (hdrbuf) pfree(hdrbuf);
if (i != jmb->HdrInfo.ActiveMsgs) {
/* warning: database corrupted! */
jmb->HdrInfo.ActiveMsgs = i;
jmb->modified = 1;
if (i == 0) {
if (jmb->actmsg) {
pfree(jmb->actmsg);
jmb->actmsg = NULL;
}
} else if (i != allocated) {
newptr = (JAMACTMSGptr)farrealloc(jmb->actmsg, sizeof(JAMACTMSG)*i);
if (newptr) jmb->actmsg = newptr;
}
} /* endif */
return 1;
}
int write_hdrinfo(int handle, JAMHDRINFO *HdrInfo)
{
byte buf[HDRINFO_SIZE], *pbuf = buf;
/* 04 bytes Signature */
memmove(pbuf, HdrInfo->Signature, (size_t)4);
pbuf += 4;
/* 04 bytes DateCreated */
put_dword(pbuf, HdrInfo->DateCreated);
pbuf += 4;
/* 04 bytes ModCounter */
put_dword(pbuf, HdrInfo->ModCounter);
pbuf += 4;
/* 04 bytes ActiveMsgs */
put_dword(pbuf, HdrInfo->ActiveMsgs);
pbuf += 4;
/* 04 bytes PasswordCRC */
put_dword(pbuf, HdrInfo->PasswordCRC);
pbuf += 4;
/* 04 bytes BaseMsgNum */
put_dword(pbuf, HdrInfo->BaseMsgNum);
pbuf += 4;
/* 04 bytes highwater */
put_dword(pbuf, HdrInfo->highwater);
pbuf += 4;
/* 996 bytes RSRVD */
memmove(pbuf, HdrInfo->RSRVD, (size_t)996);
pbuf += 996;
assert(pbuf - buf == HDRINFO_SIZE);
return (farwrite(handle, (byte far *)buf, HDRINFO_SIZE) == HDRINFO_SIZE);
}
int write_idx(int handle, JAMIDXREC *Idx)
{
byte buf[IDX_SIZE], *pbuf = buf;
/* 04 bytes UserCRC */
put_dword(pbuf, Idx->UserCRC);
pbuf += 4;
/* 04 bytes HdrOffset */
put_dword(pbuf, Idx->HdrOffset);
pbuf += 4;
assert(pbuf - buf == IDX_SIZE);
return (farwrite(handle, (byte far *)buf, IDX_SIZE) == IDX_SIZE);
}
int write_hdr(int handle, JAMHDR *Hdr)
{
byte buf[HDR_SIZE], *pbuf = buf;
/* 04 bytes Signature */
memmove(pbuf, Hdr->Signature, (size_t)4);
pbuf += 4;
/* 02 bytes Revision */
put_word(pbuf, Hdr->Revision);
pbuf += 2;
/* 02 bytes ReservedWord */
put_word(pbuf, Hdr->ReservedWord);
pbuf += 2;
/* 04 bytes SubfieldLen */
put_dword(pbuf, Hdr->SubfieldLen);
pbuf += 4;
/* 04 bytes TimesRead */
put_dword(pbuf, Hdr->TimesRead);
pbuf += 4;
/* 04 bytes MsgIdCRC */
put_dword(pbuf, Hdr->MsgIdCRC);
pbuf += 4;
/* 04 bytes ReplyCRC */
put_dword(pbuf, Hdr->ReplyCRC);
pbuf += 4;
/* 04 bytes ReplyTo */
put_dword(pbuf, Hdr->ReplyTo);
pbuf += 4;
/* 04 bytes Reply1st */
put_dword(pbuf, Hdr->Reply1st);
pbuf += 4;
/* 04 bytes ReplyNext */
put_dword(pbuf, Hdr->ReplyNext);
pbuf += 4;
/* 04 bytes DateWritten */
put_dword(pbuf, Hdr->DateWritten);
pbuf += 4;
/* 04 bytes DateReceived */
put_dword(pbuf, Hdr->DateReceived);
pbuf += 4;
/* 04 bytes DateProcessed */
put_dword(pbuf, Hdr->DateProcessed);
pbuf += 4;
/* 04 bytes MsgNum */
put_dword(pbuf, Hdr->MsgNum);
pbuf += 4;
/* 04 bytes Attribute */
put_dword(pbuf, Hdr->Attribute);
pbuf += 4;
/* 04 bytes Attribute2 */
put_dword(pbuf, Hdr->Attribute2);
pbuf += 4;
/* 04 bytes TxtOffset */
put_dword(pbuf, Hdr->TxtOffset);
pbuf += 4;
/* 04 bytes TxtLen */
put_dword(pbuf, Hdr->TxtLen);
pbuf += 4;
/* 04 bytes PasswordCRC */
put_dword(pbuf, Hdr->PasswordCRC);
pbuf += 4;
/* 04 bytes Cost */
put_dword(pbuf, Hdr->Cost);
pbuf += 4;
assert(pbuf - buf == HDR_SIZE);
return (farwrite(handle, (byte far *)buf, HDR_SIZE) == HDR_SIZE);
}
int write_subfield(int handle, JAMSUBFIELD2LISTptr *subfield, dword SubfieldLen)
{
unsigned char *buf, *pbuf;
dword datlen;
int rc;
dword i;
JAMSUBFIELD2ptr subfieldNext;
buf = (unsigned char*)palloc(SubfieldLen);
pbuf = buf;
subfieldNext = &(subfield[0]->subfield[0]);
for (i=0; i<subfield[0]->subfieldCount; i++, subfieldNext++) {
/* 02 bytes LoID */
put_word(pbuf, subfieldNext->LoID);
pbuf += 2;
/* 02 bytes HiID */
put_word(pbuf, subfieldNext->HiID);
pbuf += 2;
/* 04 bytes DatLen */
put_dword(pbuf, subfieldNext->DatLen);
datlen = subfieldNext->DatLen;
pbuf += 4;
/* DatLen bytes Buffer */
memmove(pbuf, subfieldNext->Buffer, datlen);
pbuf += datlen;
} /* endwhile */
rc =(farwrite(handle, (byte far *)buf, SubfieldLen) == SubfieldLen);
pfree(buf);
return rc;
}
syntax highlighted by Code2HTML, v. 0.9.1