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