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: gmopcbd1.cpp,v 1.9 2006/05/14 11:45:05 ssianky Exp $
23 // ------------------------------------------------------------------
24 // PCBoard msgbase handling.
25 // ------------------------------------------------------------------
26
27 #include <gdbgerr.h>
28 #include <gmemdbg.h>
29 #include <gdbgtrk.h>
30 #include <gstrall.h>
31 #include <gutlmisc.h>
32 #include <gmoprot.h>
33 #include <gmopcbd.h>
34
35
36 // ------------------------------------------------------------------
37
38 PcbData* pcbdata = NULL;
39 PcbWide* pcbwide = NULL;
40 int pcbdatano = 0;
41
42
43 // ------------------------------------------------------------------
44
PcbExit()45 void PcbExit() {
46
47 if(pcbwide) {
48 throw_free(pcbwide->lastread);
49 delete pcbwide->user;
50 }
51 throw_xrelease(pcbwide);
52 throw_xrelease(pcbdata);
53 }
54
55
56 // ------------------------------------------------------------------
57
PcbInit(const char * path,int userno)58 void PcbInit(const char* path, int userno) {
59
60 pcbdata = (PcbData*)throw_calloc(3, sizeof(PcbData));
61 pcbwide = (PcbWide*)throw_calloc(1, sizeof(PcbWide));
62
63 pcbwide->path = path;
64 pcbwide->userno = userno;
65
66 pcbwide->fhusr = pcbwide->fhinf = -1;
67
68 pcbwide->user = new PcbUser;
69 throw_new(pcbwide->user);
70
71 // Get PCBoard path
72 Path _path;
73 char* _ptr = getenv("PCBOARD");
74 if(_ptr)
75 AddBackslash(strcpy(_path, _ptr));
76 else
77 strcpy(_path, path);
78
79 Path _cnamespath;
80 *_cnamespath = NUL;
81
82 // Open PCBOARD.DAT
83 const char* _file = AddPath(_path, "PCBOARD.DAT");
84 gfile fp(_file, "rt", WideSharemode);
85 if (fp.isopen())
86 {
87 // Get some paths/filenames
88 int _line = 0;
89 char _buf[256];
90 fp.SetvBuf(NULL, _IOFBF, 8192);
91 while (fp.Fgets(_buf, sizeof(_buf)))
92 {
93 _line++;
94 if(_line == 28)
95 strxcpy(pcbwide->usersidxpath, strbtrim(_buf), sizeof(Path));
96 else if(_line == 29)
97 strxcpy(pcbwide->users, strbtrim(_buf), sizeof(Path));
98 else if(_line == 31)
99 strxcpy(_cnamespath, strbtrim(_buf), sizeof(Path));
100 else if(_line == 180)
101 strxcpy(pcbwide->usersinf, strbtrim(_buf), sizeof(Path));
102 else if(_line == 208)
103 pcbwide->foreign = atoi(_buf);
104 }
105 fp.Fclose();
106
107 // Open CNAMES.@@@
108 _file = AddPath(_cnamespath, ".@@@");
109 fp.Fopen(_file, "rb", WideSharemode);
110
111 // Get board numbers for lastread indexing in the userfiles
112 word _recsize = 0;
113 fp.SetvBuf(NULL, _IOFBF, 8192);
114 fp.Fread(&_recsize, 2);
115 if (_recsize)
116 {
117 PcbConf* _cnames = (PcbConf*)throw_calloc(1, _recsize);
118 int _rec = 0;
119 pcbwide->numareas = (int)((fp.FileLength()-2)/_recsize);
120 pcbwide->confbytelen = (pcbwide->numareas/8) + ((pcbwide->numareas%8) != 0 ? 1 : 0);
121 if(pcbwide->confbytelen < 5)
122 pcbwide->confbytelen = 5;
123 pcbwide->extconflen = pcbwide->confbytelen - 5;
124 pcbwide->lastread = (int32_t*)throw_calloc(pcbwide->numareas, sizeof(int32_t));
125 while (fp.Fread(_cnames, _recsize) == 1)
126 {
127 PcbAdjustArea((uint)_rec, _cnames->msgfile);
128 _rec++;
129 }
130 throw_free(_cnames);
131 }
132 fp.Fclose();
133
134 const char* _username = WideUsername[0];
135 pcbwide->user->gufh = ::sopen(AddPath(_path, pcbwide->users), O_RDONLY|O_BINARY, WideSharemode, S_STDRD);
136 if (pcbwide->user->gufh != -1)
137 {
138 pcbwide->user->fhinf = ::sopen(AddPath(_path, pcbwide->usersinf), O_RDONLY|O_BINARY, WideSharemode, S_STDRD);
139 if(pcbwide->user->fhinf != -1) {
140 ::read(pcbwide->user->fhinf, &pcbwide->usershdr, sizeof(PcbUsersInfHdr));
141 pcbwide->usershdrsize = sizeof(PcbUsersInfHdr) + (pcbwide->usershdr.numofapps*sizeof(PcbUsersInfApp));
142 pcbwide->user->usershdr = &pcbwide->usershdr;
143 pcbwide->user->usershdrsize = pcbwide->usershdrsize;
144 if(pcbwide->userno == -1) {
145 pcbwide->user->find(_username);
146 if(not pcbwide->user->found) {
147 pcbwide->userno = 0;
148 //WideLog->printf("* User \"%s\" not found in %sUSERS.", _username, _path);
149 //pcbwide->user->add(_username);
150 //WideLog->printf("* Now added with user number %u.", pcbwide->user->index);
151 }
152 }
153 close(pcbwide->user->fhinf);
154 }
155 close(pcbwide->user->gufh);
156 }
157 pcbwide->userno = pcbwide->user->index;
158 }
159 else {
160
161 WideLog->ErrOpen();
162 WideLog->printf("! Configured for PCBoard, but can't find it.");
163 WideLog->printf(": %s.", _file);
164 WideLog->printf("+ Advice: Add or correct the PCBOARDPATH keyword.");
165 WideLog->ErrOSInfo();
166 OpenErrorExit();
167 }
168 }
169
170
171 // ------------------------------------------------------------------
172
open()173 void PcbArea::open() {
174
175 GFTRK("PcbOpen");
176
177 isopen++;
178 if(isopen > 2) {
179 WideLog->ErrTest();
180 WideLog->printf("! Trying to open a PCBoard msgbase more than twice.");
181 WideLog->printf(": %s, %s.", echoid(), path());
182 WideLog->printf("+ Info: This indicates a serious bug.");
183 WideLog->printf("+ Advice: Report to the Author immediately.");
184 TestErrorExit();
185 }
186 if(isopen == 1) {
187 if(ispacked()) {
188 isopen--;
189 const char* newpath = Unpack(path());
190 if(newpath == NULL)
191 packed(false);
192 set_real_path(newpath ? newpath : path());
193 isopen++;
194 }
195 PcbWideOpen();
196 data_open();
197 raw_open();
198 scan();
199 }
200
201 GFTRK(0);
202 }
203
204
205 // ------------------------------------------------------------------
206
save_lastread()207 void PcbArea::save_lastread() {
208
209 GFTRK("PcbSaveLastread");
210
211 dword tmplr = Msgn->CvtReln(lastread);
212 if(board() < 40) {
213 // Write lastreads to USERS file
214 lseekset(wide->fhusr, wide->userno*sizeof(PcbUsers));
215 read(wide->fhusr, &wide->usersrec, sizeof(PcbUsers));
216 wide->usersrec.lastmsgread[board()] = L2B(tmplr);
217 lseekset(wide->fhusr, wide->userno*sizeof(PcbUsers));
218 write(wide->fhusr, &wide->usersrec, sizeof(PcbUsers));
219 }
220 else {
221 // Write lastreads to USERS.INF file
222 if(wide->extconflen) {
223 int32_t _offset = (wide->usersrec.usersinfrec-1)*wide->usershdr.totalrecsize;
224 _offset += wide->usershdrsize;
225 _offset += wide->usershdr.sizeofrec;
226 _offset += 2 * wide->confbytelen;
227 _offset += 3 * wide->extconflen;
228 _offset += sizeof(dword) * (board() - 40);
229 lseekset(wide->fhinf, _offset);
230 write(wide->fhinf, &tmplr, sizeof(dword));
231 }
232 }
233
234 GFTRK(0);
235 }
236
237
238 // ------------------------------------------------------------------
239
close()240 void PcbArea::close() {
241
242 GFTRK("PcbClose");
243
244 if(isopen) {
245 if(isopen == 1) {
246 save_lastread();
247 raw_close();
248 Msgn->Reset();
249 data_close();
250 PcbWideClose();
251 if(ispacked()) {
252 CleanUnpacked(real_path());
253 }
254 }
255 isopen--;
256 }
257 else {
258 WideLog->ErrTest();
259 WideLog->printf("! Trying to close an already closed PCBoard msgbase.");
260 WideLog->printf(": %s, %s.", echoid(), path());
261 WideLog->printf("+ Info: This indicates a potentially serious bug.");
262 WideLog->printf("+ Advice: Report to the Author immediately.");
263 TestErrorExit();
264 }
265
266 GFTRK(0);
267 }
268
269
270 // ------------------------------------------------------------------
271
suspend()272 void PcbArea::suspend() {
273
274 GFTRK("PcbSuspend");
275
276 save_lastread();
277 raw_close();
278 PcbWideClose();
279
280 GFTRK(0);
281 }
282
283
284 // ------------------------------------------------------------------
285
resume()286 void PcbArea::resume() {
287
288 GFTRK("PcbResume");
289
290 PcbWideOpen();
291 raw_open();
292
293 GFTRK(0);
294 }
295
296
297 // ------------------------------------------------------------------
298