[commit] master: Merge branch '1.3'

2021-02-03 Thread Oswald Buddenhagen via isync-devel
Skipped 2 existing revision(s) on branch 'master'.

commit 062706fcbf39bcee536ea4b5c690e2f30e122faa
Merge: fc300fd e4eac03
Author: Oswald Buddenhagen 
Date:   Wed Feb 3 15:53:05 2021 +0100

Merge branch '1.3'

Conflicts:
configure.ac
src/drv_imap.c

 src/drv_imap.c | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --cc src/drv_imap.c
index 8d7c99b,810479e..9f23e08
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@@ -1381,14 -1266,16 +1381,15 @@@ parse_list_rsp_p2( imap_store_t *ctx, l
return LIST_BAD;
}
arg = list->val;
 -  argl = list->len;
 +  argl = (int)list->len;
-   if (is_inbox( ctx, arg, argl )) {
-   // The server might be weird and have a non-uppercase INBOX. It
-   // may legitimately do so, but we need the canonical spelling.
-   memcpy( arg, "INBOX", 5 );
-   } else if ((l = strlen( ctx->prefix ))) {
-   if (!starts_with( arg, argl, ctx->prefix, l ))
+   if ((l = strlen( ctx->prefix ))) {
+   if (!starts_with( arg, argl, ctx->prefix, l )) {
+   if (is_inbox( ctx, arg, argl )) {
+   // INBOX and its subfolders bypass the 
namespace.
+   goto inbox;
+   }
 -  goto skip;
 +  return LIST_OK;
+   }
arg += l;
argl -= l;
// A folder named "INBOX" would be indistinguishable from the
@@@ -1398,14 -1285,22 +1399,22 @@@
if (is_INBOX( ctx, arg, argl )) {
if (!arg[5])  // No need to complain about subfolders 
as well.
warn( "IMAP warning: ignoring INBOX in %s\n", 
ctx->prefix );
 -  goto skip;
 +  return LIST_OK;
}
+   } else if (is_inbox( ctx, arg, argl )) {
+ inbox:
+   // The server might be weird and have a non-uppercase INBOX. It
+   // may legitimately do so, but we need the canonical spelling.
+   // Note that we do that only after prefix matching, under the
+   // assumption that the NAMESPACE (or Path) matches the
+   // capitalization of LIST.
+   memcpy( arg, "INBOX", 5 );
}
if (argl >= 5 && !memcmp( arg + argl - 5, ".lock", 5 )) /* workaround 
broken servers */
 -  goto skip;
 +  return LIST_OK;
if (map_name( arg, (char **), offsetof(string_list_t, string), 
ctx->delimiter, "/") < 0) {
warn( "IMAP warning: ignoring mailbox %s (reserved character 
'/' in name)\n", arg );
 -  goto skip;
 +  return LIST_OK;
}
narg->next = ctx->boxes;
ctx->boxes = narg;

= Full diff against 1st parent =

diff --git a/src/drv_imap.c b/src/drv_imap.c
index 8d7c99b..9f23e08 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -1382,13 +1382,14 @@ parse_list_rsp_p2( imap_store_t *ctx, list_t *list, 
char *cmd ATTR_UNUSED )
}
arg = list->val;
argl = (int)list->len;
-   if (is_inbox( ctx, arg, argl )) {
-   // The server might be weird and have a non-uppercase INBOX. It
-   // may legitimately do so, but we need the canonical spelling.
-   memcpy( arg, "INBOX", 5 );
-   } else if ((l = strlen( ctx->prefix ))) {
-   if (!starts_with( arg, argl, ctx->prefix, l ))
+   if ((l = strlen( ctx->prefix ))) {
+   if (!starts_with( arg, argl, ctx->prefix, l )) {
+   if (is_inbox( ctx, arg, argl )) {
+   // INBOX and its subfolders bypass the 
namespace.
+   goto inbox;
+   }
return LIST_OK;
+   }
arg += l;
argl -= l;
// A folder named "INBOX" would be indistinguishable from the
@@ -1400,6 +1401,14 @@ parse_list_rsp_p2( imap_store_t *ctx, list_t *list, char 
*cmd ATTR_UNUSED )
warn( "IMAP warning: ignoring INBOX in %s\n", 
ctx->prefix );
return LIST_OK;
}
+   } else if (is_inbox( ctx, arg, argl )) {
+ inbox:
+   // The server might be weird and have a non-uppercase INBOX. It
+   // may legitimately do so, but we need the canonical spelling.
+   // Note that we do that only after prefix matching, under the
+   // assumption that the NAMESPACE (or Path) matches the
+   // capitalization of LIST.
+   memcpy( arg, "INBOX", 5 );
}
if (argl >= 5 && !memcmp( arg + argl - 5, ".lock", 5 )) /* workaround 
broken servers */
return LIST_OK;


___

[commit] master: Merge branch '1.3'

2020-08-04 Thread Oswald Buddenhagen via isync-devel
Skipped 7 existing revision(s) on branch 'master'.

commit 5fee222f8408d5dd82b40d53c663b8ceffa13914
Merge: cab1460 c97e650
Author: Oswald Buddenhagen 
Date:   Tue Aug 4 14:48:58 2020 +0200

Merge branch '1.3'

 src/drv_imap.c  | 17 ++--
 src/drv_proxy.c |  4 +++-
 src/mbsync.1| 32 +++--
 src/socket.c| 54 +++--
 src/socket.h|  2 +-
 5 files changed, 61 insertions(+), 48 deletions(-)


= Full diff against 1st parent =

diff --git a/src/drv_imap.c b/src/drv_imap.c
index 8d2ebf5..7eeff82 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -1586,14 +1586,6 @@ get_cmd_result_p2( imap_store_t *ctx, imap_cmd_t *cmd, 
int response )
 
 /*** imap_cancel_store ***/
 
-
-static void
-imap_cleanup_store( imap_store_t *ctx )
-{
-   free_generic_messages( ctx->msgs );
-   free_string_list( ctx->boxes );
-}
-
 static void
 imap_cancel_store( store_t *gctx )
 {
@@ -1609,7 +1601,8 @@ imap_cancel_store( store_t *gctx )
free_list( ctx->ns_other );
free_list( ctx->ns_shared );
free_string_list( ctx->auth_mechs );
-   imap_cleanup_store( ctx );
+   free_generic_messages( ctx->msgs );
+   free_string_list( ctx->boxes );
imap_deref( ctx );
 }
 
@@ -1746,7 +1739,9 @@ imap_alloc_store( store_conf_t *conf, const char *label )
for (ctxp =  (ctx = (imap_store_t *)*ctxp); ctxp = 
>gen.next)
if (ctx->state != SST_BAD && ((imap_store_conf_t 
*)ctx->gen.conf)->server == srvc) {
*ctxp = ctx->gen.next;
-   imap_cleanup_store( ctx );
+   free_string_list( ctx->boxes );
+   ctx->boxes = NULL;
+   ctx->listed = 0;
/* One could ping the server here, but given that the 
idle timeout
 * is at least 30 minutes, this sounds pretty 
pointless. */
ctx->state = SST_HALF;
@@ -1921,7 +1916,7 @@ ensure_password( imap_server_conf_t *srvc )
if (cmd) {
FILE *fp;
int ret;
-   char buffer[2048];  // Hopefully more than enough room for 
XOAUTH2, etc. tokens
+   char buffer[8192];  // Hopefully more than enough room for 
XOAUTH2, etc. tokens
 
if (*cmd == '+') {
flushn();
diff --git a/src/drv_proxy.c b/src/drv_proxy.c
index 2ef928a..7250293 100644
--- a/src/drv_proxy.c
+++ b/src/drv_proxy.c
@@ -309,9 +309,11 @@ proxy_set_bad_callback( store_t *gctx, void (*cb)( void 
*aux ), void *aux )
 static void
 proxy_invoke_bad_callback( proxy_store_t *ctx )
 {
+   ctx->ref_count++;
debug( "%sCallback enter bad store\n", ctx->label );
ctx->bad_callback( ctx->bad_callback_aux );
-   debug( "%sCallback leave bad store\n", ctx->label ); \
+   debug( "%sCallback leave bad store\n", ctx->label );
+   proxy_store_deref( ctx );
 }
 
 //# EXCLUDE alloc_store
diff --git a/src/mbsync.1 b/src/mbsync.1
index 171727f..c8c8736 100644
--- a/src/mbsync.1
+++ b/src/mbsync.1
@@ -379,17 +379,27 @@ if you want to trust only hand-picked certificates.
 \fBCertificateFile\fR \fIpath\fR
 File containing additional X.509 certificates used to verify server
 identities.
-These certificates are always trusted, regardless of validity.
-.br
-The certificates from this file are matched only against the received
-server certificate itself; CA certificates are \fBnot\fR supported here.
-Do \fBnot\fR specify the system's CA certificate store here; see
-\fBSystemCertificates\fR instead.
-.br
-The contents for this file may be obtained using the
-\fBmbsync-get-cert\fR tool; make sure to verify the fingerprints of the
-certificates before trusting them, or transfer them securely from the
-server's network (if it is trusted).
+It may contain two types of certificates:
+.RS
+.IP Host
+These certificates are matched only against the received server certificate
+itself.
+They are always trusted, regardless of validity.
+A typical use case would be forcing acceptance of an expired certificate.
+.br
+These certificates may be obtained using the \fBmbsync-get-cert\fR tool;
+make sure to verify their fingerprints before trusting them, or transfer
+them securely from the server's network (if it can be trusted beyond the
+server itself).
+.IP CA
+These certificates are used as trust anchors when building the certificate
+chain for the received server certificate.
+They are used to supplant or supersede the system's trust store, depending
+on the \fBSystemCertificates\fR setting;
+it is not necessary and not recommended to specify the system's trust store
+itself here.
+The trust chains are fully validated.
+.RE
 .
 .TP
 \fBClientCertificate\fR \fIpath\fR
diff --git a/src/socket.c b/src/socket.c
index dbd781c..84449e7 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -41,7 +41,7 @@
 # include 
 # include 
 

[commit] master: Merge branch '1.3'

2020-07-08 Thread Oswald Buddenhagen via isync-devel
Skipped 14 existing revision(s) on branch 'master'.

commit cab14608caa7b99478c86b526179b3990359ea1e
Merge: e565d08 80deabf
Author: Oswald Buddenhagen 
Date:   Fri Nov 22 14:06:01 2019 +0100

Merge branch '1.3'

 Makefile.am   |   5 +-
 README|   7 ++
 TODO  |   2 -
 src/drv_imap.c|  58 ++
 src/drv_maildir.c |   9 ++-
 src/main.c|  26 ++-
 src/mbsync.1  | 191 --
 src/socket.c  |   5 +-
 src/sync.c|   4 +-
 src/util.c|   5 +-
 10 files changed, 194 insertions(+), 118 deletions(-)

diff --cc src/mbsync.1
index 8f6c58b,6830508..171727f
--- a/src/mbsync.1
+++ b/src/mbsync.1
@@@ -738,9 -745,9 +745,9 @@@ Default configuration fil
  .TP
  .B ~/.mbsync/
  Directory containing synchronization state files
- ..
+ .
  .SH SEE ALSO
 -mdconvert(1), isync(1), mutt(1), maildir(5)
 +mdconvert(1), mutt(1), maildir(5)
  .P
  Up to date information on \fBmbsync\fR can be found at http://isync.sf.net/
  .P

= Full diff against 1st parent =

diff --git a/Makefile.am b/Makefile.am
index 557742f..245299b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -47,7 +47,10 @@ LOG_PL = \
 print $$log."\n"; \
 }
 
-$(srcdir)/ChangeLog: log
+$(srcdir)/.git/index:
+$(srcdir)/ChangeLog: $(srcdir)/.git/index
+   $(MAKE) log
+
 log:
@test -z "$(srcdir)" || cd $(srcdir) && \
 ( ! test -d .git || \
diff --git a/README b/README
index 53c3fb1..e678cb5 100644
--- a/README
+++ b/README
@@ -54,11 +54,18 @@ change was necessary because of massive changes in the user 
interface.
 
 * Requirements
 
+perl v5.14+
 Berkeley DB 4.1+ (optional)
 OpenSSL for TLS/SSL support (optional)
 Cyrus SASL (optional)
 zlib (optional)
 
+  The build from git also requires:
+
+GNU autotools (autoconf & automake)
+perl module Date::Parse (libtimedate-perl on Debian, perl-TimeDate on
+ Fedora and Suse)
+
 * Installation
 
 ./autogen.sh (only when building from git)
diff --git a/TODO b/TODO
index b074e22..f8c6d73 100644
--- a/TODO
+++ b/TODO
@@ -37,8 +37,6 @@ Patterns.
   function being missing so far
 - this is needed for move detection, which would work only within one Channel
 
-normalize INBOX capitalization received from IMAP, to avoid anomalies.
-
 kill the concept of an INBOX, it is a relic from single-channel operation.
 if somebody needs it, he can have two stores with different Paths. the path
 can name a single (in-)box (curr. broken with maildir). an empty box name
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 76c0e3d..8d2ebf5 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -1180,7 +1180,7 @@ parse_response_code( imap_store_t *ctx, imap_cmd_t *cmd, 
char *s )
if (!(arg = next_arg(  )) ||
(ctx->uidnext = strtoul( arg, , 10 ), *earg))
{
-   error( "IMAP error: malformed NEXTUID status\n" );
+   error( "IMAP error: malformed UIDNEXT status\n" );
return RESP_CANCEL;
}
} else if (!strcmp( "CAPABILITY", arg )) {
@@ -1260,8 +1260,20 @@ parse_list_rsp_p1( imap_store_t *ctx, list_t *list, char 
*cmd ATTR_UNUSED )
return parse_list( ctx, cmd, parse_list_rsp_p2 );
 }
 
+// Use this to check whether a full path refers to the actual IMAP INBOX.
 static int
 is_inbox( imap_store_t *ctx, const char *arg, int argl )
+{
+   if (!starts_with_upper( arg, argl, "INBOX", 5 ))
+   return 0;
+   if (arg[5] && arg[5] != ctx->delimiter[0])
+   return 0;
+   return 1;
+}
+
+// Use this to check whether a path fragment collides with the canonical INBOX.
+static int
+is_INBOX( imap_store_t *ctx, const char *arg, int argl )
 {
if (!starts_with( arg, argl, "INBOX", 5 ))
return 0;
@@ -1284,16 +1296,22 @@ parse_list_rsp_p2( imap_store_t *ctx, list_t *list, 
char *cmd ATTR_UNUSED )
}
arg = list->val;
argl = list->len;
-   if ((l = strlen( ctx->prefix ))) {
-   if (starts_with( arg, argl, ctx->prefix, l )) {
-   arg += l;
-   argl -= l;
-   if (is_inbox( ctx, arg, argl )) {
-   if (!arg[5])
-   warn( "IMAP warning: ignoring INBOX in 
%s\n", ctx->prefix );
-   goto skip;
-   }
-   } else if (!is_inbox( ctx, arg, argl )) {
+   if (is_inbox( ctx, arg, argl )) {
+   // The server might be weird and have a non-uppercase INBOX. It
+   // may legitimately do so, but we need the canonical spelling.
+   memcpy( arg, "INBOX", 5 );
+   } else if ((l = strlen( ctx->prefix ))) {
+   if (!starts_with( arg, argl, ctx->prefix, l ))
+   goto skip;
+   arg += l;
+  

[commit] master: Merge branch '1.3'

2019-10-03 Thread Oswald Buddenhagen via isync-devel
Skipped 15 existing revision(s) on branch 'master'.

commit 462fed556a4ccb57c1259570583d846d343cc628
Merge: a310e7e d0a8551
Author: Oswald Buddenhagen 
Date:   Thu Oct 3 20:17:54 2019 +0200

Merge branch '1.3'

 configure.ac |   6 +--
 src/common.h |   1 +
 src/drv_imap.c   |  28 +++
 src/drv_proxy_gen.pl |   1 +
 src/mbsync.1 |  15 +++---
 src/socket.c | 111 ---
 6 files changed, 114 insertions(+), 48 deletions(-)


= Full diff against 1st parent =

diff --git a/configure.ac b/configure.ac
index 880f17c..a4c002d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,14 +18,14 @@ fi
 
 need_perl=5.14
 AC_CACHE_CHECK([whether perl is recent enough], ob_cv_perl_ver, [
-if $PERL -e "use v$need_perl;"; then
+if $PERL -e "use v$need_perl;" 2> /dev/null; then
 ob_cv_perl_ver=yes
 else
 ob_cv_perl_ver=no
 fi
 ])
 if test "x$ob_cv_perl_ver" = "xno"; then
-AC_MSG_ERROR([perl is too old])
+AC_MSG_ERROR([perl is too old, need v$need_perl])
 fi
 
 AC_CACHE_CHECK([whether strftime supports %z], ob_cv_strftime_z,
@@ -94,7 +94,7 @@ if test "x$ob_cv_with_ssl" != xno; then
 sav_LDFLAGS=$LDFLAGS
 LDFLAGS="$LDFLAGS $SSL_LDFLAGS"
 AC_CHECK_LIB(dl, dlopen, [LIBDL=-ldl])
-AC_CHECK_LIB(crypto, CRYPTO_lock, [LIBCRYPTO=-lcrypto])
+AC_CHECK_LIB(crypto, X509_cmp, [LIBCRYPTO=-lcrypto])
 AC_CHECK_LIB(ssl, SSL_connect,
  [SSL_LIBS="-lssl $LIBCRYPTO $LIBDL" have_ssl_paths=yes])
 LDFLAGS=$sav_LDFLAGS
diff --git a/src/common.h b/src/common.h
index c731126..d45929c 100644
--- a/src/common.h
+++ b/src/common.h
@@ -33,6 +33,7 @@
 typedef unsigned char uchar;
 typedef unsigned short ushort;
 typedef unsigned int uint;
+typedef unsigned long ulong;
 
 #define as(ar) (sizeof(ar)/sizeof(ar[0]))
 
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 58fc9d3..7bc88f6 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -953,7 +953,7 @@ parse_date( const char *str )
struct tm datetime;
 
memset( , 0, sizeof(datetime) );
-   if (!(end = strptime( str, "%d-%b-%Y %H:%M:%S ",  )))
+   if (!(end = strptime( str, "%e-%b-%Y %H:%M:%S ",  )))
return -1;
if ((date = timegm(  )) == -1)
return -1;
@@ -1203,17 +1203,16 @@ parse_response_code( imap_store_t *ctx, imap_cmd_t 
*cmd, char *s )
return RESP_OK;
 }
 
+static int parse_list_rsp_p1( imap_store_t *, list_t *, char * );
 static int parse_list_rsp_p2( imap_store_t *, list_t *, char * );
 
 static int
 parse_list_rsp( imap_store_t *ctx, list_t *list, char *cmd )
 {
-   char *arg;
list_t *lp;
 
if (!is_list( list )) {
free_list( list );
- bad_list:
error( "IMAP error: malformed LIST response\n" );
return LIST_BAD;
}
@@ -1223,10 +1222,19 @@ parse_list_rsp( imap_store_t *ctx, list_t *list, char 
*cmd )
return LIST_OK;
}
free_list( list );
-   if (!(arg = next_arg(  )))
-   goto bad_list;
-   if (!ctx->delimiter[0])
-   ctx->delimiter[0] = arg[0];
+   return parse_list( ctx, cmd, parse_list_rsp_p1 );
+}
+
+static int
+parse_list_rsp_p1( imap_store_t *ctx, list_t *list, char *cmd ATTR_UNUSED )
+{
+   if (!is_opt_atom( list )) {
+   error( "IMAP error: malformed LIST response\n" );
+   free_list( list );
+   return LIST_BAD;
+   }
+   if (!ctx->delimiter[0] && is_atom( list ))
+   ctx->delimiter[0] = list->val[0];
return parse_list( ctx, cmd, parse_list_rsp_p2 );
 }
 
@@ -1873,7 +1881,7 @@ ensure_password( imap_server_conf_t *srvc )
if (cmd) {
FILE *fp;
int ret;
-   char buffer[80];
+   char buffer[2048];  // Hopefully more than enough room for 
XOAUTH2, etc. tokens
 
if (*cmd == '+') {
flushn();
@@ -2079,7 +2087,7 @@ done_sasl_auth( imap_store_t *ctx, imap_cmd_t *cmd 
ATTR_UNUSED, int response )
int rc = sasl_client_step( ctx->sasl, NULL, 0, , , 
_len );
if (process_sasl_step( ctx, rc, NULL, 0, interact, , 
_len ) < 0)
warn( "Warning: SASL reported failure despite 
successful IMAP authentication. Ignoring...\n" );
-   else if (out)
+   else if (out_len > 0)
warn( "Warning: SASL wants more steps despite 
successful IMAP authentication. Ignoring...\n" );
}
 
@@ -2180,7 +2188,7 @@ imap_open_store_authenticate2( imap_store_t *ctx )
free( enc );
return;
  notsasl:
-   if (!ctx->sasl || sasl_listmech( ctx->sasl, NULL, "", "", "", 
, NULL, NULL ) != SASL_OK)
+   if (!ctx->sasl || sasl_listmech( ctx->sasl, NULL, "", " ", "", 
, NULL, NULL ) != SASL_OK)
 

[commit] master: Merge branch '1.3'

2018-11-26 Thread Oswald Buddenhagen via isync-devel
Skipped 6 existing revision(s) on branch 'master'.

commit 95d18e2778f28b7aac4f92dc6770430ee7c7ca4b
Merge: 37feedd acfa3a2
Author: Oswald Buddenhagen 
Date:   Tue Nov 27 00:51:03 2018 +0100

Merge branch '1.3'

 src/driver.c   |  9 
 src/driver.h   |  1 +
 src/drv_imap.c | 56 --
 src/socket.c   |  2 ++
 4 files changed, 62 insertions(+), 6 deletions(-)


= Full diff against 1st parent =

diff --git a/src/driver.c b/src/driver.c
index e522d14..e28d817 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -27,6 +27,15 @@
 
 driver_t *drivers[N_DRIVERS] = { _driver, _driver };
 
+int
+count_generic_messages( message_t *msgs )
+{
+   int count = 0;
+   for (; msgs; msgs = msgs->next)
+   count++;
+   return count;
+}
+
 void
 free_generic_messages( message_t *msgs )
 {
diff --git a/src/driver.h b/src/driver.h
index 00c5581..08edf20 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -261,6 +261,7 @@ struct driver {
int (*get_fail_state)( store_conf_t *conf );
 };
 
+int count_generic_messages( message_t * );
 void free_generic_messages( message_t * );
 
 void parse_generic_store( store_conf_t *store, conffile_t *cfg );
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 03eaf30..58fc9d3 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -291,7 +291,7 @@ send_imap_cmd( imap_store_t *ctx, imap_cmd_t *cmd )
int bufl, litplus, iovcnt = 1;
const char *buffmt;
conn_iovec_t iov[3];
-   char buf[1024];
+   char buf[4096];
 
cmd->tag = ++ctx->nexttag;
if (!cmd->param.data) {
@@ -448,7 +448,7 @@ imap_vprintf( const char *fmt, va_list ap )
char *d, *ed;
int maxlen;
char c;
-   char buf[1024]; /* Minimal supported command buffer size per IMAP spec. 
*/
+   char buf[4096];
 
d = buf;
ed = d + sizeof(buf);
@@ -601,8 +601,9 @@ imap_refcounted_new_cmd( imap_cmd_refcounted_state_t *sts )
free( sts ); \
}
 
-#define DONE_REFCOUNTED_STATE_ARGS(sts, ...) \
+#define DONE_REFCOUNTED_STATE_ARGS(sts, finalize, ...) \
if (!--sts->gen.ref_count) { \
+   finalize \
sts->callback( sts->gen.ret_val, __VA_ARGS__, sts->callback_aux 
); \
free( sts ); \
}
@@ -1108,7 +1109,6 @@ parse_fetch_rsp( imap_store_t *ctx, list_t *list, char *s 
ATTR_UNUSED )
if (status & M_FLAGS)
msgdata->flags = mask;
} else {
-   /* XXX this will need sorting for out-of-order (multiple 
queries) */
cur = nfcalloc( sizeof(*cur) );
*ctx->msgapp = >gen;
ctx->msgapp = >gen.next;
@@ -2593,6 +2593,47 @@ imap_load_box( store_t *gctx, uint minuid, uint maxuid, 
uint newuid, uint seenui
}
 }
 
+static int
+imap_sort_msgs_comp( const void *a_, const void *b_ )
+{
+   const message_t *a = *(const message_t * const *)a_;
+   const message_t *b = *(const message_t * const *)b_;
+
+   if (a->uid < b->uid)
+   return -1;
+   if (a->uid > b->uid)
+   return 1;
+   return 0;
+}
+
+static void
+imap_sort_msgs( imap_store_t *ctx )
+{
+   int count = count_generic_messages( ctx->msgs );
+   if (count <= 1)
+   return;
+
+   message_t **t = nfmalloc( sizeof(*t) * count );
+
+   message_t *m = ctx->msgs;
+   for (int i = 0; i < count; i++) {
+   t[i] = m;
+   m = m->next;
+   }
+
+   qsort( t, count, sizeof(*t), imap_sort_msgs_comp );
+
+   ctx->msgs = t[0];
+
+   int j;
+   for (j = 0; j < count - 1; j++)
+   t[j]->next = t[j + 1];
+   ctx->msgapp = [j]->next;
+   *ctx->msgapp = NULL;
+
+   free( t );
+}
+
 static void imap_submit_load_p2( imap_store_t *, imap_cmd_t *, int );
 
 static void
@@ -2621,7 +2662,10 @@ imap_submit_load_p2( imap_store_t *ctx, imap_cmd_t *cmd, 
int response )
 static void
 imap_submit_load_p3( imap_store_t *ctx, imap_load_box_state_t *sts )
 {
-   DONE_REFCOUNTED_STATE_ARGS(sts, ctx->msgs, ctx->total_msgs, 
ctx->recent_msgs)
+   DONE_REFCOUNTED_STATE_ARGS(sts, {
+   if (sts->gen.ret_val == DRV_OK)
+   imap_sort_msgs( ctx );
+   }, ctx->msgs, ctx->total_msgs, ctx->recent_msgs)
 }
 
 /*** imap_fetch_msg ***/
@@ -3018,7 +3062,7 @@ imap_list_store_p2( imap_store_t *ctx, imap_cmd_t *cmd, 
int response )
 static void
 imap_list_store_p3( imap_store_t *ctx, imap_list_store_state_t *sts )
 {
-   DONE_REFCOUNTED_STATE_ARGS(sts, ctx->boxes)
+   DONE_REFCOUNTED_STATE_ARGS(sts, , ctx->boxes)
 }
 
 /*** imap_cancel_cmds ***/
diff --git a/src/socket.c b/src/socket.c
index dd79619..e3fda42 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -271,6 +271,8 @@ socket_start_tls( conn_t *conn, void (*cb)( int ok, void 
*aux ) )
 
init_wakeup( 

[commit] master: Merge branch '1.3'

2018-11-26 Thread Oswald Buddenhagen via isync-devel
Skipped 1 existing revision(s) on branch 'master'.

commit 940cb3255139e97c0dec98416fa98962901f9a3e
Merge: 37feedd 17babc1
Author: Oswald Buddenhagen 
Date:   Sat Sep 8 18:48:05 2018 +0200

Merge branch '1.3'

 src/socket.c | 2 ++
 1 file changed, 2 insertions(+)

= Full diff against 1st parent =

diff --git a/src/socket.c b/src/socket.c
index dd79619..e3fda42 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -271,6 +271,8 @@ socket_start_tls( conn_t *conn, void (*cb)( int ok, void 
*aux ) )
 
init_wakeup( >ssl_fake, ssl_fake_cb, conn );
conn->ssl = SSL_new( ((server_conf_t *)conn->conf)->SSLContext );
+   if (ssl_return( "set server name", conn, SSL_set_tlsext_host_name( 
conn->ssl, conn->conf->host ) ) < 0)
+   return;
SSL_set_fd( conn->ssl, conn->fd );
SSL_set_mode( conn->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER );
socket_expect_read( conn, 1 );


___
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel


[commit] master: Merge branch '1.3'

2018-11-26 Thread Oswald Buddenhagen via isync-devel
Skipped 2 existing revision(s) on branch 'master'.

commit 3a7b4885278b1679e85020801391ba6c017c83a7
Merge: 940cb32 acfa3a2
Author: Oswald Buddenhagen 
Date:   Mon Nov 26 22:50:39 2018 +0100

Merge branch '1.3'

 src/driver.c   |  9 
 src/driver.h   |  1 +
 src/drv_imap.c | 56 --
 3 files changed, 60 insertions(+), 6 deletions(-)


= Full diff against 1st parent =

diff --git a/src/driver.c b/src/driver.c
index e522d14..e28d817 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -27,6 +27,15 @@
 
 driver_t *drivers[N_DRIVERS] = { _driver, _driver };
 
+int
+count_generic_messages( message_t *msgs )
+{
+   int count = 0;
+   for (; msgs; msgs = msgs->next)
+   count++;
+   return count;
+}
+
 void
 free_generic_messages( message_t *msgs )
 {
diff --git a/src/driver.h b/src/driver.h
index 00c5581..08edf20 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -261,6 +261,7 @@ struct driver {
int (*get_fail_state)( store_conf_t *conf );
 };
 
+int count_generic_messages( message_t * );
 void free_generic_messages( message_t * );
 
 void parse_generic_store( store_conf_t *store, conffile_t *cfg );
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 03eaf30..58fc9d3 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -291,7 +291,7 @@ send_imap_cmd( imap_store_t *ctx, imap_cmd_t *cmd )
int bufl, litplus, iovcnt = 1;
const char *buffmt;
conn_iovec_t iov[3];
-   char buf[1024];
+   char buf[4096];
 
cmd->tag = ++ctx->nexttag;
if (!cmd->param.data) {
@@ -448,7 +448,7 @@ imap_vprintf( const char *fmt, va_list ap )
char *d, *ed;
int maxlen;
char c;
-   char buf[1024]; /* Minimal supported command buffer size per IMAP spec. 
*/
+   char buf[4096];
 
d = buf;
ed = d + sizeof(buf);
@@ -601,8 +601,9 @@ imap_refcounted_new_cmd( imap_cmd_refcounted_state_t *sts )
free( sts ); \
}
 
-#define DONE_REFCOUNTED_STATE_ARGS(sts, ...) \
+#define DONE_REFCOUNTED_STATE_ARGS(sts, finalize, ...) \
if (!--sts->gen.ref_count) { \
+   finalize \
sts->callback( sts->gen.ret_val, __VA_ARGS__, sts->callback_aux 
); \
free( sts ); \
}
@@ -1108,7 +1109,6 @@ parse_fetch_rsp( imap_store_t *ctx, list_t *list, char *s 
ATTR_UNUSED )
if (status & M_FLAGS)
msgdata->flags = mask;
} else {
-   /* XXX this will need sorting for out-of-order (multiple 
queries) */
cur = nfcalloc( sizeof(*cur) );
*ctx->msgapp = >gen;
ctx->msgapp = >gen.next;
@@ -2593,6 +2593,47 @@ imap_load_box( store_t *gctx, uint minuid, uint maxuid, 
uint newuid, uint seenui
}
 }
 
+static int
+imap_sort_msgs_comp( const void *a_, const void *b_ )
+{
+   const message_t *a = *(const message_t * const *)a_;
+   const message_t *b = *(const message_t * const *)b_;
+
+   if (a->uid < b->uid)
+   return -1;
+   if (a->uid > b->uid)
+   return 1;
+   return 0;
+}
+
+static void
+imap_sort_msgs( imap_store_t *ctx )
+{
+   int count = count_generic_messages( ctx->msgs );
+   if (count <= 1)
+   return;
+
+   message_t **t = nfmalloc( sizeof(*t) * count );
+
+   message_t *m = ctx->msgs;
+   for (int i = 0; i < count; i++) {
+   t[i] = m;
+   m = m->next;
+   }
+
+   qsort( t, count, sizeof(*t), imap_sort_msgs_comp );
+
+   ctx->msgs = t[0];
+
+   int j;
+   for (j = 0; j < count - 1; j++)
+   t[j]->next = t[j + 1];
+   ctx->msgapp = [j]->next;
+   *ctx->msgapp = NULL;
+
+   free( t );
+}
+
 static void imap_submit_load_p2( imap_store_t *, imap_cmd_t *, int );
 
 static void
@@ -2621,7 +2662,10 @@ imap_submit_load_p2( imap_store_t *ctx, imap_cmd_t *cmd, 
int response )
 static void
 imap_submit_load_p3( imap_store_t *ctx, imap_load_box_state_t *sts )
 {
-   DONE_REFCOUNTED_STATE_ARGS(sts, ctx->msgs, ctx->total_msgs, 
ctx->recent_msgs)
+   DONE_REFCOUNTED_STATE_ARGS(sts, {
+   if (sts->gen.ret_val == DRV_OK)
+   imap_sort_msgs( ctx );
+   }, ctx->msgs, ctx->total_msgs, ctx->recent_msgs)
 }
 
 /*** imap_fetch_msg ***/
@@ -3018,7 +3062,7 @@ imap_list_store_p2( imap_store_t *ctx, imap_cmd_t *cmd, 
int response )
 static void
 imap_list_store_p3( imap_store_t *ctx, imap_list_store_state_t *sts )
 {
-   DONE_REFCOUNTED_STATE_ARGS(sts, ctx->boxes)
+   DONE_REFCOUNTED_STATE_ARGS(sts, , ctx->boxes)
 }
 
 /*** imap_cancel_cmds ***/


___
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel


[commit] master: Merge branch '1.3'

2018-07-19 Thread Oswald Buddenhagen via isync-devel
Skipped 4 existing revision(s) on branch 'master'.

commit 37feeddbfb8d86fcd25f90c7928d5ea139b0feb4
Merge: c4d7f01 f698f16
Author: Oswald Buddenhagen 
Date:   Sun Jul 1 13:26:10 2018 +0200

Merge branch '1.3'

 src/drv_imap.c| 14 ++
 src/drv_maildir.c |  6 +++---
 src/drv_proxy.c   |  8 
 src/socket.c  |  3 ++-
 src/socket.h  |  2 +-
 5 files changed, 20 insertions(+), 13 deletions(-)


= Full diff against 1st parent =

diff --git a/src/drv_imap.c b/src/drv_imap.c
index e782ec0..03eaf30 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -2927,7 +2927,7 @@ imap_find_new_msgs_p2( imap_store_t *ctx, imap_cmd_t 
*gcmd, int response )
cmd->uid = cmdp->uid;
cmd->gen.param.lastuid = 1;
imap_exec( ctx, >gen, imap_find_new_msgs_p3,
-  "UID FETCH *:* (UID)" );
+  "UID FETCH * (UID)" );
 }
 
 static void
@@ -3137,9 +3137,15 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep 
)
server->pass = nfstrdup( cfg->val );
else if (!strcasecmp( "PassCmd", cfg->cmd ))
server->pass_cmd = nfstrdup( cfg->val );
-   else if (!strcasecmp( "Port", cfg->cmd ))
-   server->sconf.port = parse_int( cfg );
-   else if (!strcasecmp( "Timeout", cfg->cmd ))
+   else if (!strcasecmp( "Port", cfg->cmd )) {
+   int port = parse_int( cfg );
+   if ((unsigned)port > 0x) {
+   error( "%s:%d: Invalid port number\n", 
cfg->file, cfg->line );
+   cfg->err = 1;
+   } else {
+   server->sconf.port = (ushort)port;
+   }
+   } else if (!strcasecmp( "Timeout", cfg->cmd ))
server->sconf.timeout = parse_int( cfg );
else if (!strcasecmp( "PipelineDepth", cfg->cmd )) {
if ((server->max_in_progress = parse_int( cfg )) < 1) {
diff --git a/src/drv_maildir.c b/src/drv_maildir.c
index d094146..d8c41c5 100644
--- a/src/drv_maildir.c
+++ b/src/drv_maildir.c
@@ -1573,7 +1573,7 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int 
to_trash,
uint uid;
char buf[_POSIX_PATH_MAX], nbuf[_POSIX_PATH_MAX], fbuf[NUM_FLAGS + 3], 
base[128];
 
-   bl = nfsnprintf( base, sizeof(base), "%ld.%d_%d.%s", (long)time( 0 ), 
Pid, ++MaildirCount, Hostname );
+   bl = nfsnprintf( base, sizeof(base), "%lld.%d_%d.%s", (long long)time( 
0 ), Pid, ++MaildirCount, Hostname );
if (!to_trash) {
 #ifdef USE_DB
if (ctx->usedb) {
@@ -1754,8 +1754,8 @@ maildir_trash_msg( store_t *gctx, message_t *gmsg,
for (;;) {
nfsnprintf( buf, sizeof(buf), "%s/%s/%s", ctx->path, 
subdirs[gmsg->status & M_RECENT], msg->base );
s = strstr( msg->base, ((maildir_store_conf_t 
*)gctx->conf)->info_prefix );
-   nfsnprintf( nbuf, sizeof(nbuf), "%s/%s/%ld.%d_%d.%s%s", 
ctx->trash,
-   subdirs[gmsg->status & M_RECENT], (long)time( 0 ), 
Pid, ++MaildirCount, Hostname, s ? s : "" );
+   nfsnprintf( nbuf, sizeof(nbuf), "%s/%s/%lld.%d_%d.%s%s", 
ctx->trash,
+   subdirs[gmsg->status & M_RECENT], (long long)time( 
0 ), Pid, ++MaildirCount, Hostname, s ? s : "" );
if (!rename( buf, nbuf ))
break;
if (!stat( buf,  )) {
diff --git a/src/drv_proxy.c b/src/drv_proxy.c
index 4fa40a7..2ef928a 100644
--- a/src/drv_proxy.c
+++ b/src/drv_proxy.c
@@ -242,8 +242,8 @@ proxy_@name@( store_t *gctx@decl_args@, void (*cb)( 
@decl_cb_args@void *aux ), v
static char fbuf[as(Flags) + 1];
proxy_make_flags( cmd->data->flags, fbuf );
 //# END
-//# DEFINE fetch_msg_print_fmt_cb_args , flags=%s, date=%ld, size=%d
-//# DEFINE fetch_msg_print_pass_cb_args , fbuf, cmd->data->date, cmd->data->len
+//# DEFINE fetch_msg_print_fmt_cb_args , flags=%s, date=%lld, size=%d
+//# DEFINE fetch_msg_print_pass_cb_args , fbuf, (long long)cmd->data->date, 
cmd->data->len
 //# DEFINE fetch_msg_print_cb_args
if (sts == DRV_OK && (DFlags & DEBUG_DRV_ALL)) {
printf( "%s=\n", cmd->gen.ctx->label );
@@ -257,8 +257,8 @@ proxy_@name@( store_t *gctx@decl_args@, void (*cb)( 
@decl_cb_args@void *aux ), v
static char fbuf[as(Flags) + 1];
proxy_make_flags( data->flags, fbuf );
 //# END
-//# DEFINE store_msg_print_fmt_args , flags=%s, date=%ld, size=%d, to_trash=%s
-//# DEFINE store_msg_print_pass_args , fbuf, data->date, data->len, to_trash ? 
"yes" : "no"
+//# DEFINE store_msg_print_fmt_args , flags=%s, date=%lld, size=%d, to_trash=%s
+//# DEFINE store_msg_print_pass_args , fbuf, (long long)data->date, data->len, 
to_trash ? "yes" : "no"
 //# DEFINE store_msg_print_args
if (DFlags & DEBUG_DRV_ALL) {
printf( 

[commit] master: Merge branch '1.3'

2018-04-08 Thread Oswald Buddenhagen via isync-devel
Skipped 10 existing revision(s) on branch 'master'.

commit 904858365d636d5d949253c6e6a18227249f8ef7
Merge: cbac8aa 5072032
Author: Oswald Buddenhagen 
Date:   Sun Apr 8 18:17:10 2018 +0200

Merge branch '1.3'

Conflicts:
configure.ac

 .gitignore|  1 +
 configure.ac  | 17 +
 src/config.c  |  2 ++
 src/drv_imap.c|  4 ++--
 src/drv_maildir.c | 21 +++--
 src/main.c|  4 ++--
 src/socket.h  |  4 +---
 src/sync.c|  2 +-
 src/util.c| 27 ++-
 9 files changed, 47 insertions(+), 35 deletions(-)


= Full diff against 1st parent =

diff --git a/.gitignore b/.gitignore
index 05a49c7..310c028 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,7 @@
 /install-sh
 /isync.spec
 /isync-*.tar.gz
+/isync-*.tar.gz.asc
 /missing
 /patch-stamp
 /stamp-h
diff --git a/configure.ac b/configure.ac
index fc170f8..f56ed81 100644
--- a/configure.ac
+++ b/configure.ac
@@ -11,6 +11,23 @@ fi
 
 CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
 
+AC_CHECK_PROG(PERL, perl, perl)
+if test "x$PERL" = "x"; then
+AC_MSG_ERROR([perl not found])
+fi
+
+need_perl=5.14
+AC_CACHE_CHECK([whether perl is recent enough], ob_cv_perl_ver, [
+if $PERL -e "use v$need_perl;"; then
+ob_cv_perl_ver=yes
+else
+ob_cv_perl_ver=no
+fi
+])
+if test "x$ob_cv_perl_ver" = "xno"; then
+AC_MSG_ERROR([perl is too old])
+fi
+
 AC_CACHE_CHECK([whether strftime supports %z], ob_cv_strftime_z,
 [AC_TRY_RUN(
 [#include 
diff --git a/src/config.c b/src/config.c
index 20f09d9..8ddfe26 100644
--- a/src/config.c
+++ b/src/config.c
@@ -355,6 +355,8 @@ load_config( const char *where, int pseudo )
if (store) {
if (!store->max_size)
store->max_size = INT_MAX;
+   if (!store->flat_delim)
+   store->flat_delim = "";
*storeapp = store;
storeapp = >next;
*storeapp = 0;
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 56d71cb..05afa09 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -2250,7 +2250,7 @@ imap_open_store_namespace( imap_store_t *ctx )
 
ctx->state = SST_HALF;
ctx->prefix = cfg->gen.path;
-   ctx->delimiter[0] = cfg->delimiter ? cfg->delimiter : 0;
+   ctx->delimiter[0] = cfg->delimiter;
if (((!ctx->prefix && cfg->use_namespace) || !cfg->delimiter) && 
CAP(NAMESPACE)) {
/* get NAMESPACE info */
if (!ctx->got_namespace)
@@ -2388,7 +2388,7 @@ imap_open_box_p2( imap_store_t *ctx, imap_cmd_t *gcmd, 
int response )
INIT_IMAP_CMD(imap_cmd_open_box_t, cmd, cmdp->callback, 
cmdp->callback_aux)
cmd->gen.param.lastuid = 1;
imap_exec( ctx, >gen, imap_open_box_p3,
-  "UID FETCH *:* (UID)" );
+  "UID FETCH * (UID)" );
 }
 
 static void
diff --git a/src/drv_maildir.c b/src/drv_maildir.c
index c4dd6c7..4a94696 100644
--- a/src/drv_maildir.c
+++ b/src/drv_maildir.c
@@ -1153,28 +1153,29 @@ maildir_scan( maildir_store_t *ctx, msg_t_array_alloc_t 
*msglist )
goto retry;
}
int off, in_msgid = 0;
-   while ((want_tuid || want_msgid) && fgets( 
nbuf, sizeof(nbuf), f )) {
-   int bufl = strlen( nbuf );
-   if (bufl && nbuf[bufl - 1] == '\n')
+   char lnbuf[1000];  // Says RFC2822
+   while ((want_tuid || want_msgid) && fgets( 
lnbuf, sizeof(lnbuf), f )) {
+   int bufl = strlen( lnbuf );
+   if (bufl && lnbuf[bufl - 1] == '\n')
--bufl;
-   if (bufl && nbuf[bufl - 1] == '\r')
+   if (bufl && lnbuf[bufl - 1] == '\r')
--bufl;
if (!bufl)
break;
-   if (want_tuid && starts_with( nbuf, 
bufl, "X-TUID: ", 8 )) {
+   if (want_tuid && starts_with( lnbuf, 
bufl, "X-TUID: ", 8 )) {
if (bufl < 8 + TUIDL) {
error( "Maildir error: 
malformed X-TUID header (UID %u)\n", uid );
continue;
}
-   memcpy(