isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit cb0d4b54b3600acb62989d0c285726854d23d08b
parent c121ec912f743193a87b4151c0f4f7c6c40fe6f6
Author: Michael Elkins <me@mutt.org>
Date:   Wed, 16 Jan 2002 21:22:43 +0000

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

optimize db fetch/store to not copy the base filename

Diffstat:
Mmaildir.c | 99+++++++++++++++++++++++++++++--------------------------------------------------
Msync.c | 20+++++++-------------
2 files changed, 43 insertions(+), 76 deletions(-)

diff --git a/maildir.c b/maildir.c @@ -279,11 +279,9 @@ maildir_open (const char *path, int flags) * flags) is used as the key in the db */ strfcpy (buf, p->file, sizeof (buf)); - s = strchr (p->file, ':'); - if (s) - *s = 0; - key.dptr = buf; - key.dsize = strlen (buf); + key.dptr = p->file; + s = strchr (key.dptr, ':'); + key.dsize = s ? s - key.dptr : strlen (key.dptr); key = dbm_fetch (m->db, key); if (key.dptr) { @@ -320,28 +318,35 @@ maildir_open (const char *path, int flags) int maildir_expunge (mailbox_t * mbox, int dead) { - message_t **cur = &mbox->msgs; - message_t *tmp; - char path[_POSIX_PATH_MAX]; + message_t **cur = &mbox->msgs; + message_t *tmp; + char *s; + datum key; + char path[_POSIX_PATH_MAX]; - while (*cur) - { - if ((dead == 0 && (*cur)->flags & D_DELETED) || - (dead && (*cur)->dead)) + while (*cur) { - tmp = *cur; - *cur = (*cur)->next; - snprintf (path, sizeof (path), "%s/%s/%s", - mbox->path, tmp->new ? "new" : "cur", tmp->file); - if (unlink (path)) - perror ("unlink"); - free (tmp->file); - free (tmp); + if ((dead == 0 && (*cur)->flags & D_DELETED) || + (dead && (*cur)->dead)) + { + tmp = *cur; + snprintf (path, sizeof (path), "%s/%s/%s", + mbox->path, tmp->new ? "new" : "cur", tmp->file); + if (unlink (path)) + 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 - cur = &(*cur)->next; - } - return 0; + return 0; } int @@ -350,60 +355,28 @@ maildir_update_maxuid (mailbox_t * mbox) int fd; char buf[64]; size_t len; - unsigned int uid; char path[_POSIX_PATH_MAX]; int ret = 0; 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) { perror ("open"); return -1; } - /* lock the file */ - if (do_lock (fd, F_WRLCK)) - { - 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) + /* write out the file */ + snprintf (buf, sizeof (buf), "%u\n", mbox->maxuid); + len = write (fd, buf, strlen (buf)); + if (len == (size_t) - 1) { - 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"); ret = -1; - } - else - { - ret = ftruncate (fd, len); - if (ret) - perror ("ftruncate"); - } } - ret |= do_lock (fd, F_UNLCK); - ret |= close (fd); + if (close (fd)) + ret = -1; return ret; } diff --git a/sync.c b/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) { - char path[_POSIX_PATH_MAX]; char *s; datum key, val; - strfcpy (path, f, sizeof (path)); - s = strchr (path, ':'); - if (s) - *s = 0; - key.dptr = path; - key.dsize = strlen (path); + key.dptr = (void *) f; + s = strchr (f, ':'); + key.dsize = s ? (size_t) (s - key.dptr) : strlen (f); val.dptr = (void*) &uid; val.dsize = sizeof (uid); 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 * 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; } } else if (maildir_set_uidvalidity (mbox, imap->uidvalidity)) { - puts ("Error, unable to store UIDVALIDITY"); + fputs ("ERROR: unable to store UIDVALIDITY\n", stderr); return -1; } @@ -127,9 +123,7 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags, cur->new ? "new" : "cur", cur->file); if (stat (path, &sb)) { - printf ("Error, unable to stat %s: %s (errno %d)\n", - path, strerror (errno), errno); - + perror (path); continue; /* not fatal */ } if (imap->box->max_size > 0 @@ -354,7 +348,7 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags, else { /* 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); } }