// 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$ // ------------------------------------------------------------------ // Ezycom msgbase handling // ------------------------------------------------------------------ #include #include #include #include #include #include // ------------------------------------------------------------------ void EzycomArea::lock() { GFTRK("EzycomLock"); raw_close(); data->omode = O_RDWR; data->smode = SH_DENYWR; test_raw_open(__LINE__); data->islocked = true; GFTRK(NULL); } // ------------------------------------------------------------------ void EzycomArea::unlock() { GFTRK("EzycomUnlock"); raw_close(); data->omode = O_RDONLY; data->smode = SH_DENYNO; test_raw_open(__LINE__); data->islocked = false; GFTRK(NULL); } // ------------------------------------------------------------------ void EzycomArea::save_message(int __mode, gmsg* __msg, EzycHdr& __hdr) { int _was_locked = data->islocked; if(not _was_locked) lock(); if(__mode & GMSG_NEW) __msg->msgno = (filelength(data->fhhdr) / sizeof(EzycHdr)) + 1; // Reset header memset(&__hdr, 0, sizeof(EzycHdr)); // Convert attributes __hdr.msgattr |= (byte)(__msg->attr.del() ? EZYC_MSGATTR_DELETED : 0); __hdr.msgattr |= (byte)(__msg->attr.pvt() ? EZYC_MSGATTR_PRIVATE : 0); __hdr.msgattr |= (byte)(__msg->attr.rcv() ? EZYC_MSGATTR_RECEIVED : 0); __hdr.msgattr |= (byte)(__msg->attr.loc() ? EZYC_MSGATTR_LOCAL : 0); __hdr.msgattr |= (byte)(__msg->attr.lok() ? EZYC_MSGATTR_NOKILL : 0); __hdr.netattr |= (byte)(__msg->attr.k_s() ? EZYC_NETATTR_KILLSENT : 0); __hdr.netattr |= (byte)(__msg->attr.snt() ? EZYC_NETATTR_SENT : 0); __hdr.netattr |= (byte)(__msg->attr.att() ? EZYC_NETATTR_ATTACH : 0); __hdr.netattr |= (byte)(__msg->attr.cra() ? EZYC_NETATTR_CRASH : 0); __hdr.netattr |= (byte)(__msg->attr.frq() ? EZYC_NETATTR_FREQ : 0); __hdr.netattr |= (byte)(__msg->attr.rrq() ? EZYC_NETATTR_RREQ : 0); __hdr.netattr |= (byte)(__msg->attr.arq() ? EZYC_NETATTR_AREQ : 0); __hdr.netattr |= (byte)(__msg->attr.rrc() ? EZYC_NETATTR_RREC : 0); __hdr.extattr = __msg->ezycom.extattr; __hdr.extattr |= (byte)(__msg->timesread ? EZYC_EXTATTR_SEEN : 0); if(__msg->attr.uns()) { if(isnet()) __hdr.msgattr |= EZYC_MSGATTR_NETPEND; else if(isecho()) __hdr.msgattr |= EZYC_MSGATTR_ECHOPEND; } // Delete if requested if(__mode & GMSG_DELETE) __hdr.msgattr |= EZYC_MSGATTR_DELETED; // Convert header data __hdr.posttimedate = TimeToFTime(__msg->written); __hdr.recvtimedate = TimeToFTime(__msg->arrived); SwapWord32((long*)&__hdr.posttimedate); SwapWord32((long*)&__hdr.recvtimedate); strc2p(strxcpy(__hdr.whoto, __msg->to, sizeof(__hdr.whoto))); strc2p(strxcpy(__hdr.whofrom, __msg->by, sizeof(__hdr.whofrom))); strc2p(strxcpy(__hdr.subject, __msg->re, sizeof(__hdr.subject))); __hdr.orignet.zone = __msg->oorig.zone; __hdr.orignet.net = __msg->oorig.net; __hdr.orignet.node = __msg->oorig.node; __hdr.orignet.point = __msg->oorig.point; __hdr.destnet.zone = __msg->odest.zone; __hdr.destnet.net = __msg->odest.net; __hdr.destnet.node = __msg->odest.node; __hdr.destnet.point = __msg->odest.point; __hdr.replyto = (word)__msg->link.to(); __hdr.reply1st = (word)__msg->link.first(); __hdr.cost = (word)__msg->cost; __hdr.startposition = __msg->txtstart; __hdr.messagelength = __msg->txtlength; if(__mode & GMSG_TXT) { // Write the message text uint _size = strlen(__msg->txt) + 1; if((__mode & GMSG_NEW) or (_size > __hdr.messagelength)) __hdr.startposition = filelength(data->fhtxt); lseekset(data->fhtxt, __hdr.startposition); write(data->fhtxt, __msg->txt, _size); __hdr.messagelength = _size; } // Write header record lseekset(data->fhhdr, __msg->msgno-1, sizeof(EzycHdr)); write(data->fhhdr, &__hdr, sizeof(EzycHdr)); int _fh; // Update MSGEXPRT.BBS, which tells ezymail/ezynet which areas to scan for mail _fh = test_open(AddPath(wide->msgbasepath, "MSGEXPRT.BBS"), O_WRONLY|O_CREAT|O_BINARY, SH_DENYNO); if(_fh == -1) { WideLog->ErrOpen(); WideLog->printf("! A Ezycom msgbase file could not be opened."); WideLog->printf(": %s.", AddPath(wide->msgbasepath, "MSGEXPRT.BBS")); WideLog->ErrOSInfo(); OpenErrorExit(); } byte _tmp = true; lseekset(_fh, board()-1); write(_fh, &_tmp, sizeof(byte)); ::close(_fh); // Update MSGFAST.BBS EzycFast _msgfast; _msgfast.msgboard = (word)board(); _msgfast.msgnumber = (word)__msg->msgno; _msgfast.whoto = CRC32_MASK_CCITT; char* _ptr = __msg->to; while(*_ptr) { _msgfast.whoto = updCrc32((char)toupper(*_ptr), _msgfast.whoto); _ptr++; } _fh = test_open(AddPath(wide->msgbasepath, "MSGFAST.BBS"), O_WRONLY|O_CREAT|O_BINARY, SH_DENYWR); if(_fh == -1) { WideLog->ErrOpen(); WideLog->printf("! A Ezycom msgbase file could not be opened."); WideLog->printf(": %s.", AddPath(wide->msgbasepath, "MSGFAST.BBS")); WideLog->ErrOSInfo(); OpenErrorExit(); } lseek(_fh, 0, SEEK_END); write(_fh, &_msgfast, sizeof(EzycFast)); ::close(_fh); // Update MSGCOUNT.BBS _fh = test_open(AddPath(wide->msgbasepath, "MSGCOUNT.BBS"), O_WRONLY|O_CREAT|O_BINARY, SH_DENYNO); if(_fh == -1) { WideLog->ErrOpen(); WideLog->printf("! A Ezycom msgbase file could not be opened."); WideLog->printf(": %s.", AddPath(wide->msgbasepath, "MSGCOUNT.BBS")); WideLog->ErrOSInfo(); OpenErrorExit(); } if(WideCanLock) { // Try to get the lock long _tries = 0; while(::lock(_fh, (board()-1)*2, 2) == -1) { // Tell the world if(PopupLocked(++_tries, true, AddPath(wide->msgbasepath, "MSGCOUNT.BBS")) == false) { // User requested to exit WideLog->ErrLock(); WideLog->printf("! A Ezycom msgbase file could not be locked."); WideLog->printf(": %s.", AddPath(wide->msgbasepath, "MSGCOUNT.BBS")); WideLog->ErrOSInfo(); LockErrorExit(); } } // Remove the popup window if(_tries) PopupLocked(0, 0, NULL); } word _tmpword = (word)(filelength(data->fhhdr) / sizeof(EzycHdr)); lseekset(_fh, (board()-1)*2); write(_fh, &_tmpword, sizeof(word)); ::unlock(_fh, (board()-1)*2, 2); ::close(_fh); // Update internals if new if(__mode & GMSG_NEW) { // Count our msgs data->timesposted++; // Update internal array Msgn->Append(__msg->msgno); } if(not _was_locked) unlock(); GFTRK(NULL); } // ------------------------------------------------------------------ void EzycomArea::save_hdr(int __mode, gmsg* __msg) { GFTRK("EzycomSaveHdr"); EzycHdr _hdr; save_message(__mode|GMSG_HDR, __msg, _hdr); } // ------------------------------------------------------------------ void EzycomArea::save_msg(int __mode, gmsg* __msg) { GFTRK("EzycomSaveMsg"); EzycHdr _hdr; save_message(__mode|GMSG_HDRTXT, __msg, _hdr); } // ------------------------------------------------------------------ void EzycomArea::del_msg(gmsg* __msg) { GFTRK("EzycomDelMsg"); EzycHdr _hdr; save_message(GMSG_HDR | GMSG_DELETE, __msg, _hdr); } // ------------------------------------------------------------------ void EzycomArea::new_msgno(gmsg* __msg) { GFTRK("EzycomNewMsgno"); __msg->msgno = (filelength(data->fhhdr) / sizeof(EzycHdr)) + 1; GFTRK(NULL); } // ------------------------------------------------------------------ void EzycomArea::update_timesread(gmsg* msg) { GFTRK("EzycomArea::update_timesread"); lock(); EzycHdr hdr; ::lseekset(data->fhhdr, msg->msgno-1, sizeof(EzycHdr)); ::read(data->fhhdr, &hdr, sizeof(EzycHdr)); hdr.extattr |= (byte)(msg->timesread ? EZYC_EXTATTR_SEEN : 0); ::lseekset(data->fhhdr, msg->msgno-1, sizeof(EzycHdr)); ::write(data->fhhdr, &hdr, sizeof(EzycHdr)); unlock(); GFTRK(NULL); } // ------------------------------------------------------------------