**
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
*/
#include <MailPrivate.h>
#include <stdio.h>
#include <Autolock.h>
#include <Directory.h>
#include <Entry.h>
#include <File.h>
#include <FindDirectory.h>
#include <Locker.h>
#include <Messenger.h>
#include <Path.h>
#include <String.h>
#define timeout 5e5
namespace BPrivate {
BPath
default_mail_directory()
{
BPath path;
if (find_directory(B_USER_DIRECTORY, &path) == B_OK)
path.Append("mail");
else
path.SetTo("/boot/home/mail/");
return path;
}
BPath
default_mail_in_directory()
{
BPath path = default_mail_directory();
path.Append("in");
return path;
}
BPath
default_mail_out_directory()
{
BPath path = default_mail_directory();
path.Append("out");
return path;
}
status_t
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;
}
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;
}
}
ret = B_TIMED_OUT;
while (system_time() - now < timeout)
{
ret = tmpfile.SetTo(&settings_entry, B_WRITE_ONLY | B_CREATE_FILE);
if (ret != B_BUSY) break;
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;
}
ret = B_TIMED_OUT;
while (system_time() - now < timeout)
{
ret = tmpfile.Lock();
if (ret != B_BUSY) break;
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));
return ret==B_BUSY? B_TIMED_OUT:ret;
}
tmpfile.SetSize(0);
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;
}
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;
}
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;
}
}