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: gmofido2.cpp,v 1.8 2006/05/14 11:45:05 ssianky Exp $
23 // ------------------------------------------------------------------
24 // Fido/Opus/FTSC (*.MSG) type handling
25 // ------------------------------------------------------------------
26
27 #include <cstdlib>
28 #include <gdbgtrk.h>
29 #include <gdirposx.h>
30 #include <gstrall.h>
31 #include <gmofido.h>
32
33
34 // ------------------------------------------------------------------
35
raw_scan(bool __scanpm)36 void FidoArea::raw_scan(bool __scanpm) {
37
38 GFTRK("FidoArea::raw_scan");
39
40 int _wasopen = isopen;
41 if(not _wasopen) {
42 isopen++;
43 if(ispacked()) {
44 Path tmp;
45 strxcpy(tmp, path(), sizeof(Path));
46 StripBackslash(tmp);
47 const char* newpath = Unpack(tmp);
48 if(newpath == NULL)
49 packed(false);
50 else {
51 strcpy(tmp, newpath);
52 AddBackslash(tmp);
53 }
54 set_real_path(newpath ? tmp : path());
55 }
56 }
57
58 uint _active = 0;
59 uint32_t* _msgnoptr = NULL;
60 uint32_t* _msgndx = Msgn->tag;
61
62 gposixdir d(real_path());
63 if(d.ok) {
64 if(WideDebug)
65 WideLog->printf("- %s/*.msg", d.fullpath());
66 const gdirentry *de;
67 while((de = d.nextentry("*.msg", true)) != NULL) {
68 if(WideDebug)
69 WideLog->printf("- %s", de->name.c_str());
70 uint _msgno = (uint)atol(de->name.c_str());
71 if(_msgno) {
72 if((_active % FIDO_SCANBUFSIZE) == 0) {
73 _msgndx = Msgn->Resize(_active+FIDO_SCANBUFSIZE);
74 _msgnoptr = _msgndx + _active;
75 }
76 *_msgnoptr++ = _msgno;
77 _active++;
78 }
79 }
80 }
81 else {
82 if(WideDebug)
83 WideLog->printf("- Invalid path: %s", real_path());
84 }
85
86 // Sort the index
87 Msgn->SetCount(_active);
88 Msgn->Sort();
89
90 // Get the lastread msgno
91 word _lastread = 0;
92 int _fh = ::sopen(AddPath(real_path(), wide->fidolastread), O_RDONLY|O_BINARY, WideSharemode, S_STDRD);
93 if(_fh != -1) {
94 lseekset(_fh, wide->userno, sizeof(word));
95 read(_fh, &_lastread, sizeof(word));
96 ::close(_fh);
97 }
98
99 _msgnoptr = _msgndx;
100
101 uint _count = 1;
102 uint _lastread_reln = 0;
103 uint _firstmsgno = 0;
104 uint _lastmsgno = 0;
105 uint _lastreadfound = 0;
106 FidoHdr _hdr;
107
108 if(_active) {
109
110 _firstmsgno = Msgn->at(0);
111 _lastmsgno = Msgn->at(_active-1);
112
113 while(1) {
114
115 // Set lastread pointer
116 if((*_msgnoptr >= _lastread) and (_lastread_reln == 0)) {
117 _lastreadfound = *_msgnoptr;
118 _lastread_reln = _count - (*_msgnoptr != _lastread ? 1 : 0);
119 break;
120 }
121 if((++_count) > _active)
122 break;
123 _msgnoptr++;
124 }
125 }
126
127 // If the exact lastread was not found
128 if(_active and (_lastreadfound != _lastread)) {
129
130 // Higher than highest or lower than lowest?
131 if(_lastread > _lastmsgno)
132 _lastread_reln = _active;
133 else if(_lastread < _firstmsgno)
134 _lastread_reln = 0;
135 }
136
137 // Read highwater mark
138 data->highwatermark = 0;
139 if(isecho() and wide->fidohwmarks) {
140 _fh = test_open(AddPath(real_path(), "1.msg"), O_RDONLY|O_BINARY, WideSharemode);
141 if(_fh != -1) {
142 read(_fh, &_hdr, sizeof(FidoHdr));
143 data->highwatermark = _hdr.replyto;
144 ::close(_fh);
145 }
146 }
147
148 // Update area data
149 Msgn->SetCount(_active);
150 lastread = _lastread_reln;
151 lastreadentry = _lastreadfound;
152
153 if(__scanpm) {
154 char hdr_by[37];
155 int umax = (WidePersonalmail & PM_ALLNAMES) ? WideUsernames : 1;
156 bool gotpm = false;
157
158 PMrk->ResetAll();
159
160 for(uint i = lastread+1; i<=Msgn->Count(); i++) {
161 // Build message filename
162 Path _msgfile;
163 uint msgno = Msgn->CvtReln(i);
164 build_msgname(_msgfile, msgno);
165
166 // Open the message file
167 int _fh = test_open(_msgfile, O_RDONLY|O_BINARY, WideSharemode);
168 if(_fh >= 0) {
169 read(_fh, &_hdr, sizeof(FidoHdr));
170 strxcpy(hdr_by, _hdr.to, 36);
171
172 for(int u=0; u<umax; u++) {
173 if(strieql(WideUsername[u], hdr_by)) {
174 gotpm = true;
175 break;
176 }
177 }
178 if(gotpm) {
179 if(not(_hdr.attr & FIDO_RECEIVED))
180 PMrk->Append(msgno);
181
182 gotpm = false;
183 }
184 ::close(_fh);
185 }
186 }
187 }
188
189 if(WideDebug) {
190 WideLog->printf("- %s: t:%u, l:%u, fm:%u, hm:%u, lr:%u, u:%u, pm: %i",
191 echoid(),
192 Msgn->Count(),
193 lastread,
194 _firstmsgno,
195 _lastmsgno,
196 _lastread,
197 fidowide->userno,
198 __scanpm ? (int)PMrk->Count() : -1
199 );
200 }
201
202 if(not _wasopen) {
203 if(ispacked()) {
204 CleanUnpacked(real_path());
205 }
206 isopen--;
207 }
208
209 GFTRK(0);
210 }
211
212
213 // ------------------------------------------------------------------
214
scan()215 void FidoArea::scan() {
216
217 GFTRK("FidoArea::scan");
218
219 scan_area();
220
221 GFTRK(0);
222 }
223
224
225 // ------------------------------------------------------------------
226
scan_area()227 void FidoArea::scan_area() {
228
229 GFTRK("FidoArea::scan_area");
230
231 bool was_open = make_bool(data);
232 if(not was_open)
233 data_open();
234 raw_scan(false);
235 if(not was_open)
236 data_close();
237
238 GFTRK(0);
239 }
240
241
242 // ------------------------------------------------------------------
243
scan_area_pm()244 void FidoArea::scan_area_pm() {
245
246 GFTRK("FidoArea::scan_area_pm");
247
248 bool was_open = make_bool(data);
249 if(not was_open)
250 data_open();
251 raw_scan(true);
252 if(not was_open)
253 data_close();
254
255 GFTRK(0);
256 }
257
258
259 // ------------------------------------------------------------------
260
set_highwater_mark()261 void FidoArea::set_highwater_mark() {
262
263 if(isecho()) {
264 open();
265 gmsg hmsg;
266 hmsg.msgno = 1;
267 if(load_hdr(&hmsg)) {
268 hmsg.link.to_set(Msgn->CvtReln(Msgn->Count()));
269 save_hdr(GMSG_UPDATE, &hmsg);
270 }
271 close();
272 }
273 }
274
275
276 // ------------------------------------------------------------------
277
reset_highwater_mark()278 void FidoArea::reset_highwater_mark() {
279
280 if(isecho()) {
281 open();
282 gmsg hmsg;
283 hmsg.msgno = 1;
284 if(load_hdr(&hmsg)) {
285 hmsg.link.to_set(Msgn->CvtReln(1));
286 save_hdr(GMSG_UPDATE, &hmsg);
287 }
288 close();
289 }
290 }
291
292
293 // ------------------------------------------------------------------
294