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