Esempio n. 1
0
status_t
Model::_SaveHistory(const BList& items) const
{
	BFile file;
	status_t status = _OpenFile(&file, PREFS_FILE,
		B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE,
		B_USER_SETTINGS_DIRECTORY, NULL);
	if (status != B_OK)
		return status;

	status = file.Lock();
	if (status != B_OK)
		return status;

	BMessage message;
	int32 count = items.CountItems();
	for (int32 i = 0; i < count; i++) {
		BString* string = static_cast<BString*>(items.ItemAtFast(i));

		if (message.AddString("string", string->String()) != B_OK)
			break;
	}

	status = message.Flatten(&file);
	file.SetSize(message.FlattenedSize());
	file.Sync();
	file.Unlock();

	return status;
}
Esempio n. 2
0
bool
Model::_LoadHistory(BList& items) const
{
	BFile file;
	status_t status = _OpenFile(&file, PREFS_FILE);
	if (status != B_OK)
		return false;

	status = file.Lock();
	if (status != B_OK)
		return false;

	BMessage message;
	status = message.Unflatten(&file);
	if (status != B_OK)
		return false;

	file.Unlock();

	BString string;
	for (int32 x = 0; message.FindString("string", x, &string) == B_OK; x++) {
		BString* copy = new (nothrow) BString(string);
		if (copy == NULL || !items.AddItem(copy)) {
			delete copy;
			break;
		}
	}

	return true;
}
Esempio n. 3
0
status_t
Model::LoadPrefs()
{
	BFile file;
	status_t status = _OpenFile(&file, PREFS_FILE);
	if (status != B_OK)
		return status;

	status = file.Lock();
	if (status != B_OK)
		return status;

	int32 value;

	if (file.ReadAttr("RecurseDirs", B_INT32_TYPE, 0, &value,
			sizeof(int32)) > 0)
		fRecurseDirs = (value != 0);

	if (file.ReadAttr("RecurseLinks", B_INT32_TYPE, 0, &value,
			sizeof(int32)) > 0)
		fRecurseLinks = (value != 0);

	if (file.ReadAttr("SkipDotDirs", B_INT32_TYPE, 0, &value,
			sizeof(int32)) > 0)
		fSkipDotDirs = (value != 0);

	if (file.ReadAttr("CaseSensitive", B_INT32_TYPE, 0, &value,
			sizeof(int32)) > 0)
		fCaseSensitive = (value != 0);

	if (file.ReadAttr("EscapeText", B_INT32_TYPE, 0, &value, sizeof(int32)) > 0)
		fEscapeText = (value != 0);

	if (file.ReadAttr("TextOnly", B_INT32_TYPE, 0, &value, sizeof(int32)) > 0)
		fTextOnly = (value != 0);

	if (file.ReadAttr("InvokePe", B_INT32_TYPE, 0, &value, sizeof(int32)) > 0)
		fInvokePe = (value != 0);

	if (file.ReadAttr("ShowContents", B_INT32_TYPE, 0, &value,
			sizeof(int32)) > 0)
		fShowContents = (value != 0);

	char buffer [B_PATH_NAME_LENGTH+1];
	int32 length = file.ReadAttr("FilePanelPath", B_STRING_TYPE, 0, &buffer,
		sizeof(buffer));
	if (length > 0) {
		buffer[length] = '\0';
		fFilePanelPath = buffer;
	}

	file.ReadAttr("WindowFrame", B_RECT_TYPE, 0, &fFrame, sizeof(BRect));

	if (file.ReadAttr("Encoding", B_INT32_TYPE, 0, &value, sizeof(int32)) > 0)
		fEncoding = value;

	file.Unlock();

	return B_OK;
}
void BMailRemoteStorageProtocol::SyncMailbox(const char *mailbox) {
	BPath path(runner->Chain()->MetaData()->FindString("path"));
	path.Append(mailbox);
	
	BDirectory folder(path.Path());
	
	BEntry entry;
	BFile snoodle;
	BString string;
	uint32 chain;
	bool append;
	
	while (folder.GetNextEntry(&entry) == B_OK) {
		if (!entry.IsFile())
			continue;
		while (snoodle.SetTo(&entry,B_READ_WRITE) == B_BUSY) snooze(100);
		append = false;
		
		while (snoodle.Lock() != B_OK) snooze(100);
		snoodle.Unlock();
		
		if (snoodle.ReadAttr("MAIL:chain",B_INT32_TYPE,0,&chain,sizeof(chain)) < B_OK)
			append = true;
		if (chain != runner->Chain()->ID())
			append = true;
		if (snoodle.ReadAttrString("MAIL:unique_id",&string) < B_OK)
			append = true;

		BString folder(string), id("");
		int32 j = string.FindLast('/');
		if ((!append) && (j >= 0)) {
			folder.Truncate(j);
			string.CopyInto(id,j + 1,string.Length());
			if (folder == mailbox)
				continue;
		} else {
			append = true;
		}
		
		if (append)
			AddMessage(mailbox,&snoodle,&id); //---We should check for partial messages here
		else
			CopyMessage(folder.String(),mailbox,&id);
			
		string = mailbox;
		string << '/' << id;
		/*snoodle.RemoveAttr("MAIL:unique_id");
		snoodle.RemoveAttr("MAIL:chain");*/
		chain = runner->Chain()->ID();
		snoodle.WriteAttr("MAIL:chain",B_INT32_TYPE,0,&chain,sizeof(chain));
		snoodle.WriteAttrString("MAIL:unique_id",&string);
		(*manifest) += string.String();
		(*unique_ids) += string.String();
		string = runner->Chain()->Name();
		snoodle.WriteAttrString("MAIL:account",&string);
	}
}
Esempio n. 5
0
status_t
Model::SavePrefs()
{
	BFile file;
	status_t status = _OpenFile(&file, PREFS_FILE,
		B_CREATE_FILE | B_WRITE_ONLY);
	if (status != B_OK)
		return status;

	status = file.Lock();
	if (status != B_OK)
		return status;

	int32 value = 2;
	file.WriteAttr("Version", B_INT32_TYPE, 0, &value, sizeof(int32));

	value = fRecurseDirs ? 1 : 0;
	file.WriteAttr("RecurseDirs", B_INT32_TYPE, 0, &value, sizeof(int32));

	value = fRecurseLinks ? 1 : 0;
	file.WriteAttr("RecurseLinks", B_INT32_TYPE, 0, &value, sizeof(int32));

	value = fSkipDotDirs ? 1 : 0;
	file.WriteAttr("SkipDotDirs", B_INT32_TYPE, 0, &value, sizeof(int32));

	value = fCaseSensitive ? 1 : 0;
	file.WriteAttr("CaseSensitive", B_INT32_TYPE, 0, &value, sizeof(int32));

	value = fRegularExpression ? 1 : 0;
	file.WriteAttr("RegularExpression", B_INT32_TYPE, 0, &value, sizeof(int32));

	value = fTextOnly ? 1 : 0;
	file.WriteAttr("TextOnly", B_INT32_TYPE, 0, &value, sizeof(int32));

	value = fInvokeEditor ? 1 : 0;
	file.WriteAttr("InvokeEditor", B_INT32_TYPE, 0, &value, sizeof(int32));

	file.WriteAttr("WindowFrame", B_RECT_TYPE, 0, &fFrame, sizeof(BRect));

	file.WriteAttr("FilePanelPath", B_STRING_TYPE, 0, fFilePanelPath.String(),
		fFilePanelPath.Length() + 1);

	value = fShowLines ? 1 : 0;
	file.WriteAttr("ShowLines", B_INT32_TYPE, 0, &value, sizeof(int32));

	file.WriteAttr("Encoding", B_INT32_TYPE, 0, &fEncoding, sizeof(int32));

	file.Sync();
	file.Unlock();

	return B_OK;
}
Esempio n. 6
0
status_t MailInternal::WriteMessageFile(const BMessage& archive, const BPath& path, const char* name)
{
	status_t ret = B_OK;
	BString leaf = name;
	leaf << ".tmp";
	
	BEntry settings_entry;
	BFile tmpfile;
	bigtime_t now = system_time();
	
	create_directory(path.Path(), 0777);
	{
		BDirectory account_dir(path.Path());
		ret = account_dir.InitCheck();
		if (ret != B_OK)
		{
			fprintf(stderr, "Couldn't open '%s': %s\n",
				path.Path(), strerror(ret));
			return ret;
		}
		
		// get an entry for the tempfile
		// Get it here so that failure doesn't create any problems
		ret = settings_entry.SetTo(&account_dir,leaf.String());
		if (ret != B_OK)
		{
			fprintf(stderr, "Couldn't create an entry for '%s/%s': %s\n",
				path.Path(), leaf.String(), strerror(ret));
			return ret;
		}
	}
	
	//
	// Save to a temporary file
	//
	
	// Our goal is to write to a tempfile and then use 'rename' to
	// link that file into place once it contains valid contents.
	// Given the filesystem's guarantee of atomic "rename" oper-
	// ations this will guarantee that any non-temp files in the
	// config directory are valid configuration files.
	//
	// Ideally, we would be able to do the following:
	//   BFile tmpfile(&account_dir, "tmpfile", B_WRITE_ONLY|B_CREATE_FILE);
	//   // ...
	//   tmpfile.Relink(&account_dir,"realfile");
	// But this doesn't work because there is no way in the API
	// to link based on file descriptor.  (There should be, for
	// exactly this reason, and I see no reason that it can not
	// be added to the API, but as it is not present now so we'll
	// have to deal.)  It has to be file-descriptor based because
	// (a) all a BFile knows is its node/FD and (b) the file may
	// be unlinked at any time, at which point renaming the entry
	// to clobber the "realfile" will result in an invalid con-
	// figuration file being created.
	//
	// We can't count on not clobbering the tempfile to gain
	// exclusivity because, if the system crashes between when
	// we create the tempfile an when we rename it, we will have
	// a zombie tempfile that will prevent us from doing any more
	// saves.
	//
	// What we can do is:
	//
	//    Create or open the tempfile
	//    // At this point no one will *clobber* the file, but
	//    // others may open it
	//    Lock the tempfile
	//    // At this point, no one else may open it and we have
	//    // exclusive access to it.  Because of the above, we
	//    // know that our entry is still valid
	//
	//    Truncate the tempfile
	//    Write settings
	//    Sync
	//    Rename to the realfile
	//    // this does not affect the lock, but now open-
	//    // ing the realfile will fail with B_BUSY
	//    Unlock
	//
	// If this code is the only code that changes these files,
	// then we are guaranteed that all realfiles will be valid
	// settings files.  I think that's the best we can do unless
	// we get the Relink() api.  An implementation of the above
	// follows.
	//
	
	// Create or open
	ret = B_TIMED_OUT;
	while (system_time() - now < timeout) //-ATT-no timeout arg. Setting by #define
	{
		ret = tmpfile.SetTo(&settings_entry, B_WRITE_ONLY | B_CREATE_FILE);
		if (ret != B_BUSY) break;
		
		// wait 1/100th second
		snooze((bigtime_t)1e4);
	}
	if (ret != B_OK)
	{
		fprintf(stderr, "Couldn't open '%s/%s' within the timeout period (%fs): %s\n",
			path.Path(), leaf.String(), (float)timeout/1e6, strerror(ret));
		return ret==B_BUSY? B_TIMED_OUT:ret;
	}
	
	// lock
	ret = B_TIMED_OUT;
	while (system_time() - now < timeout)
	{
		ret = tmpfile.Lock(); //-ATT-changed account_file to tmpfile. Is that allowed?
		if (ret != B_BUSY) break;
		
		// wait 1/100th second
		snooze((bigtime_t)1e4);
	}
	if (ret != B_OK)
	{
		fprintf(stderr, "Couldn't lock '%s/%s' in within the timeout period (%fs): %s\n",
			path.Path(), leaf.String(), (float)timeout/1e6, strerror(ret));
		// Can't remove it here, since it might be someone else's.
		// Leaving a zombie shouldn't cause any problems tho so
		// that's OK.
		return ret==B_BUSY? B_TIMED_OUT:ret;
	}
	
	// truncate
	tmpfile.SetSize(0);
	
	// write
	ret = archive.Flatten(&tmpfile);
	if (ret != B_OK)
	{
		fprintf(stderr, "Couldn't flatten settings to '%s/%s': %s\n",
			path.Path(), leaf.String(), strerror(ret));
		return ret;
	}
	
	// ensure it's actually writen
	ret = tmpfile.Sync();
	if (ret != B_OK)
	{
		fprintf(stderr, "Couldn't sync settings to '%s/%s': %s\n",
			path.Path(), leaf.String(), strerror(ret));
		return ret;
	}
	
	// clobber old settings
	ret = settings_entry.Rename(name,true);
	if (ret != B_OK)
	{
		fprintf(stderr, "Couldn't clobber old settings '%s/%s': %s\n",
			path.Path(), name, strerror(ret));
		return ret;
	}
	
	return B_OK;
}