make socket read/write error reporting callback-based
the functions still have synchronous return codes as well - this enables early error returns without having to resort to refcounting.
This commit is contained in:
parent
f1df2f40d1
commit
802c99edcf
|
@ -236,7 +236,7 @@ v_submit_imap_cmd( imap_store_t *ctx, struct imap_cmd *cmd,
|
||||||
|
|
||||||
while (ctx->literal_pending)
|
while (ctx->literal_pending)
|
||||||
if (get_cmd_result( ctx, 0 ) == RESP_CANCEL)
|
if (get_cmd_result( ctx, 0 ) == RESP_CANCEL)
|
||||||
goto bail2;
|
goto bail;
|
||||||
|
|
||||||
cmd->tag = ++ctx->nexttag;
|
cmd->tag = ++ctx->nexttag;
|
||||||
if (fmt)
|
if (fmt)
|
||||||
|
@ -279,8 +279,6 @@ v_submit_imap_cmd( imap_store_t *ctx, struct imap_cmd *cmd,
|
||||||
return cmd;
|
return cmd;
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
imap_invoke_bad_callback( ctx );
|
|
||||||
bail2:
|
|
||||||
done_imap_cmd( ctx, cmd, RESP_CANCEL );
|
done_imap_cmd( ctx, cmd, RESP_CANCEL );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -811,7 +809,7 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!(cmd = socket_read_line( &ctx->conn ))) {
|
if (!(cmd = socket_read_line( &ctx->conn ))) {
|
||||||
if (socket_fill( &ctx->conn ) < 0)
|
if (socket_fill( &ctx->conn ) < 0)
|
||||||
break;
|
return RESP_CANCEL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,7 +852,7 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
|
||||||
break; /* stream is likely to be useless now */
|
break; /* stream is likely to be useless now */
|
||||||
if (resp == LIST_PARTIAL) {
|
if (resp == LIST_PARTIAL) {
|
||||||
if (socket_fill( &ctx->conn ) < 0)
|
if (socket_fill( &ctx->conn ) < 0)
|
||||||
break;
|
return RESP_CANCEL;
|
||||||
goto do_fetch;
|
goto do_fetch;
|
||||||
}
|
}
|
||||||
if (parse_fetch( ctx, ctx->parse_list_sts.head ) < 0)
|
if (parse_fetch( ctx, ctx->parse_list_sts.head ) < 0)
|
||||||
|
@ -882,16 +880,16 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
|
||||||
p = cmdp->param.data;
|
p = cmdp->param.data;
|
||||||
cmdp->param.data = 0;
|
cmdp->param.data = 0;
|
||||||
if (socket_write( &ctx->conn, p, cmdp->param.data_len, GiveOwn ) < 0)
|
if (socket_write( &ctx->conn, p, cmdp->param.data_len, GiveOwn ) < 0)
|
||||||
break;
|
return RESP_CANCEL;
|
||||||
} else if (cmdp->param.cont) {
|
} else if (cmdp->param.cont) {
|
||||||
if (cmdp->param.cont( ctx, cmdp, cmd ))
|
if (cmdp->param.cont( ctx, cmdp, cmd ))
|
||||||
break;
|
return RESP_CANCEL;
|
||||||
} else {
|
} else {
|
||||||
error( "IMAP error: unexpected command continuation request\n" );
|
error( "IMAP error: unexpected command continuation request\n" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (socket_write( &ctx->conn, "\r\n", 2, KeepOwn ) < 0)
|
if (socket_write( &ctx->conn, "\r\n", 2, KeepOwn ) < 0)
|
||||||
break;
|
return RESP_CANCEL;
|
||||||
if (!cmdp->param.cont)
|
if (!cmdp->param.cont)
|
||||||
ctx->literal_pending = 0;
|
ctx->literal_pending = 0;
|
||||||
if (!tcmd)
|
if (!tcmd)
|
||||||
|
@ -1128,13 +1126,14 @@ imap_open_store( store_conf_t *conf,
|
||||||
|
|
||||||
ctx = nfcalloc( sizeof(*ctx) );
|
ctx = nfcalloc( sizeof(*ctx) );
|
||||||
ctx->gen.conf = conf;
|
ctx->gen.conf = conf;
|
||||||
ctx->conn.fd = -1;
|
|
||||||
ctx->ref_count = 1;
|
ctx->ref_count = 1;
|
||||||
ctx->callbacks.imap_open = cb;
|
ctx->callbacks.imap_open = cb;
|
||||||
ctx->callback_aux = aux;
|
ctx->callback_aux = aux;
|
||||||
set_bad_callback( &ctx->gen, (void (*)(void *))imap_open_store_bail, ctx );
|
set_bad_callback( &ctx->gen, (void (*)(void *))imap_open_store_bail, ctx );
|
||||||
ctx->in_progress_append = &ctx->in_progress;
|
ctx->in_progress_append = &ctx->in_progress;
|
||||||
|
|
||||||
|
socket_init( &ctx->conn, (void (*)( void * ))imap_invoke_bad_callback, ctx );
|
||||||
|
|
||||||
if (!socket_connect( &srvc->sconf, &ctx->conn ))
|
if (!socket_connect( &srvc->sconf, &ctx->conn ))
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
|
|
12
src/isync.h
12
src/isync.h
|
@ -79,6 +79,9 @@ typedef struct {
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void (*bad_callback)( void *aux ); /* async fail while sending or listening */
|
||||||
|
void *callback_aux;
|
||||||
|
|
||||||
int offset; /* start of filled bytes in buffer */
|
int offset; /* start of filled bytes in buffer */
|
||||||
int bytes; /* number of filled bytes in buffer */
|
int bytes; /* number of filled bytes in buffer */
|
||||||
int scanoff; /* offset to continue scanning for newline at, relative to 'offset' */
|
int scanoff; /* offset to continue scanning for newline at, relative to 'offset' */
|
||||||
|
@ -330,6 +333,15 @@ extern const char *Home;
|
||||||
|
|
||||||
/* socket.c */
|
/* socket.c */
|
||||||
|
|
||||||
|
/* call this before doing anything with the socket */
|
||||||
|
static INLINE void socket_init( conn_t *conn,
|
||||||
|
void (*bad_callback)( void *aux ),
|
||||||
|
void *aux )
|
||||||
|
{
|
||||||
|
conn->bad_callback = bad_callback;
|
||||||
|
conn->callback_aux = aux;
|
||||||
|
conn->fd = -1;
|
||||||
|
}
|
||||||
int socket_connect( const server_conf_t *conf, conn_t *sock );
|
int socket_connect( const server_conf_t *conf, conn_t *sock );
|
||||||
int socket_start_tls( const server_conf_t *conf, conn_t *sock );
|
int socket_start_tls( const server_conf_t *conf, conn_t *sock );
|
||||||
void socket_close( conn_t *sock );
|
void socket_close( conn_t *sock );
|
||||||
|
|
15
src/socket.c
15
src/socket.c
|
@ -48,6 +48,12 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
socket_fail( conn_t *conn )
|
||||||
|
{
|
||||||
|
conn->bad_callback( conn->callback_aux );
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
socket_perror( const char *func, conn_t *sock, int ret )
|
socket_perror( const char *func, conn_t *sock, int ret )
|
||||||
{
|
{
|
||||||
|
@ -65,20 +71,18 @@ socket_perror( const char *func, conn_t *sock, int ret )
|
||||||
error( "SSL_%s: %s\n", func, strerror(errno) );
|
error( "SSL_%s: %s\n", func, strerror(errno) );
|
||||||
} else
|
} else
|
||||||
error( "SSL_%s: %s\n", func, ERR_error_string( err, 0 ) );
|
error( "SSL_%s: %s\n", func, ERR_error_string( err, 0 ) );
|
||||||
return;
|
break;
|
||||||
default:
|
default:
|
||||||
error( "SSL_%s: unhandled SSL error %d\n", func, err );
|
error( "SSL_%s: unhandled SSL error %d\n", func, err );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
} else
|
||||||
}
|
|
||||||
#else
|
|
||||||
(void)sock;
|
|
||||||
#endif
|
#endif
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
perror( func );
|
perror( func );
|
||||||
else
|
else
|
||||||
error( "%s: unexpected EOF\n", func );
|
error( "%s: unexpected EOF\n", func );
|
||||||
|
socket_fail( sock );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
|
@ -361,6 +365,7 @@ socket_fill( conn_t *sock )
|
||||||
int len = sizeof(sock->buf) - n;
|
int len = sizeof(sock->buf) - n;
|
||||||
if (!len) {
|
if (!len) {
|
||||||
error( "Socket error: receive buffer full. Probably protocol error.\n" );
|
error( "Socket error: receive buffer full. Probably protocol error.\n" );
|
||||||
|
socket_fail( sock );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
assert( sock->fd >= 0 );
|
assert( sock->fd >= 0 );
|
||||||
|
|
Loading…
Reference in New Issue
Block a user