* usergoto() can now be supplied a NULL room name to signify that the caller
authorArt Cancro <ajc@citadel.org>
Mon, 13 May 2002 04:35:50 +0000 (04:35 +0000)
committerArt Cancro <ajc@citadel.org>
Mon, 13 May 2002 04:35:50 +0000 (04:35 +0000)
  has already copied the quickroom record into CC->quickroom.  Eliminates
  an extra database fetch.
* NewMailCount() now uses a per-session counter, which is incremented
  by CtdlSubmitMsg() when the user receiving a message is logged in at the
  time the message is saved.  This eliminates the need to load and scan the
  user's mailbox every time a <G>oto operation is performed.
* The old NewMailCount() function is now InitialMailCheck() and is used at
  session startup time.

citadel/msgbase.c
citadel/room_ops.c
citadel/serv_imap.c
citadel/server.h
citadel/user_ops.c
citadel/user_ops.h

index 7495257a3f23c1dbd364e298725faa68eedb38fc..20846b54bece913c535828ad9ab765a7a46f54ca 100644 (file)
@@ -1906,6 +1906,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
                if (getuser(&userbuf, recipient) == 0) {
                        MailboxName(actual_rm, sizeof actual_rm, &userbuf, MAILROOM);
                        CtdlSaveMsgPointerInRoom(actual_rm, newmsgid, 0);
+                       BumpNewMailCounter(userbuf.usernum);
                }
                else {
                        lprintf(9, "No user <%s>\n", recipient);
index 0eb87ba0e24db174cb56b99c371c0663f2928c84..01c09d73b74a78a929be81370c9051d6b254c916 100644 (file)
@@ -688,7 +688,11 @@ void cmd_lzrm(char *argbuf)
 }
 
 
-
+/*
+ * Make the specified room the current room for this session.  No validation
+ * or access control is done here -- the caller should make sure that the
+ * specified room exists and is ok to access.
+ */
 void usergoto(char *where, int display_result, int *retmsgs, int *retnew)
 {
        int a;
@@ -704,26 +708,35 @@ void usergoto(char *where, int display_result, int *retmsgs, int *retnew)
        long *msglist = NULL;
        int num_msgs = 0;
 
-       strcpy(CC->quickroom.QRname, where);
-       getroom(&CC->quickroom, where);
+       /* If the supplied room name is NULL, the caller wants us to know that
+        * it has already copied the quickroom record into CC->quickroom, so
+        * we can skip the extra database fetch.
+        */
+       if (where != NULL) {
+               strcpy(CC->quickroom.QRname, where);
+               getroom(&CC->quickroom, where);
+       }
+
+       /* Take care of all the formalities. */
 
-       lgetuser(&CC->usersupp, CC->curr_user);
+       begin_critical_section(S_USERSUPP);
        CtdlGetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
 
        /* Know the room ... but not if it's the page log room */
-       if (strcasecmp(where, config.c_logpages)) {
+       if (strcasecmp(CC->quickroom.QRname, config.c_logpages)) {
                vbuf.v_flags = vbuf.v_flags & ~V_FORGET & ~V_LOCKOUT;
                vbuf.v_flags = vbuf.v_flags | V_ACCESS;
        }
        CtdlSetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
-       lputuser(&CC->usersupp);
+       end_critical_section(S_USERSUPP);
 
-       /* check for new mail */
+       /* Check for new mail */
        newmailcount = NewMailCount();
 
        /* set info to 1 if the user needs to read the room's info file */
-       if (CC->quickroom.QRinfo > vbuf.v_lastseen)
+       if (CC->quickroom.QRinfo > vbuf.v_lastseen) {
                info = 1;
+       }
 
        get_mm();
         cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->quickroom.QRnumber, sizeof(long));
@@ -826,9 +839,11 @@ void cmd_goto(char *gargs)
        /* And if the room was found... */
        if (c == 0) {
 
-               /* let internal programs go directly to any room */
+               /* Let internal programs go directly to any room. */
                if (CC->internal_pgm) {
-                       usergoto(towhere, 1, NULL, NULL);
+                       memcpy(&CC->quickroom, &QRscratch,
+                               sizeof(struct quickroom));
+                       usergoto(NULL, 1, NULL, NULL);
                        return;
                }
 
@@ -843,7 +858,9 @@ void cmd_goto(char *gargs)
                if (ok == 1) {
                        if ((QRscratch.QRflags & QR_MAILBOX) &&
                            ((ra & UA_GOTOALLOWED))) {
-                               usergoto(towhere, 1, NULL, NULL);
+                               memcpy(&CC->quickroom, &QRscratch,
+                                       sizeof(struct quickroom));
+                               usergoto(NULL, 1, NULL, NULL);
                                return;
                        } else if ((QRscratch.QRflags & QR_PASSWORDED) &&
                            ((ra & UA_KNOWN) == 0) &&
@@ -862,7 +879,9 @@ void cmd_goto(char *gargs)
                                lprintf(9, "Failed to acquire private room\n");
                                goto NOPE;
                        } else {
-                               usergoto(towhere, 1, NULL, NULL);
+                               memcpy(&CC->quickroom, &QRscratch,
+                                       sizeof(struct quickroom));
+                               usergoto(NULL, 1, NULL, NULL);
                                return;
                        }
                }
index 05acf5c0fafd1812e7f2c06dd427d67d98a74fe7..ec3c6609f0d8ad8b6bcc1516f485289909fd3ca8 100644 (file)
@@ -411,7 +411,8 @@ void imap_select(int num_parms, char *parms[]) {
         * usergoto() formally takes us to the desired room, happily returning
         * the number of messages and number of new messages.
         */
-       usergoto(QRscratch.QRname, 0, &msgs, &new);
+       memcpy(&CC->quickroom, &QRscratch, sizeof(struct quickroom));
+       usergoto(NULL, 0, &msgs, &new);
        IMAP->selected = 1;
 
        if (!strcasecmp(parms[1], "EXAMINE")) {
index 30c190ec8291f3dcd0a8abed0170d7662fa1925e..c8cb8925444f7f3885ee5993ab45170dbb2f5e29 100644 (file)
@@ -137,6 +137,7 @@ struct CitContext {
        /* A linked list of all express messages sent to us. */
        struct ExpressMessage *FirstExpressMessage;
        int disable_exp;        /* Set to 1 to disable incoming pages */
+       int newmail;            /* Other sessions increment this */
 
        /* Masquerade... */
        char fake_username[USERNAME_SIZE];      /* Fake username <bc> */ 
index fa35581e5419b96c5b649307f166bb5158083dad..c6621951557fc57f6ffbea70a291eda2fa5c143f 100644 (file)
@@ -1254,7 +1254,7 @@ void cmd_chek(void)
        }
 
        /* check for mail */
-       mail = NewMailCount();
+       mail = InitialMailCheck();
 
        cprintf("%d %d|%d|%d\n", CIT_OK, mail, regis, vali);
 }
@@ -1360,48 +1360,84 @@ void cmd_asup(char *cmdbuf)
 }
 
 
+
+/*
+ * Check to see if the user who we just sent mail to is logged in.  If yes,
+ * bump the 'new mail' counter for their session.  That enables them to
+ * receive a new mail notification without having to hit the database.
+ */
+void BumpNewMailCounter(long which_user) {
+       struct CitContext *ptr;
+
+       begin_critical_section(S_SESSION_TABLE);
+
+       for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
+               if (ptr->usersupp.usernum == which_user) {
+                       ptr->newmail += 1;
+               }
+       }
+
+       end_critical_section(S_SESSION_TABLE);
+}
+
+
 /*
  * Count the number of new mail messages the user has
  */
 int NewMailCount()
 {
        int num_newmsgs = 0;
-       int a;
-       char mailboxname[ROOMNAMELEN];
-       struct quickroom mailbox;
-       struct visit vbuf;
-       struct cdbdata *cdbfr;
-       long *msglist = NULL;
-       int num_msgs = 0;
 
-       MailboxName(mailboxname, sizeof mailboxname, &CC->usersupp, MAILROOM);
-       if (getroom(&mailbox, mailboxname) != 0)
-               return (0);
-       CtdlGetRelationship(&vbuf, &CC->usersupp, &mailbox);
-
-       cdbfr = cdb_fetch(CDB_MSGLISTS, &mailbox.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);
-       }
-       if (num_msgs > 0)
-               for (a = 0; a < num_msgs; ++a) {
-                       if (msglist[a] > 0L) {
-                               if (msglist[a] > vbuf.v_lastseen) {
-                                       ++num_newmsgs;
-                               }
-                       }
-               }
-       if (msglist != NULL)
-               phree(msglist);
+       num_newmsgs = CC->newmail;
+       CC->newmail = 0;
 
        return (num_newmsgs);
 }
 
 
+/*
+ * Count the number of new mail messages the user has
+ */
+int InitialMailCheck()
+{
+        int num_newmsgs = 0;
+        int a;
+        char mailboxname[ROOMNAMELEN];
+        struct quickroom mailbox;
+        struct visit vbuf;
+        struct cdbdata *cdbfr;
+        long *msglist = NULL;
+        int num_msgs = 0;
+
+        MailboxName(mailboxname, sizeof mailboxname, &CC->usersupp, MAILROOM);
+        if (getroom(&mailbox, mailboxname) != 0)
+                return (0);
+        CtdlGetRelationship(&vbuf, &CC->usersupp, &mailbox);
+
+        cdbfr = cdb_fetch(CDB_MSGLISTS, &mailbox.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);
+        }
+        if (num_msgs > 0)
+                for (a = 0; a < num_msgs; ++a) {
+                        if (msglist[a] > 0L) {
+                                if (msglist[a] > vbuf.v_lastseen) {
+                                        ++num_newmsgs;
+                                }
+                        }
+                }
+        if (msglist != NULL)
+                phree(msglist);
+
+        return (num_newmsgs);
+}
+
+
+
 /*
  * Set the preferred view for the current user/room combination
  */
index 13a7f5b9aa38364de5f06815add5b5af375fe728..8217320238dfd443b3f3679b4928aa15621a39bd 100644 (file)
@@ -34,6 +34,7 @@ void cmd_agup (char *cmdbuf);
 void cmd_asup (char *cmdbuf);
 void cmd_view (char *cmdbuf);
 int NewMailCount(void);
+int InitialMailCheck(void);
 void put_visit(struct visit *newvisit);
 void CtdlGetRelationship(struct visit *vbuf,
                         struct usersupp *rel_user,
@@ -79,3 +80,4 @@ enum {
 
 int CtdlForgetThisRoom(void);
 void cmd_seen(char *argbuf);
+void BumpNewMailCounter(long);