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
24
configure.in
24
configure.in
|
@ -33,28 +33,8 @@ if test "x$ob_cv_with_ssl" != xno; then
|
||||||
])
|
])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_CACHE_CHECK(for dbm_open, ac_cv_dbmopen,
|
AC_CHECK_LIB(db, db_create, [LIBS="$LIBS -ldb"], [AC_MSG_ERROR([Berkley DB not found.])])
|
||||||
[ac_cv_dbmopen=no
|
AC_CHECK_HEADER(db.h, , [AC_MSG_ERROR([Berkley DB header file not found.])])
|
||||||
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_OUTPUT(Makefile src/Makefile debian/Makefile isync.spec)
|
AC_OUTPUT(Makefile src/Makefile debian/Makefile isync.spec)
|
||||||
|
|
||||||
|
|
|
@ -26,12 +26,7 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#if HAVE_LIBDB
|
#include <db.h>
|
||||||
# define DB_DBM_HSEARCH 1
|
|
||||||
# include <db.h>
|
|
||||||
#else
|
|
||||||
# include <ndbm.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_LIBSSL
|
#if HAVE_LIBSSL
|
||||||
# include <openssl/ssl.h>
|
# include <openssl/ssl.h>
|
||||||
|
@ -94,7 +89,7 @@ struct config
|
||||||
/* struct representing local mailbox file */
|
/* struct representing local mailbox file */
|
||||||
struct mailbox
|
struct mailbox
|
||||||
{
|
{
|
||||||
DBM *db;
|
DB *db;
|
||||||
char *path;
|
char *path;
|
||||||
message_t *msgs;
|
message_t *msgs;
|
||||||
int lockfd;
|
int lockfd;
|
||||||
|
|
|
@ -125,8 +125,8 @@ maildir_open (const char *path, int flags)
|
||||||
int count = 0;
|
int count = 0;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
const char *subdirs[] = { "cur", "new", "tmp" };
|
const char *subdirs[] = { "cur", "new", "tmp" };
|
||||||
int i;
|
int i, ret;
|
||||||
datum key;
|
DBT key, value;
|
||||||
|
|
||||||
m = calloc (1, sizeof (mailbox_t));
|
m = calloc (1, sizeof (mailbox_t));
|
||||||
m->lockfd = -1;
|
m->lockfd = -1;
|
||||||
|
@ -200,8 +200,18 @@ maildir_open (const char *path, int flags)
|
||||||
if (read_uid (m->path, "isyncmaxuid", &m->maxuid) == -1)
|
if (read_uid (m->path, "isyncmaxuid", &m->maxuid) == -1)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
snprintf (buf, sizeof (buf), "%s/isyncuidmap", m->path);
|
snprintf (buf, sizeof (buf), "%s/isyncuidmap.db", m->path);
|
||||||
m->db = dbm_open (buf, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
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)
|
if (m->db == NULL)
|
||||||
{
|
{
|
||||||
fputs ("ERROR: unable to open UID db\n", stderr);
|
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
|
/* determine the UID for this message. The basename (sans
|
||||||
* flags) is used as the key in the db
|
* flags) is used as the key in the db
|
||||||
*/
|
*/
|
||||||
key.dptr = p->file;
|
memset (&key, 0, sizeof(key));
|
||||||
s = strchr (key.dptr, ':');
|
memset (&value, 0, sizeof(value));
|
||||||
key.dsize = s ? (size_t) (s - key.dptr) : strlen (key.dptr);
|
key.data = p->file;
|
||||||
key = dbm_fetch (m->db, key);
|
s = strchr (p->file, ':');
|
||||||
if (key.dptr)
|
key.size = s ? (size_t) (s - p->file) : strlen (p->file);
|
||||||
{
|
ret = m->db->get (m->db, 0, &key, &value, 0);
|
||||||
p->uid = *(int *) key.dptr;
|
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)
|
if (p->uid > m->maxuid)
|
||||||
m->maxuid = p->uid;
|
m->maxuid = p->uid;
|
||||||
}
|
}
|
||||||
else /* XXX remove. every locally generated message triggers this */
|
|
||||||
puts ("Warning, no UID for message");
|
|
||||||
|
|
||||||
if (s)
|
if (s)
|
||||||
parse_info (p, s + 1);
|
parse_info (p, s + 1);
|
||||||
if (p->flags & D_DELETED)
|
if (p->flags & D_DELETED)
|
||||||
|
@ -262,7 +277,7 @@ maildir_open (const char *path, int flags)
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (m->db)
|
if (m->db)
|
||||||
dbm_close (m->db);
|
m->db->close (m->db, 0);
|
||||||
dotlock_unlock (&m->lockfd);
|
dotlock_unlock (&m->lockfd);
|
||||||
free (m->path);
|
free (m->path);
|
||||||
free (m);
|
free (m);
|
||||||
|
@ -278,7 +293,7 @@ maildir_expunge (mailbox_t * mbox, int dead)
|
||||||
message_t **cur = &mbox->msgs;
|
message_t **cur = &mbox->msgs;
|
||||||
message_t *tmp;
|
message_t *tmp;
|
||||||
char *s;
|
char *s;
|
||||||
datum key;
|
DBT key;
|
||||||
char path[_POSIX_PATH_MAX];
|
char path[_POSIX_PATH_MAX];
|
||||||
|
|
||||||
while (*cur)
|
while (*cur)
|
||||||
|
@ -292,10 +307,12 @@ maildir_expunge (mailbox_t * mbox, int dead)
|
||||||
if (unlink (path))
|
if (unlink (path))
|
||||||
perror (path);
|
perror (path);
|
||||||
/* remove the message from the UID map */
|
/* remove the message from the UID map */
|
||||||
key.dptr = tmp->file;
|
memset (&key, 0, sizeof(key));
|
||||||
s = strchr (key.dptr, ':');
|
key.data = tmp->file;
|
||||||
key.dsize = s ? (size_t) (s - key.dptr) : strlen (key.dptr);
|
s = strchr (tmp->file, ':');
|
||||||
dbm_delete (mbox->db, key);
|
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;
|
*cur = (*cur)->next;
|
||||||
free (tmp->file);
|
free (tmp->file);
|
||||||
free (tmp);
|
free (tmp);
|
||||||
|
@ -386,7 +403,7 @@ void
|
||||||
maildir_close (mailbox_t * mbox)
|
maildir_close (mailbox_t * mbox)
|
||||||
{
|
{
|
||||||
if (mbox->db)
|
if (mbox->db)
|
||||||
dbm_close (mbox->db);
|
mbox->db->close (mbox->db, 0);
|
||||||
|
|
||||||
/* release the mutex on the mailbox */
|
/* release the mutex on the mailbox */
|
||||||
dotlock_unlock (&mbox->lockfd);
|
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
|
static int
|
||||||
set_uid (DBM * db, const char *f, unsigned int uid)
|
set_uid (DB * db, const char *f, unsigned int uid)
|
||||||
{
|
{
|
||||||
char *s;
|
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, ':');
|
s = strchr (f, ':');
|
||||||
key.dsize = s ? (size_t) (s - key.dptr) : strlen (f);
|
key.size = s ? (size_t) (s - f) : strlen (f);
|
||||||
val.dptr = (void *) &uid;
|
val.data = (void *) &uid;
|
||||||
val.dsize = sizeof (uid);
|
val.size = sizeof (uid);
|
||||||
dbm_store (db, key, val, DBM_REPLACE);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user