예제 #1
0
파일: jLayer.cpp 프로젝트: RankoR/mqutim
void jLayer::removeAccount(const QString &account_name)
{
	QSettings settings(QSettings::NativeFormat, QSettings::UserScope, "qutim/qutim."+m_profile_name, "jabbersettings");
	QStringList accounts = settings.value("accounts/list").toStringList();
	accounts.removeAll(account_name);
	accounts.sort();
	settings.setValue("accounts/list", accounts);
	killAccount(account_name);
	QSettings dir_settings_path(QSettings::NativeFormat, QSettings::UserScope, "qutim/qutim."+m_profile_name+"/jabber."+account_name, "profilesettings");
	QDir account_dir(dir_settings_path.fileName());
	account_dir.cdUp();

	if(account_dir.exists())
		removeProfileDir(account_dir.path());
}
예제 #2
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;
}