#include "citserver.h"
#include "support.h"
#include "config.h"
-#include "serv_extensions.h"
#include "room_ops.h"
#include "user_ops.h"
#include "policy.h"
int i;
char roomname[ROOMNAMELEN];
struct ctdlroom qrbuf;
+ long *selected_msgs = NULL;
+ int num_selected = 0;
if (IMAP->num_msgs < 1) {
return(0);
if (i != 0) return(i);
/*
- * Optimization note ... ajc 2005oct09
- *
- * As we can see below, we're going to end up making lots of
- * repeated calls to CtdlCopyMsgToRoom() if the user selects
- * multiple messages and then does a copy or move operation.
- *
- * The plan (documented in this comment so I don't forget what I was
- * going to do) is to refactor CtdlCopyMsgToRoom() so that it accepts
- * a list of message ID's instead of a single one. Then we can alter
- * the code which appears below, to copy all the message pointers in
- * one shot.
- *
- * But the REAL resource waster is further down, where we call
- * the CtdlSetSeen() API for each message moved. That's a HUGE
- * performance drag. Fix that too.
- *
+ * Copy all the message pointers in one shot.
*/
+ selected_msgs = malloc(sizeof(long) * IMAP->num_msgs);
+ if (selected_msgs == NULL) return(-1);
+
for (i = 0; i < IMAP->num_msgs; ++i) {
if (IMAP->flags[i] & IMAP_SELECTED) {
- CtdlCopyMsgToRoom(IMAP->msgids[i], roomname);
+ selected_msgs[num_selected++] = IMAP->msgids[i];
}
}
- /* Set the flags... */
- i = getroom(&qrbuf, roomname);
- if (i != 0) return(i);
+ if (num_selected > 0) {
+ CtdlCopyMsgsToRoom(selected_msgs, num_selected, roomname);
+ }
+ free(selected_msgs);
+
+ /* Don't bother wasting any more time if there were no messages. */
+ if (num_selected == 0) {
+ return(0);
+ }
+
+ /* Enumerate lists of messages for which flags are toggled */
+ long *seen_yes = NULL;
+ int num_seen_yes = 0;
+ long *seen_no = NULL;
+ int num_seen_no = 0;
+ long *answ_yes = NULL;
+ int num_answ_yes = 0;
+ long *answ_no = NULL;
+ int num_answ_no = 0;
+
+ seen_yes = malloc(num_selected * sizeof(long));
+ seen_no = malloc(num_selected * sizeof(long));
+ answ_yes = malloc(num_selected * sizeof(long));
+ answ_no = malloc(num_selected * sizeof(long));
for (i = 0; i < IMAP->num_msgs; ++i) {
if (IMAP->flags[i] & IMAP_SELECTED) {
- CtdlSetSeen(&IMAP->msgids[i], 1,
- ((IMAP->flags[i] & IMAP_SEEN) ? 1 : 0),
- ctdlsetseen_seen,
- NULL, &qrbuf
- );
- CtdlSetSeen(&IMAP->msgids[i], 1,
- ((IMAP->flags[i] & IMAP_ANSWERED) ? 1 : 0),
- ctdlsetseen_answered,
- NULL, &qrbuf
- );
+ if (IMAP->flags[i] & IMAP_SEEN) {
+ seen_yes[num_seen_yes++] = IMAP->msgids[i];
+ }
+ if ((IMAP->flags[i] & IMAP_SEEN) == 0) {
+ seen_no[num_seen_no++] = IMAP->msgids[i];
+ }
+ if (IMAP->flags[i] & IMAP_ANSWERED) {
+ answ_yes[num_answ_yes++] = IMAP->msgids[i];
+ }
+ if ((IMAP->flags[i] & IMAP_ANSWERED) == 0) {
+ answ_no[num_answ_no++] = IMAP->msgids[i];
+ }
}
}
+ /* Set the flags... */
+ i = getroom(&qrbuf, roomname);
+ if (i == 0) {
+ CtdlSetSeen(seen_yes, num_seen_yes, 1, ctdlsetseen_seen, NULL, &qrbuf);
+ CtdlSetSeen(seen_no, num_seen_no, 0, ctdlsetseen_seen, NULL, &qrbuf);
+ CtdlSetSeen(answ_yes, num_answ_yes, 1, ctdlsetseen_answered, NULL, &qrbuf);
+ CtdlSetSeen(answ_no, num_answ_no, 0, ctdlsetseen_answered, NULL, &qrbuf);
+ }
+
+ free(seen_yes);
+ free(seen_no);
+ free(answ_yes);
+ free(answ_no);
+
return(0);
}
long literal_length;
long bytes_transferred;
long stripped_length = 0;
- struct CtdlMessage *msg;
+ struct CtdlMessage *msg = NULL;
long new_msgnum = (-1L);
int ret = 0;
char roomname[ROOMNAMELEN];