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 #pragma off(unreferenced)
25 static char rcs_id[]="$Id$";
26 #pragma on(unreferenced)
27 */
28 #define MSGAPI_HANDLERS
29 #define MSGAPI_NO_OLD_TYPES
30 
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <assert.h>
35 #include <stdio.h>
36 
37 #include <huskylib/compiler.h>
38 
39 #ifdef HAS_UNISTD_H
40 #include <unistd.h>
41 #endif
42 #ifdef HAS_IO_H
43 #  include <io.h>
44 #endif
45 #ifdef HAS_SHARE_H
46 #include <share.h>
47 #endif
48 #ifdef HAS_MALLOC_H
49 #include <malloc.h>
50 #endif
51 
52 #include <huskylib/huskylib.h>
53 
54 /* Swith for build DLL */
55 #define DLLEXPORT
56 #include <huskylib/huskyext.h>
57 
58 #include "old_msg.h"
59 #include "msgapi.h"
60 #include "api_sq.h"
61 #include "api_sqp.h"
62 #include "apidebug.h"
63 
64 
65 /* Read in the binary message header from the data file */
66 
_SquishReadXmsg(HMSG hmsg,PXMSG pxm,dword * pdwOfs)67 static unsigned near _SquishReadXmsg(HMSG hmsg, PXMSG pxm, dword *pdwOfs)
68 {
69   long ofs=hmsg->foRead + HSqd->cbSqhdr;
70 
71   if (*pdwOfs != (dword)ofs)
72     if (lseek(HSqd->sfd, ofs, SEEK_SET) != ofs)
73     {
74       msgapierr=MERR_BADF;
75       return FALSE;
76     }
77 
78   if (read_xmsg(HSqd->sfd, pxm) != 1)
79   {
80     msgapierr=MERR_BADF;
81     return FALSE;
82   }
83 
84   /* Update our position */
85 
86   *pdwOfs=(dword)ofs + (dword) XMSG_SIZE;
87 
88   /* If there is a UMSGID associated with this message, store it in         *
89    * memory in case we have to write the message later.  Blank it           *
90    * out so that the application cannot access it.                          */
91 
92   if (pxm->attr & MSGUID)
93   {
94       hmsg->uidUs=pxm->umsgid;
95 
96       /*
97        OG: I throw out this stupid 2 lines, because application SHOULD use
98        the umsgid !
99        */
100        /*
101        pxm->attr &= ~MSGUID;
102        pxm->umsgid=0L;
103        */
104   }
105 
106 /* Og: It's not the idea of the MsgApi to check all Data on every read.
107 */
108 /*
109   if (pxm->date_written.date.yr == 0 ||
110       pxm->__ftsc_date[0] == 0)
111   {
112      MsgCvtFTSCDateToBinary(pxm->__ftsc_date, (union stamp_combo *)&pxm->date_written);
113   }
114 */
115 
116   return TRUE;
117 }
118 
119 
120 /* Read in the control information for the current message */
121 
_SquishReadCtrl(HMSG hmsg,byte * szCtrl,dword dwCtrlLen,dword * pdwOfs)122 static unsigned near _SquishReadCtrl(HMSG hmsg, byte  *szCtrl,
123                                      dword dwCtrlLen, dword *pdwOfs)
124 {
125   long ofs=hmsg->foRead + HSqd->cbSqhdr + XMSG_SIZE;
126   unsigned uMaxLen=(unsigned)min(dwCtrlLen, hmsg->sqhRead.clen);
127 
128   /* Read the specified amount of text, but no more than specified in       *
129    * the frame header.                                                      */
130 
131 
132 /* Solving O.Kopp's problem with unintialised Return-Buffers */
133   *szCtrl = 0;
134 
135   if (*pdwOfs != (dword)ofs)
136     if (lseek(HSqd->sfd, ofs, SEEK_SET) != ofs)
137     {
138       msgapierr=MERR_BADF;
139       return FALSE;
140     }
141 
142   if (read(HSqd->sfd, (char *)szCtrl, uMaxLen) != (int)uMaxLen)
143   {
144     msgapierr=MERR_BADF;
145     return FALSE;
146   }
147 
148   *pdwOfs=(dword)ofs + (dword)uMaxLen;
149 
150   return TRUE;
151 }
152 
153 
154 /* Read in the text body for the current message */
155 
_SquishReadTxt(HMSG hmsg,byte * szTxt,dword dwTxtLen,dword * pdwOfs)156 static dword near _SquishReadTxt(HMSG hmsg, byte  *szTxt, dword dwTxtLen,
157                                  dword *pdwOfs)
158 {
159   /* Start reading from the cur_pos offset */
160 
161   long ofs=hmsg->foRead + (long)HSqd->cbSqhdr + (long)XMSG_SIZE
162                         + (long)hmsg->sqhRead.clen;
163 
164   /* Max length is the size of the msg text inside the frame */
165 
166   unsigned uMaxLen=(unsigned)(hmsg->sqhRead.msg_length -
167                               hmsg->sqhRead.clen - XMSG_SIZE);
168 
169 /* Solving theoretical problem with 0-Byte Body's (thx to O.Kopp) */
170   *szTxt = 0;
171 
172   /* Make sure that we don't try to read beyond the end of the msg */
173 
174   if (hmsg->cur_pos > uMaxLen)
175     hmsg->cur_pos=uMaxLen;
176 
177   /* Now seek to the position that we are supposed to read from */
178 
179   ofs += (long)hmsg->cur_pos;
180 
181   /* Decrement the max length by the seek posn, but don't read more than    *
182    * the user asked for.                                                    */
183 
184   uMaxLen -= (unsigned)hmsg->cur_pos;
185   uMaxLen=min(uMaxLen, (unsigned)dwTxtLen);
186 
187   /* Now try to read that information from the file */
188 
189   if (ofs != (long)*pdwOfs)
190     if (lseek(HSqd->sfd, ofs, SEEK_SET) != ofs)
191     {
192       msgapierr=MERR_BADF;
193       return (dword)-1L;
194     }
195 
196 
197   if (read(HSqd->sfd, (char *)szTxt, uMaxLen) != (int)uMaxLen)
198   {
199     msgapierr=MERR_BADF;
200     return (dword)-1L;
201   }
202 
203   *pdwOfs = (dword)ofs + (dword)uMaxLen;
204 
205 
206   /* Increment the current position by the number of bytes that we read */
207 
208   hmsg->cur_pos += (dword)uMaxLen;
209 
210   return (dword)uMaxLen;
211 }
212 
213 
214 /* Read a message from the Squish base */
215 
apiSquishReadMsg(HMSG hmsg,PXMSG pxm,dword dwOfs,dword dwTxtLen,byte * szTxt,dword dwCtrlLen,byte * szCtrl)216 dword _XPENTRY apiSquishReadMsg(HMSG hmsg, PXMSG pxm, dword dwOfs,
217                               dword dwTxtLen, byte  *szTxt,
218                               dword dwCtrlLen, byte  *szCtrl)
219 {
220   dword dwSeekOfs=(dword)-1L; /* Current offset */
221   unsigned fOkay=TRUE;        /* Any errors so far? */
222   dword dwGot=0;              /* Bytes read from file */
223 
224   /* Make sure that we have a valid handle (and that it's in read mode) */
225 
226   if (MsgInvalidHmsg(hmsg) || !_SquishReadMode(hmsg))
227     return (dword)-1L;
228 
229   /* Make sure that we can use szTxt and szCtrl as flags controlling what   *
230    * to read.                                                               */
231 
232   if (!dwTxtLen)
233     szTxt=NULL;
234 
235   if (!dwCtrlLen)
236     szCtrl=NULL;
237 
238 
239   /* Now read in the message header, the control information, and the       *
240    * message text.                                                          */
241 
242  if (pxm)
243     fOkay=_SquishReadXmsg(hmsg, pxm, &dwSeekOfs);
244 
245   if (fOkay && szCtrl)
246     fOkay=_SquishReadCtrl(hmsg, szCtrl, dwCtrlLen, &dwSeekOfs);
247 
248   if (fOkay && szTxt)
249   {
250     hmsg->cur_pos=dwOfs;
251 
252     dwGot=_SquishReadTxt(hmsg, szTxt, dwTxtLen, &dwSeekOfs);
253     if (dwGot==(dword)-1L)
254       fOkay=FALSE;
255   }
256 
257   /* If everything worked okay, return the number bytes that we read        *
258    * from the message body.                                                 */
259 
260   return fOkay ? dwGot : (dword)-1L;
261 }
262 
263 
264 
265