void MailDaemonApp::ReadyToRun() { InstallDeskbarIcon(); _InitAccounts(); _UpdateAutoCheck(fSettingsFile.AutoCheckInterval()); BVolume volume; BVolumeRoster roster; fNewMessages = 0; while (roster.GetNextVolume(&volume) == B_OK) { //{char name[255];volume.GetName(name);printf("Volume: %s\n",name);} BQuery* query = new BQuery; query->SetTarget(this); query->SetVolume(&volume); query->PushAttr(B_MAIL_ATTR_STATUS); query->PushString("New"); query->PushOp(B_EQ); query->PushAttr("BEOS:TYPE"); query->PushString("text/x-email"); query->PushOp(B_EQ); query->PushAttr("BEOS:TYPE"); query->PushString("text/x-partial-email"); query->PushOp(B_EQ); query->PushOp(B_OR); query->PushOp(B_AND); query->Fetch(); BEntry entry; while (query->GetNextEntry(&entry) == B_OK) fNewMessages++; fQueries.AddItem(query); } BString string; MDR_DIALECT_CHOICE( if (fNewMessages > 0) string << fNewMessages; else string << "No"; if (fNewMessages != 1) string << " new messages."; else string << " new message.";, if (fNewMessages > 0)
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(); }
uint32 FetchQuery(query_op op, const char* selection, vector<BString>& results, bool caseSensitive = false) { BQuery query; query.PushAttr("BEOS:TYPE"); query.PushString("application/x-vnd.Be-doc_bookmark"); query.PushOp(B_EQ); query.PushAttr("name"); query.PushString(selection, caseSensitive); query.PushOp(op); query.PushOp(B_AND); BVolume vol; BVolumeRoster roster; roster.GetBootVolume(&vol); query.SetVolume(&vol); if (B_NO_INIT == query.Fetch()) return 0; BEntry entry; BPath path; int32 counter = 0; while (query.GetNextEntry(&entry) != B_ENTRY_NOT_FOUND) { if (entry.InitCheck() == B_OK) { entry.GetPath(&path); if (path.InitCheck() == B_OK) { results.push_back(path.Path()); counter++; } } } return counter; }
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; }
status_t TeamWindow::_RetrieveMatchingSourceEntries(const BString& path, BStringList* _entries) { BPath filePath(path); status_t error = filePath.InitCheck(); if (error != B_OK) return error; _entries->MakeEmpty(); BQuery query; BString predicate; query.PushAttr("name"); query.PushString(filePath.Leaf()); query.PushOp(B_EQ); error = query.GetPredicate(&predicate); if (error != B_OK) return error; BVolumeRoster roster; BVolume volume; while (roster.GetNextVolume(&volume) == B_OK) { if (!volume.KnowsQuery()) continue; if (query.SetVolume(&volume) != B_OK) continue; error = query.SetPredicate(predicate.String()); if (error != B_OK) continue; if (query.Fetch() != B_OK) continue; entry_ref ref; while (query.GetNextRef(&ref) == B_OK) { filePath.SetTo(&ref); _entries->Add(filePath.Path()); } query.Clear(); } return B_OK; }
int32 add_query_menu_items(BMenu* menu, const char* attribute, uint32 what, const char* format, bool popup) { BVolume volume; BVolumeRoster().GetBootVolume(&volume); BQuery query; query.SetVolume(&volume); query.PushAttr(attribute); query.PushString("*"); query.PushOp(B_EQ); query.Fetch(); int32 index = 0; BEntry entry; while (query.GetNextEntry(&entry) == B_OK) { BFile file(&entry, B_READ_ONLY); if (file.InitCheck() == B_OK) { BMessage* message = new BMessage(what); entry_ref ref; entry.GetRef(&ref); message->AddRef("ref", &ref); BString value; if (file.ReadAttrString(attribute, &value) < B_OK) continue; message->AddString("attribute", value.String()); BString name; if (format != NULL) name.SetToFormat(format, value.String()); else name = value; if (index < 9 && !popup) menu->AddItem(new BMenuItem(name, message, '1' + index)); else menu->AddItem(new BMenuItem(name, message)); index++; } } return index; }
bool TStatusWindow::_Exists(const char* status) { BVolume volume; BVolumeRoster().GetBootVolume(&volume); BQuery query; query.SetVolume(&volume); query.PushAttr(INDEX_STATUS); query.PushString(status); query.PushOp(B_EQ); query.Fetch(); BEntry entry; if (query.GetNextEntry(&entry) == B_NO_ERROR) return true; return false; }
void ApplicationTypesWindow::_RemoveUninstalled() { // Note: this runs in the looper's thread, which isn't that nice int32 removed = 0; volatile bool quit = false; BWindow* progressWindow = new ProgressWindow( B_TRANSLATE("Removing uninstalled application types"), fTypeListView->FullListCountItems(), &quit); progressWindow->AddToSubset(this); progressWindow->Show(); for (int32 i = fTypeListView->FullListCountItems(); i-- > 0 && !quit;) { MimeTypeItem* item = dynamic_cast<MimeTypeItem*> (fTypeListView->FullListItemAt(i)); progressWindow->PostMessage(B_UPDATE_STATUS_BAR); if (item == NULL) continue; // search for application on all volumes bool found = false; BVolumeRoster volumeRoster; BVolume volume; while (volumeRoster.GetNextVolume(&volume) == B_OK) { if (!volume.KnowsQuery()) continue; BQuery query; query.PushAttr("BEOS:APP_SIG"); query.PushString(item->Type()); query.PushOp(B_EQ); query.SetVolume(&volume); query.Fetch(); entry_ref ref; if (query.GetNextRef(&ref) == B_OK) { found = true; break; } } if (!found) { BMimeType mimeType(item->Type()); mimeType.Delete(); removed++; // We're blocking the message loop that received the MIME changes, // so we dequeue all waiting messages from time to time if (removed % 10 == 0) UpdateIfNeeded(); } } progressWindow->PostMessage(B_QUIT_REQUESTED); static BMessageFormat format(B_TRANSLATE("{0, plural, " "one{# Application type could be removed} " "other{# Application types could be removed}}")); BString message; format.Format(message, removed); error_alert(message, B_OK, B_INFO_ALERT); }
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); } }
void MailDaemonApp::ReadyToRun() { InstallDeskbarIcon(); _InitAccounts(); _UpdateAutoCheck(fSettingsFile.AutoCheckInterval()); BVolume volume; BVolumeRoster roster; fNewMessages = 0; while (roster.GetNextVolume(&volume) == B_OK) { BQuery* query = new BQuery; query->SetTarget(this); query->SetVolume(&volume); query->PushAttr(B_MAIL_ATTR_STATUS); query->PushString("New"); query->PushOp(B_EQ); query->PushAttr("BEOS:TYPE"); query->PushString("text/x-email"); query->PushOp(B_EQ); query->PushAttr("BEOS:TYPE"); query->PushString("text/x-partial-email"); query->PushOp(B_EQ); query->PushOp(B_OR); query->PushOp(B_AND); query->Fetch(); BEntry entry; while (query->GetNextEntry(&entry) == B_OK) fNewMessages++; fQueries.AddItem(query); } BString string, numString; if (fNewMessages > 0) { if (fNewMessages != 1) string << B_TRANSLATE("%num new messages."); else string << B_TRANSLATE("%num new message."); numString << fNewMessages; string.ReplaceFirst("%num", numString); } else string = B_TRANSLATE("No new messages"); fCentralBeep = false; fNotification = new BNotification(B_INFORMATION_NOTIFICATION); fNotification->SetGroup(B_TRANSLATE("Mail status")); fNotification->SetTitle(string); fNotification->SetMessageID("daemon_status"); app_info info; be_roster->GetAppInfo(B_MAIL_DAEMON_SIGNATURE, &info); BBitmap icon(BRect(0, 0, 32, 32), B_RGBA32); BNode node(&info.ref); BIconUtils::GetVectorIcon(&node, "BEOS:ICON", &icon); fNotification->SetIcon(&icon); fLEDAnimation = new LEDAnimation; SetPulseRate(1000000); }
/*! \brief Search the filesystem for additional categories. * \details Starts a whole-filesystem query for the Event files with * categories which may be copied to the system and not appear * in the Categories' database. */ static void SearchFilesystemForAdditionalCategories( void ) { BQuery* categoryQuery = NULL; //!< The way to fill the previously-uncatched categories. Category* pCategory = NULL; //!< Used to traverse the list of categories status_t status; //!< Result of the last action. ssize_t bytesTransferred; //!< Used in I/O operations entry_ref fileToReadAttributesFrom; //!< This is the reference to file with unknown category. BFile* file = NULL; //!< This file will be initialized with fileToGetTheAttributesFrom. attr_info attribute_info; //!< Information about the attribute. rgb_color catColor; //!< Category color char buffer[ 255 ]; //!< I'll use this buffer to read Categories from files categoryQuery = new BQuery(); if ( !categoryQuery ) { /* Nothing to do */ return; } // For initialization of the BQuery, we need to find the Volume with user's data. BVolumeRoster volumeRoster; BVolume bootVolume; volumeRoster.GetBootVolume( &bootVolume ); // Setting the query to look in the boot volume categoryQuery->SetVolume( &bootVolume ); /* First item of the predicate is the type of the file. */ categoryQuery->PushAttr( "BEOS:TYPE" ); categoryQuery->PushString( kEventFileMIMEType ); categoryQuery->PushOp( B_EQ ); /* Check the category attribute type's name. */ int i = 0; BString categoryAttributeInternalName; while ( AttributesArray[ i ].internalName != 0 ) { if ( strcmp( AttributesArray[ i ].humanReadableName, "Category" ) == 0 ) { // Found the correct attribute! Now, let's take its internal name... break; } ++i; } /* Build the query predicate. * This is meaningful only if global list of categories contains any items, * and if we succeeded to find the attribute with human-readable name "Category". */ if ( ! global_ListOfCategories.IsEmpty() && ( AttributesArray[ i ].internalName != NULL ) ) { for ( int i = 0, limit = global_ListOfCategories.CountItems(); i < limit; ++i ) { pCategory = ( Category* )global_ListOfCategories.ItemAt( i ); if ( !pCategory ) continue; categoryQuery->PushAttr( AttributesArray[ i ].internalName ); categoryQuery->PushString( pCategory->categoryName.String(), true ); categoryQuery->PushOp( B_NE ); categoryQuery->PushOp( B_AND ); } // <-- end of "for ( all currently known categories )" } // <-- end of "if ( there are any items in the list of known categories )" /* The predicate that we currently have looks like this: * ((( type is Eventual ) && ( category != "Cat1" )) && ( category != "Cat2" )) && ... * The order does not matter, since we're using "AND". * * Well, let's fire and see what comes... */ categoryQuery->Fetch(); while ( ( status = categoryQuery->GetNextRef( &fileToReadAttributesFrom ) ) == B_OK ) { // Successfully retrieved next entry file = new BFile( &fileToReadAttributesFrom, B_READ_ONLY ); if ( !file || file->InitCheck() != B_OK ) continue; status = file->GetAttrInfo( AttributesArray[ i ].internalName, &attribute_info ); if ( status != B_OK ) continue; status = file->ReadAttr( AttributesArray[ i ].internalName, attribute_info.type, 0, buffer, ( attribute_info.size > 255 ) ? 255 : attribute_info.size ); if ( status != B_OK ) continue; // Succeeded to read the category name, it's in "buffer". Create the color... catColor = CreateRandomColor(); // ...and add the category to the list of categories. AddCategoryToGlobalList( BString( buffer ), catColor ); // We don't need the file anymore. delete file; } delete categoryQuery; } // <-- end of function SearchFilesystemForAdditionalCategories
BQuery* MusicCollectionWindow::_CreateQuery(BString& orgString) { BQuery* query = new BQuery; BString queryString; CaseInsensitiveString(orgString, queryString); query->PushAttr("Media:Title"); query->PushString(queryString); query->PushOp(B_CONTAINS); query->PushAttr("Audio:Album"); query->PushString(queryString); query->PushOp(B_CONTAINS); query->PushOp(B_OR); query->PushAttr("Audio:Artist"); query->PushString(queryString); query->PushOp(B_CONTAINS); query->PushOp(B_OR); if (queryString == "") { query->PushAttr("BEOS:TYPE"); query->PushString("audio/"); query->PushOp(B_BEGINS_WITH); query->PushOp(B_OR); } query->PushAttr("BEOS:TYPE"); query->PushString("audio/"); query->PushOp(B_BEGINS_WITH); query->PushAttr("name"); query->PushString(queryString); query->PushOp(B_CONTAINS); query->PushOp(B_AND); query->PushOp(B_OR); return query; }