1 //  This may look like C code, but it is really -*- C++ -*-
2 
3 //  ------------------------------------------------------------------
4 //  The Goldware Library
5 //  Copyright (C) 1990-1999 Odinn Sorensen
6 //  ------------------------------------------------------------------
7 //  This library is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU Library General Public
9 //  License as published by the Free Software Foundation; either
10 //  version 2 of the License, or (at your option) any later version.
11 //
12 //  This library is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //  Library General Public License for more details.
16 //
17 //  You should have received a copy of the GNU Library General Public
18 //  License along with this program; if not, write to the Free
19 //  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 //  MA 02111-1307, USA
21 //  ------------------------------------------------------------------
22 //  $Id: gmoezyc4.cpp,v 1.5 2006/05/14 11:45:05 ssianky Exp $
23 //  ------------------------------------------------------------------
24 //  Ezycom msgbase handling
25 //  ------------------------------------------------------------------
26 
27 #include <gcrcall.h>
28 #include <gdbgerr.h>
29 #include <gdbgtrk.h>
30 #include <gstrall.h>
31 #include <gutlmisc.h>
32 #include <gmoezyc.h>
33 
34 
35 //  ------------------------------------------------------------------
36 
lock()37 void EzycomArea::lock() {
38 
39   GFTRK("EzycomLock");
40 
41   raw_close();
42   data->omode = O_RDWR;
43   data->smode = SH_DENYWR;
44   test_raw_open(__LINE__);
45   data->islocked = true;
46 
47   GFTRK(0);
48 }
49 
50 
51 //  ------------------------------------------------------------------
52 
unlock()53 void EzycomArea::unlock() {
54 
55   GFTRK("EzycomUnlock");
56 
57   raw_close();
58   data->omode = O_RDONLY;
59   data->smode = SH_DENYNO;
60   test_raw_open(__LINE__);
61   data->islocked = false;
62 
63   GFTRK(0);
64 }
65 
66 
67 //  ------------------------------------------------------------------
68 
save_message(int __mode,gmsg * __msg,EzycHdr & __hdr)69 void EzycomArea::save_message(int __mode, gmsg* __msg, EzycHdr& __hdr) {
70 
71   int _was_locked = data->islocked;
72   if(not _was_locked)
73     lock();
74 
75   if(__mode & GMSG_NEW)
76     __msg->msgno = (filelength(data->fhhdr) / sizeof(EzycHdr)) + 1;
77 
78   // Reset header
79   memset(&__hdr, 0, sizeof(EzycHdr));
80 
81   // Convert attributes
82   __hdr.msgattr |= (byte)(__msg->attr.del() ? EZYC_MSGATTR_DELETED  : 0);
83   __hdr.msgattr |= (byte)(__msg->attr.pvt() ? EZYC_MSGATTR_PRIVATE  : 0);
84   __hdr.msgattr |= (byte)(__msg->attr.rcv() ? EZYC_MSGATTR_RECEIVED : 0);
85   __hdr.msgattr |= (byte)(__msg->attr.loc() ? EZYC_MSGATTR_LOCAL    : 0);
86   __hdr.msgattr |= (byte)(__msg->attr.lok() ? EZYC_MSGATTR_NOKILL   : 0);
87   __hdr.netattr |= (byte)(__msg->attr.k_s() ? EZYC_NETATTR_KILLSENT : 0);
88   __hdr.netattr |= (byte)(__msg->attr.snt() ? EZYC_NETATTR_SENT     : 0);
89   __hdr.netattr |= (byte)(__msg->attr.att() ? EZYC_NETATTR_ATTACH   : 0);
90   __hdr.netattr |= (byte)(__msg->attr.cra() ? EZYC_NETATTR_CRASH    : 0);
91   __hdr.netattr |= (byte)(__msg->attr.frq() ? EZYC_NETATTR_FREQ     : 0);
92   __hdr.netattr |= (byte)(__msg->attr.rrq() ? EZYC_NETATTR_RREQ     : 0);
93   __hdr.netattr |= (byte)(__msg->attr.arq() ? EZYC_NETATTR_AREQ     : 0);
94   __hdr.netattr |= (byte)(__msg->attr.rrc() ? EZYC_NETATTR_RREC     : 0);
95   __hdr.extattr = __msg->ezycom.extattr;
96   __hdr.extattr |= (byte)(__msg->timesread  ? EZYC_EXTATTR_SEEN     : 0);
97 
98   if(__msg->attr.uns()) {
99     if(isnet())
100       __hdr.msgattr |= EZYC_MSGATTR_NETPEND;
101     else if(isecho())
102       __hdr.msgattr |= EZYC_MSGATTR_ECHOPEND;
103   }
104 
105   // Delete if requested
106   if(__mode & GMSG_DELETE)
107     __hdr.msgattr |= EZYC_MSGATTR_DELETED;
108 
109   // Convert header data
110 
111   __hdr.posttimedate = TimeToFTime(__msg->written);
112   __hdr.recvtimedate = TimeToFTime(__msg->arrived);
113 
114   SwapWord32((uint32_t*)&__hdr.posttimedate);
115   SwapWord32((uint32_t*)&__hdr.recvtimedate);
116 
117   strc2p(strxcpy(__hdr.whoto,   __msg->to, sizeof(__hdr.whoto)));
118   strc2p(strxcpy(__hdr.whofrom, __msg->by, sizeof(__hdr.whofrom)));
119   strc2p(strxcpy(__hdr.subject, __msg->re, sizeof(__hdr.subject)));
120 
121   __hdr.orignet.zone  = __msg->oorig.zone;
122   __hdr.orignet.net   = __msg->oorig.net;
123   __hdr.orignet.node  = __msg->oorig.node;
124   __hdr.orignet.point = __msg->oorig.point;
125 
126   __hdr.destnet.zone  = __msg->odest.zone;
127   __hdr.destnet.net   = __msg->odest.net;
128   __hdr.destnet.node  = __msg->odest.node;
129   __hdr.destnet.point = __msg->odest.point;
130 
131   __hdr.replyto = (word)__msg->link.to();
132   __hdr.reply1st = (word)__msg->link.first();
133 
134   __hdr.cost = (word)__msg->cost;
135 
136   __hdr.startposition = __msg->txtstart;
137   __hdr.messagelength = __msg->txtlength;
138 
139   if(__mode & GMSG_TXT) {
140 
141     // Write the message text
142     uint _size = strlen(__msg->txt) + 1;
143     if((__mode & GMSG_NEW) or (_size > __hdr.messagelength))
144       __hdr.startposition = filelength(data->fhtxt);
145     lseekset(data->fhtxt, __hdr.startposition);
146     write(data->fhtxt, __msg->txt, _size);
147     __hdr.messagelength = _size;
148   }
149 
150   // Write header record
151   lseekset(data->fhhdr, __msg->msgno-1, sizeof(EzycHdr));
152   write(data->fhhdr, &__hdr, sizeof(EzycHdr));
153 
154   int _fh;
155 
156   // Update MSGEXPRT.BBS, which tells ezymail/ezynet which areas to scan for mail
157   _fh = test_open(AddPath(wide->msgbasepath, "MSGEXPRT.BBS"), O_WRONLY|O_CREAT|O_BINARY, SH_DENYNO);
158   if(_fh == -1) {
159     WideLog->ErrOpen();
160     WideLog->printf("! A Ezycom msgbase file could not be opened.");
161     WideLog->printf(": %s.", AddPath(wide->msgbasepath, "MSGEXPRT.BBS"));
162     WideLog->ErrOSInfo();
163     OpenErrorExit();
164   }
165   byte _tmp = true;
166   lseekset(_fh, board()-1);
167   write(_fh, &_tmp, sizeof(byte));
168   ::close(_fh);
169 
170   // Update MSGFAST.BBS
171   EzycFast _msgfast;
172   _msgfast.msgboard = (word)board();
173   _msgfast.msgnumber = (word)__msg->msgno;
174   _msgfast.whoto = CRC32_MASK_CCITT;
175   char* _ptr = __msg->to;
176   while(*_ptr) {
177     _msgfast.whoto = updCrc32((char)g_toupper(*_ptr), _msgfast.whoto);
178     _ptr++;
179   }
180   _fh = test_open(AddPath(wide->msgbasepath, "MSGFAST.BBS"), O_WRONLY|O_CREAT|O_BINARY, SH_DENYWR);
181   if(_fh == -1) {
182     WideLog->ErrOpen();
183     WideLog->printf("! A Ezycom msgbase file could not be opened.");
184     WideLog->printf(": %s.", AddPath(wide->msgbasepath, "MSGFAST.BBS"));
185     WideLog->ErrOSInfo();
186     OpenErrorExit();
187   }
188   lseek(_fh, 0, SEEK_END);
189   write(_fh, &_msgfast, sizeof(EzycFast));
190   ::close(_fh);
191 
192   // Update MSGCOUNT.BBS
193   _fh = test_open(AddPath(wide->msgbasepath, "MSGCOUNT.BBS"), O_WRONLY|O_CREAT|O_BINARY, SH_DENYNO);
194   if(_fh == -1) {
195     WideLog->ErrOpen();
196     WideLog->printf("! A Ezycom msgbase file could not be opened.");
197     WideLog->printf(": %s.", AddPath(wide->msgbasepath, "MSGCOUNT.BBS"));
198     WideLog->ErrOSInfo();
199     OpenErrorExit();
200   }
201 
202   if(WideCanLock) {
203 
204     // Try to get the lock
205     long _tries = 0;
206     while(::lock(_fh, (board()-1)*2, 2) == -1) {
207 
208       // Tell the world
209       if(PopupLocked(++_tries, true, AddPath(wide->msgbasepath, "MSGCOUNT.BBS")) == false) {
210 
211         // User requested to exit
212         WideLog->ErrLock();
213         WideLog->printf("! A Ezycom msgbase file could not be locked.");
214         WideLog->printf(": %s.", AddPath(wide->msgbasepath, "MSGCOUNT.BBS"));
215         WideLog->ErrOSInfo();
216         LockErrorExit();
217       }
218     }
219 
220     // Remove the popup window
221     if(_tries)
222       PopupLocked(0, 0, NULL);
223   }
224 
225   word _tmpword = (word)(filelength(data->fhhdr) / sizeof(EzycHdr));
226   lseekset(_fh, (board()-1)*2);
227   write(_fh, &_tmpword, sizeof(word));
228   ::unlock(_fh, (board()-1)*2, 2);
229   ::close(_fh);
230 
231   // Update internals if new
232   if(__mode & GMSG_NEW) {
233 
234     // Count our msgs
235     data->timesposted++;
236 
237     // Update internal array
238     Msgn->Append(__msg->msgno);
239   }
240 
241   if(not _was_locked)
242     unlock();
243 
244   GFTRK(0);
245 }
246 
247 
248 //  ------------------------------------------------------------------
249 
save_hdr(int __mode,gmsg * __msg)250 void EzycomArea::save_hdr(int __mode, gmsg* __msg) {
251 
252   GFTRK("EzycomSaveHdr");
253 
254   EzycHdr _hdr;
255   save_message(__mode|GMSG_HDR, __msg, _hdr);
256 }
257 
258 
259 //  ------------------------------------------------------------------
260 
save_msg(int __mode,gmsg * __msg)261 void EzycomArea::save_msg(int __mode, gmsg* __msg) {
262 
263   GFTRK("EzycomSaveMsg");
264 
265   EzycHdr _hdr;
266   save_message(__mode|GMSG_HDRTXT, __msg, _hdr);
267 }
268 
269 
270 //  ------------------------------------------------------------------
271 
del_msg(gmsg * __msg)272 void EzycomArea::del_msg(gmsg* __msg) {
273 
274   GFTRK("EzycomDelMsg");
275 
276   EzycHdr _hdr;
277   save_message(GMSG_HDR | GMSG_DELETE, __msg, _hdr);
278 }
279 
280 
281 //  ------------------------------------------------------------------
282 
new_msgno(gmsg * __msg)283 void EzycomArea::new_msgno(gmsg* __msg) {
284 
285   GFTRK("EzycomNewMsgno");
286 
287   __msg->msgno = (filelength(data->fhhdr) / sizeof(EzycHdr)) + 1;
288 
289   GFTRK(0);
290 }
291 
292 
293 //  ------------------------------------------------------------------
294 
update_timesread(gmsg * msg)295 void EzycomArea::update_timesread(gmsg* msg) {
296 
297   GFTRK("EzycomArea::update_timesread");
298 
299   lock();
300 
301   EzycHdr hdr;
302   ::lseekset(data->fhhdr, msg->msgno-1, sizeof(EzycHdr));
303   ::read(data->fhhdr, &hdr, sizeof(EzycHdr));
304 
305   hdr.extattr |= (byte)(msg->timesread ? EZYC_EXTATTR_SEEN : 0);
306 
307   ::lseekset(data->fhhdr, msg->msgno-1, sizeof(EzycHdr));
308   ::write(data->fhhdr, &hdr, sizeof(EzycHdr));
309 
310   unlock();
311 
312   GFTRK(0);
313 }
314 
315 
316 //  ------------------------------------------------------------------
317