/*************************************************************************** * * * 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 * * * ***************************************************************************/ /* #pragma off(unreferenced) static char rcs_id[]="$Id: sq_read.c,v 1.10 2003/01/15 05:40:38 stas_degteff Exp $"; #pragma on(unreferenced) */ #define MSGAPI_HANDLERS #define MSGAPI_NO_OLD_TYPES #include #include #include #include #include "compiler.h" #ifdef HAS_UNISTD_H #include #endif #ifdef HAS_IO_H # include #endif #ifdef HAS_SHARE_H #include #endif #ifdef HAS_MALLOC_H #include #endif #include "prog.h" #include "old_msg.h" #include "msgapi.h" #include "api_sq.h" #include "api_sqp.h" #include "apidebug.h" #include "unused.h" /* Read in the binary message header from the data file */ static unsigned near _SquishReadXmsg(HMSG hmsg, PXMSG pxm, dword *pdwOfs) { long ofs=hmsg->foRead + HSqd->cbSqhdr; if (*pdwOfs != (dword)ofs) if (lseek(HSqd->sfd, ofs, SEEK_SET) != ofs) { msgapierr=MERR_BADF; return FALSE; } if (read_xmsg(HSqd->sfd, pxm) != 1) { msgapierr=MERR_BADF; return FALSE; } /* Update our position */ *pdwOfs=(dword)ofs + (dword) XMSG_SIZE; /* If there is a UMSGID associated with this message, store it in * * memory in case we have to write the message later. Blank it * * out so that the application cannot access it. */ if (pxm->attr & MSGUID) { hmsg->uidUs=pxm->umsgid; /* OG: I throw out this stupid 2 lines, because application SHOULD use the umsgid ! */ /* pxm->attr &= ~MSGUID; pxm->umsgid=0L; */ } /* Og: It's not the idea of the MsgApi to check all Data on every read. */ /* if (pxm->date_written.date.yr == 0 || pxm->__ftsc_date[0] == 0) { MsgCvtFTSCDateToBinary(pxm->__ftsc_date, (union stamp_combo *)&pxm->date_written); } */ return TRUE; } /* Read in the control information for the current message */ static unsigned near _SquishReadCtrl(HMSG hmsg, byte *szCtrl, dword dwCtrlLen, dword *pdwOfs) { long ofs=hmsg->foRead + HSqd->cbSqhdr + XMSG_SIZE; unsigned uMaxLen=(unsigned)min(dwCtrlLen, hmsg->sqhRead.clen); /* Read the specified amount of text, but no more than specified in * * the frame header. */ /* Solving O.Kopp's problem with unintialised Return-Buffers */ *szCtrl = 0; if (*pdwOfs != (dword)ofs) if (lseek(HSqd->sfd, ofs, SEEK_SET) != ofs) { msgapierr=MERR_BADF; return FALSE; } if (read(HSqd->sfd, (char *)szCtrl, uMaxLen) != (int)uMaxLen) { msgapierr=MERR_BADF; return FALSE; } *pdwOfs=(dword)ofs + (dword)uMaxLen; return TRUE; } /* Read in the text body for the current message */ static dword near _SquishReadTxt(HMSG hmsg, byte *szTxt, dword dwTxtLen, dword *pdwOfs) { /* Start reading from the cur_pos offset */ long ofs=hmsg->foRead + (long)HSqd->cbSqhdr + (long)XMSG_SIZE + (long)hmsg->sqhRead.clen; /* Max length is the size of the msg text inside the frame */ unsigned uMaxLen=(unsigned)(hmsg->sqhRead.msg_length - hmsg->sqhRead.clen - XMSG_SIZE); /* Solving theoretical problem with 0-Byte Body's (thx to O.Kopp) */ *szTxt = 0; /* Make sure that we don't try to read beyond the end of the msg */ if (hmsg->cur_pos > uMaxLen) hmsg->cur_pos=uMaxLen; /* Now seek to the position that we are supposed to read from */ ofs += (long)hmsg->cur_pos; /* Decrement the max length by the seek posn, but don't read more than * * the user asked for. */ uMaxLen -= (unsigned)hmsg->cur_pos; uMaxLen=min(uMaxLen, (unsigned)dwTxtLen); /* Now try to read that information from the file */ if (ofs != (long)*pdwOfs) if (lseek(HSqd->sfd, ofs, SEEK_SET) != ofs) { msgapierr=MERR_BADF; return (dword)-1L; } if (read(HSqd->sfd, (char *)szTxt, uMaxLen) != (int)uMaxLen) { msgapierr=MERR_BADF; return (dword)-1L; } *pdwOfs = (dword)ofs + (dword)uMaxLen; /* Increment the current position by the number of bytes that we read */ hmsg->cur_pos += (dword)uMaxLen; return (dword)uMaxLen; } /* Read a message from the Squish base */ dword _XPENTRY apiSquishReadMsg(HMSG hmsg, PXMSG pxm, dword dwOfs, dword dwTxtLen, byte *szTxt, dword dwCtrlLen, byte *szCtrl) { dword dwSeekOfs=(dword)-1L; /* Current offset */ unsigned fOkay=TRUE; /* Any errors so far? */ dword dwGot=0; /* Bytes read from file */ /* Make sure that we have a valid handle (and that it's in read mode) */ if (MsgInvalidHmsg(hmsg) || !_SquishReadMode(hmsg)) return (dword)-1L; /* Make sure that we can use szTxt and szCtrl as flags controlling what * * to read. */ if (!dwTxtLen) szTxt=NULL; if (!dwCtrlLen) szCtrl=NULL; /* Now read in the message header, the control information, and the * * message text. */ if (pxm) fOkay=_SquishReadXmsg(hmsg, pxm, &dwSeekOfs); if (fOkay && szCtrl) fOkay=_SquishReadCtrl(hmsg, szCtrl, dwCtrlLen, &dwSeekOfs); if (fOkay && szTxt) { hmsg->cur_pos=dwOfs; if ((dwGot=_SquishReadTxt(hmsg, szTxt, dwTxtLen, &dwSeekOfs))==(dword)-1L) fOkay=FALSE; } /* If everything worked okay, return the number bytes that we read * * from the message body. */ return fOkay ? dwGot : (dword)-1L; }