[Goodies-commits] r3915 - xfce4-mailwatch-plugin/trunk/libmailwatch-core
Brian Tarricone
kelnos at xfce.org
Mon Feb 4 10:15:03 CET 2008
Author: kelnos
Date: 2008-02-04 09:15:03 +0000 (Mon, 04 Feb 2008)
New Revision: 3915
Modified:
xfce4-mailwatch-plugin/trunk/libmailwatch-core/mailwatch-mailbox-imap.c
Log:
use STATUS instead of EXAMINE+SEARCH for IMAP.
should be faster and (hopefully) less error-prone, and avoids a lot of
allocations since the response length is more or less fixed (and small).
also better handle errors. if we get "#### NO" from the STATUS request,
just return 0 new messages. that can happen if, for example, a folder
is selected in mailwatch that is later deleted or unsubscribed.
Modified: xfce4-mailwatch-plugin/trunk/libmailwatch-core/mailwatch-mailbox-imap.c
===================================================================
--- xfce4-mailwatch-plugin/trunk/libmailwatch-core/mailwatch-mailbox-imap.c 2008-02-04 05:14:24 UTC (rev 3914)
+++ xfce4-mailwatch-plugin/trunk/libmailwatch-core/mailwatch-mailbox-imap.c 2008-02-04 09:15:03 UTC (rev 3915)
@@ -568,89 +568,70 @@
imap_check_mailbox(XfceMailwatchIMAPMailbox *imailbox,
const gchar *mailbox_name)
{
-#define BUFSIZE 8191
- gint new_messages = 0, bin, i = 0;
- gchar buf[BUFSIZE+1], *p, *q, tmp[64], *buf_extra = NULL;
+ gint new_messages = 0;
+ gchar buf[4096], *p, *q, tmp[64];
+ gboolean got_OK = FALSE, got_LF = FALSE;
TRACE("entering, folder %s", mailbox_name);
- memset(buf, 0, BUFSIZE + 1);
+ memset(buf, 0, sizeof(buf));
/* ask the server to look at the mailbox */
- g_snprintf(buf, BUFSIZE, "%05d EXAMINE %s\r\n", ++imailbox->imap_tag,
- mailbox_name);
+ g_snprintf(buf, sizeof(buf), "%05d STATUS %s (UNSEEN)\r\n",
+ ++imailbox->imap_tag, mailbox_name);
if(imap_send(imailbox, buf) != strlen(buf))
return 0;
DBG(" successfully sent cmd '%s'", buf);
- /* grab the response; it should end with "##### OK " */
- if(imap_recv(imailbox, buf, BUFSIZE) < 0)
- return 0;
- g_snprintf(tmp, 64, "%05d OK ", imailbox->imap_tag);
- if(!strstr(buf, tmp))
- return 0;
- DBG(" successfully got reply '%s'", buf);
-
- /* send SEARCH command */
- g_snprintf(buf, BUFSIZE, "%05d SEARCH UNSEEN\r\n", ++imailbox->imap_tag);
- if(imap_send(imailbox, buf) != strlen(buf))
- return 0;
- DBG(" successfully sent cmd '%s'", buf);
-
- /* get response; it should have "* SEARCH" followed by a space-delimited
- * list of unseen messages. unfortunately, this means there's no upper
- * bound on string length, so we need a buffer that can grow. */
+ /* grab the response */
+ g_snprintf(tmp, sizeof(tmp), "%05d NO", imailbox->imap_tag);
do {
- buf_extra = g_realloc(buf_extra, ((BUFSIZE + 1) * (i + 1)) + 1);
- DBG("pass %d: allocated %d bytes", i+1, ((BUFSIZE + 1) * (i + 1)) + 1);
- bin = imap_recv(imailbox, buf_extra + (BUFSIZE + 1) * i, BUFSIZE + 1);
- DBG("pass %d: got %d bytes", i+1, bin);
- if(bin < 0)
- return 0;
- ++i;
- } while(bin == BUFSIZE + 1);
+ if(imap_recv(imailbox, buf, sizeof(buf)-1) <= 0) {
+ xfce_mailwatch_log_message(imailbox->mailwatch,
+ XFCE_MAILWATCH_MAILBOX(imailbox),
+ XFCE_MAILWATCH_LOG_WARNING,
+ _("The IMAP server returned a response we weren't quite expecting. This might be OK, or this plugin might need to be modified to support your mail server if the new message counts are incorrect."));
+ g_warning("Mailwatch: Odd response to SEARCH UNSEEN");
+ return 0;
+ }
+
+ if(strstr(buf, tmp))
+ return 0;
+ } while(!(p = strstr(buf, "(UNSEEN ")));
- buf_extra[(BUFSIZE + 1) * i] = 0;
- g_snprintf(tmp, 64, "%05d OK", imailbox->imap_tag);
- if(!strstr(buf_extra, tmp)) {
- xfce_mailwatch_log_message(imailbox->mailwatch,
- XFCE_MAILWATCH_MAILBOX(imailbox),
- XFCE_MAILWATCH_LOG_WARNING,
- _("The IMAP server returned a response we weren't quite expecting. This might be OK, or this plugin might need to be modified to support your mail server if the new message counts are incorrect."));
- g_warning("Mailwatch: Odd response to SEARCH UNSEEN");
- }
- p = strstr(buf_extra, "* SEARCH");
- if(!p) {
- g_free(buf_extra);
- return 0;
- }
- DBG(" successfully got reply '%s'", buf_extra);
-
- p += 8;
-
- /* find the end of the line */
- q = strstr(p, "\r");
+ q = strchr(p, ')');
if(!q)
- q = strstr(p, "\n");
- if(!q) {
- g_free(buf_extra);
return 0;
- }
*q = 0;
- DBG(" ok, we have a list of messages: '%s'", p);
+ new_messages = atoi(p+8);
+ *q = ')';
- /* find each space in the string; that's a message */
- while((p = strstr(p, " "))) {
- new_messages++;
- p++;
+ /* make sure we got the entire command; it should end with "##### OK" in it */
+ g_snprintf(tmp, sizeof(tmp), "%05d OK", imailbox->imap_tag);
+ while(!got_OK && !got_LF) {
+ DBG("looking for end, got: %s", buf);
+
+ if(!got_OK) {
+ gchar *p = strstr(buf, tmp);
+ if(p) {
+ DBG("got OK");
+ got_OK = TRUE;
+ got_LF = !!strchr(p, '\n');
+ DBG("%s LF after getting OK", got_LF?"got":"didn't get");
+ } else
+ DBG("didn't get OK");
+ } else {
+ got_LF = !!strchr(buf, '\n');
+ DBG("%s LF", got_LF?"got":"didn't get");
+ }
+
+ if(!got_OK && !got_LF && imap_recv(imailbox, buf, sizeof(buf)-1) <= 0)
+ break;
}
- g_free(buf_extra);
-
DBG("new message count in mailbox '%s' is %d", mailbox_name, new_messages);
return (guint)new_messages;
-#undef BUFSIZE
}
static void
More information about the Goodies-commits
mailing list