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