From c4d7f0189c37a3957c02e65a66c44820a6b9dc56 Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Thu, 21 Jun 2018 16:52:01 +0200 Subject: [PATCH] implement Forwarded flag maildir supports a 'P' flag which denotes the fact that a message has been 'passed' on (forwarded, bounced). notmuch syncs this to the 'passed' tag. Per https://tools.ietf.org/html/rfc5788, IMAP has a user-defined flag (keyword) '$Forwarded' that is supported by many servers and clients these days. (Technically, one should check for '$Forwarded' in the server response.) Restructure mbsync's flag parser to accept keywords (flags starting with '$') but still bail out on unknown system flags (flags starting with '\'). Support '$Forwarded' as a first keyword since it maps to maildir's 'P' and needs to be sorted in between the system flags. Signed-off-by: Michael J Gruber --- NEWS | 2 ++ src/driver.h | 9 +++++---- src/drv_imap.c | 22 ++++++++++++---------- src/drv_maildir.c | 2 +- src/drv_proxy.c | 2 +- src/sync.c | 2 +- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/NEWS b/NEWS index bea8968..ef795a8 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ The 'isync' compatibility wrapper was removed. +The IMAP '$Forwarded' / Maildir 'P' (passed) flag is supported now. + [1.3.0] Network timeout handling has been added. diff --git a/src/driver.h b/src/driver.h index 978e144..00c5581 100644 --- a/src/driver.h +++ b/src/driver.h @@ -49,10 +49,11 @@ typedef struct store_conf { /* The order is according to alphabetical maildir flag sort */ #define F_DRAFT (1<<0) /* Draft */ #define F_FLAGGED (1<<1) /* Flagged */ -#define F_ANSWERED (1<<2) /* Replied */ -#define F_SEEN (1<<3) /* Seen */ -#define F_DELETED (1<<4) /* Trashed */ -#define NUM_FLAGS 5 +#define F_PASSED (1<<2) /* Passed */ +#define F_ANSWERED (1<<3) /* Replied */ +#define F_SEEN (1<<4) /* Seen */ +#define F_DELETED (1<<5) /* Trashed */ +#define NUM_FLAGS 6 /* For message->status */ #define M_RECENT (1<<0) /* unsyncable flag; maildir_* depend on this being 1<<0 */ diff --git a/src/drv_imap.c b/src/drv_imap.c index fd46a0b..e782ec0 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -247,11 +247,12 @@ static void imap_invoke_bad_callback( imap_store_t *ctx ); /* grep for MAILBOX_DRIVER_FLAG */ /* The order is according to alphabetical maildir flag sort */ static const char *Flags[] = { - "Draft", - "Flagged", - "Answered", - "Seen", - "Deleted", + "\\Draft", /* 'D' */ + "\\Flagged", /* 'F' */ + "$Forwarded", /* 'P' */ + "\\Answered", /* 'R' */ + "\\Seen", /* 'S' */ + "\\Deleted", /* 'T' */ }; static imap_cmd_t * @@ -989,17 +990,19 @@ parse_fetch_rsp( imap_store_t *ctx, list_t *list, char *s ATTR_UNUSED ) if (is_list( tmp )) { for (flags = tmp->child; flags; flags = flags->next) { if (is_atom( flags )) { - if (flags->val[0] == '\\') { /* ignore user-defined flags for now */ - if (!strcmp( "Recent", flags->val + 1)) { + if (flags->val[0] == '\\' || flags->val[0] == '$') { + if (!strcmp( "\\Recent", flags->val)) { status |= M_RECENT; goto flagok; } for (i = 0; i < as(Flags); i++) - if (!strcmp( Flags[i], flags->val + 1 )) { + if (!strcmp( Flags[i], flags->val)) { mask |= 1 << i; goto flagok; } - if (flags->val[1] == 'X' && flags->val[2] == '-') + if (flags->val[0] == '$') + goto flagok; /* ignore unknown user-defined flags (keywords) */ + if (flags->val[0] == '\\' && flags->val[1] == 'X' && flags->val[2] == '-') goto flagok; /* ignore system flag extensions */ error( "IMAP warning: unknown system flag %s\n", flags->val ); } @@ -2664,7 +2667,6 @@ imap_make_flags( int flags, char *buf ) for (i = d = 0; i < as(Flags); i++) if (flags & (1 << i)) { buf[d++] = ' '; - buf[d++] = '\\'; for (s = Flags[i]; *s; s++) buf[d++] = *s; } diff --git a/src/drv_maildir.c b/src/drv_maildir.c index 31436f9..d094146 100644 --- a/src/drv_maildir.c +++ b/src/drv_maildir.c @@ -111,7 +111,7 @@ debug( const char *msg, ... ) /* Keep the mailbox driver flag definitions in sync: */ /* grep for MAILBOX_DRIVER_FLAG */ /* The order is according to alphabetical maildir flag sort */ -static const char Flags[] = { 'D', 'F', 'R', 'S', 'T' }; +static const char Flags[] = { 'D', 'F', 'P', 'R', 'S', 'T' }; static uchar maildir_parse_flags( const char *info_prefix, const char *base ) diff --git a/src/drv_proxy.c b/src/drv_proxy.c index 43d7411..4fa40a7 100644 --- a/src/drv_proxy.c +++ b/src/drv_proxy.c @@ -58,7 +58,7 @@ debugn( const char *msg, ... ) /* Keep the mailbox driver flag definitions in sync: */ /* grep for MAILBOX_DRIVER_FLAG */ /* The order is according to alphabetical maildir flag sort */ -static const char Flags[] = { 'D', 'F', 'R', 'S', 'T' }; +static const char Flags[] = { 'D', 'F', 'P', 'R', 'S', 'T' }; static char * proxy_make_flags( int flags, char *buf ) diff --git a/src/sync.c b/src/sync.c index d88344d..c637af4 100644 --- a/src/sync.c +++ b/src/sync.c @@ -100,7 +100,7 @@ Fprintf( FILE *f, const char *msg, ... ) /* Keep the mailbox driver flag definitions in sync: */ /* grep for MAILBOX_DRIVER_FLAG */ /* The order is according to alphabetical maildir flag sort */ -static const char Flags[] = { 'D', 'F', 'R', 'S', 'T' }; +static const char Flags[] = { 'D', 'F', 'P', 'R', 'S', 'T' }; static int parse_flags( const char *buf )