* is_msg_is_mset() has been renamed to is_msg_in_sequence_set() because
authorArt Cancro <ajc@citadel.org>
Fri, 22 Apr 2005 04:26:35 +0000 (04:26 +0000)
committerArt Cancro <ajc@citadel.org>
Fri, 22 Apr 2005 04:26:35 +0000 (04:26 +0000)
  "sequence set" is now the official terminology as of RFC3501.
* imap_set_seen_flags() no longer calls is_msg_in_sequence_set() for each
  message and for each flag.  It's just too expensive.  We now parse each
  flag's sequence set manually, marking the relevant messages as we go.

citadel/ChangeLog
citadel/imap_search.c
citadel/msgbase.c
citadel/room_ops.c
citadel/serv_imap.c
citadel/serv_pop3.c
citadel/tools.c
citadel/tools.h

index c4cd8b67a68099a5523b1c4436ee8b325fe90994..a3733a906a188d0aa055a57faad058c47406afc8 100644 (file)
@@ -1,4 +1,11 @@
  $Log$
+ Revision 645.8  2005/04/22 04:26:34  ajc
+ * is_msg_is_mset() has been renamed to is_msg_in_sequence_set() because
+   "sequence set" is now the official terminology as of RFC3501.
+ * imap_set_seen_flags() no longer calls is_msg_in_sequence_set() for each
+   message and for each flag.  It's just too expensive.  We now parse each
+   flag's sequence set manually, marking the relevant messages as we go.
+
  Revision 645.7  2005/04/22 00:52:03  ajc
  * small fix to previous commit
 
@@ -6610,3 +6617,5 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
 
+
+
index dac0ee6d1936f0ecddce2f763c5ceffefe321e3d..16cabdf9835f5a2c88b31cfb7fc7b211326f13e6 100644 (file)
@@ -361,7 +361,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
        }
 
        else if (!strcasecmp(itemlist[pos], "UID")) {
-               if (is_msg_in_mset(itemlist[pos+1], IMAP->msgids[seq-1])) {
+               if (is_msg_in_sequence_set(itemlist[pos+1], IMAP->msgids[seq-1])) {
                        match = 1;
                }
                pos += 2;
index 8808751314276648f771d7e1a516360fbff732e2..75a6830a109891b548e5979f022f81f4269f7554 100644 (file)
@@ -349,7 +349,7 @@ void CtdlSetSeen(long target_msgnum, int target_setting, int which_set) {
                        is_seen = target_setting;
                }
                else {
-                       if (is_msg_in_mset(vset, msglist[i])) {
+                       if (is_msg_in_sequence_set(vset, msglist[i])) {
                                is_seen = 1;
                        }
                }
@@ -490,7 +490,7 @@ int CtdlForEachMessage(int mode, long ref,
        if (num_msgs > 0)
                for (a = 0; a < num_msgs; ++a) {
                        thismsg = msglist[a];
-                       is_seen = is_msg_in_mset(vbuf.v_seen, thismsg);
+                       is_seen = is_msg_in_sequence_set(vbuf.v_seen, thismsg);
                        if (is_seen) lastold = thismsg;
                        if ((thismsg > 0L)
                            && (
index b335942d2b8c44cd21c99d811b4b401d90d0d5cb..47ae341289b7b03a87eb88df28dede85b4b849db 100644 (file)
@@ -152,7 +152,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
        }
 
 NEWMSG:        /* By the way, we also check for the presence of new messages */
-       if (is_msg_in_mset(vbuf.v_seen, roombuf->QRhighest) == 0) {
+       if (is_msg_in_sequence_set(vbuf.v_seen, roombuf->QRhighest) == 0) {
                retval = retval | UA_HASNEWMSGS;
        }
 
@@ -829,7 +829,7 @@ void usergoto(char *where, int display_result, int transiently,
        if (num_msgs > 0) for (a = 0; a < num_msgs; ++a) {
                if (msglist[a] > 0L) {
                        ++total_messages;
-                       if (is_msg_in_mset(vbuf.v_seen, msglist[a]) == 0) {
+                       if (is_msg_in_sequence_set(vbuf.v_seen, msglist[a]) == 0) {
                                ++new_messages;
                        }
                }
index 2eaa0b3be5c6ca169242ee707a984b0428d1acbb..ef157b2b1ca7275326d5daf3e106ff6a87894bba 100644 (file)
@@ -108,30 +108,81 @@ void imap_free_transmitted_message(void)
 
 
 /*
- * Set the \\Seen flag for messages which aren't new
+ * Set the \Seen, \Recent. and \Answered flags, based on the sequence
+ * sets stored in the visit record for this user/room.  Note that we have
+ * to parse each sequence set manually here, because calling the utility
+ * function is_msg_in_sequence_set() over and over again is too expensive.
  */
 void imap_set_seen_flags(void)
 {
        struct visit vbuf;
        int i;
+       int num_sets;
+       int s;
+       char setstr[SIZ], lostr[SIZ], histr[SIZ];
+       long lo, hi;
 
+       if (IMAP->num_msgs < 1) return;
        CtdlGetRelationship(&vbuf, &CC->user, &CC->room);
-       if (IMAP->num_msgs > 0) {
+
+       for (i = 0; i < IMAP->num_msgs; ++i) {
+               IMAP->flags[i] = IMAP->flags[i] & ~IMAP_SEEN;
+               IMAP->flags[i] |= IMAP_RECENT;
+               IMAP->flags[i] = IMAP->flags[i] & ~IMAP_ANSWERED;
+       }
+
+       /* Do the "\Seen" flag.  (Any message not "\Seen" is considered "\Recent".) */
+       num_sets = num_tokens(vbuf.v_seen, ',');
+       for (s=0; s<num_sets; ++s) {
+               extract_token(setstr, vbuf.v_seen, s, ',', sizeof setstr);
+
+               extract_token(lostr, setstr, 0, ':', sizeof lostr);
+               if (num_tokens(setstr, ':') >= 2) {
+                       extract_token(histr, setstr, 1, ':', sizeof histr);
+                       if (!strcmp(histr, "*")) {
+                               snprintf(histr, sizeof histr, "%ld", LONG_MAX);
+                       }
+               } 
+               else {
+                       strcpy(histr, lostr);
+               }
+               lo = atol(lostr);
+               hi = atol(histr);
+
                for (i = 0; i < IMAP->num_msgs; ++i) {
-                       if (is_msg_in_mset(vbuf.v_seen, IMAP->msgids[i])) {
+                       if ((IMAP->msgids[i] >= lo) && (IMAP->msgids[i] <= hi)) {
                                IMAP->flags[i] |= IMAP_SEEN;
+                               IMAP->flags[i] = IMAP->flags[i] & ~IMAP_RECENT;
                        }
-                       else {
-                               IMAP->flags[i] |= IMAP_RECENT;
+               }
+       }
+
+       /* Do the ANSWERED flag */
+       num_sets = num_tokens(vbuf.v_answered, ',');
+       for (s=0; s<num_sets; ++s) {
+               extract_token(setstr, vbuf.v_answered, s, ',', sizeof setstr);
+
+               extract_token(lostr, setstr, 0, ':', sizeof lostr);
+               if (num_tokens(setstr, ':') >= 2) {
+                       extract_token(histr, setstr, 1, ':', sizeof histr);
+                       if (!strcmp(histr, "*")) {
+                               snprintf(histr, sizeof histr, "%ld", LONG_MAX);
                        }
-                       if (is_msg_in_mset
-                           (vbuf.v_answered, IMAP->msgids[i])) {
+               } 
+               else {
+                       strcpy(histr, lostr);
+               }
+               lo = atol(lostr);
+               hi = atol(histr);
+
+               for (i = 0; i < IMAP->num_msgs; ++i) {
+                       if ((IMAP->msgids[i] >= lo) && (IMAP->msgids[i] <= hi)) {
                                IMAP->flags[i] |= IMAP_ANSWERED;
                        }
                }
        }
-}
 
+}
 
 
 
@@ -175,8 +226,6 @@ void imap_load_msgids(void)
                           imap_add_single_msgid, NULL);
 
        imap_set_seen_flags();
-       /* lprintf(CTDL_DEBUG, "imap_load_msgids() mapped %d messages\n",
-               IMAP->num_msgs); */
 }
 
 
@@ -195,7 +244,6 @@ void imap_rescan_msgids(void)
        int num_msgs = 0;
        int num_recent = 0;
 
-
        if (IMAP->selected == 0) {
                lprintf(CTDL_ERR,
                        "imap_load_msgids() can't run; no room selected\n");
index f09852c2ea0f7399bc52bad4a49f69c2ada99942..d83f01f3edb3a20d9949069b1209fb8f9ad15f2f 100644 (file)
@@ -188,7 +188,7 @@ int pop3_grab_mailbox(void) {
         CtdlGetRelationship(&vbuf, &CC->user, &CC->room);
        POP3->lastseen = (-1);
        if (POP3->num_msgs) for (i=0; i<POP3->num_msgs; ++i) {
-               if (is_msg_in_mset(vbuf.v_seen,
+               if (is_msg_in_sequence_set(vbuf.v_seen,
                   (POP3->msgs[POP3->num_msgs-1].msgnum) )) {
                        POP3->lastseen = i;
                }
index b1e95fcc46c8cb4899863852d3c54b245413bb16..abdf2bc8d5fd62fa1f75deb1192d86d859bed93f 100644 (file)
@@ -409,17 +409,14 @@ void fmt_date(char *buf, size_t n, time_t thetime, int seconds) {
 
 /*
  * Determine whether the specified message number is contained within the
- * specified set.
+ * specified sequence set.
  */
-int is_msg_in_mset(char *mset, long msgnum) {
+int is_msg_in_sequence_set(char *mset, long msgnum) {
        int num_sets;
        int s;
-       char setstr[SIZ], lostr[SIZ], histr[SIZ];       /* was 1024 */
+       char setstr[SIZ], lostr[SIZ], histr[SIZ];
        long lo, hi;
 
-       /*
-        * Now set it for all specified messages.
-        */
        num_sets = num_tokens(mset, ',');
        for (s=0; s<num_sets; ++s) {
                extract_token(setstr, mset, s, ',', sizeof setstr);
index f34eef4be79f2c18dc88d6a50d444994c63830bb..32c02f11fdffe9ec68eb7ef3597660da1a767b55 100644 (file)
@@ -11,7 +11,7 @@ void striplt(char *);
 int haschar(const char *st, int ch);
 void remove_token(char *source, int parmnum, char separator);
 void fmt_date(char *buf, size_t n, time_t thetime, int seconds);
-int is_msg_in_mset(char *mset, long msgnum);
+int is_msg_in_sequence_set(char *mset, long msgnum);
 char *memreadline(char *start, char *buf, int maxlen);
 
 #ifndef HAVE_STRNCASECMP