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:
parent
c121ec912f
commit
cb0d4b54b3
99
maildir.c
99
maildir.c
|
@ -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
20
sync.c
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user