sync uid database after every message. this is accompanied by a dbm ->
db4 migration. patch by theodore, with some final polishing by me.
This commit is contained in:
		
							parent
							
								
									052195c982
								
							
						
					
					
						commit
						180f5fa201
					
				
					 4 changed files with 56 additions and 57 deletions
				
			
		
							
								
								
									
										24
									
								
								configure.in
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								configure.in
									
										
									
									
									
								
							|  | @ -33,28 +33,8 @@ if test "x$ob_cv_with_ssl" != xno; then | |||
|       ]) | ||||
| fi | ||||
| 
 | ||||
| AC_CACHE_CHECK(for dbm_open, ac_cv_dbmopen, | ||||
| 	[ac_cv_dbmopen=no | ||||
| 	AC_TRY_LINK([#include <ndbm.h>], | ||||
| 		[dbm_open(0,0,0);],[ac_cv_dbmopen=yes])]) | ||||
| if test $ac_cv_dbmopen = no; then | ||||
| 	AC_CACHE_CHECK([for dbm_open in -ldb], ac_cv_libdb, | ||||
| 		[save_LIBS="$LIBS" | ||||
| 		LIBS="$LIBS -ldb" | ||||
| 		ac_cv_libdb=no | ||||
| 		AC_TRY_LINK([#define DB_DBM_HSEARCH 1 | ||||
| #include <db.h>], | ||||
| 			[dbm_open(0,0,0);], | ||||
| 			[ac_cv_libdb=yes]) | ||||
| 		LIBS="$save_LIBS"]) | ||||
| 
 | ||||
| 	if test $ac_cv_libdb = yes; then | ||||
| 		LIBS="$LIBS -ldb" | ||||
| 		AC_DEFINE(HAVE_LIBDB, 1, [Define if you have libdb]) | ||||
| 	else | ||||
| 		AC_MSG_ERROR([Could not find dbm_open(), you must install libdb]) | ||||
| 	fi | ||||
| fi | ||||
| AC_CHECK_LIB(db, db_create, [LIBS="$LIBS -ldb"], [AC_MSG_ERROR([Berkley DB not found.])]) | ||||
| AC_CHECK_HEADER(db.h, , [AC_MSG_ERROR([Berkley DB header file not found.])]) | ||||
| 
 | ||||
| AC_OUTPUT(Makefile src/Makefile debian/Makefile isync.spec) | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,12 +26,7 @@ | |||
| 
 | ||||
| #include <sys/types.h> | ||||
| 
 | ||||
| #if HAVE_LIBDB | ||||
| # define DB_DBM_HSEARCH 1 | ||||
| # include <db.h> | ||||
| #else | ||||
| # include <ndbm.h> | ||||
| #endif | ||||
| #include <db.h> | ||||
| 
 | ||||
| #if HAVE_LIBSSL | ||||
| # include <openssl/ssl.h> | ||||
|  | @ -94,7 +89,7 @@ struct config | |||
| /* struct representing local mailbox file */ | ||||
| struct mailbox | ||||
| { | ||||
|     DBM *db; | ||||
|     DB *db; | ||||
|     char *path; | ||||
|     message_t *msgs; | ||||
|     int lockfd; | ||||
|  |  | |||
|  | @ -125,8 +125,8 @@ maildir_open (const char *path, int flags) | |||
|     int count = 0; | ||||
|     struct stat sb; | ||||
|     const char *subdirs[] = { "cur", "new", "tmp" }; | ||||
|     int i; | ||||
|     datum key; | ||||
|     int i, ret; | ||||
|     DBT key, value; | ||||
| 
 | ||||
|     m = calloc (1, sizeof (mailbox_t)); | ||||
|     m->lockfd = -1; | ||||
|  | @ -200,8 +200,18 @@ maildir_open (const char *path, int flags) | |||
|     if (read_uid (m->path, "isyncmaxuid", &m->maxuid) == -1) | ||||
| 	goto err; | ||||
| 
 | ||||
|     snprintf (buf, sizeof (buf), "%s/isyncuidmap", m->path); | ||||
|     m->db = dbm_open (buf, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); | ||||
|     snprintf (buf, sizeof (buf), "%s/isyncuidmap.db", m->path); | ||||
|     if (db_create (&m->db, 0, 0)) { | ||||
| 	    fputs ("dbcreate failed\n", stderr); | ||||
| 	    goto err; | ||||
|     } | ||||
|     if ((ret = m->db->set_pagesize (m->db, 4096)) != 0 || | ||||
| 	(ret = m->db->set_h_ffactor (m->db, 40)) != 0 || | ||||
| 	(ret = m->db->set_h_nelem (m->db, 1)) != 0) { | ||||
| 	    fputs ("Error configuring database\n", stderr); | ||||
| 	    goto err; | ||||
|     } | ||||
|     m->db->open (m->db, buf, 0, DB_HASH, DB_CREATE, S_IRUSR | S_IWUSR); | ||||
|     if (m->db == NULL) | ||||
|     { | ||||
| 	fputs ("ERROR: unable to open UID db\n", stderr); | ||||
|  | @ -237,19 +247,24 @@ maildir_open (const char *path, int flags) | |||
| 	    /* determine the UID for this message.  The basename (sans
 | ||||
| 	     * flags) is used as the key in the db | ||||
| 	     */ | ||||
| 	    key.dptr = p->file; | ||||
| 	    s = strchr (key.dptr, ':'); | ||||
| 	    key.dsize = s ? (size_t) (s - key.dptr) : strlen (key.dptr); | ||||
| 	    key = dbm_fetch (m->db, key); | ||||
| 	    if (key.dptr) | ||||
| 	    { | ||||
| 		p->uid = *(int *) key.dptr; | ||||
| 	    memset (&key, 0, sizeof(key)); | ||||
| 	    memset (&value, 0, sizeof(value)); | ||||
| 	    key.data = p->file; | ||||
| 	    s = strchr (p->file, ':'); | ||||
| 	    key.size = s ? (size_t) (s - p->file) : strlen (p->file); | ||||
| 	    ret = m->db->get (m->db, 0, &key, &value, 0); | ||||
| 	    if (ret == DB_NOTFOUND) { | ||||
| 		/* Every locally generated message triggers this ... */ | ||||
| 		/*printf ("Warning, no UID for message %.*s\n",
 | ||||
| 			key.size, p->file);*/ | ||||
| 	    } else if (ret) { | ||||
| 		fprintf (stderr, "Unexpected error (%d) from db_get(%.*s)\n",  | ||||
| 			 ret, key.size, p->file); | ||||
| 	    } else if (ret == 0) { | ||||
| 		p->uid = *((int *) value.data); | ||||
| 		if (p->uid > m->maxuid) | ||||
| 		    m->maxuid = p->uid; | ||||
| 	    } | ||||
| 	    else /* XXX remove. every locally generated message triggers this */ | ||||
| 		puts ("Warning, no UID for message"); | ||||
| 
 | ||||
| 	    if (s) | ||||
| 		parse_info (p, s + 1); | ||||
| 	    if (p->flags & D_DELETED) | ||||
|  | @ -262,7 +277,7 @@ maildir_open (const char *path, int flags) | |||
| 
 | ||||
|   err: | ||||
|     if (m->db) | ||||
| 	dbm_close (m->db); | ||||
| 	m->db->close (m->db, 0); | ||||
|     dotlock_unlock (&m->lockfd); | ||||
|     free (m->path); | ||||
|     free (m); | ||||
|  | @ -278,7 +293,7 @@ maildir_expunge (mailbox_t * mbox, int dead) | |||
|     message_t **cur = &mbox->msgs; | ||||
|     message_t *tmp; | ||||
|     char *s; | ||||
|     datum key; | ||||
|     DBT key; | ||||
|     char path[_POSIX_PATH_MAX]; | ||||
| 
 | ||||
|     while (*cur) | ||||
|  | @ -292,10 +307,12 @@ maildir_expunge (mailbox_t * mbox, int dead) | |||
| 	    if (unlink (path)) | ||||
| 		perror (path); | ||||
| 	    /* remove the message from the UID map */ | ||||
| 	    key.dptr = tmp->file; | ||||
| 	    s = strchr (key.dptr, ':'); | ||||
| 	    key.dsize = s ? (size_t) (s - key.dptr) : strlen (key.dptr); | ||||
| 	    dbm_delete (mbox->db, key); | ||||
| 	    memset (&key, 0, sizeof(key)); | ||||
| 	    key.data = tmp->file; | ||||
| 	    s = strchr (tmp->file, ':'); | ||||
| 	    key.size = s ? (size_t) (s - tmp->file) : strlen (key.data); | ||||
| 	    mbox->db->del (mbox->db, 0, &key, 0); | ||||
| 	    mbox->db->sync (mbox->db, 0); | ||||
| 	    *cur = (*cur)->next; | ||||
| 	    free (tmp->file); | ||||
| 	    free (tmp); | ||||
|  | @ -386,7 +403,7 @@ void | |||
| maildir_close (mailbox_t * mbox) | ||||
| { | ||||
|     if (mbox->db) | ||||
| 	dbm_close (mbox->db); | ||||
| 	mbox->db->close (mbox->db, 0); | ||||
| 
 | ||||
|     /* release the mutex on the mailbox */ | ||||
|     dotlock_unlock (&mbox->lockfd); | ||||
|  |  | |||
							
								
								
									
										21
									
								
								src/sync.c
									
										
									
									
									
								
							
							
						
						
									
										21
									
								
								src/sync.c
									
										
									
									
									
								
							|  | @ -46,17 +46,24 @@ find_msg (message_t * list, unsigned int uid) | |||
| } | ||||
| 
 | ||||
| static int | ||||
| set_uid (DBM * db, const char *f, unsigned int uid) | ||||
| set_uid (DB * db, const char *f, unsigned int uid) | ||||
| { | ||||
|     char *s; | ||||
|     datum key, val; | ||||
|     DBT key, val; | ||||
|     int ret; | ||||
| 
 | ||||
|     key.dptr = (void *) f; | ||||
|     memset (&key, 0, sizeof(key)); | ||||
|     memset (&val, 0, sizeof(val)); | ||||
|     key.data = (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); | ||||
|     key.size = s ? (size_t) (s - f) : strlen (f); | ||||
|     val.data = (void *) &uid; | ||||
|     val.size = sizeof (uid); | ||||
|     ret = db->put (db, 0, &key, &val, 0); | ||||
|     if (ret < 0) | ||||
| 	fprintf (stderr, "Unexpected error (%d) from db_put(%.*s, %d)\n",  | ||||
| 		 ret, key.size, f, uid); | ||||
|     db->sync(db, 0); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue