summaryrefslogtreecommitdiffstats
path: root/imap
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>2000-07-28 18:41:40 +0000
committerThomas Roessler <roessler@does-not-exist.org>2000-07-28 18:41:40 +0000
commit7149d9f6d644256d9e5e8e6c5b37d8245f5246b7 (patch)
tree47d2f401acaeea8185299017719886af3e524594 /imap
parent8b8dc628b8e3ea057673e18035fe65b5478a5f22 (diff)
Use UIDs instead of sequence numbers in IMAP. (Brendan)
Diffstat (limited to 'imap')
-rw-r--r--imap/imap.c107
-rw-r--r--imap/imap_private.h2
-rw-r--r--imap/message.c4
3 files changed, 62 insertions, 51 deletions
diff --git a/imap/imap.c b/imap/imap.c
index 7f9738cc..fc834d1d 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -42,6 +42,8 @@ static int imap_get_delim (IMAP_DATA *idata);
static char* imap_get_flags (LIST** hflags, char* s);
static int imap_check_acl (IMAP_DATA *idata);
static int imap_check_capabilities (IMAP_DATA *idata);
+static void imap_set_flag (IMAP_DATA* idata, int aclbit, int flag,
+ const char* str, char* flags);
int imap_create_mailbox (CONTEXT* ctx, char* mailbox)
{
@@ -916,23 +918,25 @@ int imap_close_connection (CONTEXT *ctx)
return 0;
}
-static void imap_set_flag (CONTEXT *ctx, int aclbit, int flag, const char *str,
- char *flags)
+/* imap_set_flag: append str to flags if we currently have permission
+ * according to aclbit */
+static void imap_set_flag (IMAP_DATA* idata, int aclbit, int flag,
+ const char *str, char *flags)
{
- if (mutt_bit_isset (CTX_DATA->rights, aclbit))
+ if (mutt_bit_isset (idata->rights, aclbit))
if (flag)
strcat (flags, str);
}
-/* imap_make_msg_set: make an IMAP4rev1 message set out of a set of headers,
- * given a flag enum to filter on.
- * Params: buf: to write message set into
+/* imap_make_msg_set: make an IMAP4rev1 UID message set out of a set of
+ * headers, given a flag enum to filter on.
+ * Params: idata: IMAP_DATA containing context containing header set
+ * buf: to write message set into
* buflen: length of buffer
- * ctx: CONTEXT containing header set
* flag: enum of flag type on which to filter
* changed: include only changed messages in message set
* Returns: number of messages in message set (0 if no matches) */
-int imap_make_msg_set (char* buf, size_t buflen, CONTEXT* ctx, int flag,
+int imap_make_msg_set (IMAP_DATA* idata, char* buf, size_t buflen, int flag,
int changed)
{
HEADER** hdrs; /* sorted local copy */
@@ -950,59 +954,65 @@ int imap_make_msg_set (char* buf, size_t buflen, CONTEXT* ctx, int flag,
*buf = '\0';
/* make copy of header pointers to sort in natural order */
- hdrs = safe_calloc (ctx->msgcount, sizeof (HEADER*));
- memcpy (hdrs, ctx->hdrs, ctx->msgcount * sizeof (HEADER*));
-
- oldsort = Sort;
- Sort = SORT_ORDER;
- qsort ((void*) hdrs, ctx->msgcount, sizeof (HEADER*),
- mutt_get_sort_func (SORT_ORDER));
- Sort = oldsort;
+ hdrs = safe_calloc (idata->ctx->msgcount, sizeof (HEADER*));
+ memcpy (hdrs, idata->ctx->hdrs, idata->ctx->msgcount * sizeof (HEADER*));
+ if (Sort != SORT_ORDER)
+ {
+ oldsort = Sort;
+ Sort = SORT_ORDER;
+ qsort ((void*) hdrs, idata->ctx->msgcount, sizeof (HEADER*),
+ mutt_get_sort_func (SORT_ORDER));
+ Sort = oldsort;
+ }
+
tmp = safe_malloc (buflen);
- for (n = 0; n < ctx->msgcount; n++)
+ for (n = 0; n < idata->ctx->msgcount; n++)
{
match = 0;
- switch (flag)
- {
- case M_DELETE:
- if (hdrs[n]->deleted)
- match = 1;
- break;
- case M_TAG:
- if (hdrs[n]->tagged)
- match = 1;
- break;
- }
+ /* don't include pending expunged messages */
+ if (hdrs[n]->active)
+ switch (flag)
+ {
+ case M_DELETE:
+ if (hdrs[n]->deleted)
+ match = 1;
+ break;
+ case M_TAG:
+ if (hdrs[n]->tagged)
+ match = 1;
+ break;
+ }
if (match && (!changed || hdrs[n]->changed))
{
count++;
if (setstart == 0)
{
- setstart = n+1;
+ setstart = HEADER_DATA (hdrs[n])->uid;
if (!buf[0])
- snprintf (buf, buflen, "%u", n+1);
+ snprintf (buf, buflen, "%u", HEADER_DATA (hdrs[n])->uid);
else
{
strncpy (tmp, buf, buflen);
- snprintf (buf, buflen, "%s,%u", tmp, n+1);
+ snprintf (buf, buflen, "%s,%u", tmp, HEADER_DATA (hdrs[n])->uid);
}
}
/* tie up if the last message also matches */
- else if (n == ctx->msgcount-1)
+ else if (n == idata->ctx->msgcount-1)
{
strncpy (tmp, buf, buflen);
- snprintf (buf, buflen, "%s:%u", tmp, n+1);
+ snprintf (buf, buflen, "%s:%u", tmp, HEADER_DATA (hdrs[n])->uid);
}
}
- else if (setstart)
+ /* this message is not expunged and doesn't match. End current set. */
+ else if (setstart && hdrs[n]->active)
{
- if (n > setstart)
+ if (HEADER_DATA (hdrs[n-1])->uid > setstart)
{
strncpy (tmp, buf, buflen);
- snprintf (buf, buflen, "%s:%u", tmp, n);
+ snprintf (buf, buflen, "%s:%u", tmp, HEADER_DATA (hdrs[n-1])->uid);
}
setstart = 0;
}
@@ -1056,13 +1066,14 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
/* if we are expunging anyway, we can do deleted messages very quickly... */
if (expunge && mutt_bit_isset (idata->rights, IMAP_ACL_DELETE))
{
- deleted = imap_make_msg_set (buf, sizeof (buf), ctx, M_DELETE, 1);
+ deleted = imap_make_msg_set (idata, buf, sizeof (buf), M_DELETE, 1);
/* if we have a message set, then let's delete */
if (deleted)
{
mutt_message (_("Marking %d messages deleted..."), deleted);
- snprintf (tmp, sizeof (tmp), "STORE %s +FLAGS.SILENT (\\Deleted)", buf);
+ snprintf (tmp, sizeof (tmp), "UID STORE %s +FLAGS.SILENT (\\Deleted)",
+ buf);
if (imap_exec (buf, sizeof (buf), idata, tmp, 0) != 0)
/* continue, let regular store try before giving up */
dprint(2, (debugfile, "imap_sync_mailbox: fast delete failed\n"));
@@ -1083,14 +1094,14 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
flags[0] = '\0';
- imap_set_flag (ctx, IMAP_ACL_SEEN, ctx->hdrs[n]->read, "\\Seen ",
- flags);
- imap_set_flag (ctx, IMAP_ACL_WRITE, ctx->hdrs[n]->flagged, "\\Flagged ",
+ imap_set_flag (idata, IMAP_ACL_SEEN, ctx->hdrs[n]->read, "\\Seen ",
flags);
- imap_set_flag (ctx, IMAP_ACL_WRITE, ctx->hdrs[n]->replied,
+ imap_set_flag (idata, IMAP_ACL_WRITE, ctx->hdrs[n]->flagged,
+ "\\Flagged ", flags);
+ imap_set_flag (idata, IMAP_ACL_WRITE, ctx->hdrs[n]->replied,
"\\Answered ", flags);
- imap_set_flag (ctx, IMAP_ACL_DELETE, ctx->hdrs[n]->deleted, "\\Deleted ",
- flags);
+ imap_set_flag (idata, IMAP_ACL_DELETE, ctx->hdrs[n]->deleted,
+ "\\Deleted ", flags);
/* now make sure we don't lose custom tags */
if (mutt_bit_isset (idata->rights, IMAP_ACL_WRITE))
@@ -1102,10 +1113,10 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
* explicitly revoke all system flags (if we have permission) */
if (!*flags)
{
- imap_set_flag (ctx, IMAP_ACL_SEEN, 1, "\\Seen ", flags);
- imap_set_flag (ctx, IMAP_ACL_WRITE, 1, "\\Flagged ", flags);
- imap_set_flag (ctx, IMAP_ACL_WRITE, 1, "\\Answered ", flags);
- imap_set_flag (ctx, IMAP_ACL_DELETE, 1, "\\Deleted ", flags);
+ imap_set_flag (idata, IMAP_ACL_SEEN, 1, "\\Seen ", flags);
+ imap_set_flag (idata, IMAP_ACL_WRITE, 1, "\\Flagged ", flags);
+ imap_set_flag (idata, IMAP_ACL_WRITE, 1, "\\Answered ", flags);
+ imap_set_flag (idata, IMAP_ACL_DELETE, 1, "\\Deleted ", flags);
mutt_remove_trailing_ws (flags);
diff --git a/imap/imap_private.h b/imap/imap_private.h
index 9aa65605..3f56380f 100644
--- a/imap/imap_private.h
+++ b/imap/imap_private.h
@@ -166,7 +166,7 @@ typedef struct
/* -- private IMAP functions -- */
/* imap.c */
-int imap_make_msg_set (char* buf, size_t buflen, CONTEXT* ctx, int flag,
+int imap_make_msg_set (IMAP_DATA* idata, char* buf, size_t buflen, int flag,
int changed);
int imap_open_connection (IMAP_DATA* idata);
IMAP_DATA* imap_conn_find (const ACCOUNT* account, int flags);
diff --git a/imap/message.c b/imap/message.c
index 3c798ac7..56736512 100644
--- a/imap/message.c
+++ b/imap/message.c
@@ -516,7 +516,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
/* Null HEADER* means copy tagged messages */
if (!h)
{
- rc = imap_make_msg_set (buf, sizeof (buf), ctx, M_TAG, 0);
+ rc = imap_make_msg_set (CTX_DATA, buf, sizeof (buf), M_TAG, 0);
if (!rc)
{
dprint (1, (debugfile, "imap_copy_messages: No messages tagged\n"));
@@ -533,7 +533,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
/* let's get it on */
strncpy (mbox, cmd, sizeof (mbox));
imap_munge_mbox_name (mmbox, sizeof (mmbox), cmd);
- snprintf (cmd, sizeof (cmd), "COPY %s %s", buf, mmbox);
+ snprintf (cmd, sizeof (cmd), "UID COPY %s %s", buf, mmbox);
rc = imap_exec (buf, sizeof (buf), CTX_DATA, cmd, IMAP_CMD_FAIL_OK);
if (rc == -2)
{