1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
|
/***************************************************************************
* *
* Squish Developers Kit Source, Version 2.00 *
* Copyright 1989-1994 by SCI Communications. All rights reserved. *
* *
* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE *
* SQUISH DEVELOPERS KIT LICENSING AGREEMENT IN SQDEV.PRN. IF YOU DO NOT *
* FIND THE TEXT OF THIS AGREEMENT IN THE AFOREMENTIONED FILE, OR IF YOU *
* DO NOT HAVE THIS FILE, YOU SHOULD IMMEDIATELY CONTACT THE AUTHOR AT *
* ONE OF THE ADDRESSES LISTED BELOW. IN NO EVENT SHOULD YOU PROCEED TO *
* USE THIS FILE WITHOUT HAVING ACCEPTED THE TERMS OF THE SQUISH *
* DEVELOPERS KIT LICENSING AGREEMENT, OR SUCH OTHER AGREEMENT AS YOU ARE *
* ABLE TO REACH WITH THE AUTHOR. *
* *
* You can contact the author at one of the address listed below: *
* *
* Scott Dudley FidoNet 1:249/106 *
* 777 Downing St. Internet sjd@f106.n249.z1.fidonet.org *
* Kingston, Ont. CompuServe >INTERNET:sjd@f106.n249.z1.fidonet.org *
* Canada K7M 5N3 BBS 1-613-634-3058, V.32bis *
* *
***************************************************************************/
/* $Id: api_sq.h,v 1.6 2002/06/10 12:59:18 mche Exp $ */
#ifndef __API_SQ_H_DEFINED
#define __API_SQ_H_DEFINED
#include "compiler.h"
struct _sqhdr;
struct _sqidx;
typedef struct _sqidx SQIDX;
typedef struct _sqhdr SQHDR;
typedef long FOFS;
/* Try to access a locked Squish base up to five times */
#define SQUISH_LOCK_RETRY 5
/* Expand the Squish index by 64 records at a time */
#define SQUIQSH_IDX_EXPAND 64
/* No frame offset */
#define NULL_FRAME ((FOFS)0L)
/* Frame types for sqhdr.frame_type */
#define FRAME_NORMAL 0x00 /* Normal text frame */
#define FRAME_FREE 0x01 /* Part of the free chain */
#define FRAME_LZSS 0x02 /* Not implemented */
#define FRAME_UPDATE 0x03 /* Frame is being updated by another task */
/* BItmask for sqidx.hash to indicate that the msg was received */
#define IDXE_MSGREAD 0x80000000Lu
/* Macros for accessing the hidden parts of data structures */
#define Sqd ((SQDATA *)(ha->apidata))
#define HSqd ((SQDATA *)(((struct _msgh *)hmsg)->ha->apidata))
/* Squish frame header. This comes before each and every message in a *
* Squish message base. */
struct _sqhdr
{
#define SQHDRID 0xafae4453L
dword id; /* sqhdr.id must always equal SQHDRID */
FOFS next_frame; /* Next frame in the linked list */
FOFS prev_frame; /* Prior frame in the linked list */
dword frame_length; /* Length of this frame */
dword msg_length; /* Length used in this frame by XMSG, ctrl and text */
dword clen; /* Length used in this frame by ctrl info only */
word frame_type; /* Type of frame -- see above FRAME_XXXX */
word rsvd; /* Reserved for future use */
};
/* An individual index entry in <area>.SQI */
struct _sqidx
{
FOFS ofs; /* Offset of the frame relating to this msg */
UMSGID umsgid; /* Unique message identifier of this msg */
dword hash; /* SquishHash of msg.to for this msg */
};
/* Header block at offset 0 of <area>.SQD */
typedef struct _sqbase
{
word len; /* LENGTH OF THIS STRUCTURE! */ /* 0 */
word rsvd1; /* reserved */ /* 2 */
dword num_msg; /* Number of messages in area */ /* 4 */
dword high_msg; /* Highest msg in area. Same as num_msg*/ /* 8 */
dword skip_msg; /* Skip killing first x msgs in area */ /* 12 */
dword high_water; /* Msg# (not umsgid) of HWM */ /* 16 */
dword uid; /* Number of the next UMSGID to use */ /* 20 */
byte base[80]; /* Base name of SquishFile */ /* 24 */
FOFS begin_frame; /* Offset of first frame in file */ /* 104 */
FOFS last_frame; /* Offset to last frame in file */ /* 108 */
FOFS free_frame; /* Offset of first FREE frame in file */ /* 112 */
FOFS last_free_frame; /* Offset of last free frame in file */ /* 116 */
FOFS end_frame; /* Pointer to end of file */ /* 120 */
dword max_msg; /* Max # of msgs to keep in area */ /* 124 */
word keep_days; /* Max age of msgs in area (SQPack) */ /* 128 */
word sz_sqhdr; /* sizeof(SQHDR) */ /* 130 */
byte rsvd2[124]; /* Reserved by Squish for future use*/ /* 132 */
/* total: 256 */
} SQBASE;
typedef struct
{
dword dwUsed; /* Number of entries used in this seg */
dword dwMax; /* Number of entries allocated in this seg */
SQIDX far *psqi; /* Pointer to index entries for this segment */
} SQIDXSEG;
/* Handle to a Squish index file */
typedef struct
{
#define ID_HIDX 0x9fee
word id; /* Must be ID_HIDX */
HAREA ha; /* Area to which this index belongs */
long lAllocatedRecords; /* Space allocated in idx file */
long lDeltaLo; /* Low # of changed msg */
long lDeltaHi; /* High # of changed msg */
int fBuffer; /* Use index buffer? */
int cSeg; /* Number of segments used */
SQIDXSEG *pss; /* Segments containing messages */
} *HIDX;
/* Private data in handle passed among API functions which handle message *
* areas. */
typedef struct _sqdata
{
word cbSqbase; /* Length of the .SQD file header */
word cbSqhdr; /* Length of a .SQD frame header */
dword dwMaxMsg; /* Max number of msgs in area */
word wMaxDays; /* Max age (in days) of msgs in area */
word wSkipMsg; /* Number of msgs to skip before keeping wMaxMsg */
dword dwHighWater; /* High water message NUMBER */
UMSGID uidNext; /* Next UMSGID to assign */
FOFS foFirst; /* Offset of first frame in file */
FOFS foLast; /* Offset to last frame in file */
FOFS foFree; /* Offset of first FREE frame in file */
FOFS foLastFree; /* Offset of last free frame in file */
FOFS foEnd; /* Pointer to end of file */
FOFS foNext; /* Next frame in the linked list */
FOFS foPrev; /* Prior frame in the linked list */
FOFS foCur; /* Current frame position */
word fHaveExclusive; /* Are we currently updating the base header? */
word fLocked; /* Do we have byte 0 locked? */
word fLockFunc; /* Number of times we have called Lock w/o Unlock */
int sfd; /* SquishFile handle */
int ifd; /* SquishIndex handle */
SQBASE sqbDelta; /* Last _sqbase read from .SQD file */
/* Linked lists indicating open resources */
HAREA haNext; /* Next area in the list of open areas */
HMSG hmsgOpen; /* List of open messages */
HIDX hix; /* Index handle for current base */
} SQDATA;
/* Message handle. This is passed back and forth between all of the *
* API functions that handle specific messages. */
struct _msgh
{
HAREA ha; /* Area to which this message belongs */
dword id; /* Must always equal MSGH_ID */
dword bytes_written; /* Bytes written to this msg so far */
dword cur_pos; /* Current read posn within msg */
/* Squish-specific information starts here */
dword dwMsg; /* This message number */
/* Frame offset of this message, IF we are reading a message. *
* *
* However, if we are writing a message, this may hold one of *
* several things, depending on the value of wMode: *
* *
* *
* wMode==MOPEN_CREATE: If we are writing a completely new message, *
* this field is zero. Otherwise, if we are *
* creating a message on top of an existing *
* message, this will hold the frame offset of *
* the old message. *
* wMode==MOPEN_RW This holds the offset of the message that *
* or MOPEN_WRITE we are rewriting (same as foWrite) */
FOFS foRead;
/* SQHDR used when reading. *
* *
* If writing, this will hold the frame header of the message that we *
* replaced. (We only replaced a message if foRead != NULL_FRAME) */
SQHDR sqhRead;
/* If we are writing a message, this holds the offset of the current *
* frame header. If no frame header has been allocated for the message *
* yet, this field will be NULL_FRAME. */
FOFS foWrite;
/* If we are writing a message, this holds the frame that we wrote. This *
* SQHDR is only valid when foWrite != NULL_FRAME. */
SQHDR sqhWrite;
/* If we know the UMSGID for this message, uidUs is non-zero */
UMSGID uidUs;
dword dwWritePos; /* Current write position */
word wMode; /* MOPEN_READ, MOPEN_WRITE, or MOPEN_RW */
word fDiskErr; /* Has a disk error occurred? */
word fWritten; /* Have we already written to this message? */
HMSG hmsgNext; /* Next msg in the list of open msgs */
};
#define SQHDR_SIZE 28
#define SQIDX_SIZE 12
#define SQBASE_SIZE 256
SMAPI_EXT int read_xmsg(int handle, XMSG *pxmsg);
SMAPI_EXT int write_xmsg(int handle, XMSG *pxmsg);
SMAPI_EXT int read_sqhdr(int, SQHDR *);
SMAPI_EXT int write_sqhdr(int, SQHDR *);
SMAPI_EXT int read_sqidx(int, SQIDX *, dword);
SMAPI_EXT int write_sqidx(int, SQIDX *, dword);
SMAPI_EXT int read_sqbase(int handle, struct _sqbase *psqbase);
SMAPI_EXT int write_sqbase(int handle, struct _sqbase *psqbase);
#endif /* __API_SQ_H_DEFINED */
|