Merge branch '1.3'

This commit is contained in:
Oswald Buddenhagen 2018-11-27 00:51:03 +01:00
commit 95d18e2778
4 changed files with 62 additions and 6 deletions

View File

@ -27,6 +27,15 @@
driver_t *drivers[N_DRIVERS] = { &maildir_driver, &imap_driver }; 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 void
free_generic_messages( message_t *msgs ) free_generic_messages( message_t *msgs )
{ {

View File

@ -261,6 +261,7 @@ struct driver {
int (*get_fail_state)( store_conf_t *conf ); int (*get_fail_state)( store_conf_t *conf );
}; };
int count_generic_messages( message_t * );
void free_generic_messages( message_t * ); void free_generic_messages( message_t * );
void parse_generic_store( store_conf_t *store, conffile_t *cfg ); void parse_generic_store( store_conf_t *store, conffile_t *cfg );

View File

@ -291,7 +291,7 @@ send_imap_cmd( imap_store_t *ctx, imap_cmd_t *cmd )
int bufl, litplus, iovcnt = 1; int bufl, litplus, iovcnt = 1;
const char *buffmt; const char *buffmt;
conn_iovec_t iov[3]; conn_iovec_t iov[3];
char buf[1024]; char buf[4096];
cmd->tag = ++ctx->nexttag; cmd->tag = ++ctx->nexttag;
if (!cmd->param.data) { if (!cmd->param.data) {
@ -448,7 +448,7 @@ imap_vprintf( const char *fmt, va_list ap )
char *d, *ed; char *d, *ed;
int maxlen; int maxlen;
char c; char c;
char buf[1024]; /* Minimal supported command buffer size per IMAP spec. */ char buf[4096];
d = buf; d = buf;
ed = d + sizeof(buf); ed = d + sizeof(buf);
@ -601,8 +601,9 @@ imap_refcounted_new_cmd( imap_cmd_refcounted_state_t *sts )
free( sts ); \ free( sts ); \
} }
#define DONE_REFCOUNTED_STATE_ARGS(sts, ...) \ #define DONE_REFCOUNTED_STATE_ARGS(sts, finalize, ...) \
if (!--sts->gen.ref_count) { \ if (!--sts->gen.ref_count) { \
finalize \
sts->callback( sts->gen.ret_val, __VA_ARGS__, sts->callback_aux ); \ sts->callback( sts->gen.ret_val, __VA_ARGS__, sts->callback_aux ); \
free( sts ); \ free( sts ); \
} }
@ -1108,7 +1109,6 @@ parse_fetch_rsp( imap_store_t *ctx, list_t *list, char *s ATTR_UNUSED )
if (status & M_FLAGS) if (status & M_FLAGS)
msgdata->flags = mask; msgdata->flags = mask;
} else { } else {
/* XXX this will need sorting for out-of-order (multiple queries) */
cur = nfcalloc( sizeof(*cur) ); cur = nfcalloc( sizeof(*cur) );
*ctx->msgapp = &cur->gen; *ctx->msgapp = &cur->gen;
ctx->msgapp = &cur->gen.next; 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 imap_submit_load_p2( imap_store_t *, imap_cmd_t *, int );
static void static void
@ -2621,7 +2662,10 @@ imap_submit_load_p2( imap_store_t *ctx, imap_cmd_t *cmd, int response )
static void static void
imap_submit_load_p3( imap_store_t *ctx, imap_load_box_state_t *sts ) 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 *******************/ /******************* imap_fetch_msg *******************/
@ -3018,7 +3062,7 @@ imap_list_store_p2( imap_store_t *ctx, imap_cmd_t *cmd, int response )
static void static void
imap_list_store_p3( imap_store_t *ctx, imap_list_store_state_t *sts ) 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 *******************/ /******************* imap_cancel_cmds *******************/

View File

@ -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 ); init_wakeup( &conn->ssl_fake, ssl_fake_cb, conn );
conn->ssl = SSL_new( ((server_conf_t *)conn->conf)->SSLContext ); 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_fd( conn->ssl, conn->fd );
SSL_set_mode( conn->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER ); SSL_set_mode( conn->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER );
socket_expect_read( conn, 1 ); socket_expect_read( conn, 1 );