/*
* read in the .imp file, or make one if it doesn't exist.
* make sure all flags and uids are consistent.
* return the mailbox lock.
*/
static Mblock*
openimp(Box *box, int new)
{
char buf[ERRMAX];
int fd;
Biobuf b;
Mblock *ml;
Qid qid;
/*
* mailbox is unreachable, so mark all messages expunged
* clean up .imp files as well.
*/
static void
mboxgone(Box *box)
{
char buf[ERRMAX];
Msg *m;
/*
* read messages in the mailbox
* mark message that no longer exist as expunged
* returns -1 for failure, 0 if no new messages, 1 if new messages.
*/
enum {
Gone = 2, /* don't unexpunge messages */
};
static int
readbox(Box *box)
{
char buf[ERRMAX];
int i, n, fd, new, id;
Dir *d;
Msg *m, *last;
static void
sequence(Box *box)
{
Msg **a, *m;
int n, i;
n = 0;
for(m = box->msgs; m; m = m->next)
n++;
a = ezmalloc(n * sizeof *a);
i = 0;
for(m = box->msgs; m; m = m->next)
a[i++] = m;
qsort(a, n, sizeof *a, uidcmp);
for(i = 0; i < n - 1; i++)
a[i]->next = a[i + 1];
for(i = 0; i < n; i++)
if(a[i]->seq && a[i]->seq != i + 1)
bye("internal error assigning message numbers");
else
a[i]->seq = i + 1;
box->msgs = nil;
if(n > 0){
a[n - 1]->next = nil;
box->msgs = a[0];
}
box->max = n;
memset(a, 0, n*sizeof *a);
free(a);
}
/*
* strategy:
* every mailbox file has an associated .imp file
* which maps upas/fs message digests to uids & message flags.
*
* the .imp files are locked by /mail/fs/usename/L.mbox.
* whenever the flags can be modified, the lock file
* should be opened, thereby locking the uid & flag state.
* for example, whenever new uids are assigned to messages,
* and whenever flags are changed internally, the lock file
* should be open and locked. this means the file must be
* opened during store command, and when changing the \seen
* flag for the fetch command.
*
* if no .imp file exists, a null one must be created before
* assigning uids.
*
* the .imp file has the following format
* imp : "imap internal mailbox description\n"
* uidvalidity " " uidnext "\n"
* messagelines
*
* messagelines :
* | messagelines digest " " uid " " flags "\n"
*
* uid, uidnext, and uidvalidity are 32 bit decimal numbers
* printed right justified in a field Nuid characters long.
* the 0 uid implies that no uid has been assigned to the message,
* but the flags are valid. note that message lines are in mailbox
* order, except possibly for 0 uid messages.
*
* digest is an ascii hex string Ndigest characters long.
*
* flags has a character for each of NFlag flag fields.
* if the flag is clear, it is represented by a "-".
* set flags are represented as a unique single ascii character.
* the currently assigned flags are, in order:
* Fseen s
* Fanswered a
* Fflagged f
* Fdeleted D
* Fdraft d
*/
Box*
openbox(char *name, char *fsname, int writable)
{
char err[ERRMAX];
int new;
Box *box;
Mblock *ml;