void POP3Protocol::CheckForDeletedMessages() { { // Delete things from the manifest no longer on the server BStringList list; NotHere(fUniqueIDs, fManifest, &list); fManifest.Remove(list); } if (!fSettings.FindBool("delete_remote_when_local") || fManifest.CountStrings() == 0) return; BStringList toDelete; BStringList queryContents; BVolumeRoster volumes; BVolume volume; while (volumes.GetNextVolume(&volume) == B_OK) { BQuery fido; entry_ref entry; fido.SetVolume(&volume); fido.PushAttr(B_MAIL_ATTR_ACCOUNT_ID); fido.PushInt32(fAccountSettings.AccountID()); fido.PushOp(B_EQ); fido.Fetch(); BString uid; while (fido.GetNextRef(&entry) == B_OK) { BNode(&entry).ReadAttrString("MAIL:unique_id", &uid); queryContents.Add(uid); } } NotHere(queryContents, fManifest, &toDelete); for (int32 i = 0; i < toDelete.CountStrings(); i++) { printf("delete mail on server uid %s\n", toDelete.StringAt(i).String()); Delete(fUniqueIDs.IndexOf(toDelete.StringAt(i))); } // Don't remove ids from fUniqueIDs, the indices have to stay the same when // retrieving new messages. fManifest.Remove(toDelete); // TODO: at some point the purged manifest should be written to disk // otherwise it will grow forever }
void POP3Protocol::CheckForDeletedMessages() { { //---Delete things from the manifest no longer on the server BStringList temp; fManifest.NotThere(fUniqueIDs, &temp); fManifest -= temp; } if (!fSettings.FindBool("delete_remote_when_local") || fManifest.CountItems() == 0) return; BStringList to_delete; BStringList query_contents; BVolumeRoster volumes; BVolume volume; while (volumes.GetNextVolume(&volume) == B_OK) { BQuery fido; entry_ref entry; fido.SetVolume(&volume); fido.PushAttr(B_MAIL_ATTR_ACCOUNT_ID); fido.PushInt32(fAccountSettings.AccountID()); fido.PushOp(B_EQ); fido.Fetch(); BString uid; while (fido.GetNextRef(&entry) == B_OK) { BNode(&entry).ReadAttrString("MAIL:unique_id", &uid); query_contents.AddItem(uid.String()); } } query_contents.NotHere(fManifest, &to_delete); for (int32 i = 0; i < to_delete.CountItems(); i++) { printf("delete mail on server uid %s\n", to_delete[i]); Delete(fUniqueIDs.IndexOf(to_delete[i])); } //*(unique_ids) -= to_delete; --- This line causes bad things to // happen (POP3 client uses the wrong indices to retrieve // messages). Without it, bad things don't happen. fManifest -= to_delete; }
void DeskbarView::_RefreshMailQuery() { for (int32 i = 0; i < fNewMailQueries.CountItems(); i++) delete ((BQuery *)(fNewMailQueries.ItemAt(i))); fNewMailQueries.MakeEmpty(); BVolumeRoster volumes; BVolume volume; fNewMessages = 0; while (volumes.GetNextVolume(&volume) == B_OK) { BQuery *newMailQuery = new BQuery; newMailQuery->SetTarget(this); newMailQuery->SetVolume(&volume); newMailQuery->PushAttr(B_MAIL_ATTR_READ); newMailQuery->PushInt32(B_UNREAD); newMailQuery->PushOp(B_EQ); newMailQuery->PushAttr("BEOS:TYPE"); newMailQuery->PushString("text/x-email"); newMailQuery->PushOp(B_EQ); newMailQuery->PushAttr("BEOS:TYPE"); newMailQuery->PushString("text/x-partial-email"); newMailQuery->PushOp(B_EQ); newMailQuery->PushOp(B_OR); newMailQuery->PushOp(B_AND); newMailQuery->Fetch(); BEntry entry; while (newMailQuery->GetNextEntry(&entry) == B_OK) { if (entry.InitCheck() == B_OK) { entry_ref ref; entry.GetRef(&ref); if (!_EntryInTrash(&ref)) fNewMessages++; } } fNewMailQueries.AddItem(newMailQuery); } fStatus = (fNewMessages > 0) ? kStatusNewMail : kStatusNoMail; Invalidate(); }
void MailDaemonApp::SendPendingMessages(BMessage* msg) { BVolumeRoster roster; BVolume volume; map<int32, send_mails_info> messages; int32 account = -1; if (msg->FindInt32("account", &account) != B_OK) account = -1; if (!msg->HasString("message_path")) { while (roster.GetNextVolume(&volume) == B_OK) { BQuery query; query.SetVolume(&volume); query.PushAttr(B_MAIL_ATTR_FLAGS); query.PushInt32(B_MAIL_PENDING); query.PushOp(B_EQ); query.PushAttr(B_MAIL_ATTR_FLAGS); query.PushInt32(B_MAIL_PENDING | B_MAIL_SAVE); query.PushOp(B_EQ); if (account >= 0) { query.PushAttr(B_MAIL_ATTR_ACCOUNT_ID); query.PushInt32(account); query.PushOp(B_EQ); query.PushOp(B_AND); } query.PushOp(B_OR); query.Fetch(); BEntry entry; while (query.GetNextEntry(&entry) == B_OK) { if (_IsEntryInTrash(entry)) continue; BNode node; while (node.SetTo(&entry) == B_BUSY) snooze(1000); if (!_IsPending(node)) continue; int32 messageAccount; if (node.ReadAttr(B_MAIL_ATTR_ACCOUNT_ID, B_INT32_TYPE, 0, &messageAccount, sizeof(int32)) < 0) messageAccount = -1; off_t size = 0; node.GetSize(&size); entry_ref ref; entry.GetRef(&ref); messages[messageAccount].files.push_back(ref); messages[messageAccount].totalSize += size; } } } else { const char* path; if (msg->FindString("message_path", &path) != B_OK) return; off_t size = 0; if (BNode(path).GetSize(&size) != B_OK) return; BEntry entry(path); entry_ref ref; entry.GetRef(&ref); messages[account].files.push_back(ref); messages[account].totalSize += size; } map<int32, send_mails_info>::iterator iter = messages.begin(); for (; iter != messages.end(); iter++) { OutboundProtocolThread* protocolThread = _FindOutboundProtocol( iter->first); if (!protocolThread) continue; send_mails_info& info = iter->second; if (info.files.size() == 0) continue; MailProtocol* protocol = protocolThread->Protocol(); protocolThread->Lock(); protocol->SetTotalItems(info.files.size()); protocol->SetTotalItemsSize(info.totalSize); protocolThread->Unlock(); protocolThread->SendMessages(iter->second.files, info.totalSize); } }