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