// This may look like C code, but it is really -*- C++ -*- // ------------------------------------------------------------------ // The Goldware Library // Copyright (C) 1990-1999 Odinn Sorensen // ------------------------------------------------------------------ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this program; if not, write to the Free // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, // MA 02111-1307, USA // ------------------------------------------------------------------ // $Id$ // ------------------------------------------------------------------ // Fido/Opus/FTSC (*.MSG) type handling // ------------------------------------------------------------------ #include #include #include #include #include // ------------------------------------------------------------------ void FidoArea::raw_scan(bool __scanpm) { GFTRK("FidoArea::raw_scan"); int _wasopen = isopen; if(not _wasopen) { isopen++; if(ispacked()) { Path tmp; strxcpy(tmp, path(), sizeof(Path)); StripBackslash(tmp); const char* newpath = Unpack(tmp); if(newpath == NULL) packed(false); else { strcpy(tmp, newpath); AddBackslash(tmp); } set_real_path(newpath ? tmp : path()); } } uint _active = 0; uint32_t* _msgnoptr = NULL; uint32_t* _msgndx = Msgn->tag; gposixdir d(real_path()); if(d.ok) { if(WideDebug) WideLog->printf("- %s/*.msg", d.fullpath()); const gdirentry *de; while((de = d.nextentry("*.msg", true)) != NULL) { if(WideDebug) WideLog->printf("- %s", de->name.c_str()); uint _msgno = (uint)atol(de->name.c_str()); if(_msgno) { if((_active % FIDO_SCANBUFSIZE) == 0) { _msgndx = Msgn->Resize(_active+FIDO_SCANBUFSIZE); _msgnoptr = _msgndx + _active; } *_msgnoptr++ = _msgno; _active++; } } } else { if(WideDebug) WideLog->printf("- Invalid path: %s", real_path()); } // Sort the index Msgn->SetCount(_active); Msgn->Sort(); // Get the lastread msgno word _lastread = 0; int _fh = ::sopen(AddPath(real_path(), wide->fidolastread), O_RDONLY|O_BINARY, WideSharemode, S_STDRD); if(_fh != -1) { lseekset(_fh, wide->userno, sizeof(word)); read(_fh, &_lastread, sizeof(word)); ::close(_fh); } _msgnoptr = _msgndx; uint _count = 1; uint _lastread_reln = 0; uint _firstmsgno = 0; uint _lastmsgno = 0; uint _lastreadfound = 0; FidoHdr _hdr; if(_active) { _firstmsgno = Msgn->at(0); _lastmsgno = Msgn->at(_active-1); while(1) { // Set lastread pointer if((*_msgnoptr >= _lastread) and (_lastread_reln == 0)) { _lastreadfound = *_msgnoptr; _lastread_reln = _count - (*_msgnoptr != _lastread ? 1 : 0); break; } if((++_count) > _active) break; _msgnoptr++; } } // If the exact lastread was not found if(_active and (_lastreadfound != _lastread)) { // Higher than highest or lower than lowest? if(_lastread > _lastmsgno) _lastread_reln = _active; else if(_lastread < _firstmsgno) _lastread_reln = 0; } // Read highwater mark data->highwatermark = 0; if(isecho() and wide->fidohwmarks) { _fh = test_open(AddPath(real_path(), "1.msg"), O_RDONLY|O_BINARY, WideSharemode); if(_fh != -1) { read(_fh, &_hdr, sizeof(FidoHdr)); data->highwatermark = _hdr.replyto; ::close(_fh); } } // Update area data Msgn->SetCount(_active); lastread = _lastread_reln; lastreadentry = _lastreadfound; if(__scanpm) { char hdr_by[37]; int umax = (WidePersonalmail & PM_ALLNAMES) ? WideUsernames : 1; bool gotpm = false; PMrk->ResetAll(); for(uint i = lastread+1; i<=Msgn->Count(); i++) { // Build message filename Path _msgfile; uint msgno = Msgn->CvtReln(i); build_msgname(_msgfile, msgno); // Open the message file int _fh = test_open(_msgfile, O_RDONLY|O_BINARY, WideSharemode); if(_fh >= 0) { read(_fh, &_hdr, sizeof(FidoHdr)); strxcpy(hdr_by, _hdr.to, 36); for(int u=0; uAppend(msgno); gotpm = false; } ::close(_fh); } } } if(WideDebug) { WideLog->printf("- %s: t:%u, l:%u, fm:%u, hm:%u, lr:%u, u:%u, pm: %i", echoid(), Msgn->Count(), lastread, _firstmsgno, _lastmsgno, _lastread, fidowide->userno, __scanpm ? (int)PMrk->Count() : -1 ); } if(not _wasopen) { if(ispacked()) { CleanUnpacked(real_path()); } isopen--; } GFTRK(0); } // ------------------------------------------------------------------ void FidoArea::scan() { GFTRK("FidoArea::scan"); scan_area(); GFTRK(0); } // ------------------------------------------------------------------ void FidoArea::scan_area() { GFTRK("FidoArea::scan_area"); bool was_open = make_bool(data); if(not was_open) data_open(); raw_scan(false); if(not was_open) data_close(); GFTRK(0); } // ------------------------------------------------------------------ void FidoArea::scan_area_pm() { GFTRK("FidoArea::scan_area_pm"); bool was_open = make_bool(data); if(not was_open) data_open(); raw_scan(true); if(not was_open) data_close(); GFTRK(0); } // ------------------------------------------------------------------ void FidoArea::set_highwater_mark() { if(isecho()) { open(); gmsg hmsg; hmsg.msgno = 1; if(load_hdr(&hmsg)) { hmsg.link.to_set(Msgn->CvtReln(Msgn->Count())); save_hdr(GMSG_UPDATE, &hmsg); } close(); } } // ------------------------------------------------------------------ void FidoArea::reset_highwater_mark() { if(isecho()) { open(); gmsg hmsg; hmsg.msgno = 1; if(load_hdr(&hmsg)) { hmsg.link.to_set(Msgn->CvtReln(1)); save_hdr(GMSG_UPDATE, &hmsg); } close(); } } // ------------------------------------------------------------------