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: gmosqsh1.cpp,v 1.9 2006/05/14 11:45:05 ssianky Exp $
23 //  ------------------------------------------------------------------
24 //  Squish msgbase handling and Maximus user functions.
25 //  ------------------------------------------------------------------
26 
27 #include <gdbgerr.h>
28 #include <gmemdbg.h>
29 #include <gdbgtrk.h>
30 #include <gstrall.h>
31 #include <gmosqsh.h>
32 
33 
34 //  ------------------------------------------------------------------
35 
36 SqshData* squishdata = NULL;
37 SqshWide* squishwide = NULL;
38 int       squishdatano = 0;
39 
40 
41 //  ------------------------------------------------------------------
42 
data_open()43 void SquishArea::data_open() {
44 
45   wide = squishwide;
46   data = squishdata + (squishdatano++);
47   data->islocked = false;
48   data->softlock = false;
49   data->fhsqd = data->fhsqi = -1;
50   data->idx = NULL;
51 }
52 
53 
54 //  ------------------------------------------------------------------
55 
data_close()56 void SquishArea::data_close() {
57 
58   squishdatano--;
59 }
60 
61 
62 //  ------------------------------------------------------------------
63 
SquishExit()64 void SquishExit() {
65 
66   if(squishwide)
67     delete squishwide->user;
68   throw_release(squishwide);
69   throw_release(squishdata);
70 }
71 
72 
73 //  ------------------------------------------------------------------
74 
SquishInit(const char * userpath,int userno,int direct,int recycle,int squishscan)75 void SquishInit(const char* userpath, int userno, int direct, int recycle, int squishscan) {
76 
77   squishdata = (SqshData*)throw_calloc(3, sizeof(SqshData));
78   squishwide = (SqshWide*)throw_calloc(1, sizeof(SqshWide));
79 
80   squishwide->userpath = userpath;
81   squishwide->userno = userno;
82   squishwide->direct = direct;
83   squishwide->recycle = recycle;
84   squishwide->squishscan = squishscan;
85 
86   squishwide->user = new MaximusUser;
87   throw_new(squishwide->user);
88 
89   Path userfile;
90   strxcpy(userfile, AddPath(userpath, "USER.BBS"), sizeof(Path));
91   const char* _username = WideUsername[0];
92   if (squishwide->userno == -1)
93   {
94     squishwide->user->gufh = ::sopen(userfile, O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW);
95     if (squishwide->user->gufh != -1)
96     {
97       squishwide->user->find(_username);
98       if(not squishwide->user->found) {
99         WideLog->printf("* User \"%s\" not found in %s.", _username, userfile);
100         squishwide->user->add(_username);
101         WideLog->printf("* Now added with user number %u.", squishwide->user->index);
102       }
103       close(squishwide->user->gufh);
104     }
105     squishwide->userno = squishwide->user->index;
106   }
107 }
108 
109 
110 //  ------------------------------------------------------------------
111 
raw_close()112 void SquishArea::raw_close() {
113 
114   GFTRK("SquishRawClose");
115 
116   if(data->fhsqi != -1)  ::close(data->fhsqi);  data->fhsqi = -1;
117   if(data->fhsqd != -1)  ::close(data->fhsqd);  data->fhsqd = -1;
118 
119   GFTRK(0);
120 }
121 
122 
123 //  ------------------------------------------------------------------
124 
test_open(const char * __file)125 int SquishArea::test_open(const char* __file) {
126 
127   GFTRK("SquishTestOpen");
128 
129   int _fh;
130   long _tries = 0;
131 
132   do {
133 
134     _fh = ::sopen(__file, O_RDWR|O_BINARY|O_CREAT, WideSharemode, S_STDRW);
135     if(_fh == -1) {
136 
137       // Tell the world
138       if((errno != EACCES) or (PopupLocked(++_tries, false, __file) == false)) {
139 
140         // User requested to exit
141         WideLog->ErrOpen();
142         raw_close();
143         WideLog->printf("! A Squish msgbase file could not be opened.");
144         WideLog->printf(": %s.", __file);
145         WideLog->ErrOSInfo();
146         OpenErrorExit();
147       }
148     }
149   } while(_fh == -1);
150 
151   // Remove the popup window
152   if(_tries)
153     PopupLocked(0, 0, NULL);
154 
155   GFTRK(0);
156 
157   return _fh;
158 }
159 
160 
161 //  ------------------------------------------------------------------
162 
raw_open()163 void SquishArea::raw_open() {
164 
165   GFTRK("SquishRawOpen");
166 
167   data->fhsqd = test_open(AddPath(real_path(), ".sqd"));
168   data->fhsqi = test_open(AddPath(real_path(), ".sqi"));
169 
170   GFTRK(0);
171 }
172 
173 
174 //  ------------------------------------------------------------------
175 //  Open the Squish message base
176 
open()177 void SquishArea::open() {
178 
179   GFTRK("SquishOpen");
180 
181   isopen++;
182   if(isopen > 2) {
183     WideLog->ErrTest();
184     WideLog->printf("! Trying to open a Squish msgbase more than twice.");
185     WideLog->printf(": %s, %s.", echoid(), path());
186     WideLog->printf("+ Info: This indicates a serious bug.");
187     WideLog->printf("+ Advice: Report to the Author immediately.");
188     TestErrorExit();
189   }
190   if(isopen == 1) {
191     if(ispacked()) {
192       isopen--;
193       const char* newpath = Unpack(path());
194       if(newpath == NULL)
195         packed(false);
196       set_real_path(newpath ? newpath : path());
197       isopen++;
198     }
199     data_open();
200     raw_open();
201     refresh();
202     scan();
203   }
204 
205   GFTRK(0);
206 }
207 
208 
209 //  ------------------------------------------------------------------
210 
save_lastread()211 void SquishArea::save_lastread() {
212 
213   GFTRK("SquishSaveLastread");
214 
215   int _fh = ::sopen(AddPath(real_path(), ".sql"), O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW);
216   if(_fh != -1) {
217     lseekset(_fh, wide->userno, sizeof(dword));
218     dword _lastread = Msgn->CvtReln(lastread);
219     write(_fh, &_lastread, sizeof(dword));
220     ::close(_fh);
221   }
222 
223   GFTRK(0);
224 }
225 
226 
227 //  ------------------------------------------------------------------
228 
close()229 void SquishArea::close() {
230 
231   GFTRK("SquishClose");
232 
233   if(isopen) {
234     if(isopen == 1) {
235       save_lastread();
236       raw_close();
237       Msgn->Reset();
238       throw_xrelease(data->idx);
239       data_close();
240       if(ispacked()) {
241         CleanUnpacked(real_path());
242       }
243     }
244     isopen--;
245   }
246   else {
247     WideLog->ErrTest();
248     WideLog->printf("! Trying to close an already closed Squish msgbase.");
249     WideLog->printf(": %s, %s.", echoid(), path());
250     WideLog->printf("+ Info: This indicates a potentially serious bug.");
251     WideLog->printf("+ Advice: Report to the Author immediately.");
252     TestErrorExit();
253   }
254 
255   GFTRK(0);
256 }
257 
258 
259 //  ------------------------------------------------------------------
260 
suspend()261 void SquishArea::suspend() {
262 
263   GFTRK("SquishSuspend");
264 
265   save_lastread();
266   raw_close();
267 
268   GFTRK(0);
269 }
270 
271 
272 //  ------------------------------------------------------------------
273 
resume()274 void SquishArea::resume() {
275 
276   GFTRK("SquishResume");
277 
278   raw_open();
279 
280   GFTRK(0);
281 }
282 
283 
284 //  ------------------------------------------------------------------
285