Bladeren bron

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

optimize db fetch/store to not copy the base filename
Michael Elkins 23 jaren geleden
bovenliggende
commit
cb0d4b54b3
2 gewijzigde bestanden met toevoegingen van 43 en 76 verwijderingen
  1. 36 63
      maildir.c
  2. 7 13
      sync.c

+ 36 - 63
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;
 }

+ 7 - 13
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);
 		}
 	    }