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);
}
-
+/*
+ * 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;
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));
/* 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;
}
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) &&
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;
}
}
* 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")) {
/* 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> */
}
/* check for mail */
- mail = NewMailCount();
+ mail = InitialMailCheck();
cprintf("%d %d|%d|%d\n", CIT_OK, mail, regis, vali);
}
}
+
+/*
+ * 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
*/
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,
int CtdlForgetThisRoom(void);
void cmd_seen(char *argbuf);
+void BumpNewMailCounter(long);