to want to use it.
* Optimized the IMAP operations which scan for expunged and added messages.
These loops no longer make multiple traversals through the message list.
$Log$
+ Revision 605.34 2003/04/08 04:03:37 ajc
+ * Implemented the ".SILENT" protocol option in IMAP STORE. Certain apps seem
+ to want to use it.
+ * Optimized the IMAP operations which scan for expunged and added messages.
+ These loops no longer make multiple traversals through the message list.
+
Revision 605.33 2003/04/07 05:02:23 ajc
* Reworked all the "list rooms" operations so that they only require one
pass through the database.
Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
* Initial CVS import
-
/*
* imap_do_store() calls imap_do_store_msg() to output the deta of an
* individual message, once it has been successfully loaded from disk.
+ *
+ * We also implement the ".SILENT" protocol option here. Leave it to an
+ * idiot like Mark Crispin to make things unnecessarily complicated.
*/
void imap_do_store_msg(int seq, char *oper, unsigned int bits_to_twiddle) {
+ int silent = 0;
if (!strncasecmp(oper, "FLAGS", 5)) {
IMAP->flags[seq] &= IMAP_MASK_SYSTEM;
IMAP->flags[seq] |= bits_to_twiddle;
+ silent = strncasecmp(&oper[5], ".SILENT", 7);
}
else if (!strncasecmp(oper, "+FLAGS", 6)) {
IMAP->flags[seq] |= bits_to_twiddle;
+ silent = strncasecmp(&oper[6], ".SILENT", 7);
}
else if (!strncasecmp(oper, "-FLAGS", 6)) {
IMAP->flags[seq] &= (~bits_to_twiddle);
+ silent = strncasecmp(&oper[6], ".SILENT", 7);
}
if (bits_to_twiddle & IMAP_SEEN) {
((IMAP->flags[seq] & IMAP_SEEN) ? 1 : 0) );
}
- cprintf("* %d FETCH (", seq+1);
- imap_fetch_flags(seq);
- cprintf(")\r\n");
+ /* 'silent' is actually the value returned from a strncasecmp() so
+ * we want that option only if its value is zero. Seems backwards
+ * but that's the way it's supposed to be.
+ */
+ if (silent) {
+ cprintf("* %d FETCH (", seq+1);
+ imap_fetch_flags(seq);
+ cprintf(")\r\n");
+ }
}
/*
* imap_store() calls imap_do_store() to perform the actual bit twiddling
- * on flags. We brazenly ignore the ".silent" protocol option because it's not
- * harmful to send the data anyway. Fix it yourself if you don't like that.
+ * on the flags.
*/
void imap_do_store(int num_items, char **itemlist) {
int i;
int original_num_msgs = 0;
long original_highest = 0L;
- int i;
- int count;
+ int i, j;
+ int message_still_exists;
+ struct cdbdata *cdbfr;
+ long *msglist = NULL;
+ int num_msgs = 0;
+
if (IMAP->selected == 0) {
lprintf(5, "imap_load_msgids() can't run; no room selected\n");
return;
}
+ /* Load the *current* message list from disk, so we can compare it
+ * to what we have in memory.
+ */
+ cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->quickroom.QRnumber, sizeof(long));
+ if (cdbfr != NULL) {
+ msglist = mallok(cdbfr->len);
+ memcpy(msglist, cdbfr->ptr, cdbfr->len);
+ num_msgs = cdbfr->len / sizeof(long);
+ cdb_free(cdbfr);
+ }
+ else {
+ num_msgs = 0;
+ }
/*
* Check to see if any of the messages we know about have been expunged
if (IMAP->num_msgs > 0)
for (i=0; i<IMAP->num_msgs; ++i) {
- count = CtdlForEachMessage(MSGS_EQ, IMAP->msgids[i],
- NULL, NULL, NULL, NULL);
+ message_still_exists = 0;
+ if (num_msgs > 0) for (j = 0; j < num_msgs; ++j) {
+ if (msglist[j] == IMAP->msgids[i]) {
+ message_still_exists = 1;
+ }
+ }
- if (count == 0) {
+ if (message_still_exists == 0) {
cprintf("* %d EXPUNGE\r\n", i+1);
/* Here's some nice stupid nonsense. When a message
/*
* Now peruse the room for *new* messages only.
*/
- CtdlForEachMessage(MSGS_GT, original_highest, NULL, NULL,
- imap_add_single_msgid, NULL);
-
+ if (num_msgs > 0) for (j=0; j<num_msgs; ++j) {
+ if (msglist[j] > original_highest) {
+ imap_add_single_msgid(msglist[j], NULL);
+ }
+ }
imap_set_seen_flags();
/*
cprintf("* %d EXISTS\r\n", IMAP->num_msgs);
}
+ if (num_msgs != 0) phree(msglist);
}
*/
void imap_expunge(int num_parms, char *parms[]) {
int num_expunged = 0;
- imap_do_expunge();
+
+ num_expunged = imap_do_expunge();
cprintf("%s OK expunged %d messages.\r\n", parms[0], num_expunged);
}