diff --git a/README b/README index 66a0017..aa020de 100644 --- a/README +++ b/README @@ -61,7 +61,7 @@ isync executable still exists; it is a compatibility wrapper around mbsync. * Requirements - Berkley DB 4.2+ + Berkley DB 4.2+ (optional) OpenSSL for TLS/SSL support (optional) * Installation diff --git a/configure.ac b/configure.ac index 20230e5..16314b2 100644 --- a/configure.ac +++ b/configure.ac @@ -146,8 +146,9 @@ AC_CACHE_CHECK([for Berkley DB >= 4.2], ac_cv_berkdb4, db->truncate(db, 0, 0, 0); db->open(db, 0, "foo", "foo", DB_HASH, DB_CREATE, 0)], [ac_cv_berkdb4=yes])]) -if test "x$ac_cv_berkdb4" = xno; then - AC_MSG_ERROR([Berkley DB >= 4.2 not found.]) +if test "x$ac_cv_berkdb4" = xyes; then + AC_SUBST([DB_LIBS], ["-ldb"]) + AC_DEFINE(USE_DB, 1, [if Berkley DB should be used]) fi have_zlib= @@ -165,7 +166,8 @@ AC_ARG_ENABLE(compat, if test "x$ob_cv_enable_compat" != xno; then AC_CHECK_FUNCS(getopt_long) fi -AM_CONDITIONAL(with_compat, test "x$ob_cv_enable_compat" != xno) +AM_CONDITIONAL(with_compat, test "x$ob_cv_enable_compat" != xno -a "x$ac_cv_berkdb4" = xyes) +AM_CONDITIONAL(with_mdconvert, test "x$ac_cv_berkdb4" = xyes) AC_CONFIG_FILES([Makefile src/Makefile src/compat/Makefile isync.spec]) AC_OUTPUT @@ -186,4 +188,9 @@ if test -n "$have_zlib"; then else AC_MSG_RESULT([Not using zlib]) fi +if test "x$ac_cv_berkdb4" = xyes; then + AC_MSG_RESULT([Using Berkley DB]) +else + AC_MSG_RESULT([Not using Berkley DB]) +fi AC_MSG_RESULT() diff --git a/src/Makefile.am b/src/Makefile.am index 0a49f21..b548d60 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,20 +3,23 @@ compat_dir = compat endif SUBDIRS = $(compat_dir) -bin_PROGRAMS = mbsync mdconvert - mbsync_SOURCES = main.c sync.c config.c util.c socket.c driver.c drv_imap.c drv_maildir.c -mbsync_LDADD = -ldb $(SSL_LIBS) $(SOCK_LIBS) $(SASL_LIBS) $(Z_LIBS) +mbsync_LDADD = $(DB_LIBS) $(SSL_LIBS) $(SOCK_LIBS) $(SASL_LIBS) $(Z_LIBS) noinst_HEADERS = common.h config.h driver.h sync.h socket.h mdconvert_SOURCES = mdconvert.c -mdconvert_LDADD = -ldb +mdconvert_LDADD = $(DB_LIBS) +if with_mdconvert +mdconvert_prog = mdconvert +mdconvert_man = mdconvert.1 +endif EXTRA_PROGRAMS = tst_timers tst_timers_SOURCES = tst_timers.c util.c -man_MANS = mbsync.1 mdconvert.1 +bin_PROGRAMS = mbsync $(mdconvert_prog) +man_MANS = mbsync.1 $(mdconvert_man) exampledir = $(docdir)/examples example_DATA = mbsyncrc.sample diff --git a/src/compat/Makefile.am b/src/compat/Makefile.am index c234f0f..6a99942 100644 --- a/src/compat/Makefile.am +++ b/src/compat/Makefile.am @@ -1,7 +1,7 @@ bin_PROGRAMS = isync isync_SOURCES = main.c config.c convert.c util.c -isync_LDADD = -ldb +isync_LDADD = $(DB_LIBS) noinst_HEADERS = isync.h man_MANS = isync.1 diff --git a/src/drv_imap.c b/src/drv_imap.c index 72a8fd1..7b41864 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -1780,6 +1780,7 @@ ensure_password( imap_server_conf_t *srvc ) #ifdef HAVE_LIBSASL static sasl_callback_t sasl_callbacks[] = { + { SASL_CB_USER, NULL, NULL }, { SASL_CB_AUTHNAME, NULL, NULL }, { SASL_CB_PASS, NULL, NULL }, { SASL_CB_LIST_END, NULL, NULL } @@ -1794,6 +1795,7 @@ process_sasl_interact( sasl_interact_t *interact, imap_server_conf_t *srvc ) switch (interact->id) { case SASL_CB_LIST_END: return 0; + case SASL_CB_USER: case SASL_CB_AUTHNAME: val = ensure_user( srvc ); break; @@ -2610,7 +2612,7 @@ imap_list_store( store_t *gctx, int flags, imap_store_t *ctx = (imap_store_t *)gctx; struct imap_cmd_refcounted_state *sts = imap_refcounted_new_state( cb, aux ); - if (((flags & LIST_PATH) && + if (((flags & LIST_PATH) && (!(flags & LIST_INBOX) || !is_inbox( ctx, ctx->prefix, -1 )) && imap_exec( ctx, imap_refcounted_new_cmd( sts ), imap_refcounted_done_box, "LIST \"\" \"%\\s*\"", ctx->prefix ) < 0) || ((flags & LIST_INBOX) && (!(flags & LIST_PATH) || *ctx->prefix) && diff --git a/src/drv_maildir.c b/src/drv_maildir.c index 045dd9c..b96950c 100644 --- a/src/drv_maildir.c +++ b/src/drv_maildir.c @@ -38,7 +38,6 @@ #include #include -#define USE_DB 1 #ifdef __linux__ # define LEGACY_FLOCK 1 #endif @@ -229,10 +228,12 @@ maildir_invoke_bad_callback( store_t *ctx ) ctx->bad_callback( ctx->bad_callback_aux ); } -static int maildir_list_inbox( store_t *gctx, int *flags ); +static int maildir_list_inbox( store_t *gctx, int flags, const char *basePath ); +static int maildir_list_path( store_t *gctx, int flags, const char *inbox ); static int -maildir_list_recurse( store_t *gctx, int isBox, int *flags, const char *inbox, int inboxLen, +maildir_list_recurse( store_t *gctx, int isBox, int flags, + const char *inbox, int inboxLen, const char *basePath, int basePathLen, char *path, int pathLen, char *name, int nameLen ) { DIR *dir; @@ -259,7 +260,14 @@ maildir_list_recurse( store_t *gctx, int isBox, int *flags, const char *inbox, i const char *ent = de->d_name; pl = pathLen + nfsnprintf( path + pathLen, _POSIX_PATH_MAX - pathLen, "%s", ent ); if (inbox && equals( path, pl, inbox, inboxLen )) { - if (maildir_list_inbox( gctx, flags ) < 0) { + /* Inbox nested into Path. List now if it won't be listed separately anyway. */ + if (!(flags & LIST_INBOX) && maildir_list_inbox( gctx, flags, 0 ) < 0) { + closedir( dir ); + return -1; + } + } else if (basePath && equals( path, pl, basePath, basePathLen )) { + /* Path nested into Inbox. List now if it won't be listed separately anyway. */ + if (!(flags & LIST_PATH) && maildir_list_path( gctx, flags, 0 ) < 0) { closedir( dir ); return -1; } @@ -280,7 +288,7 @@ maildir_list_recurse( store_t *gctx, int isBox, int *flags, const char *inbox, i } } nl = nameLen + nfsnprintf( name + nameLen, _POSIX_PATH_MAX - nameLen, "%s", ent ); - if (maildir_list_recurse( gctx, 1, flags, inbox, inboxLen, path, pl, name, nl ) < 0) { + if (maildir_list_recurse( gctx, 1, flags, inbox, inboxLen, basePath, basePathLen, path, pl, name, nl ) < 0) { closedir( dir ); return -1; } @@ -291,27 +299,25 @@ maildir_list_recurse( store_t *gctx, int isBox, int *flags, const char *inbox, i } static int -maildir_list_inbox( store_t *gctx, int *flags ) +maildir_list_inbox( store_t *gctx, int flags, const char *basePath ) { char path[_POSIX_PATH_MAX], name[_POSIX_PATH_MAX]; - *flags &= ~LIST_INBOX; return maildir_list_recurse( - gctx, 2, flags, 0, 0, + gctx, 2, flags, 0, 0, basePath, basePath ? strlen( basePath ) - 1 : 0, path, nfsnprintf( path, _POSIX_PATH_MAX, "%s", ((maildir_store_conf_t *)gctx->conf)->inbox ), name, nfsnprintf( name, _POSIX_PATH_MAX, "INBOX" ) ); } static int -maildir_list_path( store_t *gctx, int *flags ) +maildir_list_path( store_t *gctx, int flags, const char *inbox ) { - const char *inbox = ((maildir_store_conf_t *)gctx->conf)->inbox; char path[_POSIX_PATH_MAX], name[_POSIX_PATH_MAX]; if (maildir_validate_path( gctx->conf ) < 0) return -1; return maildir_list_recurse( - gctx, 0, flags, inbox, strlen( inbox ), + gctx, 0, flags, inbox, inbox ? strlen( inbox ) : 0, 0, 0, path, nfsnprintf( path, _POSIX_PATH_MAX, "%s", gctx->conf->path ), name, 0 ); } @@ -320,8 +326,8 @@ static void maildir_list_store( store_t *gctx, int flags, void (*cb)( int sts, void *aux ), void *aux ) { - if (((flags & LIST_PATH) && maildir_list_path( gctx, &flags ) < 0) || - ((flags & LIST_INBOX) && maildir_list_inbox( gctx, &flags ) < 0)) { + if (((flags & LIST_PATH) && maildir_list_path( gctx, flags, ((maildir_store_conf_t *)gctx->conf)->inbox ) < 0) || + ((flags & LIST_INBOX) && maildir_list_inbox( gctx, flags, gctx->conf->path ) < 0)) { maildir_invoke_bad_callback( gctx ); cb( DRV_CANCELED, aux ); } else { @@ -1366,6 +1372,7 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int to_trash, } box = gctx->path; } else { + uid = 0; box = ctx->trash; } @@ -1464,7 +1471,7 @@ maildir_set_msg_flags( store_t *gctx, message_t *gmsg, int uid ATTR_UNUSED, int for (i = 0; i < as(Flags); i++) { if ((p = strchr( s, Flags[i] ))) { if (del & (1 << i)) { - memcpy( p, p + 1, fl - (p - s) ); + memmove( p, p + 1, fl - (p - s) ); fl--; } } else if (add & (1 << i)) {