remove the uid from the db when a message is deleted from the maildir

optimize db fetch/store to not copy the base filename
This commit is contained in:
Michael Elkins 2002-01-16 21:22:43 +00:00
parent c121ec912f
commit cb0d4b54b3
2 changed files with 43 additions and 76 deletions

View File

@ -279,11 +279,9 @@ maildir_open (const char *path, int flags)
* flags) is used as the key in the db * flags) is used as the key in the db
*/ */
strfcpy (buf, p->file, sizeof (buf)); strfcpy (buf, p->file, sizeof (buf));
s = strchr (p->file, ':'); key.dptr = p->file;
if (s) s = strchr (key.dptr, ':');
*s = 0; key.dsize = s ? s - key.dptr : strlen (key.dptr);
key.dptr = buf;
key.dsize = strlen (buf);
key = dbm_fetch (m->db, key); key = dbm_fetch (m->db, key);
if (key.dptr) if (key.dptr)
{ {
@ -320,28 +318,35 @@ maildir_open (const char *path, int flags)
int int
maildir_expunge (mailbox_t * mbox, int dead) maildir_expunge (mailbox_t * mbox, int dead)
{ {
message_t **cur = &mbox->msgs; message_t **cur = &mbox->msgs;
message_t *tmp; message_t *tmp;
char path[_POSIX_PATH_MAX]; char *s;
datum key;
char path[_POSIX_PATH_MAX];
while (*cur) while (*cur)
{
if ((dead == 0 && (*cur)->flags & D_DELETED) ||
(dead && (*cur)->dead))
{ {
tmp = *cur; if ((dead == 0 && (*cur)->flags & D_DELETED) ||
*cur = (*cur)->next; (dead && (*cur)->dead))
snprintf (path, sizeof (path), "%s/%s/%s", {
mbox->path, tmp->new ? "new" : "cur", tmp->file); tmp = *cur;
if (unlink (path)) snprintf (path, sizeof (path), "%s/%s/%s",
perror ("unlink"); mbox->path, tmp->new ? "new" : "cur", tmp->file);
free (tmp->file); if (unlink (path))
free (tmp); perror (path);
/* remove the message from the UID map */
key.dptr = tmp->file;
s = strchr (key.dptr, ':');
key.dsize = s ? s - key.dptr : strlen (key.dptr);
dbm_delete (mbox->db, key);
*cur = (*cur)->next;
free (tmp->file);
free (tmp);
}
else
cur = &(*cur)->next;
} }
else return 0;
cur = &(*cur)->next;
}
return 0;
} }
int int
@ -350,60 +355,28 @@ maildir_update_maxuid (mailbox_t * mbox)
int fd; int fd;
char buf[64]; char buf[64];
size_t len; size_t len;
unsigned int uid;
char path[_POSIX_PATH_MAX]; char path[_POSIX_PATH_MAX];
int ret = 0; int ret = 0;
snprintf (path, sizeof (path), "%s/isyncmaxuid", mbox->path); snprintf (path, sizeof (path), "%s/isyncmaxuid", mbox->path);
fd = open (path, O_RDWR | O_CREAT, 0600); fd = open (path, O_WRONLY | O_CREAT, 0600);
if (fd == -1) if (fd == -1)
{ {
perror ("open"); perror ("open");
return -1; return -1;
} }
/* lock the file */ /* write out the file */
if (do_lock (fd, F_WRLCK)) snprintf (buf, sizeof (buf), "%u\n", mbox->maxuid);
len = write (fd, buf, strlen (buf));
if (len == (size_t) - 1)
{ {
close (fd);
return -1;
}
/* read the file again just to make sure it wasn't updated while
* we were doing something else
*/
len = read (fd, buf, sizeof (buf) - 1);
buf[len] = 0;
uid = atol (buf);
if (uid > mbox->maxuid)
{
fputs ("ERROR: maxuid is now higher (fatal)\n", stderr);
ret = -1;
}
if (!ret)
{
/* rewind */
lseek (fd, 0, SEEK_SET);
/* write out the file */
snprintf (buf, sizeof (buf), "%u\n", mbox->maxuid);
len = write (fd, buf, strlen (buf));
if (len == (size_t) - 1)
{
perror ("write"); perror ("write");
ret = -1; ret = -1;
}
else
{
ret = ftruncate (fd, len);
if (ret)
perror ("ftruncate");
}
} }
ret |= do_lock (fd, F_UNLCK); if (close (fd))
ret |= close (fd); ret = -1;
return ret; return ret;
} }

20
sync.c
View File

@ -42,16 +42,12 @@ find_msg (message_t * list, unsigned int uid)
static int set_uid (DBM *db, const char *f, unsigned int uid) static int set_uid (DBM *db, const char *f, unsigned int uid)
{ {
char path[_POSIX_PATH_MAX];
char *s; char *s;
datum key, val; datum key, val;
strfcpy (path, f, sizeof (path)); key.dptr = (void *) f;
s = strchr (path, ':'); s = strchr (f, ':');
if (s) key.dsize = s ? (size_t) (s - key.dptr) : strlen (f);
*s = 0;
key.dptr = path;
key.dsize = strlen (path);
val.dptr = (void*) &uid; val.dptr = (void*) &uid;
val.dsize = sizeof (uid); val.dsize = sizeof (uid);
dbm_store (db, key, val, DBM_REPLACE); dbm_store (db, key, val, DBM_REPLACE);
@ -81,13 +77,13 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags,
/* if the UIDVALIDITY value has changed, it means all our /* if the UIDVALIDITY value has changed, it means all our
* local UIDs are invalid, so we can't sync. * local UIDs are invalid, so we can't sync.
*/ */
puts ("Error, UIDVALIDITY changed on server (fatal)"); fputs ("ERROR: UIDVALIDITY changed on server (fatal)\n", stderr);
return -1; return -1;
} }
} }
else if (maildir_set_uidvalidity (mbox, imap->uidvalidity)) else if (maildir_set_uidvalidity (mbox, imap->uidvalidity))
{ {
puts ("Error, unable to store UIDVALIDITY"); fputs ("ERROR: unable to store UIDVALIDITY\n", stderr);
return -1; return -1;
} }
@ -127,9 +123,7 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags,
cur->new ? "new" : "cur", cur->file); cur->new ? "new" : "cur", cur->file);
if (stat (path, &sb)) if (stat (path, &sb))
{ {
printf ("Error, unable to stat %s: %s (errno %d)\n", perror (path);
path, strerror (errno), errno);
continue; /* not fatal */ continue; /* not fatal */
} }
if (imap->box->max_size > 0 if (imap->box->max_size > 0
@ -354,7 +348,7 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags,
else else
{ {
/* update the db with the UID mapping for this file */ /* update the db with the UID mapping for this file */
set_uid (mbox->db, newpath, cur->uid); set_uid (mbox->db, p + 1, cur->uid);
} }
} }