384 lines
12 KiB
C++
384 lines
12 KiB
C++
// This may look like C code, but it is really -*- C++ -*-
|
|
|
|
// ------------------------------------------------------------------
|
|
// The Goldware Library
|
|
// Copyright (C) 1990-1999 Odinn Sorensen
|
|
// Copyright (C) 1999-2000 Alex. S. Aganichev
|
|
// ------------------------------------------------------------------
|
|
// 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$
|
|
// ------------------------------------------------------------------
|
|
// Hudson / Goldbase msgbase handling
|
|
// ------------------------------------------------------------------
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
template <class msgn_t, class rec_t, class attr_t, class board_t, class last_t, bool __HUDSON>
|
|
void _HudsWide<msgn_t, rec_t, attr_t, board_t, last_t, __HUDSON>::update_netecho(const char* __name, msgn_t __hdridx, int __delete)
|
|
{
|
|
GFTRK("HudsUpdateNetEcho");
|
|
|
|
Path name;
|
|
strcpy(name, AddPath(syspath, __name));
|
|
|
|
gfile _fh;
|
|
test_open(_fh, name, O_CREAT);
|
|
|
|
// Get size of the file
|
|
uint _total = (uint)(_fh.FileLength()/sizeof(msgn_t));
|
|
|
|
// Allocate memory for the scanning index
|
|
msgn_t* _scanidx = (msgn_t*)throw_calloc(_total+5, sizeof(msgn_t));
|
|
|
|
// Read the scanning index
|
|
_fh.Read(_scanidx, _total*sizeof(msgn_t));
|
|
|
|
// Close the file
|
|
_fh.Close();
|
|
|
|
// Search for the specified header index
|
|
uint _pos = 0;
|
|
uint _closest = 0;
|
|
while(_pos < _total) {
|
|
if(_scanidx[_pos] <= __hdridx)
|
|
_closest = _pos;
|
|
if(_scanidx[_pos] == __hdridx)
|
|
break;
|
|
_pos++;
|
|
}
|
|
|
|
// Delete or add the header index
|
|
if(__delete) {
|
|
if(_total and (_scanidx[_closest] == __hdridx)) {
|
|
if(_closest != _total) {
|
|
memmove(_scanidx+_closest, _scanidx+_closest+1, (_total-_closest+1)*sizeof(msgn_t));
|
|
}
|
|
--_total;
|
|
}
|
|
}
|
|
else {
|
|
if(_total) {
|
|
if(_scanidx[_closest] != __hdridx) {
|
|
if(_scanidx[_closest] < __hdridx)
|
|
_closest++;
|
|
if(_closest != _total)
|
|
memmove(_scanidx+_closest+1, _scanidx+_closest, (_total-_closest)*sizeof(msgn_t));
|
|
++_total;
|
|
}
|
|
}
|
|
else
|
|
++_total;
|
|
_scanidx[_closest++] = __hdridx;
|
|
}
|
|
|
|
// Write the changed scanning file from scratch
|
|
if (_total)
|
|
{
|
|
test_open(_fh, __name, O_CREAT|O_TRUNC);
|
|
_fh.Write(_scanidx, _total*sizeof(msgn_t));
|
|
_fh.Close();
|
|
}
|
|
else {
|
|
// If the last header index was removed, delete the file
|
|
remove(__name);
|
|
}
|
|
|
|
// Free the memory
|
|
throw_free(_scanidx);
|
|
|
|
GFTRK(0);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
template <class msgn_t, class rec_t, class attr_t, class board_t, class last_t, bool __HUDSON>
|
|
void _HudsArea<msgn_t, rec_t, attr_t, board_t, last_t, __HUDSON>::save_message(int __mode, gmsg* __msg, HudsHdr& __hdr) {
|
|
|
|
// Lock msgbase before doing anything
|
|
int _was_locked = wide->islocked;
|
|
if(not _was_locked)
|
|
lock();
|
|
|
|
// Find header index
|
|
msgn_t _hdridx;
|
|
if (__mode & GMSG_NEW)
|
|
{
|
|
__msg->msgno = wide->msginfo.high + 1;
|
|
_hdridx = (msgn_t)(wide->fhhdr.FileLength()/sizeof(HudsHdr));
|
|
}
|
|
else {
|
|
_hdridx = get_hdr_idx(__msg, __FILE__, __LINE__);
|
|
}
|
|
|
|
__hdr.board = (board_t)board();
|
|
__hdr.msgno = (msgn_t)__msg->msgno;
|
|
__hdr.replyto = (msgn_t)__msg->link.to();
|
|
__hdr.reply1st = (msgn_t)__msg->link.first();
|
|
|
|
struct tm _tmp; ggmtime(&_tmp, &__msg->written);
|
|
strc2p(strftimei(__hdr.date, 9, "%m-%d-%y", &_tmp));
|
|
strc2p(strftimei(__hdr.time, 6, "%H:%M", &_tmp));
|
|
|
|
strc2p(strxcpy(__hdr.to, __msg->to, sizeof(__hdr.to)));
|
|
strc2p(strxcpy(__hdr.by, __msg->by, sizeof(__hdr.by)));
|
|
strc2p(strxcpy(__hdr.re, __msg->re, sizeof(__hdr.re)));
|
|
|
|
__hdr.origzone = (byte)__msg->oorig.zone;
|
|
__hdr.orignet = __msg->oorig.net;
|
|
__hdr.orignode = __msg->oorig.node;
|
|
|
|
__hdr.destzone = (byte)__msg->odest.zone;
|
|
__hdr.destnet = __msg->odest.net;
|
|
__hdr.destnode = __msg->odest.node;
|
|
|
|
__hdr.cost = (word)__msg->cost;
|
|
__hdr.timesread = (word)__msg->timesread;
|
|
|
|
// Transfer attributes
|
|
__hdr.msgattr = __hdr.netattr = 0;
|
|
__hdr.msgattr |= (byte)(__msg->attr.del() ? HUDS_DELETED : 0);
|
|
__hdr.msgattr |= (byte)(__msg->attr.pvt() ? HUDS_PVT : 0);
|
|
__hdr.msgattr |= (byte)(__msg->attr.rcv() ? HUDS_RECEIVED : 0);
|
|
__hdr.msgattr |= (byte)(__msg->attr.loc() ? HUDS_LOCAL : 0);
|
|
__hdr.msgattr |= (byte)(__msg->attr.grp() ? HUDS_GROUPMSG : 0);
|
|
__hdr.netattr |= (byte)(__msg->attr.k_s() ? HUDS_KILLSENT : 0);
|
|
__hdr.netattr |= (byte)(__msg->attr.snt() ? HUDS_SENT : 0);
|
|
__hdr.netattr |= (byte)(__msg->attr.att() ? HUDS_ATTACH : 0);
|
|
__hdr.netattr |= (byte)(__msg->attr.cra() ? HUDS_CRASH : 0);
|
|
__hdr.netattr |= (byte)(__msg->attr.rrq() ? HUDS_RETRECREQ : 0);
|
|
__hdr.netattr |= (byte)(__msg->attr.arq() ? HUDS_AUDITREQ : 0);
|
|
__hdr.netattr |= (byte)(__msg->attr.rrc() ? HUDS_RETREC : 0);
|
|
__hdr.netattr |= (byte)(__msg->attr.frq() ? HUDS_FREQ : 0);
|
|
if(isnet())
|
|
__hdr.msgattr |= HUDS_NETMSG;
|
|
if(__msg->attr.uns()) {
|
|
if(isnet())
|
|
__hdr.msgattr |= HUDS_NETTRANS;
|
|
else if(isecho())
|
|
__hdr.msgattr |= HUDS_ECHOTRANS;
|
|
}
|
|
|
|
if(__mode & GMSG_DELETE)
|
|
__hdr.msgattr |= HUDS_DELETED;
|
|
|
|
__hdr.startrec = (msgn_t)__msg->txtstart;
|
|
__hdr.numrecs = (word)__msg->txtlength;
|
|
|
|
// Write to MSGTXT.BBS/DAT
|
|
if(__mode & GMSG_TXT) {
|
|
|
|
// If the msg is new or the text is too large to fit
|
|
uint _txtlen = strlen(__msg->txt)+1;
|
|
if((__mode & GMSG_NEW) or (_txtlen > __msg->txtlength*255L))
|
|
__hdr.startrec = (msgn_t)(wide->fhtxt.FileLength()/256L);
|
|
|
|
// Calculate the number of text records to write
|
|
register uint _fullrecs = _txtlen / 255;
|
|
register byte _extrarec = (byte)(_txtlen % 255);
|
|
__hdr.numrecs = (word)(_fullrecs + (_extrarec ? 1 : 0));
|
|
|
|
// Seek to the text write position
|
|
wide->fhtxt.LseekSet(__hdr.startrec*256L);
|
|
|
|
// Write the message text
|
|
register uint _count = 0;
|
|
register char* _txt = __msg->txt;
|
|
char _txtbuf[256];
|
|
char* _txtptr = _txtbuf + 1;
|
|
*_txtbuf = 255;
|
|
while (_count < _fullrecs)
|
|
{
|
|
memcpy(_txtptr, _txt, 255);
|
|
wide->fhtxt.Write(_txtbuf, 256);
|
|
_txt += 255;
|
|
_count++;
|
|
}
|
|
if (_extrarec)
|
|
{
|
|
*_txtbuf = _extrarec;
|
|
memset(_txtptr, 0, 255);
|
|
memcpy(_txtptr, _txt, _extrarec);
|
|
wide->fhtxt.Write(_txtbuf, 256);
|
|
}
|
|
}
|
|
|
|
// Write to MSGHDR.BBS/DAT
|
|
wide->fhhdr.LseekSet(_hdridx*sizeof(HudsHdr));
|
|
wide->fhhdr.Write(&__hdr, sizeof(HudsHdr));
|
|
|
|
// Write to MSGIDX.BBS/DAT
|
|
if(__mode & GMSG_NEW) {
|
|
wide->msgidxsize += sizeof(HudsIdx);
|
|
wide->msgidxptr = (HudsIdx*)throw_realloc(wide->msgidxptr, wide->msgidxsize+sizeof(HudsIdx));
|
|
}
|
|
HudsIdx* _idxp = wide->msgidxptr + (uint)_hdridx;
|
|
_idxp->board = __hdr.board;
|
|
_idxp->msgno = (msgn_t)((__mode & GMSG_DELETE) ? (__HUDSON ? HUDS_DELETEDMSGNO : GOLD_DELETEDMSGNO) : __hdr.msgno);
|
|
wide->fhidx.LseekSet(_hdridx*sizeof(HudsIdx));
|
|
wide->fhidx.Write(_idxp, sizeof(HudsIdx));
|
|
|
|
// Write to MSGTOIDX.BBS/DAT
|
|
wide->fhtoi.LseekSet(_hdridx*sizeof(HudsToIdx));
|
|
if (__mode & GMSG_DELETE)
|
|
wide->fhtoi.Write("\xB* Deleted *\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(HudsToIdx));
|
|
else if(__hdr.msgattr & HUDS_RECEIVED)
|
|
wide->fhtoi.Write("\xC* Received *\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(HudsToIdx));
|
|
else
|
|
wide->fhtoi.Write(__hdr.to, sizeof(HudsToIdx));
|
|
|
|
// Write to MSGINFO.BBS/DAT
|
|
if(__mode & GMSG_DELETE) {
|
|
wide->msginfo.total--;
|
|
wide->msginfo.active[__hdr.board-1]--;
|
|
if(__hdr.msgno == wide->msginfo.low) {
|
|
register uint _count = 0;
|
|
register msgn_t _total = (msgn_t)(wide->msgidxsize/sizeof(HudsIdx));
|
|
register HudsIdx* _msgidx_ptr = wide->msgidxptr;
|
|
while((_count++) < _total) {
|
|
if(_msgidx_ptr->msgno != (__HUDSON ? HUDS_DELETEDMSGNO : GOLD_DELETEDMSGNO)) {
|
|
wide->msginfo.low = _msgidx_ptr->msgno;
|
|
break;
|
|
}
|
|
_msgidx_ptr++;
|
|
}
|
|
}
|
|
if(__hdr.msgno == wide->msginfo.high) {
|
|
register uint _count = (uint)(wide->msgidxsize/sizeof(HudsIdx));
|
|
register HudsIdx* _msgidx_ptr = wide->msgidxptr + (_count-1);
|
|
while(_count--) {
|
|
if(_msgidx_ptr->msgno != (__HUDSON ? HUDS_DELETEDMSGNO : GOLD_DELETEDMSGNO)) {
|
|
wide->msginfo.high = _msgidx_ptr->msgno;
|
|
break;
|
|
}
|
|
_msgidx_ptr--;
|
|
}
|
|
}
|
|
}
|
|
else if(__mode & GMSG_NEW) {
|
|
wide->msginfo.total++;
|
|
wide->msginfo.active[__hdr.board-1]++;
|
|
if(__hdr.msgno < wide->msginfo.low)
|
|
wide->msginfo.low = __hdr.msgno;
|
|
if(__hdr.msgno > wide->msginfo.high)
|
|
wide->msginfo.high = __hdr.msgno;
|
|
}
|
|
wide->fhinf.LseekSet(0);
|
|
wide->fhinf.Write(&wide->msginfo, sizeof(HudsInfo));
|
|
|
|
// Update scanning files
|
|
if((__hdr.msgattr & HUDS_NETTRANS) or (__mode & GMSG_DELETE))
|
|
wide->update_netecho(__HUDSON ? "netmail" HUDS_EXT : "netmail" GOLD_EXT, _hdridx, __hdr.msgattr & HUDS_DELETED);
|
|
if((__hdr.msgattr & HUDS_ECHOTRANS) or (__mode & GMSG_DELETE))
|
|
wide->update_netecho(__HUDSON ? "echomail" HUDS_EXT : "echomail" GOLD_EXT, _hdridx, __hdr.msgattr & HUDS_DELETED);
|
|
|
|
if(__mode & GMSG_NEW) {
|
|
|
|
// Count our msgs
|
|
wide->timesposted++;
|
|
|
|
// Add new msgno to index
|
|
Msgn->Append(__msg->msgno);
|
|
}
|
|
|
|
// Unlock msgbase after use
|
|
if(not _was_locked)
|
|
unlock();
|
|
|
|
GFTRK(0);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
template <class msgn_t, class rec_t, class attr_t, class board_t, class last_t, bool __HUDSON>
|
|
void _HudsArea<msgn_t, rec_t, attr_t, board_t, last_t, __HUDSON>::save_hdr(int __mode, gmsg* __msg) {
|
|
|
|
GFTRK("HudsSaveHdr");
|
|
|
|
HudsHdr _hdr;
|
|
save_message(__mode|GMSG_HDR, __msg, _hdr);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
template <class msgn_t, class rec_t, class attr_t, class board_t, class last_t, bool __HUDSON>
|
|
void _HudsArea<msgn_t, rec_t, attr_t, board_t, last_t, __HUDSON>::save_msg(int __mode, gmsg* __msg) {
|
|
|
|
GFTRK("HudsSaveMsg");
|
|
|
|
HudsHdr _hdr;
|
|
save_message(__mode|GMSG_HDRTXT, __msg, _hdr);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
template <class msgn_t, class rec_t, class attr_t, class board_t, class last_t, bool __HUDSON>
|
|
void _HudsArea<msgn_t, rec_t, attr_t, board_t, last_t, __HUDSON>::del_msg(gmsg* __msg) {
|
|
|
|
GFTRK("HudsDelMsg");
|
|
|
|
HudsHdr _hdr;
|
|
save_message(GMSG_HDR | GMSG_DELETE, __msg, _hdr);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
template <class msgn_t, class rec_t, class attr_t, class board_t, class last_t, bool __HUDSON>
|
|
void _HudsArea<msgn_t, rec_t, attr_t, board_t, last_t, __HUDSON>::new_msgno(gmsg* __msg) {
|
|
|
|
GFTRK("HudsNewMsgno");
|
|
|
|
__msg->msgno = wide->msginfo.high + 1;
|
|
|
|
GFTRK(0);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
template <class msgn_t, class rec_t, class attr_t, class board_t, class last_t, bool __HUDSON>
|
|
void _HudsArea<msgn_t, rec_t, attr_t, board_t, last_t, __HUDSON>::update_timesread(gmsg* msg) {
|
|
|
|
GFTRK("HudsArea::update_timesread");
|
|
|
|
lock();
|
|
|
|
msgn_t hdridx = get_hdr_idx(msg, __FILE__, __LINE__);
|
|
wide->fhhdr.LseekSet(hdridx*sizeof(HudsHdr));
|
|
|
|
HudsHdr hdr;
|
|
wide->fhhdr.Read(&hdr, sizeof(HudsHdr));
|
|
|
|
hdr.timesread = (word)msg->timesread;
|
|
|
|
wide->fhhdr.LseekSet(hdridx*sizeof(HudsHdr));
|
|
wide->fhhdr.Write(&hdr, sizeof(HudsHdr));
|
|
|
|
unlock();
|
|
|
|
GFTRK(0);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|