Explorar o código

Merge branch '1.3'

Oswald Buddenhagen %!s(int64=6) %!d(string=hai) anos
pai
achega
95d18e2778
Modificáronse 4 ficheiros con 62 adicións e 6 borrados
  1. 9 0
      src/driver.c
  2. 1 0
      src/driver.h
  3. 50 6
      src/drv_imap.c
  4. 2 0
      src/socket.c

+ 9 - 0
src/driver.c

@@ -27,6 +27,15 @@
 
 driver_t *drivers[N_DRIVERS] = { &maildir_driver, &imap_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 )
 {

+ 1 - 0
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 );

+ 50 - 6
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 = &cur->gen;
 		ctx->msgapp = &cur->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 = &t[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 *******************/

+ 2 - 0
src/socket.c

@@ -271,6 +271,8 @@ socket_start_tls( conn_t *conn, void (*cb)( int ok, void *aux ) )
 
 	init_wakeup( &conn->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 );