示例#1
0
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;
	}
}
示例#2
0
// -------------------------------------------------------------------------
// 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;
}
示例#3
0
    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;
    }
示例#4
0
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);
}
示例#5
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);
	}
}
示例#7
0
/*!
	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;
}
示例#8
0
/*
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;
}
示例#9
0
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;
}
示例#10
0
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;
}
示例#11
0
/***********************************************************
 * 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"));
			}
		);
	}
示例#12
0
	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;
	}
示例#13
0
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;
}