commit 0dd0cf34e373503f9b9c61edbcc8c23826db7c62
Author: Oswald Buddenhagen <[email protected]>
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 make the
socket object refcounted like the imap context is.
src/drv_imap.c | 25 ++++++++++++++++---------
src/isync.h | 12 ++++++++++++
src/socket.c | 15 ++++++++++-----
3 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 3bbee11..3cab01a 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -232,7 +232,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)
@@ -275,8 +275,6 @@ v_submit_imap_cmd( imap_store_t *ctx, struct imap_cmd *cmd,
return cmd;
bail:
- ctx->gen.bad_callback( ctx->gen.bad_callback_aux );
- bail2:
done_imap_cmd( ctx, cmd, RESP_CANCEL );
return NULL;
}
@@ -808,7 +806,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;
}
@@ -851,7 +849,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)
@@ -876,16 +874,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 ) < 0)
- 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)
@@ -959,6 +957,14 @@ get_cmd_result_p2( imap_store_t *ctx, struct imap_cmd
*cmd, int response )
}
}
+static void
+imap_socket_fail( void *aux )
+{
+ imap_store_t *ctx = (imap_store_t *)aux;
+
+ ctx->gen.bad_callback( ctx->gen.bad_callback_aux );
+}
+
/******************* imap_cancel_store *******************/
static void
@@ -1091,12 +1097,13 @@ imap_open_store( store_conf_t *conf,
ctx = nfcalloc( sizeof(*ctx) );
ctx->gen.conf = conf;
- ctx->conn.fd = -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, imap_socket_fail, ctx );
+
if (!socket_connect( &srvc->sconf, &ctx->conn ))
goto bail;
diff --git a/src/isync.h b/src/isync.h
index b605fff..91f0d12 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' */
@@ -333,6 +336,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 6941226..ad00c9f 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 );
------------------------------------------------------------------------------
Xperia(TM) PLAY
It's a major breakthrough. An authentic gaming
smartphone on the nation's most reliable network.
And it wants your games.
http://p.sf.net/sfu/verizon-sfdev
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel