Skip to content

Commit

Permalink
net_imap, mod_webmail: Fixes for ALERT handling.
Browse files Browse the repository at this point in the history
* net_imap: Use a node write function that may be used from
  threads other than the owner's, to avoid warnings about
  writing from another thread.
* mod_webmail: Properly handle and display ALERT messages.
  • Loading branch information
InterLinked1 committed Nov 25, 2023
1 parent 96cb5dc commit 424dab9
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 6 deletions.
15 changes: 15 additions & 0 deletions modules/mod_webmail.c
Original file line number Diff line number Diff line change
Expand Up @@ -3113,6 +3113,20 @@ static int process_idle(struct imap_client *client, char *s)
webmail_log(3, client, "<= %s\n", s);

if (!STARTS_WITH(s, "* ")) {
/* Maybe it's a tagged response terminating the IDLE command? */
const char *next = bbs_strcnext(s, ' '); /* Skip the tag, assuming that's what it is */
if (STARTS_WITH(next, "NO ") || STARTS_WITH(next, "OK ")) { /* Done this way instead of strsep to leave original message intact */
next += 3;
if (!strlen_zero(next)) {
/* Maybe it's an [ALERT] or something like that.
* Should display to the user. */
bbs_strterm(s, '\n');
bbs_debug(5, "Interesting IDLE response... '%s'\n", next);
client_set_status(client->ws, "%s", next);
/* on_poll_activity will start IDLE again */
return 0;
}
}
bbs_warning("Unexpected IDLE response (not untagged): %s\n", s);
return -1;
}
Expand Down Expand Up @@ -3393,6 +3407,7 @@ static int on_text_message(struct ws_session *ws, void *data, const char *buf, s
if (client_imap_select(ws, client, client->imap, json_object_string_value(root, "folder"))) {
goto cleanup;
}
client_set_status(ws, "%s", ""); /* Clear any previous status message */
/* Send an unsolicited list of messages (implicitly fetch the first page). */
res = handle_fetchlist(ws, client, command, 1, json_object_int_value(root, "pagesize"), json_object_string_value(root, "sort"), json_object_string_value(root, "filter"));
} else if (!strcmp(command, "FETCHLIST")) {
Expand Down
20 changes: 14 additions & 6 deletions nets/net_imap.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ static int cli_imap_sessions(struct bbs_cli_args *a)
{
struct imap_session *imap;

bbs_dprintf(a->fdout, "%4s %-25s %-25s %7s %s\n", "Node", "Current Mailbox", "Current Folder", "Proxied", "Client ID");
bbs_dprintf(a->fdout, "%4s %-25s %-25s %4s %7s %s\n", "Node", "Current Mailbox", "Current Folder", "Idle", "Proxied", "Client ID");
RWLIST_RDLOCK(&sessions);
RWLIST_TRAVERSE(&sessions, imap, entry) {
char mbox_buf[32];
Expand All @@ -257,8 +257,8 @@ static int cli_imap_sessions(struct bbs_cli_args *a)
mbox_name = mbox_buf;
}
}
bbs_dprintf(a->fdout, "%4u %-25s %-25s %7s %s\n",
imap->node->id, S_IF(mbox_name), S_IF(imap->folder), imap->client ? "Yes" : "No", S_IF(imap->clientid));
bbs_dprintf(a->fdout, "%4u %-25s %-25s %4s %7s %s\n",
imap->node->id, S_IF(mbox_name), S_IF(imap->folder), BBS_YN(imap->idle), imap->client ? "Yes" : "No", S_IF(imap->clientid));
}
RWLIST_UNLOCK(&sessions);
return 0;
Expand Down Expand Up @@ -4829,10 +4829,18 @@ static int alertmsg(unsigned int userid, const char *msg)
/* Untested: Trojita */
}

s->alerted = 1;
/* Do not send a random untagged EXISTS, e.g. * EXISTS 999999, or that will cause ~Thunderbird to ignore the ALERT */
_imap_reply_nolock(s, "%s NO [ALERT] %s\r\n", s->savedtag, msg); /* Use tag from IDLE request. This must be a NO, not an OK. */
s->idle = 0; /* Since we sent a tagged reply, the IDLE is technically terminated now. */
__imap_parallel_reply(s, "%s NO [ALERT] %s\r\n", s->savedtag, msg); /* Use tag from IDLE request. This must be a NO, not an OK. */
if (!strlen_zero(s->clientid) && strstr(s->clientid, "wssmail")) {
/* libetpan doesn't seem to care about IDLE replies that aren't a response to a command it sent.
* So we can ignore this and continue on idling. */
/* s->idle remains 1, s->alerted remains 0 */
} else {
s->idle = 0; /* Since we sent a tagged reply, the IDLE is technically terminated now. */
/* We only seem to be able to send an alert once for most clients.
* If we're just it's not an issue, then we don't set this flag. */
s->alerted = 1;
}
res = 0;
pthread_mutex_unlock(&s->lock);
}
Expand Down

0 comments on commit 424dab9

Please sign in to comment.