Example #1
0
void
LiveQuery::_PerformQuery(BQuery& query)
{
	status_t status = query.Fetch();
	if (status != B_OK) {
		fprintf(stderr, "%s: bad query expression\n", kProgramName);
		return;
	}

	int32 count = 0;

	BEntry entry;
	BPath path;
	while (query.GetNextEntry(&entry) == B_OK) {
		if (sFilesOnly && !entry.IsFile())
			continue;

		if (entry.GetPath(&path) != B_OK) {
			fprintf(stderr, "%s: could not get path for entry\n", kProgramName);
			continue;
		}

		printf("%s\n", sEscapeMetaChars ? BString().CharacterEscape(
				path.Path(), " ()?*&\"'[]^\\~|;!<>*$\t", '\\').String()
			: path.Path());

		count++;
	}

	printf("FOUND %ld entries\n", count);
}
Example #2
0
void
TReplicantTray::RunAddOnQuery(BVolume* volume, const char* predicate)
{
	// Since the new BFS supports querying for attributes without
	// an index, we only run the query if the index exists (for
	// newly mounted devices only - the Deskbar will automatically
	// create an index for every device mounted at startup).
	index_info info;
	if (!volume->KnowsQuery()
		|| fs_stat_index(volume->Device(), kStatusPredicate, &info) != 0)
		return;

	// run a new query on a specific volume and make it live
	BQuery query;
	query.SetVolume(volume);
	query.SetPredicate(predicate);
	query.Fetch();

	int32 id;
	BEntry entry;
	while (query.GetNextEntry(&entry) == B_OK) {
		// scan any entries returned
		// attempt to load them as add-ons
		// collisions are handled in LoadAddOn
		LoadAddOn(&entry, &id);
	}
}
Example #3
0
status_t
QueryEntryListCollection::FetchOneQuery(const BQuery* copyThis,
	BHandler* target, BObjectList<BQuery>* list, BVolume* volume)
{
	BQuery* query = new (nothrow) BQuery;
	if (query == NULL)
		return B_NO_MEMORY;

	// have to fake a copy constructor here because BQuery doesn't have
	// a copy constructor
	BString buffer;
	const_cast<BQuery*>(copyThis)->GetPredicate(&buffer);
	query->SetPredicate(buffer.String());

	query->SetTarget(BMessenger(target));
	query->SetVolume(volume);

	status_t result = query->Fetch();
	if (result != B_OK) {
		PRINT(("fetch error %s\n", strerror(result)));
		delete query;
		return result;
	}

	list->AddItem(query);

	return B_OK;
}
Example #4
0
bool
GeneralView::_CanFindServer(entry_ref* ref)
{
	// Try searching with be_roster
	if (be_roster->FindApp(kNotificationServerSignature, ref) == B_OK)
		return true;

	// Try with a query and take the first result
	BVolumeRoster vroster;
	BVolume volume;
	char volName[B_FILE_NAME_LENGTH];

	vroster.Rewind();

	while (vroster.GetNextVolume(&volume) == B_OK) {
		if ((volume.InitCheck() != B_OK) || !volume.KnowsQuery())
			continue;

		volume.GetName(volName);

		BQuery *query = new BQuery();
		query->SetPredicate("(BEOS:APP_SIG==\""kNotificationServerSignature"\")");
		query->SetVolume(&volume);
		query->Fetch();

		if (query->GetNextRef(ref) == B_OK)
			return true;
	}

	return false;
}
Example #5
0
void
LiveQuery::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case kMsgAddQuery:
		{
			int32 device;
			const char* predicate;
			if (message->FindInt32("volume", &device) != B_OK
				|| message->FindString("predicate", &predicate) != B_OK)
				break;

			BVolume volume(device);
			BQuery* query = new BQuery;

			// Set up the volume and predicate for the query.
			query->SetVolume(&volume);
			query->SetPredicate(predicate);
			query->SetTarget(this);

			fQueries.AddItem(query);
			_PerformQuery(*query);
			break;
		}

		case B_QUERY_UPDATE:
		{
			int32 what;
			message->FindInt32("opcode", &what);

			int32 device;
			int64 directory;
			int64 node;
			const char* name;
			message->FindInt32("device", &device);
			message->FindInt64("directory", &directory);
			message->FindInt64("node", &node);
			message->FindString("name", &name);

			switch (what) {
				case B_ENTRY_CREATED:
				{
					printf("CREATED %s\n", name);
					break;
				}
				case B_ENTRY_REMOVED:
					printf("REMOVED %s\n", name);
					break;
			}
			break;
		}

		default:
			BApplication::MessageReceived(message);
			break;
	}
}
Example #6
0
void
THeaderView::InitEmailCompletion()
{
	// get boot volume
	BVolume volume;
	BVolumeRoster().GetBootVolume(&volume);

	BQuery query;
	query.SetVolume(&volume);
	query.SetPredicate("META:email=**");
		// Due to R5 BFS bugs, you need two stars, META:email=** for the query.
		// META:email="*" will just return one entry and stop, same with
		// META:email=* and a few other variations.  Grumble.
	query.Fetch();
	entry_ref ref;

	while (query.GetNextRef (&ref) == B_OK) {
		BNode file;
		if (file.SetTo(&ref) == B_OK) {
			// Add the e-mail address as an auto-complete string.
			BString email;
			if (file.ReadAttrString("META:email", &email) >= B_OK)
				fEmailList.AddChoice(email.String());

			// Also add the quoted full name as an auto-complete string.  Can't
			// do unquoted since auto-complete isn't that smart, so the user
			// will have to type a quote mark if he wants to select someone by
			// name.
			BString fullName;
			if (file.ReadAttrString("META:name", &fullName) >= B_OK) {
				if (email.FindFirst('<') < 0) {
					email.ReplaceAll('>', '_');
					email.Prepend("<");
					email.Append(">");
				}
				fullName.ReplaceAll('\"', '_');
				fullName.Prepend("\"");
				fullName << "\" " << email;
				fEmailList.AddChoice(fullName.String());
			}

			// support for 3rd-party People apps.  Looks like a job for
			// multiple keyword (so you can have several e-mail addresses in
			// one attribute, perhaps comma separated) indices!  Which aren't
			// yet in BFS.
			for (int16 i = 2; i < 6; i++) {
				char attr[16];
				sprintf(attr, "META:email%d", i);
				if (file.ReadAttrString(attr, &email) >= B_OK)
					fEmailList.AddChoice(email.String());
			}
		}
	}
}
status_t
CDDBQuery::_OpenContentFile(const int32 &discID)
{
	// Makes sure that the lookup has a valid file to work with for the CD
	// content. Returns true if there is an existing file, false if a lookup is
	// required.

	BFile file;
	BString predicate;
	predicate << "CD:key == " << discID;
	entry_ref ref;

	BVolumeRoster roster;
	BVolume volume;
	roster.Rewind();
	while (roster.GetNextVolume(&volume) == B_OK) {
		if (volume.IsReadOnly() || !volume.IsPersistent() || !volume.KnowsAttr()
			|| !volume.KnowsQuery())
			continue;

		// make sure the volume we are looking at is indexed right
		fs_create_index(volume.Device(), "CD:key", B_INT32_TYPE, 0);

		BQuery query;
		query.SetVolume(&volume);
		query.SetPredicate(predicate.String());
		if (query.Fetch() != B_OK)
			continue;

		if (query.GetNextRef(&ref) == B_OK) 
			break;
	}

	status_t status = fCDData.Load(ref);
	if (status == B_NO_INIT) {
		// We receive this error when the Load() function couldn't load the
		// track times This just means that we get it from the SCSI data given
		// to us in SetToCD
		vector<CDAudioTime> times;
		GetTrackTimes(&fSCSIData,times);

		for (int32 i = 0; i < fCDData.CountTracks(); i++) {
			CDAudioTime *item = fCDData.TrackTimeAt(i);
			*item = times[i + 1] - times[i];
		}

		status = B_OK;
	}

	return status;
}
Example #8
0
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;
}
Example #9
0
BPopUpMenu*
TPrefsWindow::_BuildSignatureMenu(char* sig)
{
	char name[B_FILE_NAME_LENGTH];
	BEntry entry;
	BFile file;
	BMenuItem* item;
	BMessage* msg;
	BQuery query;
	BVolume vol;
	BVolumeRoster volume;

	BPopUpMenu* menu = new BPopUpMenu("");

	msg = new BMessage(P_SIG);
	msg->AddString("signature", B_TRANSLATE("None"));
	menu->AddItem(item = new BMenuItem(B_TRANSLATE("None"), msg));
	if (!strcmp(sig, B_TRANSLATE("None")))
		item->SetMarked(true);

	msg = new BMessage(P_SIG);
	msg->AddString("signature", B_TRANSLATE("Random"));
	menu->AddItem(item = new BMenuItem(B_TRANSLATE("Random"), msg));
	if (!strcmp(sig, B_TRANSLATE("Random")))
		item->SetMarked(true);
	menu->AddSeparatorItem();

	volume.GetBootVolume(&vol);
	query.SetVolume(&vol);
	query.SetPredicate("_signature = *");
	query.Fetch();

	while (query.GetNextEntry(&entry) == B_NO_ERROR) {
		file.SetTo(&entry, O_RDONLY);
		if (file.InitCheck() == B_NO_ERROR) {
			msg = new BMessage(P_SIG);
			file.ReadAttr("_signature", B_STRING_TYPE, 0, name, sizeof(name));
			msg->AddString("signature", name);
			menu->AddItem(item = new BMenuItem(name, msg));
			if (!strcmp(sig, name))
				item->SetMarked(true);
		}
	}
	return menu;
}
Example #10
0
void
Feeder::AddQuery(BVolume *volume)
{
	fVolumeList.AddItem((void*)volume) ;

	BQuery *query = new BQuery ;	
	query->SetVolume(volume) ;
	
	// query->SetPredicate("name = *.txt") ;
	query->SetPredicate("last_modified > %now%") ;
	query->SetTarget(this) ;
	
	if (query->Fetch() == B_OK) {
		RetrieveStaticRefs(query) ;
		fQueryList.AddItem((void *)query) ;
	} else
		delete query ;
}
void
MusicCollectionWindow::_StartNewQuery()
{
	fQueryReader->Reset();
	fQueryHandler->Reset();

	BString orgString = fQueryField->Text();
	((ListViewListener<FileListItem>*)fEntryViewInterface)->SetQueryString(
		orgString);

	BVolume volume;
	//BVolumeRoster().GetBootVolume(&volume);
	BVolumeRoster roster;
	while (roster.GetNextVolume(&volume) == B_OK) {
		if (!volume.KnowsQuery())
			continue;
		BQuery* query = _CreateQuery(orgString);
		query->SetVolume(&volume);
		fQueryReader->AddQuery(query);
	}

	fQueryReader->Run();
}
Example #12
0
int
main(int argc, char** argv)
{
	if (argc < 2) {
		fprintf(stderr, "usage: %s <message-code>\n", __progname);
		return -1;
	}

	int32 number = atol(argv[1]);

	BQuery query;
	query.SetPredicate("name=ServerProtocol.h");

	// search on current volume only
	dev_t device = dev_for_path(".");
	BVolume volume(device);

	query.SetVolume(&volume);
	query.Fetch();

	status_t status;
	BEntry entry;
	while ((status = query.GetNextEntry(&entry)) == B_OK) {
		BPath path(&entry);
		puts(path.Path());
		if (strstr(path.Path(), "headers/private/app/ServerProtocol.h") != NULL) {
			print_code(path, number);
			break;
		}
	}

	if (status != B_OK) {
		fprintf(stderr, "%s: could not find ServerProtocol.h", __progname);
		return -1;
	}
	return 0;
}
Example #13
0
void
Feeder::RemoveQuery(BVolume *volume)
{
	BQuery *query ;
	BVolume* iter_volume ;
	
	for(int i = 0 ; (iter_volume = (BVolume*)fVolumeList.ItemAt(i)) != NULL
		; i++) {
			if (iter_volume->Device() == volume->Device()) {
				fVolumeList.RemoveItem(iter_volume) ;
				break ;
			}
	}

	for (int i = 0 ; (query = (BQuery*)fQueryList.ItemAt(i)) != NULL ; i++) {
		if (volume->Device() == query->TargetDevice()) {
			query->Clear() ;
			fQueryList.RemoveItem(query) ;
			delete query ;
			delete volume ;
			break ;
		}
	}
}
Example #14
0
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
}
Example #15
0
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;
}
Example #16
0
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;
}
Example #17
0
void
QueryView::GetInitialEntries()
{	
	fEntryCount = 0;	
	entry_ref ref;

//	slaad
	BNode n(&ref);
	vollist vols;
	
	ExtractQueryVolumes(&n, &vols);
	vollist::iterator vIt;
	
	for (vIt = vols.begin(); vIt != vols.end(); vIt++) {
		BQuery *query = new BQuery();
		query->SetVolume(&(*vIt));
		query->SetPredicate(fPredicate.String());
		query->SetTarget(this);
		query->Fetch();
	
		while( query->GetNextRef(&ref) == B_OK )
		{
			// eiman
			BEntry entry(&ref);
			node_ref node;
			entry.GetNodeRef(&node);
			
			BMessage msg;
			msg.AddInt32("opcode",B_ENTRY_CREATED);
			msg.AddString("name",ref.name);
			msg.AddInt64("directory",ref.directory);
			msg.AddInt32("device",ref.device);
			msg.AddInt64("node",node.node);
			if ( !ShouldIgnore(&msg) )
			{
				fEntryCount++;
			}
		}
		
		fQueries.push_back(query);
	};
	
	#ifdef DEBUG
	BeDC dc("QueryWatcher");
	BString str;
	str<<Name()<<" initial count: "<<fEntryCount;
	dc.SendMessage(str.String());
	#endif

	UpdateDisplay();
}
Example #18
0
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;
}
/*!	\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
Example #20
0
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;
}
Example #21
0
void
PersonView::BuildGroupMenu()
{
	if (fGroups == NULL)
		return;

	BMenuItem* item;
	while ((item = fGroups->ItemAt(0)) != NULL) {
		fGroups->RemoveItem(item);
		delete item;
	}

	int32 count = 0;

	BVolumeRoster volumeRoster;
	BVolume volume;
	while (volumeRoster.GetNextVolume(&volume) == B_OK) {
		BQuery query;
		query.SetVolume(&volume);

		char buffer[256];
		snprintf(buffer, sizeof(buffer), "%s=*", fCategoryAttribute.String());
		query.SetPredicate(buffer);
		query.Fetch();

		BEntry entry;
		while (query.GetNextEntry(&entry) == B_OK) {
			BFile file(&entry, B_READ_ONLY);
			attr_info info;

			if (file.InitCheck() == B_OK
				&& file.GetAttrInfo(fCategoryAttribute, &info) == B_OK
				&& info.size > 1) {
				if (info.size > (off_t)sizeof(buffer))
					info.size = sizeof(buffer);

				if (file.ReadAttr(fCategoryAttribute.String(), B_STRING_TYPE,
						0, buffer, info.size) < 0) {
					continue;
				}

				const char *text = buffer;
				while (true) {
					char* offset = strstr(text, ",");
					if (offset != NULL)
						offset[0] = '\0';

					if (!fGroups->FindItem(text)) {
						int32 index = 0;
						while ((item = fGroups->ItemAt(index)) != NULL) {
							if (strcmp(text, item->Label()) < 0)
								break;
							index++;
						}
						BMessage* message = new BMessage(M_GROUP_MENU);
						message->AddString("group", text);
						fGroups->AddItem(new BMenuItem(text, message), index);
						count++;
					}
					if (offset) {
						text = offset + 1;
						while (*text == ' ')
							text++;
					}
					else
						break;
				}
			}
		}
	}

	if (count == 0) {
		fGroups->AddItem(item = new BMenuItem(
			B_TRANSLATE_CONTEXT("none", "Groups list"),
			new BMessage(M_GROUP_MENU)));
		item->SetEnabled(false);
	}

	fGroups->SetTargetForItems(this);
}
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);
}
int
main(int argc, char* argv[])
{
	team_info teamInfo;
	int32 cookie = 0;
	while (get_next_team_info(&cookie, &teamInfo) == B_OK) {
		if (!strncmp(teamInfo.args, "/boot/beos/", 11)
			|| !strncmp(teamInfo.args, "/boot/system/", 13)) {
			// this is a system component and not worth to investigate
			continue;
		}

		thread_info threadInfo;
		int32 threadCookie = 0;
		while (get_next_thread_info(teamInfo.team, &threadCookie, &threadInfo)
				== B_OK) {
			// search for the roster thread
			if (!strcmp(threadInfo.name, "_roster_thread_")) {
				port_id port = find_port("haiku-test:roster");
				port_info portInfo;
				if (get_port_info(port, &portInfo) == B_OK
					&& portInfo.team == teamInfo.team) {
					puts("The Haiku Registrar is already running.");
					return 0;
				}
			}
		}
	}

	// the Haiku registrar doesn't seem to run yet, change this

	BPath currentPath(".");

	BQuery query;
	query.SetPredicate("name==test_registrar");

	// search on current volume only
	dev_t device = dev_for_path(".");
	BVolume volume(device);

	query.SetVolume(&volume);
	query.Fetch();

	entry_ref ref;
	while (query.GetNextRef(&ref) == B_OK) {
		BPath path(&ref);
		if (path.InitCheck() != B_OK)
			continue;

		const char* registrarPath = path.Path();
		const char* generatedPath = strstr(registrarPath, "generated");
		if (generatedPath == NULL)
			continue;

		if (!strncmp(currentPath.Path(), registrarPath, generatedPath - registrarPath)) {
			// gotcha!
			if (launch_registrar(registrarPath) == B_OK)
				return 0;
		}
	}

	// As a fallback (maybe the volume does not support queries for example)
	// try to find the test_registrar in the current folder...
	BString registrarPath(argv[0]);
	registrarPath.RemoveLast(__progname);
	registrarPath.Append("test_registrar");
	if (launch_registrar(registrarPath.String()) == B_OK)
		return 0;

	fprintf(stderr, "%s: Could not find the Haiku Registrar.\n"
		"    (This tool only works when used in the Haiku tree, but maybe\n"
		"    the registrar just needs to be built.)\n",
		__progname);
	return -1;
}
Example #24
0
/***********************************************************
 * InitGUI
 ***********************************************************/
void
HAddressView::InitGUI()
{
	float divider = StringWidth(_("Subject:")) + 20;
	divider = max_c(divider , StringWidth(_("From:"))+20);
	divider = max_c(divider , StringWidth(_("To:"))+20);
	divider = max_c(divider , StringWidth(_("Bcc:"))+20);
	
	BRect rect = Bounds();
	rect.top += 5;
	rect.left += 20 + divider;
	rect.right = Bounds().right - 5;
	rect.bottom = rect.top + 25;
	
	BTextControl *ctrl;
	ResourceUtils rutils;
	const char* name[] = {"to","subject","from","cc","bcc"};
	
	for(int32 i = 0;i < 5;i++)
	{
		ctrl = new BTextControl(BRect(rect.left,rect.top
								,(i == 1)?rect.right+divider:rect.right
								,rect.bottom)
								,name[i],"","",NULL
								,B_FOLLOW_LEFT_RIGHT|B_FOLLOW_TOP,B_WILL_DRAW|B_NAVIGABLE);
		
		if(i == 1)
		{
			ctrl->SetLabel(_("Subject:"));
			ctrl->SetDivider(divider);
			ctrl->MoveBy(-divider,0);
		}else{
			ctrl->SetDivider(0);
		}
		BMessage *msg = new BMessage(M_MODIFIED);
		msg->AddPointer("pointer",ctrl);
		ctrl->SetModificationMessage(msg);
		ctrl->SetEnabled(!fReadOnly);
		AddChild(ctrl);
	
		rect.OffsetBy(0,25);
		switch(i)
		{
		case 0:
			fTo = ctrl;
			break;
		case 1:
			fSubject = ctrl;
			break;
		case 2:
			fFrom = ctrl;
			fFrom->SetEnabled(false);
			fFrom->SetFlags(fFrom->Flags() & ~B_NAVIGABLE);
			break;
		case 3:
			fCc = ctrl;
			break;
		case 4:
			fBcc = ctrl;
			break;
		}
	}
	//
	BRect menuRect= Bounds();
	menuRect.top += 5;
	menuRect.left += 22;
	menuRect.bottom = menuRect.top + 25;
	menuRect.right = menuRect.left + 16;
	
	BMenu *toMenu = new BMenu(_("To:"));
	BMenu *ccMenu = new BMenu(_("Cc:"));
	BMenu *bccMenu = new BMenu(_("Bcc:"));
	BQuery query;
	BVolume volume;
	BVolumeRoster().GetBootVolume(&volume);
	query.SetVolume(&volume);
	query.SetPredicate("((META:email=*)&&(BEOS:TYPE=application/x-person))");

	if(!fReadOnly && query.Fetch() == B_OK)
	{
		BString addr[4],name,group,nick;
		entry_ref ref;
		BList peopleList;
	
	
		while(query.GetNextRef(&ref) == B_OK)
		{
			BNode node(&ref);
			if(node.InitCheck() != B_OK)
				continue;
			
			ReadNodeAttrString(&node,"META:name",&name);		
			ReadNodeAttrString(&node,"META:email",&addr[0]);
			ReadNodeAttrString(&node,"META:email2",&addr[1]);
			ReadNodeAttrString(&node,"META:email3",&addr[2]);
			ReadNodeAttrString(&node,"META:email4",&addr[3]);
			ReadNodeAttrString(&node,"META:group",&group);
			ReadNodeAttrString(&node,"META:nickname",&nick);
			
			for(int32 i = 0;i < 4;i++)
			{
				if(addr[i].Length() > 0)
				{
					if(nick.Length() > 0)
					{
						nick += " <";
						nick += addr[i];
						nick += ">";
						fAddrList.AddItem(strdup(nick.String()));
					}
					fAddrList.AddItem(strdup(addr[i].String()));
					
					BString title = name;
					title << " <" << addr[i] << ">";
				
					AddPersonToList(peopleList,title.String(),group.String());
				}
			}
		}
		
		// Sort people data
		peopleList.SortItems(HAddressView::SortPeople);
		// Build menus
		BTextControl *control[3] = {fTo,fCc,fBcc};
		BMenu *menus[3] = {toMenu,ccMenu,bccMenu};
		int32 count = peopleList.CountItems();
		PersonData *data;
		bool needSeparator = false;
		bool hasSeparator = false;
		for(int32 k = 0;k < 3;k++)
		{
			for(int32 i = 0;i < count;i++)
			{
				BMessage *msg = new BMessage(M_ADDR_MSG);
				msg->AddPointer("pointer",control[k]);
				data =  (PersonData*)peopleList.ItemAt(i);
				msg->AddString("email",data->email);
				if(needSeparator && !hasSeparator && strlen(data->group) == 0)
				{
					menus[k]->AddSeparatorItem();
					hasSeparator = true;
				}else
					needSeparator = true;
				AddPerson(menus[k],data->email,data->group,msg,0,0);
			}
			hasSeparator = false;
			needSeparator = false;
		}
		// free all data
		while(count > 0)
		{
			data =  (PersonData*)peopleList.RemoveItem(--count);
			free(data->email);
			free(data->group);
			delete data;
		}
	}
	BMenuField *field = new BMenuField(menuRect,"ToMenu","",toMenu,
							B_FOLLOW_TOP|B_FOLLOW_LEFT,B_WILL_DRAW);
	field->SetDivider(0);
	field->SetEnabled(!fReadOnly);
	AddChild(field);
	
	rect = menuRect;
	rect.OffsetBy(0,28);
	rect.left = Bounds().left + 5;
	rect.right = rect.left + 16;
	rect.top += 26;
	rect.bottom = rect.top + 16;
	ArrowButton *arrow = new ArrowButton(rect,"addr_arrow"
										,new BMessage(M_EXPAND_ADDRESS));
	AddChild(arrow);
	//==================== From menu
	BMenu *fromMenu = new BMenu(_("From:"));
	BPath path;
	::find_directory(B_USER_SETTINGS_DIRECTORY,&path);
	path.Append(APP_NAME);
	path.Append("Accounts");
	BDirectory dir(path.Path());
	BEntry entry;
	status_t err = B_OK;
	int32 account_count = 0;
	while(err == B_OK)
	{
		if((err = dir.GetNextEntry(&entry)) == B_OK && !entry.IsDirectory())
		{
			char name[B_FILE_NAME_LENGTH+1];
			entry.GetName(name);
			BMessage *msg = new BMessage(M_ACCOUNT_CHANGE);
			msg->AddString("name",name);
			BMenuItem *item = new BMenuItem(name,msg);
			fromMenu->AddItem(item);
			item->SetTarget(this,Window());
			account_count++;
		}
	}
	if(account_count != 0)
	{
		int32 smtp_account;
		((HApp*)be_app)->Prefs()->GetData("smtp_account",&smtp_account);
		BMenuItem *item(NULL);
		if(account_count > smtp_account)
			item = fromMenu->ItemAt(smtp_account);
		if(!item)
			item = fromMenu->ItemAt(0);
		if(item)
		{
			ChangeAccount(item->Label());
			item->SetMarked(true);
		}
	}else{
		(new BAlert("",_("Could not find mail accounts"),_("OK"),NULL,NULL,B_WIDTH_AS_USUAL,B_INFO_ALERT))->Go();
		Window()->PostMessage(B_QUIT_REQUESTED);
	}
	fromMenu->SetRadioMode(true);
	
	menuRect.OffsetBy(0,25*2);
	field = new BMenuField(menuRect,"FromMenu","",fromMenu,
							B_FOLLOW_TOP|B_FOLLOW_LEFT,B_WILL_DRAW);
	field->SetDivider(0);
	
	AddChild(field);
	//=================== CC menu
	menuRect.OffsetBy(0,25);
	field = new BMenuField(menuRect,"CcMenu","",ccMenu,
							B_FOLLOW_TOP|B_FOLLOW_LEFT,B_WILL_DRAW);
	field->SetDivider(0);
	field->SetEnabled(!fReadOnly);
	AddChild(field);

	//=================== BCC menu	
	menuRect.OffsetBy(0,25);
	field = new BMenuField(menuRect,"BccMenu","",bccMenu,
							B_FOLLOW_TOP|B_FOLLOW_LEFT,B_WILL_DRAW);
	field->SetDivider(0);
	field->SetEnabled(!fReadOnly);
	AddChild(field);
	

}
Example #25
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 (file.ReadAttrString("META:group", &groups) < B_OK || groups.Length() == 0)
			continue;

		BString address;
		file.ReadAttrString("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;
	}
}
Example #26
0
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);
}
Example #27
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();
}
Example #28
0
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);
	}
}
Example #29
0
bool duplicates_exist (const char * signature)
{
	BVolumeRoster	roster;
	BVolume			volume;
	BQuery			query;
	BString			query_string	=	"BEOS:APP_SIG=";
	BEntry			entry;
	mode_t			permissions;
	uid_t			owner;
	gid_t			group;
	int32			query_hits		=	0;
	
	query_string += signature;
	
	while (roster.GetNextVolume(& volume) == B_OK)
	{
		if (volume.KnowsQuery())
		{
			PRINT(("volume.KnowsQuery()\n"));
			
			char volname [B_FILE_NAME_LENGTH];
			volume.GetName(volname);
			PRINT(("volume: %s\n", volname));
			
			query.Clear();
			
			if (query.SetVolume(& volume) == B_OK)
			{
				PRINT(("query.SetVolume(& volume) == B_OK\n"));
			
				if (query.SetPredicate(query_string.String()) == B_OK)
				{
					PRINT(("query.SetPredicate(%s) == B_OK\n", query_string.String()));
				
					if (query.Fetch() == B_OK)
					{
						PRINT(("query.Fetch() == B_OK\n"));
					
						while (query.GetNextEntry(& entry) == B_OK)
						{
							PRINT(("query.GetNextEntry(& entry) == B_OK\n"));
							
							entry.GetPermissions(& permissions);
							entry.GetOwner(& owner);
							entry.GetGroup(& group);
							
							BPath path (& entry);

							// if (access(path.Path(), X_OK))

							if	(((owner == getuid()) && (permissions & S_IXUSR))
							||	((group == getgid()) && (permissions & S_IXGRP))
							||	(permissions & S_IXOTH))
							{
								PRINT(("path is executable: %s\n", path.Path()));
								query_hits++;
							}
							else
							{
								PRINT(("path is NOT executable: %s\n", path.Path()));
							}
						}
					}
				}
			}
		}
	
		fflush(stdout);
	}
	
	if (query_hits > 1)
		return true;
	else
		return false;
}
Example #30
0
QueryEntryListCollection::QueryEntryListCollection(Model* model,
	BHandler* target, PoseList* oldPoseList)
	:	fQueryListRep(new QueryListRep(new BObjectList<BQuery>(5, true)))
{
	Rewind();
	attr_info info;
	BQuery query;

	if (!model->Node()) {
		fStatus = B_ERROR;
		return;
	}

	// read the actual query string
	fStatus = model->Node()->GetAttrInfo(kAttrQueryString, &info);
	if (fStatus != B_OK)
		return;

	BString buffer;
	if (model->Node()->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(model->Node(), 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 (model->Node()->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 (model->Node()->GetAttrInfo(kAttrQueryVolume, &info) == B_OK) {
		char* buffer = NULL;

		if ((buffer = (char*)malloc((size_t)info.size)) != NULL
			&& model->Node()->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;
}