/* * 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. */ #include #include #ifdef UNIX #include #endif #include "alc.h" #include "prog.h" #include "msgapi.h" #include "apidebug.h" #include "unused.h" void _SquishCloseOpenAreas(void); void _SquishInit(); void _SquishDeInit(); static byte *intl = (byte *) "INTL"; static byte *fmpt = (byte *) "FMPT"; static byte *topt = (byte *) "TOPT"; static byte *area_colon = (byte *) "AREA:"; static char *copyright = "MSGAPI - Copyright 1991 by Scott J. Dudley. All rights reserved."; /* Global error value for message API routines */ word _stdc msgapierr = 0; struct _minf _stdc mi; void _MsgCloseApi(void) { /* TODO: DeInit (close open areas etc.) for all msgbase types */ _SquishDeInit(); } #ifdef UNIX /* Just a dummy alarm-fnct */ static void alrm(int x) {} #endif sword EXPENTRY MsgOpenApi(struct _minf *minf) { #ifdef UNIX struct sigaction alrmact; #endif unused(copyright); mi.req_version = minf->req_version; mi.def_zone = minf->def_zone; mi.haveshare = minf->haveshare = shareloaded(); /* Version 2 Requested */ if (mi.req_version > 1 && mi.req_version < 50) { mi.smapi_version = minf->smapi_version = MSGAPI_VERSION; mi.smapi_subversion = minf->smapi_subversion = MSGAPI_SUBVERSION; } _SquishInit(); atexit(_MsgCloseApi); /* * Set the dummy alarm-fcnt to supress stupid messages. */ #ifdef UNIX memset(&alrmact, 0, sizeof(alrmact)); alrmact.sa_handler = alrm; sigaction(SIGALRM, &alrmact, 0); #endif return 0; } sword EXPENTRY MsgCloseApi(void) { _MsgCloseApi(); return 0; } MSG *EXPENTRY MsgOpenArea(byte * name, word mode, word type) { if (type & MSGTYPE_SQUISH) return SquishOpenArea(name, mode, type); else if (type & MSGTYPE_JAM) return JamOpenArea(name, mode, type); else return SdmOpenArea(name, mode, type); /* Hey, i'm reading correct ? If not SQUISH and not JAM it must be SDM ? That's a good thing to make incompatible code, but we're not M$ ! TODO: Use MSGTYPE_SDM for checking type-parameter. There could be other developer who wants to extend the API with another Base-Type */ } int MsgDeleteBase(char * name, word type) { if (type & MSGTYPE_SQUISH) return SquishDeleteBase(name); else if (type & MSGTYPE_JAM) return JamDeleteBase(name); else return SdmDeleteBase(name); } sword EXPENTRY MsgValidate(word type, byte * name) { if (type & MSGTYPE_SQUISH) return SquishValidate(name); else if (type & MSGTYPE_JAM) return JamValidate(name); else return SdmValidate(name); } /* * Check to see if a message handle is valid. This function should work * for ALL handlers tied into MsgAPI. This also checks to make sure that * the area which the message is from is also valid (ie. the message handle * isn't valid unless the area handle of that message is also valid). */ sword MSGAPI InvalidMsgh(MSGH * msgh) { if (msgh == NULL || msgh->id != MSGH_ID || InvalidMh(msgh->sq)) { msgapierr = MERR_BADH; return TRUE; } return FALSE; } /* Check to ensure that a message area handle is valid. */ sword MSGAPI InvalidMh(MSG * mh) { if (mh == NULL || mh->id != MSGAPI_ID) { msgapierr = MERR_BADH; return TRUE; } return FALSE; } byte *StripNasties(byte * str) { byte *p; p = str; while (*p != '\0') { if (*p < ' ') { *p = ' '; } p++; } return str; } /* Copy the text itself to a buffer, or count its length if out==NULL */ static word near _CopyToBuf(byte * p, byte * out, byte ** end) { word len = 0; if (out) { *out++ = '\001'; } len++; while (*p == '\015' || *p == '\012' || *p == (byte) '\215') { p++; } while (*p == '\001' || strncmp((char *) p, (char *) area_colon, 5) == 0) { /* Skip over the first ^a */ if (*p == '\001') { p++; } while (*p && *p != '\015' && *p != '\012' && *p != (byte) '\215') { if (out) { *out++ = *p; } p++; len++; } if (out) { *out++ = '\001'; } len++; while (*p == '\015' || *p == '\012' || *p == (byte) '\215') { p++; } } /* Cap the string */ if (out) { *out = '\0'; } len++; /* Make sure to leave no trailing x01's. */ if (out && out[-1] == '\001') { out[-1] = '\0'; } /* Now store the new end location of the kludge lines */ if (end) { *end = p; } return len; } byte *EXPENTRY CopyToControlBuf(byte * txt, byte ** newtext, unsigned *length) { byte *cbuf, *end; word clen; /* Figure out how long the control info is */ clen = _CopyToBuf(txt, NULL, NULL); /* Allocate memory for it */ #define SAFE_CLEN 20 cbuf = palloc(clen + SAFE_CLEN); if (cbuf == NULL) { return NULL; } memset(cbuf, '\0', clen + SAFE_CLEN); /* Now copy the text itself */ clen = _CopyToBuf(txt, cbuf, &end); if (length) { *length -= (size_t) (end - txt); } if (newtext) { *newtext = end; } return cbuf; } byte *EXPENTRY GetCtrlToken(byte *where, byte *what) { byte *end, *out; unsigned int len; if (where == NULL || what == NULL) return NULL; len = strlen(what); do { where = (byte *)strchr((char *)where, '\001'); if (where == NULL) break; where++; } while (strncmp((char *)where, (char *)what, len)); if (where == NULL || strlen(where)net && ndest.node == dest->node && norig.net == orig->net && norig.node == orig->node) { *dest = ndest; *orig = norig; /* * Only remove the INTL line if it's not gaterouted, which is * why we do it here. */ /* mtt: DO NOT CHANGE THE MSGTEXT!!! */ /* RemoveFromCtrl(ctrl, intl); */ } } /* Handle the FMPT kludge */ s = GetCtrlToken(ctrl, fmpt); if (s != NULL) { orig->point = (word) atoi((char *) s + 5); pfree(s); /* mtt: DO NO CHANGE THE MSGTEXT!!!! */ /* RemoveFromCtrl(ctrl, fmpt); */ } /* Handle TOPT too */ s = GetCtrlToken(ctrl, topt); if (s != NULL) { dest->point = (word) atoi((char *) s + 5); pfree(s); /* mtt: DO NOT CHANGE THE MSGTEXT!!! */ /* RemoveFromCtrl(ctrl, topt); */ } } byte *EXPENTRY CvtCtrlToKludge(byte * ctrl) { byte *from, *to, *buf; size_t clen; clen = strlen((char *) ctrl) + NumKludges((char *) ctrl) + 20; buf = palloc(clen); if (buf == NULL) { return NULL; } to = buf; /* Convert ^aKLUDGE^aKLUDGE... into ^aKLUDGE\r^aKLUDGE\r... */ from = ctrl; while (*from == '\001' && from[1]) { /* Only copy out the ^a if it's NOT the area: line */ if (!eqstrn((char *) from + 1, (char *) area_colon, 5)) { *to++ = *from; } from++; while (*from && *from != '\001') { *to++ = *from++; } *to++ = '\r'; } *to = '\0'; return buf; } void EXPENTRY RemoveFromCtrl(byte * ctrl, byte * what) { byte *p; unsigned int len = strlen(what); while (1) { ctrl = strchr((char *)ctrl, '\001'); if (ctrl == NULL) return; if (strncmp((char *)ctrl+1, (char *)what, len)) { ctrl++; continue; } if (strlen((char *)ctrl + 1) < len) return; /* found */ p = strchr((char *)ctrl + 1, '\001'); if (p == NULL) { *ctrl = '\0'; return; } strocpy((char *)ctrl, (char *)p); } } word EXPENTRY NumKludges(char *txt) { word nk = 0; char *p; for(p=txt; ((p=strchr(p, '\001'))!=NULL); p++) nk++; return nk; }