]> code.citadel.org Git - citadel.git/commitdiff
* Began implementation of per-message seen/unseen attribute
authorArt Cancro <ajc@citadel.org>
Sat, 21 Apr 2001 04:55:54 +0000 (04:55 +0000)
committerArt Cancro <ajc@citadel.org>
Sat, 21 Apr 2001 04:55:54 +0000 (04:55 +0000)
13 files changed:
citadel/ChangeLog
citadel/citadel.h
citadel/imap_fetch.c
citadel/msgbase.c
citadel/room_ops.c
citadel/serv_expire.c
citadel/serv_imap.c
citadel/serv_pop3.c
citadel/server.h
citadel/techdoc/session.txt
citadel/tools.c
citadel/tools.h
citadel/user_ops.c

index 77462e0a68e456cfa4c98efba6f0eedea282eab4..014b9851690d6ce14c93086db24fc6f7c02dbe3d 100644 (file)
@@ -1,4 +1,7 @@
  $Log$
+ Revision 573.129  2001/04/21 04:55:51  ajc
+ * Began implementation of per-message seen/unseen attribute
+
  Revision 573.128  2001/04/20 03:39:54  ajc
  * IMAP LIST/LSUB: made it case insensitive.  Also minor IMAP code cleanup.
 
@@ -2506,4 +2509,3 @@ 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 3a8580011585defed8a411e4559ca2ff6016fae1..5da1f1d826d979cbd1fb935036ffe47f43fae1bd 100644 (file)
@@ -261,3 +261,7 @@ struct floor {
 #define        INTERNETCFG     "application/x-citadel-internet-config"
 
 #define TRACE  lprintf(9, "Checkpoint: %s, %d\n", __FILE__, __LINE__)
+
+#ifndef LONG_MAX
+#define LONG_MAX 2147483647L
+#endif
index d01d5063786fad063f9ab1a2fa389fcaecc18ad2..a380732dba2e4ca4c683c5e24e0764916afed54a 100644 (file)
@@ -62,6 +62,7 @@ void imap_fetch_uid(int seq) {
 void imap_fetch_flags(int seq) {
        cprintf("FLAGS (");
        if (IMAP->flags[seq] & IMAP_DELETED) cprintf("\\Deleted ");
+       if (IMAP->flags[seq] & IMAP_SEEN) cprintf("\\Seen ");
        cprintf(")");
 }
 
index 35ac831a7876855b8641ead0954d8d17f9647121..b7533685ce112792aea83b66041b8f849f7b9544 100644 (file)
@@ -289,6 +289,7 @@ int CtdlForEachMessage(int mode, long ref,
        long thismsg;
        struct SuppMsgInfo smi;
        struct CtdlMessage *msg;
+       int is_seen;
 
        /* Learn about the user and room in question */
        get_mm();
@@ -354,14 +355,14 @@ 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);
                        if ((thismsg > 0)
                            && (
 
                                       (mode == MSGS_ALL)
-                                      || ((mode == MSGS_OLD) && (thismsg <= vbuf.v_lastseen))
-                                      || ((mode == MSGS_NEW) && (thismsg > vbuf.v_lastseen))
-                                      || ((mode == MSGS_NEW) && (thismsg >= vbuf.v_lastseen)
-                                   && (CC->usersupp.flags & US_LASTOLD))
+                                      || ((mode == MSGS_OLD) && (is_seen))
+                                      || ((mode == MSGS_NEW) && (!is_seen))
+                                           /* FIXME handle lastold mode */
                                       || ((mode == MSGS_LAST) && (a >= (num_msgs - ref)))
                                   || ((mode == MSGS_FIRST) && (a < ref))
                                || ((mode == MSGS_GT) && (thismsg > ref))
index 4cfeae3125a8a7bc6cac3f3d974f4d1934962b85..923d6d760fe33564bc6d28bc6b5d319c5d2acdc6 100644 (file)
@@ -113,7 +113,7 @@ int CtdlRoomAccess(struct quickroom *roombuf, struct usersupp *userbuf)
        }
 
 NEWMSG:        /* By the way, we also check for the presence of new messages */
-       if ((roombuf->QRhighest) > (vbuf.v_lastseen)) {
+       if (is_msg_in_mset(vbuf.v_seen, roombuf->QRhighest) == 0) {
                retval = retval | UA_HASNEWMSGS;
        }
        return (retval);
@@ -698,7 +698,7 @@ void usergoto(char *where, int display_result, int *retmsgs, int *retnew)
        if (num_msgs > 0) for (a = 0; a < num_msgs; ++a) {
                if (msglist[a] > 0L) {
                        ++total_messages;
-                       if (msglist[a] > vbuf.v_lastseen) {
+                       if (is_msg_in_mset(vbuf.v_seen, msglist[a]) == 0) {
                                ++new_messages;
                        }
                }
index 127b05ccd889af0b65809e7074e6308ae007a0fe..857e69deaffccd4d144cbba58195c6f91850a73e 100644 (file)
 #include "tools.h"
 
 
-struct oldvisit {
-       char v_roomname[ROOMNAMELEN];
-       long v_generation;
-       long v_lastseen;
-       unsigned int v_flags;
-};
-
 struct PurgeList {
        struct PurgeList *next;
        char name[ROOMNAMELEN]; /* use the larger of username or roomname */
index c2280788ccd3822a850df77fed013c9d7b23da33..ced8035b79a21103af5740fea14ed5f066416304 100644 (file)
@@ -81,6 +81,26 @@ void imap_free_transmitted_message(void) {
 }
 
 
+/*
+ * Set the \\Seen flag for messages which aren't new
+ */
+void imap_set_seen_flags(void) {
+       struct visit vbuf;
+       int i;
+
+       CtdlGetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
+       if (IMAP->num_msgs > 0) {
+               for (i=0; i<IMAP->num_msgs; ++i) {
+                       if (is_msg_in_mset(vbuf.v_seen, IMAP->msgids[i])) {
+                               IMAP->flags[i] |= IMAP_SEEN;
+                       }
+               }
+       }
+}
+
+
+
+
 /*
  * Back end for imap_load_msgids()
  *
@@ -125,6 +145,7 @@ void imap_load_msgids(void) {
        CtdlForEachMessage(MSGS_ALL, 0L, (-63), NULL, NULL,
                imap_add_single_msgid, NULL);
 
+       imap_set_seen_flags();
        lprintf(9, "imap_load_msgids() mapped %d messages\n", IMAP->num_msgs);
 }
 
@@ -189,6 +210,8 @@ void imap_rescan_msgids(void) {
        CtdlForEachMessage(MSGS_GT, original_highest, (-63), NULL, NULL,
                imap_add_single_msgid, NULL);
 
+       imap_set_seen_flags();
+
        /*
         * If new messages have arrived, tell the client about them.
         */
@@ -388,8 +411,8 @@ void imap_select(int num_parms, char *parms[]) {
        /* FIXME ... much more info needs to be supplied here */
        cprintf("* %d EXISTS\r\n", msgs);
        cprintf("* %d RECENT\r\n", new);
-       cprintf("* FLAGS (\\Deleted)\r\n");
-       cprintf("* OK [PERMANENTFLAGS (\\Deleted)] permanent flags\r\n");
+       cprintf("* FLAGS (\\Deleted \\Seen)\r\n");
+       cprintf("* OK [PERMANENTFLAGS (\\Deleted \\Seen)] permanent flags\r\n");
        cprintf("* OK [UIDVALIDITY 0] UIDs valid\r\n");
        cprintf("%s OK [%s] %s completed\r\n",
                parms[0],
index b91800243c5cd735f4b49fb7cf5fb8b7b152c8ea..0b4c4a674db14aef4589e212ce471cfa17b3ed38 100644 (file)
@@ -163,7 +163,8 @@ int pop3_grab_mailbox(void) {
         CtdlGetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
        POP3->lastseen = (-1);
        if (POP3->num_msgs) for (i=0; i<POP3->num_msgs; ++i) {
-               if ((POP3->msgs[POP3->num_msgs-1].msgnum) <= vbuf.v_lastseen) {
+               if (is_msg_in_mset(vbuf.v_seen,
+                  (POP3->msgs[POP3->num_msgs-1].msgnum) )) {
                        POP3->lastseen = i;
                }
        }
@@ -441,7 +442,8 @@ void pop3_update(void) {
                lgetuser(&CC->usersupp, CC->curr_user);
 
                CtdlGetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
-               vbuf.v_lastseen = POP3->msgs[POP3->num_msgs-1].msgnum;
+               sprintf(vbuf.v_seen, "*:%ld",
+                       POP3->msgs[POP3->num_msgs-1].msgnum);
                CtdlSetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
 
                lputuser(&CC->usersupp);
index 33ceef4a4f2449df5222a0119bd6fedb8f406ba6..69d4b25b79fc294aeabc55b3a571e44a4b8e31f9 100644 (file)
@@ -345,6 +345,7 @@ struct visit {
        long v_usernum;
        long v_lastseen;
        unsigned int v_flags;
+       char v_seen[SIZ];
 };
 
 #define V_FORGET       1       /* User has zapped this room        */
index 77eff271ff706752dcb84e16bda2ad5a4c2737a0..6df534eb73d4a921a12c70ba1bba5f98341508e6 100644 (file)
@@ -580,7 +580,8 @@ contain the name of the system and the name of the directory, such as:
  
  SLRP   (Set Last-message-Read Pointer)
  
- This command is used to mark messages as having been read.  Its sole parameter
+ This command marks all messages in the current room as read (seen) up to and
+including the specified number.  Its sole parameter
 is the number of the last message that has been read.  This allows the pointer
 to be set at any arbitrary point in the room.  Optionally, the parameter
 "highest" may be used instead of a message number, to set the pointer to the
index 4a5ee52c7a9d66d7bfc55e4cf97dbb80c80b16c0..edf78219592a94da780b1f8c19eb482a327f8d75 100644 (file)
@@ -385,6 +385,38 @@ void fmt_date(char *buf, time_t thetime) {
 
 
 
+/*
+ * Determine whether the specified message number is contained within the
+ * specified set.
+ */
+int is_msg_in_mset(char *mset, long msgnum) {
+       int num_sets;
+       int s;
+       char setstr[SIZ], lostr[SIZ], histr[SIZ];       /* was 1024 */
+       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, ',');
+
+               extract_token(lostr, setstr, 0, ':');
+               if (num_tokens(setstr, ':') >= 2) {
+                       extract_token(histr, setstr, 1, ':');
+                       if (!strcmp(histr, "*")) {
+                               sprintf(histr, "%ld", LONG_MAX);
+                       }
+               } 
+               else {
+                       strcpy(histr, lostr);
+               }
+               lo = atol(lostr);
+               hi = atol(histr);
 
+               if ((msgnum >= lo) && (msgnum <= hi)) return(1);
+       }
 
-
+       return(0);
+}
index 6b8ea443027ae571c2d3c3bfe85f255c556307d9..9dfbc845b2095f44952867f8ceb0de47bf1f64ed 100644 (file)
@@ -11,6 +11,7 @@ int haschar(char *st, int ch);
 int collapsed_strcmp(char *s1, char *s2);
 void remove_token(char *source, int parmnum, char separator);
 void fmt_date(char *buf, time_t thetime);
+int is_msg_in_mset(char *mset, long msgnum);
 
 #ifndef HAVE_STRNCASECMP
 int strncasecmp(char *, char *, int)
index 17e1c1d1acbad117550f9f1caa777527454cd458..cbc39e68b6d87f8bdcc254df784e8de3236cca29 100644 (file)
@@ -213,7 +213,11 @@ void CtdlGetRelationship(struct visit *vbuf,
                       ((cdbvisit->len > sizeof(struct visit)) ?
                        sizeof(struct visit) : cdbvisit->len));
                cdb_free(cdbvisit);
-               return;
+       }
+
+       /* Set v_seen if necessary */
+       if (vbuf->v_seen[0] == 0) {
+               sprintf(vbuf->v_seen, "*:%ld", vbuf->v_lastseen);
        }
 }
 
@@ -835,8 +839,9 @@ void cmd_slrp(char *new_ptr)
        long newlr;
        struct visit vbuf;
 
-       if (CtdlAccessCheck(ac_logged_in))
+       if (CtdlAccessCheck(ac_logged_in)) {
                return;
+       }
 
        if (!strncasecmp(new_ptr, "highest", 7)) {
                newlr = CC->quickroom.QRhighest;
@@ -848,6 +853,7 @@ void cmd_slrp(char *new_ptr)
 
        CtdlGetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
        vbuf.v_lastseen = newlr;
+       sprintf(vbuf.v_seen, "*:%ld", newlr);
        CtdlSetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
 
        lputuser(&CC->usersupp);