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