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 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 #ifndef MSGAPI 25 #define MSGAPI 26 27 #include <huskylib/compiler.h> 28 #include <huskylib/huskylib.h> 29 30 31 #ifdef __BEOS__ 32 #include <OS.h> 33 #endif 34 35 #define MSGAREA_NORMAL 0x00 36 #define MSGAREA_CREATE 0x01 37 #define MSGAREA_CRIFNEC 0x02 38 39 /* Message & messagebase types (FIDO/OPUS, jam, squish, passthrough, ...) */ 40 /* - types by storage type */ 41 #define MSGTYPE_STORAGES 0x0F /* MSGTYPE_SDM | MSGTYPE_SQUISH | MSGTYPE_PASSTHROUGH | MSGTYPE_JAM */ 42 #define MSGTYPE_SDM 0x01 43 #define MSGTYPE_SQUISH 0x02 44 #define MSGTYPE_PASSTHROUGH 0x04 45 #define MSGTYPE_JAM 0x08 46 /* - types by area type (echo, net, ...) */ 47 #define MSGTYPE_AREAS 0x1C0 /* MSGTYPE_ECHO | ... */ 48 #define MSGTYPE_ECHO 0x80 49 #define MSGTYPE_NOTH 0x0100 /* What is it ?... unknown... */ 50 51 /* Special message number values */ 52 #define MSGNUM_CUR ((dword)-1L) 53 #define MSGNUM_PREV ((dword)-2L) 54 #define MSGNUM_NEXT ((dword)-3L) 55 56 #define MSGNUM_current MSGNUM_CUR 57 #define MSGNUM_previous MSGNUM_PREV 58 #define MSGNUM_next MSGNUM_NEXT 59 60 #define MOPEN_CREATE 0 61 #define MOPEN_READ 1 62 #define MOPEN_WRITE 2 63 #define MOPEN_RW 3 64 65 #ifdef __UNIX__ 66 #define FILEMODE_NETMAIL (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) 67 #define FILEMODE_ECHOMAIL (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) 68 #else 69 #define FILEMODE_NETMAIL (S_IREAD | S_IWRITE) 70 #define FILEMODE_ECHOMAIL (S_IREAD | S_IWRITE) 71 #endif 72 #define FILEMODE(a) ((a) ? FILEMODE_ECHOMAIL : FILEMODE_NETMAIL) 73 74 struct _msgapi; 75 struct _msgh; 76 struct _xmsg; 77 struct _netaddr; 78 79 typedef struct _msgapi MSGA; 80 typedef struct _msgapi *HAREA; 81 typedef struct _msgh MSGH; 82 typedef struct _msgh *HMSG; 83 typedef struct _xmsg *PXMSG; 84 typedef struct _netaddr NETADDR; 85 typedef NETADDR *PNETADDR; 86 typedef dword UMSGID; 87 88 #define MSGAPI_VERSION 2 89 #define MSGAPI_SUBVERSION 0x250 90 #define SMAPI_VERSION "2.5.1" 91 92 struct _minf 93 { 94 word req_version; 95 word def_zone; 96 word haveshare; /* filled in by msgapi routines - no need to set this */ 97 98 /* Version 2 Information */ 99 word smapi_version; 100 word smapi_subversion; 101 }; 102 103 /* 104 * The eXtended message structure. Translation between this structure, 105 * and the structure used by the individual message base formats, is done 106 * on-the-fly by the API routines. 107 */ 108 109 typedef struct _xmsg 110 { 111 /* Bitmasks for 'attr' */ 112 113 #define MSGPRIVATE 0x0001 114 #define MSGCRASH 0x0002 115 #define MSGREAD 0x0004 116 #define MSGSENT 0x0008 117 #define MSGFILE 0x0010 118 #define MSGFWD 0x0020 /* is also called intransit flag */ 119 #define MSGORPHAN 0x0040 120 #define MSGKILL 0x0080 121 #define MSGLOCAL 0x0100 122 #define MSGHOLD 0x0200 123 #define MSGXX2 0x0400 /* you can use this flag as "Direct" attribute */ 124 #define MSGFRQ 0x0800 125 #define MSGRRQ 0x1000 126 #define MSGCPT 0x2000 127 #define MSGARQ 0x4000 128 #define MSGURQ 0x8000 129 #define MSGSCANNED 0x00010000L 130 #define MSGUID 0x00020000L /* xmsg.uid field contains umsgid of msg */ 131 #define MSGIMM 0x00040000L /* Use only if msgtype == MSGTYPE_JAM ! 132 Used to map the Jam "immediate" attribute. */ 133 #define MSGLOCKED 0x40000000L /* this seems to be a feature of golded */ 134 #define MSGREADTMR 0x80000000L /* Taimyr */ 135 136 137 dword attr; 138 #define XMSG_FROM_SIZE 36 139 #define XMSG_TO_SIZE 36 140 #define XMSG_SUBJ_SIZE 72 141 142 byte from[XMSG_FROM_SIZE]; 143 byte to[XMSG_TO_SIZE]; 144 byte subj[XMSG_SUBJ_SIZE]; 145 146 NETADDR orig; /* Origination and destination addresses */ 147 NETADDR dest; 148 149 struct _stamp date_written; /* When user wrote the msg (UTC) */ 150 struct _stamp date_arrived; /* When msg arrived on-line (UTC) */ 151 sword utc_ofs; /* Offset from UTC of message writer, in 152 * minutes. */ 153 154 #define MAX_REPLY 9 /* Max number of stored replies to one msg */ 155 156 UMSGID replyto; 157 UMSGID replies[MAX_REPLY]; 158 dword umsgid; /* UMSGID of this message, if (attr&MSGUID) */ 159 /* This field is only stored on disk -- it * 160 * is not read into memory. */ 161 162 byte __ftsc_date[20]; /* Obsolete date information. If it weren't 163 * for the fact that FTSC standards say that 164 * one cannot modify an in-transit message, 165 * I'd be VERY tempted to axe this field 166 * entirely, and recreate an FTSC-compatible 167 * date field using the information in 168 * 'date_written' upon export. Nobody should 169 * use this field, except possibly for tossers 170 * and scanners. All others should use one 171 * of the two binary datestamps, above. */ 172 173 } 174 XMSG; 175 176 /* XMSG_SIZE is not sizeof(XMSG) but size of squish message header. 177 * This value used for disk i/o operations with squish messagebase. 178 */ 179 #define XMSG_SIZE (94 + XMSG_FROM_SIZE + XMSG_TO_SIZE + XMSG_SUBJ_SIZE) 180 181 #define xmreply1st replies[0] 182 #define xmreplynext replies[MAX_REPLY-1] 183 #define xmtimesread replies[MAX_REPLY-2] 184 #define xmcost replies[MAX_REPLY-3] 185 #define getHAREA(x) ((HAREA) x) 186 187 /* 188 * This is a 'message area handle', as returned by MsgOpenArea(), and 189 * required by calls to all other message functions. This structure must 190 * always be accessed through the API functions, and never modified 191 * directly. 192 */ 193 194 struct _msgapi 195 { 196 #define MSGAPI_ID 0x0201414DL 197 198 dword id; /* Must always equal MSGAPI_ID */ 199 200 word len; /* LENGTH OF THIS STRUCTURE! */ 201 word type; 202 203 dword num_msg; 204 dword cur_msg; 205 dword high_msg; 206 dword high_water; 207 208 word sz_xmsg; 209 210 byte locked; /* Base is locked from use by other tasks */ 211 byte isecho; /* Is this an EchoMail area? */ 212 213 /* Function pointers for manipulating messages within this area. */ 214 215 struct _apifuncs 216 { 217 sword(_XPENTRY * CloseArea) (HAREA mh); 218 MSGH *(_XPENTRY * OpenMsg) (HAREA mh, word mode, dword n); 219 sword(_XPENTRY * CloseMsg) (MSGH * msgh); 220 dword(_XPENTRY * ReadMsg) (MSGH * msgh, XMSG * msg, dword ofs, dword bytes, byte * text, dword cbyt, byte * ctxt); 221 sword(_XPENTRY * WriteMsg) (MSGH * msgh, word append, XMSG * msg, byte * text, dword textlen, dword totlen, dword clen, byte * ctxt); 222 sword(_XPENTRY * KillMsg) (HAREA mh, dword msgnum); 223 sword(_XPENTRY * Lock) (HAREA mh); 224 sword(_XPENTRY * Unlock) (HAREA mh); 225 sword(_XPENTRY * SetCurPos) (MSGH * msgh, dword pos); 226 dword(_XPENTRY * GetCurPos) (MSGH * msgh); 227 UMSGID(_XPENTRY * MsgnToUid) (HAREA mh, dword msgnum); 228 dword(_XPENTRY * UidToMsgn) (HAREA mh, UMSGID umsgid, word type); 229 dword(_XPENTRY * GetHighWater) (HAREA mh); 230 sword(_XPENTRY * SetHighWater) (HAREA mh, dword hwm); 231 dword(_XPENTRY * GetTextLen) (MSGH * msgh); 232 dword(_XPENTRY * GetCtrlLen) (MSGH * msgh); 233 /* Version 1 Functions */ 234 UMSGID (_XPENTRY * GetNextUid)(HAREA harea); 235 /* Version 2 Functions */ 236 dword (_XPENTRY * GetHash)(HAREA harea, dword msgnum); 237 } *api; 238 239 /* 240 * Pointer to application-specific data. API_SQ.C and API_SDM.C use 241 * this for different things, so again, no applications should muck 242 * with anything in here. 243 */ 244 245 void *apidata; 246 247 248 #ifdef ALTLOCKING 249 char *lck_path; 250 int lck_handle; 251 #endif 252 }; 253 254 255 /* 256 * This is a 'dummy' message handle. The other message handlers (contained 257 * in API_SQ.C and API_SDM.C) will define their own structures, with some 258 * application-specified variables instead of other[]. Applications should 259 * not mess with anything inside the _msgh (or MSGH) structure. 260 */ 261 262 #define MSGH_ID 0x0302484DL 263 264 #if !defined(MSGAPI_HANDLERS) /*&& !defined(NO_MSGH_DEF) */ /* NO_MSGH_DEF unused */ 265 struct _msgh 266 { 267 MSGA *sq; 268 dword id; 269 270 dword bytes_written; 271 dword cur_pos; 272 }; 273 #endif 274 275 /* #include "api_brow.h" */ 276 277 /* 278 * This variable is modified whenever an error occurs with the MsgXxx() 279 * functions. If msgapierr == 0, then no error occurred. 280 */ 281 HUSKYEXT word _stdc msgapierr; 282 283 extern struct _minf _stdc mi; 284 285 #define palloc(s) malloc(s) 286 #define pfree(s) { if (s) { free(s); s = NULL; } } 287 #define farpalloc(s) farmalloc(s) 288 #define farpfree(s) { if (s) { farfree(s); s = NULL; } } 289 290 /* Constants for 'type' argument of MsgUidToMsgn() */ 291 292 #define UID_EXACT 0x00 293 #define UID_NEXT 0x01 294 #define UID_PREV 0x02 295 296 /* Values for 'msgapierr', above. */ 297 298 #define MERR_NONE 0 /* No error */ 299 #define MERR_BADH 1 /* Invalid handle passed to function */ 300 #define MERR_BADF 2 /* Invalid or corrupted file */ 301 #define MERR_NOMEM 3 /* Not enough memory for specified operation */ 302 #define MERR_NODS 4 /* Maybe not enough disk space for operation */ 303 #define MERR_NOENT 5 /* File/message does not exist */ 304 #define MERR_BADA 6 /* Bad argument passed to msgapi function */ 305 #define MERR_EOPEN 7 /* Couldn't close - messages still open */ 306 #define MERR_NOLOCK 8 /* Base needs to be locked to perform operation */ 307 #define MERR_SHARE 9 /* Resource in use by other process */ 308 #define MERR_EACCES 10 /* Access denied (can't write to read-only, etc) */ 309 #define MERR_BADMSG 11 /* Bad message frame (Squish) */ 310 #define MERR_TOOBIG 12 /* Too much text/ctrlinfo to fit in frame (Squish)*/ 311 #define MERR_BADNAME 13 /* Bad area name or file name */ 312 #define MERR_LIMIT 14 /* Messagebase limit is reached */ 313 314 /* 315 * Now, a set of macros, which call the specified API function. These 316 * will map calls for 'MsgOpenMsg()' into 'SquishOpenMsg()', 'SdmOpenMsg()', 317 * or '<insert fave message type here>'. Applications should always call 318 * these macros, instead of trying to call the manipulation functions 319 * directly. 320 */ 321 322 #define MsgCloseArea(mh) (*(mh)->api->CloseArea) (mh) 323 #define MsgOpenMsg(mh,mode,n) (*(mh)->api->OpenMsg)(mh,mode,n) 324 #define MsgCloseMsg(msgh) ((*(((struct _msgh *)msgh)->sq->api->CloseMsg))(msgh)) 325 #define MsgReadMsg(msgh,msg,ofs,b,t,cl,ct) (*(((struct _msgh *)msgh)->sq->api->ReadMsg))(msgh,msg,ofs,b,t,cl,ct) 326 #define MsgWriteMsg(gh,a,m,t,tl,ttl,cl,ct) (*(((struct _msgh *)gh)->sq->api->WriteMsg))(gh,a,m,t,tl,ttl,cl,ct) 327 #define MsgKillMsg(mh,msgnum) (*(mh)->api->KillMsg)(mh,msgnum) 328 #define MsgLock(mh) (*(mh)->api->Lock)(mh) 329 #define MsgUnlock(mh) (*(mh)->api->Unlock)(mh) 330 #define MsgGetCurPos(msgh) (*(((struct _msgh *)msgh)->sq->api->GetCurPos))(msgh) 331 #define MsgSetCurPos(msgh,pos) (*(((struct _msgh *)msgh)->sq->api->SetCurPos))(msgh,pos) 332 #define MsgMsgnToUid(mh,msgn) (*(mh)->api->MsgnToUid)(mh,msgn) 333 #define MsgUidToMsgn(mh,umsgid,t) (*(mh)->api->UidToMsgn)(mh,umsgid,t) 334 #define MsgGetHighWater(mh) (*(mh)->api->GetHighWater)(mh) 335 #define MsgSetHighWater(mh,n) (*(mh)->api->SetHighWater)(mh,n) 336 #define MsgGetTextLen(msgh) (*(((struct _msgh *)msgh)->sq->api->GetTextLen))(msgh) 337 #define MsgGetCtrlLen(msgh) (*(((struct _msgh *)msgh)->sq->api->GetCtrlLen))(msgh) 338 #define MsgGetNextUid(ha) (*(ha)->api->GetNextUid)(ha) 339 340 /* 341 * These don't actually call any functions, but are macros used to access 342 * private data inside the _msgh structure. 343 */ 344 345 #define MsgCurMsg(mh) ((mh)->cur_msg) 346 #define MsgNumMsg(mh) ((mh)->num_msg) 347 #define MsgHighMsg(mh) ((mh)->high_msg) 348 #define MsgGetCurMsg(mh) ((mh)->cur_msg) 349 #define MsgGetNumMsg(mh) ((mh)->num_msg) 350 #define MsgGetHighMsg(mh) ((mh)->high_msg) 351 352 #define MsgStripDebris(str) StripNasties(str) 353 #define MsgCreateCtrlBuf(t, n, l) CopyToControlBuf(t, n, l) 354 #define MsgGetCtrlToken(where, what) GetCtrlToken(where, what) 355 #define MsgCvt4D(c, o, d) ConvertControlInfo(c, o, d) 356 #define MsgCvtCtrlToKludge(ctrl) CvtCtrlToKludge(ctrl) 357 #define MsgRemoveToken(c, w) RemoveFromCtrl(c, w) 358 #define MsgGetNumKludges(txt) NumKludges(txt) 359 #define MsgWrite4D(msg, wf, ctrl) WriteZPInfo(msg, wf, ctrl) 360 #define MsgInvalidHmsg(mh) InvalidMsgh(mh) 361 #define MsgInvalidHarea(mh) InvalidMh(mh) 362 363 #define MsgCvtFTSCDateToBinary(a, b) ASCII_Date_To_Binary(a,b) 364 365 HUSKYEXT const char * _XPENTRY smapi_cvs_date(); 366 HUSKYEXT sword _XPENTRY MsgOpenApi(struct _minf *minf); 367 HUSKYEXT sword _XPENTRY MsgCloseApi(void); 368 369 HUSKYEXT MSGA *_XPENTRY MsgOpenArea(byte * name, word mode, word type); 370 HUSKYEXT int MsgDeleteBase(char * name, word type); 371 sword _XPENTRY MsgValidate(word type, byte * name); 372 /* sword _XPENTRY MsgBrowseArea(BROWSE * b); // used nowhere */ 373 374 sword MSGAPI InvalidMsgh(MSGH * msgh); 375 sword MSGAPI InvalidMh(MSGA * mh); 376 sword MSGAPI InvalidMsg(XMSG * msg); 377 378 void _XPENTRY SquishSetMaxMsg(MSGA * sq, dword max_msgs, dword skip_msgs, dword age); 379 HUSKYEXT dword _XPENTRY SquishHash(byte * f); 380 381 MSGA *MSGAPI SdmOpenArea(byte * name, word mode, word type); 382 sword MSGAPI SdmValidate(byte * name); 383 int SdmDeleteBase(char * name); 384 385 MSGA *MSGAPI SquishOpenArea(byte * name, word mode, word type); 386 sword MSGAPI SquishValidate(byte * name); 387 int SquishDeleteBase(char * name); 388 389 MSGA *MSGAPI JamOpenArea(byte * name, word mode, word type); 390 sword MSGAPI JamValidate(byte * name); 391 int JamDeleteBase(char * name); 392 int JamCloseOpenAreas(); 393 394 HUSKYEXT byte *_XPENTRY CvtCtrlToKludge(byte * ctrl); 395 HUSKYEXT byte *_XPENTRY GetCtrlToken(byte * where, byte * what); 396 HUSKYEXT byte *_XPENTRY CopyToControlBuf(byte * txt, byte ** newtext, unsigned *length); 397 void _XPENTRY ConvertControlInfo(byte * ctrl, NETADDR * orig, NETADDR * dest); 398 word _XPENTRY NumKludges(char *txt); 399 HUSKYEXT void _XPENTRY RemoveFromCtrl(byte * ctrl, byte * what); 400 401 /* Check version of fidoconfig library 402 * return zero if test passed 403 * test cvs need for DLL version only, using #include <smapi/cvsdate.h> 404 const char *smapidate(){ 405 static const 406 #include "../smapi/cvsdate.h" 407 return cvs_date; 408 } 409 CheckSmapiVersion( ..., smapidate()); 410 */ 411 HUSKYEXT int _XPENTRY CheckSmapiVersion( int need_major, int need_minor, 412 int need_patch, const char *cvs_date_string ); 413 414 /* Return MSGAPI error text (string constant). 415 */ 416 HUSKYEXT char * _XPENTRY strmerr(int msgapierr); 417 418 419 #if !defined(__OS2__) && !defined(__FLAT__) && !defined(__UNIX__) && !defined(__NT__) 420 #ifndef farread 421 sword far pascal farread(sword handle, byte far * buf, word len); 422 #endif 423 #ifndef farwrite 424 sword far pascal farwrite(sword handle, byte far * buf, word len); 425 #endif 426 #endif 427 428 byte *_fast Address(NETADDR * a); 429 byte *StripNasties(byte * str); 430 431 #if defined(__DOS__) 432 sword far pascal shareloaded(void); 433 #elif defined(__OS2__) || defined(__NT__) || defined(__UNIX__) 434 #define shareloaded() TRUE 435 #else 436 #define shareloaded() FALSE 437 #endif 438 439 #endif 440 441 #ifdef __cplusplus 442 } 443 #endif 444 445