Skipped 2 existing revision(s) on branch '1.4'.
commit 444601a1e07b8b3e74a4a20b31c71b16f3c61994
Merge: a86e6f8 ed3bfda
Author: Oswald Buddenhagen <[email protected]>
Date: Thu Jun 3 11:04:56 2021 +0200
Merge branch '1.3' into 1.4
Conflicts:
configure.ac
src/drv_imap.c
src/drv_imap.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --cc src/drv_imap.c
index edae95c,4cc3b2a..3c85c4d
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@@ -110,142 -94,111 +110,141 @@@ typedef struct
typedef struct imap_cmd imap_cmd_t;
-struct imap_store {
+union imap_store {
store_t gen;
- const char *label; /* foreign */
- const char *prefix;
- const char *name;
- int ref_count;
- uint opts;
- enum { SST_BAD, SST_HALF, SST_GOOD } state;
- /* trash folder's existence is not confirmed yet */
- enum { TrashUnknown, TrashChecking, TrashKnown } trashnc;
- uint got_namespace:1;
- char delimiter[2]; /* hierarchy delimiter */
- list_t *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info */
- string_list_t *boxes; // _list results
- char listed; // was _list already run with these flags?
- // note that the message counts do _not_ reflect stats from msgs,
- // but mailbox totals. also, don't trust them beyond the initial load.
- int total_msgs, recent_msgs;
- uint uidvalidity, uidnext;
- message_t *msgs;
- message_t **msgapp; /* FETCH results */
- uint caps; /* CAPABILITY results */
- string_list_t *auth_mechs;
- parse_list_state_t parse_list_sts;
- /* command queue */
- int nexttag, num_in_progress;
- imap_cmd_t *pending, **pending_append;
- imap_cmd_t *in_progress, **in_progress_append;
- int buffer_mem; /* memory currently occupied by buffers in the queue */
-
- /* Used during sequential operations like connect */
- enum { GreetingPending = 0, GreetingBad, GreetingOk, GreetingPreauth }
greeting;
- int expectBYE; /* LOGOUT is in progress */
- int expectEOF; /* received LOGOUT's OK or unsolicited BYE */
- int canceling; /* imap_cancel() is in progress */
- union {
- void (*imap_open)( int sts, void *aux );
- void (*imap_cancel)( void *aux );
- } callbacks;
- void *callback_aux;
+ struct {
+ STORE(union imap_store)
+ const char *label; // foreign
+ const char *name;
+ char *prefix;
+ uint ref_count;
+ uint opts;
+ enum { SST_BAD, SST_HALF, SST_GOOD } state;
+ // The trash folder's existence is not confirmed yet
+ enum { TrashUnknown, TrashChecking, TrashKnown } trashnc;
+ // What kind of BODY-less FETCH response we're expecting
+ enum { FetchNone, FetchMsgs, FetchUidNext } fetch_sts;
+ uint got_namespace:1;
+ uint has_forwarded:1;
+ char delimiter[2]; // Hierarchy delimiter
+ char *ns_prefix, ns_delimiter; // NAMESPACE info
+ string_list_t *boxes; // _list results
+ char listed; // was _list already run with these flags?
+ // note that the message counts do _not_ reflect stats from
msgs,
+ // but mailbox totals.
+ int total_msgs, recent_msgs;
+ uint uidvalidity, uidnext;
+ imap_message_t **msgapp, *msgs; // FETCH results
+ uint caps; // CAPABILITY results
+ string_list_t *auth_mechs;
+ parse_list_state_t parse_list_sts;
+ // Command queue
+ imap_cmd_t *pending, **pending_append;
+ imap_cmd_t *in_progress, **in_progress_append;
+ imap_cmd_t *wait_check, **wait_check_append;
+ int nexttag, num_in_progress, num_wait_check;
+ uint buffer_mem; // Memory currently occupied by buffers in
the queue
+
+ // Used during sequential operations like connect
+ enum { GreetingPending = 0, GreetingBad, GreetingOk,
GreetingPreauth } greeting;
+ int expectBYE; // LOGOUT is in progress
+ int expectEOF; // received LOGOUT's OK or unsolicited BYE
+ int canceling; // imap_cancel() is in progress
+ union {
+ void (*imap_open)( int sts, void *aux );
+ void (*imap_cancel)( void *aux );
+ } callbacks;
+ void *callback_aux;
#ifdef HAVE_LIBSASL
- sasl_conn_t *sasl;
- int sasl_cont;
+ sasl_conn_t *sasl;
+ int sasl_cont;
#endif
- void (*bad_callback)( void *aux );
- void *bad_callback_aux;
+ void (*bad_callback)( void *aux );
+ void *bad_callback_aux;
- conn_t conn; /* this is BIG, so put it last */
+ conn_t conn; // This is BIG, so put it last
+ };
};
-struct imap_cmd {
- struct imap_cmd *next;
- char *cmd;
- int tag;
-
- struct {
- /* Will be called on each continuation request until it resets
this pointer.
- * Needs to invoke bad_callback and return -1 on error,
otherwise return 0. */
- int (*cont)( imap_store_t *ctx, imap_cmd_t *cmd, const char
*prompt );
- void (*done)( imap_store_t *ctx, imap_cmd_t *cmd, int response
);
- char *data;
- int data_len;
- uint uid; /* to identify fetch responses */
- char high_prio; /* if command is queued, put it at the front of
the queue. */
- char to_trash; /* we are storing to trash, not current. */
- char create; /* create the mailbox if we get an error which
suggests so. */
- char failok; /* Don't complain about NO response. */
- char lastuid; /* querying the last UID in the mailbox. */
+#define IMAP_CMD \
+ struct imap_cmd *next; \
+ char *cmd; \
+ int tag; \
+ \
+ struct { \
+ /* Will be called on each continuation request until it resets
this pointer. \
+ * Needs to invoke bad_callback and return -1 on error,
otherwise return 0. */ \
+ int (*cont)( imap_store_t *ctx, imap_cmd_t *cmd, const char
*prompt ); \
+ void (*done)( imap_store_t *ctx, imap_cmd_t *cmd, int response
); \
+ char *data; \
+ uint data_len; \
+ uint uid; /* to identify fetch responses */ \
+ char high_prio; /* if command is queued, put it at the front
of the queue. */ \
+ char wait_check; /* Don't report success until subsequent
CHECK success. */ \
+ char to_trash; /* we are storing to trash, not current. */ \
+ char create; /* create the mailbox if we get an error which
suggests so. */ \
+ char failok; /* Don't complain about NO response. */ \
} param;
+
+struct imap_cmd {
+ IMAP_CMD
};
-typedef struct {
- imap_cmd_t gen;
- void (*callback)( int sts, void *aux );
+#define IMAP_CMD_SIMPLE \
+ IMAP_CMD \
+ void (*callback)( int sts, void *aux ); \
void *callback_aux;
+
+typedef union {
+ imap_cmd_t gen;
+ struct {
+ IMAP_CMD_SIMPLE
+ };
} imap_cmd_simple_t;
-typedef struct {
+typedef union {
imap_cmd_simple_t gen;
- msg_data_t *msg_data;
+ struct {
+ IMAP_CMD_SIMPLE
+ msg_data_t *msg_data;
+ };
} imap_cmd_fetch_msg_t;
-typedef struct {
+typedef union {
imap_cmd_t gen;
- void (*callback)( int sts, uint uid, void *aux );
- void *callback_aux;
+ struct {
+ IMAP_CMD
+ void (*callback)( int sts, uint uid, void *aux );
+ void *callback_aux;
- uint out_uid;
+ };
} imap_cmd_out_uid_t;
-typedef struct {
+typedef union {
imap_cmd_t gen;
- void (*callback)( int sts, message_t *msgs, void *aux );
- void *callback_aux;
- message_t **out_msgs;
- uint uid;
+ struct {
+ IMAP_CMD
+ void (*callback)( int sts, message_t *msgs, void *aux );
+ void *callback_aux;
+ imap_message_t **out_msgs;
+ uint uid;
+ };
} imap_cmd_find_new_t;
-typedef struct {
- int ref_count;
+#define IMAP_CMD_REFCOUNTED_STATE \
+ uint ref_count; \
int ret_val;
-} imap_cmd_refcounted_state_t;
typedef struct {
+ IMAP_CMD_REFCOUNTED_STATE
+} imap_cmd_refcounted_state_t;
+
+typedef union {
imap_cmd_t gen;
- imap_cmd_refcounted_state_t *state;
+ struct {
+ IMAP_CMD
+ imap_cmd_refcounted_state_t *state;
+ };
} imap_cmd_refcounted_t;
#define CAP(cap) (ctx->caps & (1 << (cap)))
@@@ -1283,17 -1181,24 +1282,28 @@@ parse_response_code( imap_store_t *ctx
/* RFC2060 says that these messages MUST be displayed
* to the user
*/
- for (; isspace( (uchar)*p ); p++);
- error( "*** IMAP ALERT *** %s\n", p );
+ if (!s) {
+ error( "IMAP error: malformed ALERT status\n" );
+ return RESP_CANCEL;
+ }
+ for (; isspace( (uchar)*s ); s++);
+ error( "*** IMAP ALERT *** %s\n", s );
- } else if (cmd && !strcmp( "APPENDUID", arg )) {
+ } else if (!strcmp( "APPENDUID", arg )) {
+ // The checks ensure that:
+ // - cmd => this is the final tagged response of a command, at
which
+ // point cmd was already removed from ctx->in_progress, so
param.uid
+ // is available for reuse.
+ // - !param.uid => the command isn't actually a FETCH. This
doesn't
+ // really matter, as the field is safe to overwrite given the
+ // previous condition; it just has no effect for non-APPENDs.
+ if (!cmd || cmd->param.uid) {
+ error( "IMAP error: unexpected APPENDUID status\n" );
+ return RESP_CANCEL;
+ }
if (!(arg = next_arg( &s )) ||
(ctx->uidvalidity = strtoul( arg, &earg, 10 ), *earg) ||
!(arg = next_arg( &s )) ||
- (((imap_cmd_out_uid_t *)cmd)->out_uid = strtoul( arg,
&earg, 10 ), *earg != ']'))
- (cmd->param.uid = strtoul( arg, &earg, 10 ), *earg))
++ (cmd->param.uid = strtoul( arg, &earg, 10 ), *earg != ']'))
{
error( "IMAP error: malformed APPENDUID status\n" );
return RESP_CANCEL;
@@@ -3165,15 -2965,14 +3175,14 @@@ imap_store_msg( store_t *gctx, msg_data
INIT_IMAP_CMD(imap_cmd_out_uid_t, cmd, cb, aux)
ctx->buffer_mem += data->len;
- cmd->gen.param.data_len = data->len;
- cmd->gen.param.data = data->data;
+ cmd->param.data_len = data->len;
+ cmd->param.data = data->data;
- cmd->out_uid = 0;
if (to_trash) {
- cmd->gen.param.create = 1;
- cmd->gen.param.to_trash = 1;
+ cmd->param.create = 1;
+ cmd->param.to_trash = 1;
if (prepare_trash( &buf, ctx ) < 0) {
- cb( DRV_BOX_BAD, -1, aux );
+ cb( DRV_BOX_BAD, 0, aux );
return;
}
} else {
@@@ -3203,7 -2999,7 +3212,7 @@@ imap_store_msg_p2( imap_store_t *ctx AT
imap_cmd_out_uid_t *cmdp = (imap_cmd_out_uid_t *)cmd;
transform_msg_response( &response );
- cmdp->callback( response, cmdp->out_uid, cmdp->callback_aux );
- cmdp->callback( response, cmdp->gen.param.uid, cmdp->callback_aux );
++ cmdp->callback( response, cmdp->param.uid, cmdp->callback_aux );
}
/******************* imap_find_new_msgs *******************/
===== Full diff against 1st parent =====
diff --git a/src/drv_imap.c b/src/drv_imap.c
index edae95c..3c85c4d 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -217,7 +217,6 @@ typedef union {
IMAP_CMD
void (*callback)( int sts, uint uid, void *aux );
void *callback_aux;
- uint out_uid;
};
} imap_cmd_out_uid_t;
@@ -1289,11 +1288,22 @@ parse_response_code( imap_store_t *ctx, imap_cmd_t
*cmd, char *s )
}
for (; isspace( (uchar)*s ); s++);
error( "*** IMAP ALERT *** %s\n", s );
- } else if (cmd && !strcmp( "APPENDUID", arg )) {
+ } else if (!strcmp( "APPENDUID", arg )) {
+ // The checks ensure that:
+ // - cmd => this is the final tagged response of a command, at
which
+ // point cmd was already removed from ctx->in_progress, so
param.uid
+ // is available for reuse.
+ // - !param.uid => the command isn't actually a FETCH. This
doesn't
+ // really matter, as the field is safe to overwrite given the
+ // previous condition; it just has no effect for non-APPENDs.
+ if (!cmd || cmd->param.uid) {
+ error( "IMAP error: unexpected APPENDUID status\n" );
+ return RESP_CANCEL;
+ }
if (!(arg = next_arg( &s )) ||
(ctx->uidvalidity = strtoul( arg, &earg, 10 ), *earg) ||
!(arg = next_arg( &s )) ||
- (((imap_cmd_out_uid_t *)cmd)->out_uid = strtoul( arg,
&earg, 10 ), *earg != ']'))
+ (cmd->param.uid = strtoul( arg, &earg, 10 ), *earg != ']'))
{
error( "IMAP error: malformed APPENDUID status\n" );
return RESP_CANCEL;
@@ -3167,7 +3177,6 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int
to_trash,
ctx->buffer_mem += data->len;
cmd->param.data_len = data->len;
cmd->param.data = data->data;
- cmd->out_uid = 0;
if (to_trash) {
cmd->param.create = 1;
@@ -3203,7 +3212,7 @@ imap_store_msg_p2( imap_store_t *ctx ATTR_UNUSED,
imap_cmd_t *cmd, int response
imap_cmd_out_uid_t *cmdp = (imap_cmd_out_uid_t *)cmd;
transform_msg_response( &response );
- cmdp->callback( response, cmdp->out_uid, cmdp->callback_aux );
+ cmdp->callback( response, cmdp->param.uid, cmdp->callback_aux );
}
/******************* imap_find_new_msgs *******************/
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel