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

Reply via email to