int imap_do_copy(char *destination_folder) {
int i;
char roomname[ROOMNAMELEN];
+ struct ctdlroom qrbuf;
+ struct timeval tv1, tv2, tv3;
+
+ if (IMAP->num_msgs < 1) {
+ return(0);
+ }
i = imap_grabroom(roomname, destination_folder, 0);
if (i != 0) return(i);
- if (IMAP->num_msgs > 0) {
- for (i = 0; i < IMAP->num_msgs; ++i) {
- if (IMAP->flags[i] & IMAP_SELECTED) {
- CtdlCopyMsgToRoom(
- IMAP->msgids[i],
- roomname
- );
- }
+ /*
+ * 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.
+ *
+ */
+ gettimeofday(&tv1, NULL);
+ for (i = 0; i < IMAP->num_msgs; ++i) {
+ if (IMAP->flags[i] & IMAP_SELECTED) {
+ CtdlCopyMsgToRoom(IMAP->msgids[i], roomname);
+ }
+ }
+
+ /* Set the flags... */
+ gettimeofday(&tv2, NULL);
+ i = getroom(&qrbuf, roomname);
+ if (i != 0) return(i);
+
+ 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
+ );
}
}
+ gettimeofday(&tv3, NULL);
+ lprintf(CTDL_DEBUG, "Copying the pointers took %ld microseconds\n",
+ (tv2.tv_usec + (tv2.tv_sec * 1000))
+ - (tv1.tv_usec + (tv1.tv_sec * 1000))
+ );
+ lprintf(CTDL_DEBUG, "Setting the flags took %ld microseconds\n",
+ (tv3.tv_usec + (tv3.tv_sec * 1000))
+ - (tv2.tv_usec + (tv2.tv_sec * 1000))
+ );
return(0);
}
+
/*
* This function is called by the main command loop.
*/
safestrncpy(flags, new_message_flags, sizeof flags);
for (i=0; i<num_tokens(flags, ' '); ++i) {
- extract_token(this_flag, flags, i, ' ');
+ extract_token(this_flag, flags, i, ' ', sizeof this_flag);
if (this_flag[0] == '\\') strcpy(this_flag, &this_flag[1]);
if (!strcasecmp(this_flag, "Seen")) {
- CtdlSetSeen(new_msgnum, 1, ctdlsetseen_seen);
+ CtdlSetSeen(&new_msgnum, 1, 1, ctdlsetseen_seen,
+ NULL, NULL);
}
if (!strcasecmp(this_flag, "Answered")) {
- CtdlSetSeen(new_msgnum, 1, ctdlsetseen_answered);
+ CtdlSetSeen(&new_msgnum, 1, 1, ctdlsetseen_answered,
+ NULL, NULL);
}
}
}
IMAP->transmitted_message[literal_length] = 0; /* reterminate it */
lprintf(CTDL_DEBUG, "Converting message format\n");
- msg = convert_internet_message(IMAP->transmitted_message);
+ msg = convert_internet_message(IMAP->transmitted_message);
IMAP->transmitted_message = NULL;
IMAP->transmitted_length = 0;
ret = imap_grabroom(roomname, parms[2], 0);
if (ret != 0) {
- cprintf("%s NO Invalid mailbox name or location, or access denied\r\n",
+ cprintf("%s NO Invalid mailbox name or access denied\r\n",
parms[0]);
return;
}
}
usergoto(roomname, 0, 0, &msgs, &new);
- /* If the user is locally authenticated, FORCE the From: header to
- * show up as the real sender. FIXME do we really want to do this?
+ /* If the user is locally authenticated, FORCE the From: header to
+ * show up as the real sender. FIXME do we really want to do this?
* Probably should make it site-definable or even room-definable.
*
* For now, we allow "forgeries" if the room is one of the user's
* private mailboxes.
- */
- if (CC->logged_in) {
+ */
+ if (CC->logged_in) {
if ( (CC->room.QRflags & QR_MAILBOX) == 0) {
- if (msg->cm_fields['A'] != NULL) free(msg->cm_fields['A']);
- if (msg->cm_fields['N'] != NULL) free(msg->cm_fields['N']);
- if (msg->cm_fields['H'] != NULL) free(msg->cm_fields['H']);
- msg->cm_fields['A'] = strdup(CC->user.fullname);
- msg->cm_fields['N'] = strdup(config.c_nodename);
- msg->cm_fields['H'] = strdup(config.c_humannode);
+ if (msg->cm_fields['A'] != NULL) free(msg->cm_fields['A']);
+ if (msg->cm_fields['N'] != NULL) free(msg->cm_fields['N']);
+ if (msg->cm_fields['H'] != NULL) free(msg->cm_fields['H']);
+ msg->cm_fields['A'] = strdup(CC->user.fullname);
+ msg->cm_fields['N'] = strdup(config.c_nodename);
+ msg->cm_fields['H'] = strdup(config.c_humannode);
}
- }
+ }
/*
* Can we post here?
else {
/* Yes ... go ahead and post! */
if (msg != NULL) {
- new_msgnum = CtdlSubmitMsg(msg, NULL, "");
+ new_msgnum = CtdlSubmitMsg(msg, NULL, "");
}
if (new_msgnum >= 0L) {
cprintf("%s OK APPEND completed\r\n", parms[0]);