commit 55e75d98a8a15a25994df9dfd51af9a645d36cae Author: Oswald Buddenhagen <o...@kde.org> Date: Sun Mar 27 16:50:32 2011 +0200
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. src/drv_imap.c | 17 ++++++++--------- src/isync.h | 12 ++++++++++++ src/socket.c | 15 ++++++++++----- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/drv_imap.c b/src/drv_imap.c index 71c432f..64e0e44 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -236,7 +236,7 @@ v_submit_imap_cmd( imap_store_t *ctx, struct imap_cmd *cmd, while (ctx->literal_pending) if (get_cmd_result( ctx, 0 ) == RESP_CANCEL) - goto bail2; + goto bail; cmd->tag = ++ctx->nexttag; if (fmt) @@ -279,8 +279,6 @@ v_submit_imap_cmd( imap_store_t *ctx, struct imap_cmd *cmd, return cmd; bail: - imap_invoke_bad_callback( ctx ); - bail2: done_imap_cmd( ctx, cmd, RESP_CANCEL ); return NULL; } @@ -811,7 +809,7 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd ) for (;;) { if (!(cmd = socket_read_line( &ctx->conn ))) { if (socket_fill( &ctx->conn ) < 0) - break; + return RESP_CANCEL; continue; } @@ -854,7 +852,7 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd ) break; /* stream is likely to be useless now */ if (resp == LIST_PARTIAL) { if (socket_fill( &ctx->conn ) < 0) - break; + return RESP_CANCEL; goto do_fetch; } 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; cmdp->param.data = 0; if (socket_write( &ctx->conn, p, cmdp->param.data_len, GiveOwn ) < 0) - break; + return RESP_CANCEL; } else if (cmdp->param.cont) { if (cmdp->param.cont( ctx, cmdp, cmd )) - break; + return RESP_CANCEL; } else { error( "IMAP error: unexpected command continuation request\n" ); break; } if (socket_write( &ctx->conn, "\r\n", 2, KeepOwn ) < 0) - break; + return RESP_CANCEL; if (!cmdp->param.cont) ctx->literal_pending = 0; if (!tcmd) @@ -1128,13 +1126,14 @@ imap_open_store( store_conf_t *conf, ctx = nfcalloc( sizeof(*ctx) ); ctx->gen.conf = conf; - ctx->conn.fd = -1; ctx->ref_count = 1; ctx->callbacks.imap_open = cb; ctx->callback_aux = aux; set_bad_callback( &ctx->gen, (void (*)(void *))imap_open_store_bail, ctx ); 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 )) goto bail; diff --git a/src/isync.h b/src/isync.h index 7de6f33..ff27ed3 100644 --- a/src/isync.h +++ b/src/isync.h @@ -79,6 +79,9 @@ typedef struct { SSL *ssl; #endif + void (*bad_callback)( void *aux ); /* async fail while sending or listening */ + void *callback_aux; + int offset; /* start 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' */ @@ -330,6 +333,15 @@ extern const char *Home; /* 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_start_tls( const server_conf_t *conf, conn_t *sock ); void socket_close( conn_t *sock ); diff --git a/src/socket.c b/src/socket.c index 076c075..7d0d24e 100644 --- a/src/socket.c +++ b/src/socket.c @@ -49,6 +49,12 @@ #include <netdb.h> static void +socket_fail( conn_t *conn ) +{ + conn->bad_callback( conn->callback_aux ); +} + +static void socket_perror( const char *func, conn_t *sock, int ret ) { #ifdef HAVE_LIBSSL @@ -65,20 +71,18 @@ socket_perror( const char *func, conn_t *sock, int ret ) error( "SSL_%s: %s\n", func, strerror(errno) ); } else error( "SSL_%s: %s\n", func, ERR_error_string( err, 0 ) ); - return; + break; default: error( "SSL_%s: unhandled SSL error %d\n", func, err ); break; } - return; - } -#else - (void)sock; + } else #endif if (ret < 0) perror( func ); else error( "%s: unexpected EOF\n", func ); + socket_fail( sock ); } #ifdef HAVE_LIBSSL @@ -361,6 +365,7 @@ socket_fill( conn_t *sock ) int len = sizeof(sock->buf) - n; if (!len) { error( "Socket error: receive buffer full. Probably protocol error.\n" ); + socket_fail( sock ); return -1; } assert( sock->fd >= 0 ); ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ isync-devel mailing list isync-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/isync-devel