commit cf79cd9fc0077d5c871a5b5deaf778bf0914cc33
Author: Oswald Buddenhagen <[email protected]>
Date: Sat Jul 27 14:31:13 2013 +0200
make parse_list() callback based
this allows us to parse IMAP literals ({}) in every list.
src/drv_imap.c | 100 +++++++++++++++++++++++++++++++++--------------
1 files changed, 70 insertions(+), 30 deletions(-)
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 1f40bf2..34d2c47 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -70,8 +70,11 @@ typedef struct _list {
#define MAX_LIST_DEPTH 5
+struct imap_store;
+
typedef struct parse_list_state {
list_t *head, **stack[MAX_LIST_DEPTH];
+ int (*callback)( struct imap_store *ctx, list_t *list, char *cmd );
int level, need_bytes;
} parse_list_state_t;
@@ -642,18 +645,63 @@ parse_list_init( parse_list_state_t *sts )
sts->stack[0] = &sts->head;
}
-static list_t *
-parse_list( char **sp )
+static int
+parse_list_continue( imap_store_t *ctx, char *s )
+{
+ list_t *list;
+ int resp;
+ if ((resp = parse_imap_list( ctx, &s, &ctx->parse_list_sts )) ==
LIST_PARTIAL)
+ return 0;
+ list = (resp == LIST_BAD) ? 0 : ctx->parse_list_sts.head;
+ ctx->parse_list_sts.head = 0;
+ return ctx->parse_list_sts.callback( ctx, list, s );
+}
+
+static int
+parse_list( imap_store_t *ctx, char *s, int (*cb)( imap_store_t *ctx, list_t
*list, char *s ) )
+{
+ parse_list_init( &ctx->parse_list_sts );
+ ctx->parse_list_sts.callback = cb;
+ return parse_list_continue( ctx, s );
+}
+
+static int parse_namespace_rsp_p2( imap_store_t *, list_t *, char * );
+static int parse_namespace_rsp_p3( imap_store_t *, list_t *, char * );
+
+static int
+parse_namespace_rsp_fail( void )
+{
+ error( "IMAP error: malformed NAMESPACE response\n" );
+ return -1;
+}
+
+static int
+parse_namespace_rsp( imap_store_t *ctx, list_t *list, char *s )
{
- parse_list_state_t sts;
- parse_list_init( &sts );
- if (parse_imap_list( 0, sp, &sts ) == LIST_OK)
- return sts.head;
- return NULL;
+ if (!(ctx->ns_personal = list))
+ return parse_namespace_rsp_fail();
+ return parse_list( ctx, s, parse_namespace_rsp_p2 );
}
static int
-parse_fetch( imap_store_t *ctx, list_t *list )
+parse_namespace_rsp_p2( imap_store_t *ctx, list_t *list, char *s )
+{
+ if (!(ctx->ns_other = list))
+ return parse_namespace_rsp_fail();
+ return parse_list( ctx, s, parse_namespace_rsp_p3 );
+}
+
+static int
+parse_namespace_rsp_p3( imap_store_t *ctx, list_t *list, char *s )
+{
+ (void)s;
+ if (!(ctx->ns_shared = list))
+ return parse_namespace_rsp_fail();
+ return 0;
+}
+
+static int
+parse_fetch_rsp( imap_store_t *ctx, list_t *list, char *s )
{
list_t *tmp, *flags;
char *body = 0, *tuid = 0;
@@ -663,6 +711,7 @@ parse_fetch( imap_store_t *ctx, list_t *list )
int uid = 0, mask = 0, status = 0, size = 0;
unsigned i;
+ (void)s;
if (!is_list( list )) {
error( "IMAP error: bogus FETCH response\n" );
free_list( list );
@@ -832,14 +881,16 @@ parse_response_code( imap_store_t *ctx, struct imap_cmd
*cmd, char *s )
}
static int
-parse_list_rsp( imap_store_t *ctx, char *cmd )
+parse_list_rsp( imap_store_t *ctx, list_t *list, char *cmd )
{
char *arg;
- list_t *list, *lp;
+ list_t *lp;
int l;
- if (!(list = parse_list( &cmd )))
+ if (!list) {
+ error( "IMAP error: malformed LIST response\n" );
return -1;
+ }
if (list->val == LIST)
for (lp = list->child; lp; lp = lp->next)
if (is_atom( lp ) && !strcasecmp( lp->val, "\\NoSelect"
)) {
@@ -922,11 +973,12 @@ imap_socket_read( void *aux )
int resp, resp2, tag, greeted;
greeted = ctx->greeting;
- if (ctx->parse_list_sts.level) {
- cmd = 0;
- goto do_fetch;
- }
for (;;) {
+ if (ctx->parse_list_sts.level) {
+ if (parse_list_continue( ctx, 0 ) < 0)
+ break;
+ continue;
+ }
if (!(cmd = socket_read_line( &ctx->conn )))
return;
@@ -943,12 +995,8 @@ imap_socket_read( void *aux )
}
if (!strcmp( "NAMESPACE", arg )) {
- if (!(ctx->ns_personal = parse_list( &cmd )) ||
- !(ctx->ns_other = parse_list( &cmd )) ||
- !(ctx->ns_shared = parse_list( &cmd ))) {
- error( "IMAP error: malformed NAMESPACE
response\n" );
+ if (parse_list( ctx, cmd, parse_namespace_rsp )
< 0)
break;
- }
} else if (ctx->greeting == GreetingPending && !strcmp(
"PREAUTH", arg )) {
ctx->greeting = GreetingPreauth;
parse_response_code( ctx, 0, cmd );
@@ -961,23 +1009,15 @@ imap_socket_read( void *aux )
} else if (!strcmp( "CAPABILITY", arg )) {
parse_capability( ctx, cmd );
} else if (!strcmp( "LIST", arg )) {
- if (parse_list_rsp( ctx, cmd ) < 0) {
- error( "IMAP error: malformed LIST
response\n" );
+ if (parse_list( ctx, cmd, parse_list_rsp ) < 0)
break;
- }
} else if ((arg1 = next_arg( &cmd ))) {
if (!strcmp( "EXISTS", arg1 ))
ctx->gen.count = atoi( arg );
else if (!strcmp( "RECENT", arg1 ))
ctx->gen.recent = atoi( arg );
else if(!strcmp ( "FETCH", arg1 )) {
- parse_list_init( &ctx->parse_list_sts );
- do_fetch:
- if ((resp = parse_imap_list( ctx, &cmd,
&ctx->parse_list_sts )) == LIST_BAD)
- break; /* stream is likely to
be useless now */
- if (resp == LIST_PARTIAL)
- return;
- if (parse_fetch( ctx,
ctx->parse_list_sts.head ) < 0)
+ if (parse_list( ctx, cmd,
parse_fetch_rsp ) < 0)
break; /* this may mean
anything, so prefer not to spam the log */
}
} else {
------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel