298 lines
8.2 KiB
C++
298 lines
8.2 KiB
C++
// 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$
|
|
// ------------------------------------------------------------------
|
|
// PCBoard msgbase handling.
|
|
// ------------------------------------------------------------------
|
|
|
|
#include <gdbgerr.h>
|
|
#include <gmemdbg.h>
|
|
#include <gdbgtrk.h>
|
|
#include <gstrall.h>
|
|
#include <gutlmisc.h>
|
|
#include <gmoprot.h>
|
|
#include <gmopcbd.h>
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
PcbData* pcbdata = NULL;
|
|
PcbWide* pcbwide = NULL;
|
|
int pcbdatano = 0;
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
void PcbExit() {
|
|
|
|
if(pcbwide) {
|
|
throw_free(pcbwide->lastread);
|
|
delete pcbwide->user;
|
|
}
|
|
throw_xrelease(pcbwide);
|
|
throw_xrelease(pcbdata);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
void PcbInit(const char* path, int userno) {
|
|
|
|
pcbdata = (PcbData*)throw_calloc(3, sizeof(PcbData));
|
|
pcbwide = (PcbWide*)throw_calloc(1, sizeof(PcbWide));
|
|
|
|
pcbwide->path = path;
|
|
pcbwide->userno = userno;
|
|
|
|
pcbwide->fhusr = pcbwide->fhinf = -1;
|
|
|
|
pcbwide->user = new PcbUser;
|
|
throw_new(pcbwide->user);
|
|
|
|
// Get PCBoard path
|
|
Path _path;
|
|
char* _ptr = getenv("PCBOARD");
|
|
if(_ptr)
|
|
AddBackslash(strcpy(_path, _ptr));
|
|
else
|
|
strcpy(_path, path);
|
|
|
|
Path _cnamespath;
|
|
*_cnamespath = NUL;
|
|
|
|
// Open PCBOARD.DAT
|
|
const char* _file = AddPath(_path, "PCBOARD.DAT");
|
|
gfile fp(_file, "rt", WideSharemode);
|
|
if (fp.isopen())
|
|
{
|
|
// Get some paths/filenames
|
|
int _line = 0;
|
|
char _buf[256];
|
|
fp.SetvBuf(NULL, _IOFBF, 8192);
|
|
while (fp.Fgets(_buf, sizeof(_buf)))
|
|
{
|
|
_line++;
|
|
if(_line == 28)
|
|
strxcpy(pcbwide->usersidxpath, strbtrim(_buf), sizeof(Path));
|
|
else if(_line == 29)
|
|
strxcpy(pcbwide->users, strbtrim(_buf), sizeof(Path));
|
|
else if(_line == 31)
|
|
strxcpy(_cnamespath, strbtrim(_buf), sizeof(Path));
|
|
else if(_line == 180)
|
|
strxcpy(pcbwide->usersinf, strbtrim(_buf), sizeof(Path));
|
|
else if(_line == 208)
|
|
pcbwide->foreign = atoi(_buf);
|
|
}
|
|
fp.Fclose();
|
|
|
|
// Open CNAMES.@@@
|
|
_file = AddPath(_cnamespath, ".@@@");
|
|
fp.Fopen(_file, "rb", WideSharemode);
|
|
|
|
// Get board numbers for lastread indexing in the userfiles
|
|
word _recsize = 0;
|
|
fp.SetvBuf(NULL, _IOFBF, 8192);
|
|
fp.Fread(&_recsize, 2);
|
|
if (_recsize)
|
|
{
|
|
PcbConf* _cnames = (PcbConf*)throw_calloc(1, _recsize);
|
|
int _rec = 0;
|
|
pcbwide->numareas = (int)((fp.FileLength()-2)/_recsize);
|
|
pcbwide->confbytelen = (pcbwide->numareas/8) + ((pcbwide->numareas%8) != 0 ? 1 : 0);
|
|
if(pcbwide->confbytelen < 5)
|
|
pcbwide->confbytelen = 5;
|
|
pcbwide->extconflen = pcbwide->confbytelen - 5;
|
|
pcbwide->lastread = (int32_t*)throw_calloc(pcbwide->numareas, sizeof(int32_t));
|
|
while (fp.Fread(_cnames, _recsize) == 1)
|
|
{
|
|
PcbAdjustArea((uint)_rec, _cnames->msgfile);
|
|
_rec++;
|
|
}
|
|
throw_free(_cnames);
|
|
}
|
|
fp.Fclose();
|
|
|
|
const char* _username = WideUsername[0];
|
|
pcbwide->user->gufh = ::sopen(AddPath(_path, pcbwide->users), O_RDONLY|O_BINARY, WideSharemode, S_STDRD);
|
|
if (pcbwide->user->gufh != -1)
|
|
{
|
|
pcbwide->user->fhinf = ::sopen(AddPath(_path, pcbwide->usersinf), O_RDONLY|O_BINARY, WideSharemode, S_STDRD);
|
|
if(pcbwide->user->fhinf != -1) {
|
|
::read(pcbwide->user->fhinf, &pcbwide->usershdr, sizeof(PcbUsersInfHdr));
|
|
pcbwide->usershdrsize = sizeof(PcbUsersInfHdr) + (pcbwide->usershdr.numofapps*sizeof(PcbUsersInfApp));
|
|
pcbwide->user->usershdr = &pcbwide->usershdr;
|
|
pcbwide->user->usershdrsize = pcbwide->usershdrsize;
|
|
if(pcbwide->userno == -1) {
|
|
pcbwide->user->find(_username);
|
|
if(not pcbwide->user->found) {
|
|
pcbwide->userno = 0;
|
|
//WideLog->printf("* User \"%s\" not found in %sUSERS.", _username, _path);
|
|
//pcbwide->user->add(_username);
|
|
//WideLog->printf("* Now added with user number %u.", pcbwide->user->index);
|
|
}
|
|
}
|
|
close(pcbwide->user->fhinf);
|
|
}
|
|
close(pcbwide->user->gufh);
|
|
}
|
|
pcbwide->userno = pcbwide->user->index;
|
|
}
|
|
else {
|
|
|
|
WideLog->ErrOpen();
|
|
WideLog->printf("! Configured for PCBoard, but can't find it.");
|
|
WideLog->printf(": %s.", _file);
|
|
WideLog->printf("+ Advice: Add or correct the PCBOARDPATH keyword.");
|
|
WideLog->ErrOSInfo();
|
|
OpenErrorExit();
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
void PcbArea::open() {
|
|
|
|
GFTRK("PcbOpen");
|
|
|
|
isopen++;
|
|
if(isopen > 2) {
|
|
WideLog->ErrTest();
|
|
WideLog->printf("! Trying to open a PCBoard msgbase more than twice.");
|
|
WideLog->printf(": %s, %s.", echoid(), path());
|
|
WideLog->printf("+ Info: This indicates a serious bug.");
|
|
WideLog->printf("+ Advice: Report to the Author immediately.");
|
|
TestErrorExit();
|
|
}
|
|
if(isopen == 1) {
|
|
if(ispacked()) {
|
|
isopen--;
|
|
const char* newpath = Unpack(path());
|
|
if(newpath == NULL)
|
|
packed(false);
|
|
set_real_path(newpath ? newpath : path());
|
|
isopen++;
|
|
}
|
|
PcbWideOpen();
|
|
data_open();
|
|
raw_open();
|
|
scan();
|
|
}
|
|
|
|
GFTRK(0);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
void PcbArea::save_lastread() {
|
|
|
|
GFTRK("PcbSaveLastread");
|
|
|
|
dword tmplr = Msgn->CvtReln(lastread);
|
|
if(board() < 40) {
|
|
// Write lastreads to USERS file
|
|
lseekset(wide->fhusr, wide->userno*sizeof(PcbUsers));
|
|
read(wide->fhusr, &wide->usersrec, sizeof(PcbUsers));
|
|
wide->usersrec.lastmsgread[board()] = L2B(tmplr);
|
|
lseekset(wide->fhusr, wide->userno*sizeof(PcbUsers));
|
|
write(wide->fhusr, &wide->usersrec, sizeof(PcbUsers));
|
|
}
|
|
else {
|
|
// Write lastreads to USERS.INF file
|
|
if(wide->extconflen) {
|
|
int32_t _offset = (wide->usersrec.usersinfrec-1)*wide->usershdr.totalrecsize;
|
|
_offset += wide->usershdrsize;
|
|
_offset += wide->usershdr.sizeofrec;
|
|
_offset += 2 * wide->confbytelen;
|
|
_offset += 3 * wide->extconflen;
|
|
_offset += sizeof(dword) * (board() - 40);
|
|
lseekset(wide->fhinf, _offset);
|
|
write(wide->fhinf, &tmplr, sizeof(dword));
|
|
}
|
|
}
|
|
|
|
GFTRK(0);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
void PcbArea::close() {
|
|
|
|
GFTRK("PcbClose");
|
|
|
|
if(isopen) {
|
|
if(isopen == 1) {
|
|
save_lastread();
|
|
raw_close();
|
|
Msgn->Reset();
|
|
data_close();
|
|
PcbWideClose();
|
|
if(ispacked()) {
|
|
CleanUnpacked(real_path());
|
|
}
|
|
}
|
|
isopen--;
|
|
}
|
|
else {
|
|
WideLog->ErrTest();
|
|
WideLog->printf("! Trying to close an already closed PCBoard msgbase.");
|
|
WideLog->printf(": %s, %s.", echoid(), path());
|
|
WideLog->printf("+ Info: This indicates a potentially serious bug.");
|
|
WideLog->printf("+ Advice: Report to the Author immediately.");
|
|
TestErrorExit();
|
|
}
|
|
|
|
GFTRK(0);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
void PcbArea::suspend() {
|
|
|
|
GFTRK("PcbSuspend");
|
|
|
|
save_lastread();
|
|
raw_close();
|
|
PcbWideClose();
|
|
|
|
GFTRK(0);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
void PcbArea::resume() {
|
|
|
|
GFTRK("PcbResume");
|
|
|
|
PcbWideOpen();
|
|
raw_open();
|
|
|
|
GFTRK(0);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|