diff -Naur cyrus-imapd-2.5.ori/imap/imapd.c cyrus-imapd-2.5/imap/imapd.c --- cyrus-imapd-2.5.ori/imap/imapd.c 2013-07-31 13:09:24.089114102 +0200 +++ cyrus-imapd-2.5/imap/imapd.c 2013-07-31 13:16:34.880113725 +0200 @@ -320,6 +320,7 @@ { "MOVE", 2 }, /* draft */ { "SPECIAL-USE", 2 }, { "CREATE-SPECIAL-USE", 2 }, + { "DIGEST=SHA1", 2 }, #ifdef HAVE_SSL { "URLAUTH", 2 }, @@ -4376,6 +4377,13 @@ } else goto badatt; break; + + case 'D': + if (!strcmp(fetchatt.s, "DIGEST.SHA1")) { + fetchitems |= FETCH_GUID; + } + else goto badatt; + break; case 'E': if (!strcmp(fetchatt.s, "ENVELOPE")) { @@ -4414,6 +4422,12 @@ if (!strcmp(fetchatt.s, "RFC822")) { fa->fetchitems |= FETCH_RFC822|FETCH_SETSEEN; } + else if (!strcmp(fetchatt.s, "RFC822.SHA1")) { + fetchitems |= FETCH_SHA1; + } + else if (!strcmp(fetchatt.s, "RFC822.FILESIZE")) { + fetchitems |= FETCH_FILESIZE; + } else if (!strcmp(fetchatt.s, "RFC822.HEADER")) { fa->fetchitems |= FETCH_HEADER; } diff -Naur cyrus-imapd-2.5.ori/imap/imapd.h cyrus-imapd-2.5/imap/imapd.h --- cyrus-imapd-2.5.ori/imap/imapd.h 2013-07-31 13:09:24.087113533 +0200 +++ cyrus-imapd-2.5/imap/imapd.h 2013-07-31 13:17:44.405190499 +0200 @@ -124,7 +124,10 @@ /* FETCH_UNCACHEDHEADER = (1<<11) -- obsolete */ FETCH_IS_PARTIAL = (1<<12), /* this is the PARTIAL command */ FETCH_MODSEQ = (1<<13), - FETCH_ANNOTATION = (1<<14) + FETCH_ANNOTATION = (1<<14), + FETCH_GUID = (1<<15), + FETCH_SHA1 = (1<<16), + FETCH_FILESIZE = (1<<17) }; enum { diff -Naur cyrus-imapd-2.5.ori/imap/index.c cyrus-imapd-2.5/imap/index.c --- cyrus-imapd-2.5.ori/imap/index.c 2013-07-31 13:09:24.085114556 +0200 +++ cyrus-imapd-2.5/imap/index.c 2013-07-31 13:21:23.728242893 +0200 @@ -2950,7 +2950,7 @@ } /* Open the message file if we're going to need it */ - if ((fetchitems & (FETCH_HEADER|FETCH_TEXT|FETCH_RFC822)) || + if ((fetchitems & (FETCH_HEADER|FETCH_TEXT|FETCH_SHA1|FETCH_RFC822)) || fetchargs->cache_atleast > record.cache_version || fetchargs->binsections || fetchargs->sizesections || fetchargs->bodysections) { @@ -2976,6 +2976,11 @@ if (fetchitems & FETCH_UID) { prot_printf(state->out, "%cUID %u", sepchar, record.uid); sepchar = ' '; + if (fetchitems & FETCH_GUID) { + prot_printf(state->out, "%cDIGEST.SHA1 %s", sepchar, + message_guid_encode(&im->record.guid)); + sepchar = ' '; + } } if (fetchitems & FETCH_INTERNALDATE) { time_t msgdate = record.internaldate; @@ -2996,6 +3001,25 @@ prot_printf(state->out, "%cRFC822.SIZE %u", sepchar, record.size); sepchar = ' '; + if (fetchitems & FETCH_FILESIZE) { + if (!msg_base) { + char *fname = mailbox_message_fname(mailbox, im->record.uid); + struct stat sbuf; + /* Find the size of the message file */ + if (stat(fname, &sbuf) == -1) + syslog(LOG_ERR, "IOERROR: stat on %s: %m", fname); + else + msg_size = sbuf.st_size; + } + prot_printf(state->out, "%cRFC822.FILESIZE %lu", sepchar, (long unsigned)msg_size); + sepchar = ' '; + } + if (fetchitems & FETCH_SHA1) { + struct message_guid tmpguid; + message_guid_generate(&tmpguid, msg_base, msg_size); + prot_printf(state->out, "%cRFC822.SHA1 %s", sepchar, message_guid_encode(&tmpguid)); + sepchar = ' '; + } } if ((fetchitems & FETCH_ANNOTATION)) { prot_printf(state->out, "%cANNOTATION (", sepchar);