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: gmofido1.cpp,v 1.11 2006/05/14 11:45:05 ssianky Exp $
23 // ------------------------------------------------------------------
24 // Fido/Opus/FTSC (*.MSG) type handling
25 // ------------------------------------------------------------------
26
27 #include <cstdlib>
28 #include <cerrno>
29 #include <gdbgerr.h>
30 #include <gmemdbg.h>
31 #include <gdbgtrk.h>
32 #include <gstrall.h>
33 #include <gmofido.h>
34
35
36 // ------------------------------------------------------------------
37
38 FidoWide* fidowide = NULL;
39 FidoData* fidodata = NULL;
40 int fidodatano = 0;
41
42
43 // ------------------------------------------------------------------
44
data_open()45 void FidoArea::data_open() {
46
47 wide = fidowide;
48 data = fidodata + (fidodatano++);
49 }
50
51
52 // ------------------------------------------------------------------
53
data_close()54 void FidoArea::data_close() {
55
56 fidodatano--;
57 }
58
59
60 // ------------------------------------------------------------------
61
build_msgname(char * __buf,uint32_t __msgno)62 char* FidoArea::build_msgname(char* __buf, uint32_t __msgno) {
63
64 sprintf(__buf, "%s%u.msg", real_path(), __msgno);
65 return __buf;
66 }
67
68
69 // ------------------------------------------------------------------
70
test_open(const char * __file,int __openmode,int __sharemode,int __fail)71 int FidoArea::test_open(const char* __file, int __openmode, int __sharemode, int __fail) {
72
73 GFTRK("FidoTestOpen");
74
75 int _fh;
76 long _tries = 0;
77
78 do {
79
80 _fh = ::sopen(__file, __openmode, __sharemode, S_STDRW);
81 if(_fh == -1) {
82
83 if((errno != EACCES) or (PopupLocked(++_tries, false, __file) == false)) {
84
85 // Return instead of halting if requested
86 if((errno != EACCES) and not __fail) {
87 GFTRK(0);
88 return _fh;
89 }
90
91 // User requested to exit
92 WideLog->ErrOpen();
93 WideLog->printf("! A Fido message file could not be opened.");
94 WideLog->printf(": %s", __file);
95 WideLog->ErrOSInfo();
96 OpenErrorExit();
97 }
98 }
99 } while(_fh == -1);
100
101 // Remove the popup window
102 if(_tries)
103 PopupLocked(0, 0, NULL);
104
105 GFTRK(0);
106
107 return _fh;
108 }
109
110
111 // ------------------------------------------------------------------
112
FidoExit()113 void FidoExit() {
114
115 if(fidowide)
116 delete fidowide->user;
117 throw_release(fidowide);
118 throw_release(fidodata);
119 }
120
121
122 // ------------------------------------------------------------------
123
FidoInit(const char * fidolastread,int fidohwmarks,int fidonullfix,int fidouserno,const char * squishuserpath)124 void FidoInit(const char* fidolastread, int fidohwmarks, int fidonullfix, int fidouserno, const char* squishuserpath) {
125
126 fidodata = (FidoData*)throw_calloc(3, sizeof(FidoData));
127 fidowide = (FidoWide*)throw_calloc(1, sizeof(FidoWide));
128
129 fidowide->fidolastread = fidolastread;
130 fidowide->fidohwmarks = fidohwmarks;
131 fidowide->fidonullfix = fidonullfix;
132 fidowide->userno = fidouserno;
133 fidowide->squishuserpath = squishuserpath;
134
135 fidowide->user = new MaximusUser;
136 throw_new(fidowide->user);
137
138 const char* _username = WideUsername[0];
139 if(fidowide->userno == -1) {
140 Path userfile;
141 strxcpy(userfile, AddPath(fidowide->squishuserpath, "USER.BBS"), sizeof(Path));
142 fidowide->user->gufh = ::sopen(userfile, O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW);
143 if (fidowide->user->gufh != -1)
144 {
145 fidowide->user->find(_username);
146 if(not fidowide->user->found) {
147 WideLog->printf("* User \"%s\" not found in %s.", _username, userfile);
148 fidowide->user->add(_username);
149 WideLog->printf("* Now added with user number %u.", fidowide->user->index);
150 }
151 ::close(fidowide->user->gufh);
152 }
153 fidowide->userno = fidowide->user->index;
154 }
155 }
156
157
158 // ------------------------------------------------------------------
159
open()160 void FidoArea::open() {
161
162 GFTRK("FidoOpen");
163
164 isopen++;
165 if(isopen > 2) {
166 WideLog->ErrTest();
167 WideLog->printf("! Trying to open a *.MSG msgbase more than twice.");
168 WideLog->printf(": %s, %s.", echoid(), path());
169 WideLog->printf("+ Info: This indicates a serious bug.");
170 WideLog->printf("+ Advice: Report to the Author immediately.");
171 TestErrorExit();
172 }
173 if(isopen == 1) {
174 if(ispacked()) {
175 isopen--;
176 Path tmp;
177 strxcpy(tmp, path(), sizeof(Path));
178 StripBackslash(tmp);
179 const char* newpath = Unpack(tmp);
180 if(newpath == NULL)
181 packed(false);
182 else {
183 strcpy(tmp, newpath);
184 AddBackslash(tmp);
185 }
186 set_real_path(newpath ? tmp : path());
187 isopen++;
188 }
189 data_open();
190 scan();
191 }
192
193 GFTRK(0);
194 }
195
196
197 // ------------------------------------------------------------------
198
save_lastread()199 void FidoArea::save_lastread() {
200
201 GFTRK("FidoSaveLastread");
202
203 int _fh = ::sopen(AddPath(real_path(), wide->fidolastread), O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW);
204 if(_fh != -1) {
205 word _lastread = (word)Msgn->CvtReln(lastread);
206 lseekset(_fh, wide->userno, sizeof(word));
207 write(_fh, &_lastread, sizeof(word));
208 ::close(_fh);
209 }
210
211 GFTRK(0);
212 }
213
214
215 // ------------------------------------------------------------------
216
close()217 void FidoArea::close() {
218
219 GFTRK("FidoClose");
220
221 if(isopen) {
222 if(isopen == 1) {
223 save_lastread();
224 Msgn->Reset();
225 data_close();
226 if(ispacked()) {
227 CleanUnpacked(real_path());
228 }
229 }
230 isopen--;
231 }
232 else {
233 WideLog->ErrTest();
234 WideLog->printf("! Trying to close an already closed *.MSG msgbase.");
235 WideLog->printf(": %s, %s.", echoid(), path());
236 WideLog->printf("+ Info: This indicates a potentially serious bug.");
237 WideLog->printf("+ Advice: Report to the Author immediately.");
238 TestErrorExit();
239 }
240
241 GFTRK(0);
242 }
243
244
245 // ------------------------------------------------------------------
246
suspend()247 void FidoArea::suspend() {
248
249 GFTRK("FidoSuspend");
250
251 save_lastread();
252
253 GFTRK(0);
254 }
255
256
257 // ------------------------------------------------------------------
258
resume()259 void FidoArea::resume() {
260
261 GFTRK("FidoResume");
262
263 GFTRK(0);
264 }
265
266
267 // ------------------------------------------------------------------
268