void THeaderView::InitGroupCompletion() { // get boot volume BVolume volume; BVolumeRoster().GetBootVolume(&volume); // Build a list of all unique groups and the addresses they expand to. BQuery query; query.SetVolume(&volume); query.SetPredicate("META:group=**"); query.Fetch(); map<BString *, BString *, CompareBStrings> groupMap; entry_ref ref; BNode file; while (query.GetNextRef(&ref) == B_OK) { if (file.SetTo(&ref) != B_OK) continue; BString groups; if (ReadAttrString(&file, "META:group", &groups) < B_OK || groups.Length() == 0) continue; BString address; ReadAttrString(&file, "META:email", &address); // avoid adding an empty address if (address.Length() == 0) continue; char *group = groups.LockBuffer(groups.Length()); char *next = strchr(group, ','); for (;;) { if (next) *next = 0; while (*group && *group == ' ') group++; BString *groupString = new BString(group); BString *addressListString = NULL; // nobody is in this group yet, start it off if (groupMap[groupString] == NULL) { addressListString = new BString(*groupString); addressListString->Append(" "); groupMap[groupString] = addressListString; } else { addressListString = groupMap[groupString]; addressListString->Append(", "); delete groupString; } // Append the user's address to the end of the string with the // comma separated list of addresses. If not present, add the // < and > brackets around the address. if (address.FindFirst ('<') < 0) { address.ReplaceAll ('>', '_'); address.Prepend ("<"); address.Append(">"); } addressListString->Append(address); if (!next) break; group = next + 1; next = strchr(group, ','); } } map<BString *, BString *, CompareBStrings>::iterator iter; for (iter = groupMap.begin(); iter != groupMap.end();) { BString *group = iter->first; BString *addr = iter->second; fEmailList.AddChoice(addr->String()); ++iter; groupMap.erase(group); delete group; delete addr; } }
// ------------------------------------------------------------------------- // Bulkload b-tree from hash table in mem // <pairs>: // <num>: number of entries void BTree::BulkLoad(Pair* pairs, int num) { int start_block = -1; int end_block = -1; BNode* prev_node = NULL; BNode* cur_node = NULL; bool first_node = true; // --------------------------------------------------------------------- // Build leaf node from <pairs> (level = 0) // --------------------------------------------------------------------- for (int i = 0; i < num; ++i) { int id = pairs[i].id(); float key = pairs[i].projection(); if (cur_node == NULL) { cur_node = new BNode(); cur_node->Init(0, this); if (first_node) { first_node = false; start_block = cur_node->block(); } else { cur_node->set_left_sibling(prev_node); prev_node->set_right_sibling(cur_node); delete prev_node; prev_node = NULL; } end_block = cur_node->block(); } cur_node->AddNewChild(key, id); if (cur_node->IsFull()) { prev_node = cur_node; cur_node = NULL; } } // release space delete prev_node; prev_node = NULL; delete cur_node; cur_node = NULL; // ------------------------------------------------------------------------- // Build the b-tree level by level // ------------------------------------------------------------------------- int cur_level = 1; int last_start_block = start_block; int last_end_block = end_block; // when lastEndBlock == lastStartBlock mean it's only one node, as root while (last_end_block > last_start_block) { first_node = true; for (int block = last_start_block; block <= last_end_block; ++block) { BNode* child = new BNode(); child->InitFromFile(this, block); float key = child->GetKeyOfNode(); delete child; if (cur_node == NULL) { cur_node = new BNode(); cur_node->Init(cur_level, this); if (first_node) { first_node = false; start_block = cur_node->block(); } else { cur_node->set_left_sibling(prev_node); prev_node->set_right_sibling(cur_node); delete prev_node; prev_node = NULL; } end_block = cur_node->block(); } cur_node->AddNewChild(key, block); if (cur_node->IsFull()) { prev_node = cur_node; cur_node = NULL; } } // next level cur_level++; last_start_block = start_block; last_end_block = end_block; // release the space delete prev_node; prev_node = NULL; delete cur_node; cur_node = NULL; } root_block_ = last_start_block; }
void ShutdownRuleSet::load(const QString& file) { QFile fptr(file); if (!fptr.open(QIODevice::ReadOnly)) { Out(SYS_GEN | LOG_DEBUG) << "Failed to open file " << file << " : " << fptr.errorString() << endl; return; } QByteArray data = fptr.readAll(); BDecoder dec(data, false); BNode* node = 0; try { clear(); node = dec.decode(); if (!node || node->getType() != BNode::LIST) throw bt::Error("Toplevel node not a list"); BListNode* const l = (BListNode*)node; Uint32 i = 0; for (; i < l->getNumChildren(); ++i) { if (l->getChild(i)->getType() != BNode::DICT) break; BDictNode* const d = l->getDict(i); if (!d) continue; ShutdownRule rule; rule.action = (Action)d->getInt("Action"); rule.target = (Target)d->getInt("Target"); rule.trigger = (Trigger)d->getInt("Trigger"); rule.hit = d->keys().contains("hit") && d->getInt("hit") == 1; rule.tc = 0; if (d->getValue("Torrent")) { const QByteArray hash = d->getByteArray("Torrent"); bt::TorrentInterface* const tc = torrentForHash(hash); if (tc) rule.tc = tc; else continue; // no valid torrent found so skip this rule } rules.append(rule); } on = (l->getInt(i++) == 1); if (i < l->getNumChildren()) all_rules_must_be_hit = (l->getInt(i) == 1); else all_rules_must_be_hit = false; } catch (bt::Error& err) { Out(SYS_GEN | LOG_DEBUG) << "Failed to parse " << file << " : " << err.toString() << endl; } delete node; }
void QPopupMenu::EntryCreated(const entry_ref &ref, ino_t node) { BNode file; if (file.SetTo(&ref) < B_OK) return; // Make sure the pop-up menu is ready for additions. Need a bunch of // groups at the top, a divider line, and miscellaneous people added below // the line. int32 items = CountItems(); if (!items) AddSeparatorItem(); // Does the file have a group attribute? OK to have none. BString groups; const char *kNoGroup = "NoGroup!"; ReadAttrString(&file, "META:group", &groups); if (groups.Length() <= 0) groups = kNoGroup; // Add the e-mail address to the all people group. Then add it to all the // group menus that it exists in (based on the comma separated list of // groups from the People file), optionally making the group menu if it // doesn't exist. If it's in the special NoGroup! list, then add it below // the groups. bool allPeopleGroupDone = false; BMenu *groupMenu; do { BString group; if (!allPeopleGroupDone) { // Create the default group for all people, if it doesn't exist yet. group = "All People"; allPeopleGroupDone = true; } else { // Break out the next group from the comma separated string. int32 comma; if ((comma = groups.FindFirst(',')) > 0) { groups.MoveInto(group, 0, comma); groups.Remove(0, 1); } else group.Adopt(groups); } // trim white spaces int32 i = 0; for (i = 0; isspace(group.ByteAt(i)); i++) {} if (i) group.Remove(0, i); for (i = group.Length() - 1; isspace(group.ByteAt(i)); i--) {} group.Truncate(i + 1); groupMenu = NULL; BMenuItem *superItem = NULL; // Corresponding item for group menu. if (group.Length() > 0 && group != kNoGroup) { BMenu *sub; // Look for submenu with label == group name for (int32 i = 0; i < items; i++) { if ((sub = SubmenuAt(i)) != NULL) { superItem = sub->Superitem(); if (!strcmp(superItem->Label(), group.String())) { groupMenu = sub; i++; break; } } } // If no submenu, create one if (!groupMenu) { // Find where it should go (alphabetical) int32 mindex = 0; for (; mindex < fGroups; mindex++) { if (strcmp(ItemAt(mindex)->Label(), group.String()) > 0) break; } groupMenu = new BMenu(group.String()); groupMenu->SetFont(be_plain_font); AddItem(groupMenu, mindex); superItem = groupMenu->Superitem(); superItem->SetMessage(new BMessage(B_SIMPLE_DATA)); if (fTargetHandler) superItem->SetTarget(fTargetHandler); fGroups++; } } BString name; ReadAttrString(&file, "META:name", &name); BString email; ReadAttrString(&file, "META:email", &email); if (email.Length() != 0 || name.Length() != 0) AddPersonItem(&ref, node, name, email, NULL, groupMenu, superItem); // support for 3rd-party People apps for (int16 i = 2; i < 6; i++) { char attr[16]; sprintf(attr, "META:email%d", i); if (ReadAttrString(&file, attr, &email) >= B_OK && email.Length() > 0) AddPersonItem(&ref, node, name, email, attr, groupMenu, superItem); } } while (groups.Length() > 0); }
BMenuItem* BRecentItemsList::GetNextMenuItem(const BMessage* fileOpenInvokeMessage, const BMessage* containerOpenInvokeMessage, BHandler* target, entry_ref* currentItemRef) { entry_ref ref; if (GetNextRef(&ref) != B_OK) return NULL; Model model(&ref, true); if (model.InitCheck() != B_OK) return NULL; bool container = false; if (model.IsSymLink()) { Model* newResolvedModel = NULL; Model* result = model.LinkTo(); if (result == NULL) { newResolvedModel = new Model(model.EntryRef(), true, true); if (newResolvedModel->InitCheck() != B_OK) { // broken link, still can show though, bail delete newResolvedModel; result = NULL; } else result = newResolvedModel; } else { BModelOpener opener(result); // open the model, if it ain't open already PoseInfo poseInfo; BNode* resultNode = result->Node(); if (resultNode != NULL) { resultNode->ReadAttr(kAttrPoseInfo, B_RAW_TYPE, 0, &poseInfo, sizeof(poseInfo)); } result->CloseNode(); ref = *result->EntryRef(); container = result->IsContainer(); } model.SetLinkTo(result); } else { ref = *model.EntryRef(); container = model.IsContainer(); } // if user asked for it, return the current item ref if (currentItemRef != NULL) *currentItemRef = ref; BMessage* message; if (container && containerOpenInvokeMessage) message = new BMessage(*containerOpenInvokeMessage); else if (!container && fileOpenInvokeMessage) message = new BMessage(*fileOpenInvokeMessage); else message = new BMessage(B_REFS_RECEIVED); message->AddRef("refs", model.EntryRef()); // Truncate the name if necessary BString truncatedString(model.Name()); be_plain_font->TruncateString(&truncatedString, B_TRUNCATE_END, BNavMenu::GetMaxMenuWidth()); ModelMenuItem* item = NULL; if (!container || !fNavMenuFolders) item = new ModelMenuItem(&model, truncatedString.String(), message); else { // add another nav menu item if it's a directory BNavMenu* menu = new BNavMenu(truncatedString.String(), message->what, target, 0); menu->SetNavDir(&ref); item = new ModelMenuItem(&model, menu); item->SetMessage(message); } if (item != NULL && target != NULL) item->SetTarget(target); return item; }
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); } }
/*! Convert the plain text (UTF8) from inSource to plain or styled text in outDestination */ status_t translate_from_text(BPositionIO* source, const char* encoding, bool forceEncoding, BPositionIO* destination, uint32 outType) { if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT) return B_BAD_VALUE; // find the length of the text off_t size = source->Seek(0, SEEK_END); if (size < 0) return (status_t)size; if (size > UINT32_MAX && outType == B_STYLED_TEXT_FORMAT) return B_NOT_SUPPORTED; status_t status = source->Seek(0, SEEK_SET); if (status < B_OK) return status; if (outType == B_STYLED_TEXT_FORMAT) { // output styled text headers status = output_headers(destination, (uint32)size); if (status != B_OK) return status; } class MallocBuffer { public: MallocBuffer() : fBuffer(NULL), fSize(0) {} ~MallocBuffer() { free(fBuffer); } void* Buffer() { return fBuffer; } size_t Size() const { return fSize; } status_t Allocate(size_t size) { fBuffer = malloc(size); if (fBuffer != NULL) { fSize = size; return B_OK; } return B_NO_MEMORY; } private: void* fBuffer; size_t fSize; } encodingBuffer; BMallocIO encodingIO; uint32 encodingID = 0; // defaults to UTF-8 or no encoding BNode* node = dynamic_cast<BNode*>(source); if (node != NULL) { // determine encoding, if available const BCharacterSet* characterSet = NULL; bool hasAttribute = false; if (encoding != NULL && !forceEncoding) { BString name; if (node->ReadAttrString("be:encoding", &name) == B_OK) { encoding = name.String(); hasAttribute = true; } else { int32 value; ssize_t bytesRead = node->ReadAttr("be:encoding", B_INT32_TYPE, 0, &value, sizeof(value)); if (bytesRead == (ssize_t)sizeof(value)) { hasAttribute = true; if (value != 65535) characterSet = BCharacterSetRoster::GetCharacterSetByConversionID(value); } } } else { hasAttribute = true; // we don't write the encoding in this case } if (characterSet == NULL && encoding != NULL) characterSet = BCharacterSetRoster::FindCharacterSetByName(encoding); if (characterSet != NULL) { encodingID = characterSet->GetConversionID(); encodingBuffer.Allocate(READ_BUFFER_SIZE * 4); } if (!hasAttribute && encoding != NULL) { // add encoding attribute, so that someone opening the file can // retrieve it for persistance node->WriteAttr("be:encoding", B_STRING_TYPE, 0, encoding, strlen(encoding)); } } off_t outputSize = 0; ssize_t bytesRead; int32 state = 0; // output the actual text part of the data do { uint8 buffer[READ_BUFFER_SIZE]; bytesRead = source->Read(buffer, READ_BUFFER_SIZE); if (bytesRead < B_OK) return bytesRead; if (bytesRead == 0) break; if (encodingBuffer.Size() == 0) { // default, no encoding ssize_t bytesWritten = destination->Write(buffer, bytesRead); if (bytesWritten != bytesRead) { if (bytesWritten < B_OK) return bytesWritten; return B_ERROR; } outputSize += bytesRead; } else { // decode text file to UTF-8 char* pos = (char*)buffer; int32 encodingLength = encodingIO.BufferLength(); int32 bytesLeft = bytesRead; int32 bytes; do { encodingLength = READ_BUFFER_SIZE * 4; bytes = bytesLeft; status = convert_to_utf8(encodingID, pos, &bytes, (char*)encodingBuffer.Buffer(), &encodingLength, &state); if (status < B_OK) return status; ssize_t bytesWritten = destination->Write(encodingBuffer.Buffer(), encodingLength); if (bytesWritten < encodingLength) { if (bytesWritten < B_OK) return bytesWritten; return B_ERROR; } pos += bytes; bytesLeft -= bytes; outputSize += encodingLength; } while (encodingLength > 0 && bytesLeft > 0); } } while (bytesRead > 0); if (outType != B_STYLED_TEXT_FORMAT) return B_OK; if (encodingBuffer.Size() != 0 && size != outputSize) { if (outputSize > UINT32_MAX) return B_NOT_SUPPORTED; // we need to update the header as the decoded text size has changed status = destination->Seek(0, SEEK_SET); if (status == B_OK) status = output_headers(destination, (uint32)outputSize); if (status == B_OK) status = destination->Seek(0, SEEK_END); if (status < B_OK) return status; } // Read file attributes if outputting styled data // and source is a BNode object if (node == NULL) return B_OK; // Try to read styles - we only propagate an error if the actual on-disk // data is likely to be okay const char *kAttrName = "styles"; attr_info info; if (node->GetAttrInfo(kAttrName, &info) != B_OK) return B_OK; if (info.type != B_RAW_TYPE || info.size < 160) { // styles seem to be broken, but since we got the text, // we don't propagate the error return B_OK; } uint8* flatRunArray = new (std::nothrow) uint8[info.size]; if (flatRunArray == NULL) return B_NO_MEMORY; bytesRead = node->ReadAttr(kAttrName, B_RAW_TYPE, 0, flatRunArray, info.size); if (bytesRead != info.size) return B_OK; output_styles(destination, size, flatRunArray, info.size); delete[] flatRunArray; return B_OK; }
/* iterate over add-on-folders and collect information about each catalog-add-ons (types of catalogs) into fCatalogAddOnInfos. */ status_t LocaleRosterData::_InitializeCatalogAddOns() { BAutolock lock(fLock); if (!lock.IsLocked()) return B_ERROR; // add info about embedded default catalog: CatalogAddOnInfo* defaultCatalogAddOnInfo = new(std::nothrow) CatalogAddOnInfo("Default", "", DefaultCatalog::kDefaultCatalogAddOnPriority); if (!defaultCatalogAddOnInfo) return B_NO_MEMORY; defaultCatalogAddOnInfo->fInstantiateFunc = DefaultCatalog::Instantiate; defaultCatalogAddOnInfo->fCreateFunc = DefaultCatalog::Create; fCatalogAddOnInfos.AddItem((void*)defaultCatalogAddOnInfo); BStringList folders; BPathFinder::FindPaths(B_FIND_PATH_ADD_ONS_DIRECTORY, "locale/catalogs/", B_FIND_PATH_EXISTING_ONLY, folders); BPath addOnPath; BDirectory addOnFolder; char buf[4096]; status_t err; for (int32 f = 0; f < folders.CountStrings(); f++) { BString addOnFolderName = folders.StringAt(f); err = addOnFolder.SetTo(addOnFolderName.String()); if (err != B_OK) continue; // scan through all the folder's entries for catalog add-ons: int32 count; int8 priority; entry_ref eref; BNode node; BEntry entry; dirent* dent; while ((count = addOnFolder.GetNextDirents((dirent*)buf, sizeof(buf))) > 0) { dent = (dirent*)buf; while (count-- > 0) { if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0 && strcmp(dent->d_name, "x86") != 0 && strcmp(dent->d_name, "x86_gcc2") != 0) { // we have found (what should be) a catalog-add-on: eref.device = dent->d_pdev; eref.directory = dent->d_pino; eref.set_name(dent->d_name); entry.SetTo(&eref, true); // traverse through any links to get to the real thang! node.SetTo(&entry); priority = -1; if (node.ReadAttr(kPriorityAttr, B_INT8_TYPE, 0, &priority, sizeof(int8)) <= 0) { // add-on has no priority-attribute yet, so we load it // to fetch the priority from the corresponding // symbol... BString fullAddOnPath(addOnFolderName); fullAddOnPath << "/" << dent->d_name; image_id image = load_add_on(fullAddOnPath.String()); if (image >= B_OK) { uint8* prioPtr; if (get_image_symbol(image, "gCatalogAddOnPriority", B_SYMBOL_TYPE_DATA, (void**)&prioPtr) == B_OK) { priority = *prioPtr; node.WriteAttr(kPriorityAttr, B_INT8_TYPE, 0, &priority, sizeof(int8)); } unload_add_on(image); } } if (priority >= 0) { // add-ons with priority < 0 will be ignored CatalogAddOnInfo* addOnInfo = new(std::nothrow) CatalogAddOnInfo(dent->d_name, addOnFolderName, priority); if (addOnInfo) fCatalogAddOnInfos.AddItem((void*)addOnInfo); } } // Bump the dirent-pointer by length of the dirent just handled: dent = (dirent*)((char*)dent + dent->d_reclen); } } } fCatalogAddOnInfos.SortItems(CompareInfos); return B_OK; }
void DockItem::SetTo( const entry_ref *ref ) { BEntry entry; BPath path; BSymLink symLink; BMimeType type; BMimeType appType; // Traverse the symbolic link if necessary. entry.SetTo( ref, true ); entry.GetRef( &mRef ); /* if ( entry.IsSymLink() ) { symLink.SetTo( ref ); symLink.GetLinkedPath( &path ); printf( "path = %s\n", path.Path() ); entry.SetTo( path.Path() ); entry.GetRef( &mRef ); } else { mRef = *ref; } */ // Retrieve the ref's name. entry.SetTo( &mRef ); entry.GetName( mCaption ); entry.GetPath( &path ); PRINT(( "entry ref name (%s)\n", mCaption )); PRINT(( "path = %s\n", path.Path() )); // Retrieve mime type. BNode node; node.SetTo( &mRef ); BNodeInfo nodeInfo( &node ); nodeInfo.GetType( mMimeType ); type.SetType( mMimeType ); // Remember the node type. if ( node.IsDirectory() ) { mNodeType = kFolder; } else { mNodeType = kFile; } /* // First retrieve custom icon. (GetTrackerIcon's not perfect yet) if ( ::GetTrackerIcon( &mRef, mLargeIcon, mSmallIcon ) != B_NO_ERROR ) { this->GetGenericIcon(); } */ if ( BNodeInfo::GetTrackerIcon( &mRef, mLargeIcon, B_LARGE_ICON ) < B_NO_ERROR ) { PRINT(( "Couldn't retrieve icon\n" )); GetGenericIcon(); } if ( BNodeInfo::GetTrackerIcon( &mRef, mSmallIcon, B_MINI_ICON ) < B_NO_ERROR ) { PRINT(( "Couldn't retrive mini icon\n" )); GetGenericIcon(); } MakeHighlitIcon(); mHasRef = true; }
status_t CreateAppMetaMimeThread::DoMimeUpdate(const entry_ref* ref, bool* _entryIsDir) { if (ref == NULL) return B_BAD_VALUE; BNode typeNode; BFile file; status_t status = file.SetTo(ref, B_READ_ONLY); if (status < B_OK) return status; bool isDir = file.IsDirectory(); if (_entryIsDir != NULL) *_entryIsDir = isDir; if (isDir) return B_OK; BAppFileInfo appInfo(&file); status = appInfo.InitCheck(); if (status < B_OK) return status; // Read the app sig (which consequently keeps us from updating // non-applications, since we get an error if the file has no // app sig) BString signature; status = file.ReadAttrString("BEOS:APP_SIG", &signature); if (status < B_OK) return B_BAD_TYPE; // Init our various objects BMimeType mime; status = mime.SetTo(signature.String()); if (status < B_OK) return status; InstallNotificationDeferrer _(fDatabase, signature.String()); if (!mime.IsInstalled()) mime.Install(); BString path = "/"; path.Append(signature); path.ToLower(); // Signatures and MIME types are case insensitive, but we want to // preserve the case wherever possible path.Prepend(get_database_directory().c_str()); status = typeNode.SetTo(path.String()); if (status < B_OK) return status; // Preferred App attr_info info; if (status == B_OK && (fForce || typeNode.GetAttrInfo(kPreferredAppAttr, &info) != B_OK)) status = mime.SetPreferredApp(signature.String()); // Short Description (name of the application) if (status == B_OK && (fForce || typeNode.GetAttrInfo(kShortDescriptionAttr, &info) != B_OK)) status = mime.SetShortDescription(ref->name); // App Hint if (status == B_OK && (fForce || typeNode.GetAttrInfo(kAppHintAttr, &info) != B_OK)) status = mime.SetAppHint(ref); // Vector Icon if (status == B_OK && (fForce || typeNode.GetAttrInfo(kIconAttr, &info) != B_OK)) { uint8* data = NULL; size_t size = 0; if (appInfo.GetIcon(&data, &size) == B_OK) { status = mime.SetIcon(data, size); free(data); } } // Mini Icon BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, B_CMAP8); if (status == B_OK && (fForce || typeNode.GetAttrInfo(kMiniIconAttr, &info) != B_OK)) { if (appInfo.GetIcon(&miniIcon, B_MINI_ICON) == B_OK) status = mime.SetIcon(&miniIcon, B_MINI_ICON); } // Large Icon BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_CMAP8); if (status == B_OK && (fForce || typeNode.GetAttrInfo(kLargeIconAttr, &info) != B_OK)) { if (appInfo.GetIcon(&largeIcon, B_LARGE_ICON) == B_OK) status = mime.SetIcon(&largeIcon, B_LARGE_ICON); } // Supported Types bool setSupportedTypes = false; BMessage supportedTypes; if (status == B_OK && (fForce || typeNode.GetAttrInfo(kSupportedTypesAttr, &info) != B_OK)) { if (appInfo.GetSupportedTypes(&supportedTypes) == B_OK) setSupportedTypes = true; } // defer notifications for supported types const char* type; for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++) fDatabase->DeferInstallNotification(type); // set supported types if (setSupportedTypes) status = mime.SetSupportedTypes(&supportedTypes); // Icons for supported types for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++) { // vector icon uint8* data = NULL; size_t size = 0; if (status == B_OK && appInfo.GetIconForType(type, &data, &size) == B_OK) { status = mime.SetIconForType(type, data, size); free(data); } // mini icon if (status == B_OK && appInfo.GetIconForType(type, &miniIcon, B_MINI_ICON) == B_OK) status = mime.SetIconForType(type, &miniIcon, B_MINI_ICON); // large icon if (status == B_OK && appInfo.GetIconForType(type, &largeIcon, B_LARGE_ICON) == B_OK) status = mime.SetIconForType(type, &largeIcon, B_LARGE_ICON); } // undefer notifications for supported types for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++) fDatabase->UndeferInstallNotification(type); return status; }
/*********************************************************** * Fetching ***********************************************************/ void HQueryItem::Fetching() { bool some_success = false; BVolume volume; BVolumeRoster roster; while (fQueries.CountItems()) { delete static_cast<BQuery *>(fQueries.RemoveItem((int32)0)); } uint32 count_items = 0; while (roster.GetNextVolume(&volume) == B_OK) { BQuery *query = new BQuery; fQueries.AddItem((void*)query); query->Clear(); query->SetTarget(*fMessenger); query->SetVolume(&volume); query->SetPredicate(fPredicate.String()); char type[B_MIME_TYPE_LENGTH+1]; BNode node; HMailItem *item(NULL); if(query->Fetch() == B_OK) { some_success = true; entry_ref ref; char buf[4096]; dirent *dent; int32 count; int32 offset; while (((count = query->GetNextDirents((dirent *)buf, 4096)) > 0) && (!fCancel)) { offset = 0; /* Now we step through the dirents. */ while (count-- > 0) { dent = (dirent *)buf + offset; offset += dent->d_reclen; /* Skip . and .. directory */ if(::strcmp(dent->d_name,".") == 0 || ::strcmp(dent->d_name,"..")== 0) continue; ref.device = dent->d_pdev; ref.directory = dent->d_pino; ref.set_name(dent->d_name); if(node.SetTo(&ref) != B_OK) continue; node.ReadAttr("BEOS:TYPE",'MIMS',0,type,B_MIME_TYPE_LENGTH); if(::strcmp(type,B_MAIL_TYPE) == 0) { fMailList.AddItem(item = new HMailItem(ref)); if(item && !item->IsRead() ) count_items++; } } } }DEBUG_ONLY( else{ PRINT(("Query fetching was failed\n")); } ); }
bool HTTPTracker::updateData(const QByteArray & data) { //#define DEBUG_PRINT_RESPONSE #ifdef DEBUG_PRINT_RESPONSE Out(SYS_TRK | LOG_DEBUG) << "Data : " << endl; Out(SYS_TRK | LOG_DEBUG) << QString(data) << endl; #endif // search for dictionary, there might be random garbage infront of the data int i = 0; while (i < data.size()) { if (data[i] == 'd') break; i++; } if (i == data.size()) { failures++; failed(i18n("Invalid response from tracker")); return false; } BDecoder dec(data, false, i); BNode* n = 0; try { n = dec.decode(); } catch (...) { failures++; failed(i18n("Invalid data from tracker")); return false; } if (!n || n->getType() != BNode::DICT) { failures++; failed(i18n("Invalid response from tracker")); return false; } BDictNode* dict = (BDictNode*)n; if (dict->getData("failure reason")) { BValueNode* vn = dict->getValue("failure reason"); error = vn->data().toString(); delete n; failures++; failed(error); return false; } if (dict->getData("warning message")) { BValueNode* vn = dict->getValue("warning message"); warning = vn->data().toString(); } else warning.clear(); BValueNode* vn = dict->getValue("interval"); // if no interval is specified, use 5 minutes if (vn) interval = vn->data().toInt(); else interval = 5 * 60; vn = dict->getValue("incomplete"); if (vn) leechers = vn->data().toInt(); vn = dict->getValue("complete"); if (vn) seeders = vn->data().toInt(); BListNode* ln = dict->getList("peers"); if (!ln) { // no list, it might however be a compact response vn = dict->getValue("peers"); if (vn && vn->data().getType() == Value::STRING) { QByteArray arr = vn->data().toByteArray(); for (int i = 0;i < arr.size();i += 6) { Uint8 buf[6]; for (int j = 0;j < 6;j++) buf[j] = arr[i + j]; Uint32 ip = ReadUint32(buf, 0); addPeer(net::Address(ip, ReadUint16(buf, 4)), false); } } } else { for (Uint32 i = 0;i < ln->getNumChildren();i++) { BDictNode* dict = dynamic_cast<BDictNode*>(ln->getChild(i)); if (!dict) continue; BValueNode* ip_node = dict->getValue("ip"); BValueNode* port_node = dict->getValue("port"); if (!ip_node || !port_node) continue; net::Address addr(ip_node->data().toString(), port_node->data().toInt()); addPeer(addr, false); } } // Check for IPv6 compact peers vn = dict->getValue("peers6"); if (vn && vn->data().getType() == Value::STRING) { QByteArray arr = vn->data().toByteArray(); for (int i = 0;i < arr.size();i += 18) { Q_IPV6ADDR ip; memcpy(ip.c, arr.data() + i, 16); quint16 port = ReadUint16((const Uint8*)arr.data() + i, 16); addPeer(net::Address(ip, port), false); } } delete n; return true; }
QueryEntryListCollection::QueryEntryListCollection(Model* model, BHandler* target, PoseList* oldPoseList) : fQueryListRep(new QueryListRep(new BObjectList<BQuery>(5, true))) { Rewind(); attr_info info; BQuery query; BNode* modelNode = model->Node(); if (modelNode == NULL) { fStatus = B_ERROR; return; } // read the actual query string fStatus = modelNode->GetAttrInfo(kAttrQueryString, &info); if (fStatus != B_OK) return; BString buffer; if (modelNode->ReadAttr(kAttrQueryString, B_STRING_TYPE, 0, buffer.LockBuffer((int32)info.size), (size_t)info.size) != info.size) { fStatus = B_ERROR; return; } buffer.UnlockBuffer(); // read the extra options MoreOptionsStruct saveMoreOptions; if (ReadAttr(modelNode, kAttrQueryMoreOptions, kAttrQueryMoreOptionsForeign, B_RAW_TYPE, 0, &saveMoreOptions, sizeof(MoreOptionsStruct), &MoreOptionsStruct::EndianSwap) != kReadAttrFailed) { fQueryListRep->fShowResultsFromTrash = saveMoreOptions.searchTrash; } fStatus = query.SetPredicate(buffer.String()); fQueryListRep->fOldPoseList = oldPoseList; fQueryListRep->fDynamicDateQuery = false; fQueryListRep->fRefreshEveryHour = false; fQueryListRep->fRefreshEveryMinute = false; if (modelNode->ReadAttr(kAttrDynamicDateQuery, B_BOOL_TYPE, 0, &fQueryListRep->fDynamicDateQuery, sizeof(bool)) != sizeof(bool)) { fQueryListRep->fDynamicDateQuery = false; } if (fQueryListRep->fDynamicDateQuery) { // only refresh every minute on debug builds fQueryListRep->fRefreshEveryMinute = buffer.IFindFirst("second") != -1 || buffer.IFindFirst("minute") != -1; fQueryListRep->fRefreshEveryHour = fQueryListRep->fRefreshEveryMinute || buffer.IFindFirst("hour") != -1; #if !DEBUG // don't refresh every minute unless we are running debug build fQueryListRep->fRefreshEveryMinute = false; #endif } if (fStatus != B_OK) return; bool searchAllVolumes = true; status_t result = B_OK; // get volumes to perform query on if (modelNode->GetAttrInfo(kAttrQueryVolume, &info) == B_OK) { char* buffer = NULL; if ((buffer = (char*)malloc((size_t)info.size)) != NULL && modelNode->ReadAttr(kAttrQueryVolume, B_MESSAGE_TYPE, 0, buffer, (size_t)info.size) == info.size) { BMessage message; if (message.Unflatten(buffer) == B_OK) { for (int32 index = 0; ;index++) { ASSERT(index < 100); BVolume volume; // match a volume with the info embedded in // the message result = MatchArchivedVolume(&volume, &message, index); if (result == B_OK) { // start the query on this volume result = FetchOneQuery(&query, target, fQueryListRep->fQueryList, &volume); if (result != B_OK) continue; searchAllVolumes = false; } else if (result != B_DEV_BAD_DRIVE_NUM) { // if B_DEV_BAD_DRIVE_NUM, the volume just isn't // mounted this time around, keep looking for more // if other error, bail break; } } } } free(buffer); } if (searchAllVolumes) { // no specific volumes embedded in query, search everything BVolumeRoster roster; BVolume volume; roster.Rewind(); while (roster.GetNextVolume(&volume) == B_OK) if (volume.IsPersistent() && volume.KnowsQuery()) { result = FetchOneQuery(&query, target, fQueryListRep->fQueryList, &volume); if (result != B_OK) continue; } } fStatus = B_OK; return; }