bool open_sub(bool wr) { postrec p; close_sub(); if (wr) { fileSub.SetName(subdat_fn); fileSub.Open(WFile::modeBinary | WFile::modeCreateFile | WFile::modeReadWrite, WFile::shareUnknown, WFile::permReadWrite); if (fileSub.IsOpen()) { // re-read info from file, to be safe believe_cache = false; fileSub.Seek(0L, WFile::seekBegin); fileSub.Read(&p, sizeof(postrec)); SetNumMessagesInCurrentMessageArea(p.owneruser); } } else { fileSub.SetName(subdat_fn); fileSub.Open(WFile::modeReadOnly | WFile::modeBinary); } return fileSub.IsOpen(); }
void write_post(int mn, postrec * pp) { postrec *p1; if (fileSub.IsOpen()) { fileSub.Seek(mn * sizeof(postrec), WFile::seekBegin); fileSub.Write(pp, sizeof(postrec)); if (believe_cache) { if (mn >= cache_start && mn < (cache_start + MAX_TO_CACHE)) { p1 = cache + (mn - cache_start); if (p1 != pp) { *p1 = *pp; } } } } }
void mailr() { mailrec m, m1; filestatusrec fsr; WFile *pFileEmail = OpenEmailFile(false); WWIV_ASSERT(pFileEmail); if (pFileEmail->IsOpen()) { int nRecordNumber = pFileEmail->GetLength() / sizeof(mailrec) - 1; char c = ' '; while (nRecordNumber >= 0 && c != 'Q' && !hangup) { pFileEmail->Seek(nRecordNumber * sizeof(mailrec), WFile::seekBegin); pFileEmail->Read(&m, sizeof(mailrec)); if (m.touser != 0) { pFileEmail->Close(); do { WUser user; GetApplication()->GetUserManager()->ReadUser(&user, m.touser); GetSession()->bout << "|#1 To|#7: |#" << GetSession()->GetMessageColor() << user.GetUserNameAndNumber( m.touser) << wwiv::endl; int tp = 80; int nn = 0; if (m.status & status_source_verified) { tp -= 2; } if (m.status & status_new_net) { tp -= 1; if (wwiv::strings::GetStringLength(m.title) <= tp) { nn = m.title[tp + 1]; } else { nn = 0; } } else { nn = 0; } set_net_num(nn); GetSession()->bout << "|#1Subj|#7: |#" << GetSession()->GetMessageColor() << m.title << wwiv::endl; if (m.status & status_file) { WFile attachDat(syscfg.datadir, ATTACH_DAT); if (attachDat.Open(WFile::modeReadOnly | WFile::modeBinary, WFile::shareUnknown, WFile::permReadWrite)) { bool found = false; long lAttachFileSize = attachDat.Read(&fsr, sizeof(fsr)); while (lAttachFileSize > 0 && !found) { if (m.daten == static_cast<unsigned long>(fsr.id)) { GetSession()->bout << "|#1Filename|#0.... |#2" << fsr.filename << " (" << fsr.numbytes << " bytes)|#0\r\n"; found = true; } if (!found) { lAttachFileSize = attachDat.Read(&fsr, sizeof(fsr)); } } if (!found) { GetSession()->bout << "|#1Filename|#0.... |#2File : Unknown or Missing|#0\r\n"; } attachDat.Close(); } else { GetSession()->bout << "|#1Filename|#0.... |#2|#2File : Unknown or Missing|#0\r\n"; } } bool next; read_message1(&(m.msg), (char)(m.anony & 0x0f), true, &next, "email", m.fromsys, m.fromuser); GetSession()->bout << "|#2R,D,Q,<space> : "; if (next) { c = ' '; } else { c = onek("QRD "); } if (c == 'D') { pFileEmail = OpenEmailFile(true); pFileEmail->Seek(nRecordNumber * sizeof(mailrec), WFile::seekBegin); pFileEmail->Read(&m1, sizeof(mailrec)); if (memcmp(&m, &m1, sizeof(mailrec)) == 0) { delmail(pFileEmail, nRecordNumber); bool found = false; if (m.status & status_file) { WFile attachFile(syscfg.datadir, ATTACH_DAT); if (attachFile.Open(WFile::modeReadWrite | WFile::modeBinary)) { long lAttachFileSize = attachFile.Read(&fsr, sizeof(fsr)); while (lAttachFileSize > 0 && !found) { if (m.daten == static_cast<unsigned long>(fsr.id)) { found = true; fsr.id = 0; attachFile.Seek(static_cast<long>(sizeof(filestatusrec)) * -1L, WFile::seekCurrent); attachFile.Write(&fsr, sizeof(filestatusrec)); WFile::Remove(GetApplication()->GetAttachmentDirectory().c_str(), fsr.filename); } else { attachFile.Read(&fsr, sizeof(filestatusrec)); } } attachFile.Close(); } } } else { GetSession()->bout << "Mail file changed; try again.\r\n"; } pFileEmail->Close(); if (!GetSession()->IsUserOnline() && m.touser == 1 && m.tosys == 0) { GetSession()->GetCurrentUser()->SetNumMailWaiting(GetSession()->GetCurrentUser()->GetNumMailWaiting() - 1); } } GetSession()->bout.NewLine(2); } while ((c == 'R') && (!hangup)); pFileEmail = OpenEmailFile(false); WWIV_ASSERT(pFileEmail); if (!pFileEmail->IsOpen()) { break; } } nRecordNumber -= 1; } pFileEmail->Close(); } delete pFileEmail; }
void close_sub() { if (fileSub.IsOpen()) { fileSub.Close(); } }
postrec *get_post(int mn) // Returns info for a post. Maintains a cache. Does not correct anything // if the sub has changed. { postrec p; bool bCloseSubFile = false; if (mn == 0) { return nullptr; } if (subchg == 1) { // sub has changed (detected in GetApplication()->GetStatusManager()->Read); invalidate cache believe_cache = false; // kludge: subch==2 leaves subch indicating change, but the '2' value // indicates, to this routine, that it has been handled at this level subchg = 2; } // see if we need new cache info if (!believe_cache || mn < cache_start || mn >= (cache_start + MAX_TO_CACHE)) { if (!fileSub.IsOpen()) { // open the sub data file, if necessary if (!open_sub(false)) { return nullptr; } bCloseSubFile = true; } // re-read # msgs, if needed if (subchg == 2) { fileSub.Seek(0L, WFile::seekBegin); fileSub.Read(&p, sizeof(postrec)); SetNumMessagesInCurrentMessageArea(p.owneruser); // another kludge: subch==3 indicates we have re-read # msgs also // only used so we don't do this every time through subchg = 3; // adjust msgnum, if it is no longer valid if (mn > GetNumMessagesInCurrentMessageArea()) { mn = GetNumMessagesInCurrentMessageArea(); } } // select new starting point of cache if (mn >= last_msgnum) { // going forward if (GetNumMessagesInCurrentMessageArea() <= MAX_TO_CACHE) { cache_start = 1; } else if (mn > (GetNumMessagesInCurrentMessageArea() - MAX_TO_CACHE)) { cache_start = GetNumMessagesInCurrentMessageArea() - MAX_TO_CACHE + 1; } else { cache_start = mn; } } else { // going backward if (mn > MAX_TO_CACHE) { cache_start = mn - MAX_TO_CACHE + 1; } else { cache_start = 1; } } if (cache_start < 1) { cache_start = 1; } // read in some sub info fileSub.Seek(cache_start * sizeof(postrec), WFile::seekBegin); fileSub.Read(cache, MAX_TO_CACHE * sizeof(postrec)); // now, close the file, if necessary if (bCloseSubFile) { close_sub(); } // cache is now valid believe_cache = true; } // error if msg # invalid if (mn < 1 || mn > GetNumMessagesInCurrentMessageArea()) { return nullptr; } last_msgnum = mn; return (cache + (mn - cache_start)); }