const gchar *path,
gint *messages,
gint *recent,
- gint *unseen,
- guint32 *uid_validity);
+ guint32 *uid_next,
+ guint32 *uid_validity,
+ gint *unseen);
static void imap_parse_namespace (IMAPSession *session,
IMAPFolder *folder);
IMAPSession *session = (IMAPSession *)session_list->data;
imap_cmd_logout(SESSION(session)->sock);
- imap_session_destroy(session);
+ session_destroy(SESSION(session));
}
}
return NULL;
}
+ ok = imap_select(session, IMAP_FOLDER(folder), item->path,
+ NULL, NULL, NULL, NULL);
+ statusbar_pop_all();
+ if (ok != IMAP_SUCCESS) {
+ g_warning(_("can't select mailbox %s\n"), item->path);
+ g_free(filename);
+ return NULL;
+ }
+
debug_print(_("getting message %d...\n"), uid);
ok = imap_cmd_fetch(SESSION(session)->sock, (guint32)uid, filename);
return FALSE;
}
-void imap_scan_folder(Folder *folder, FolderItem *item)
+gint imap_scan_folder(Folder *folder, FolderItem *item)
{
IMAPSession *session;
gint messages, recent, unseen;
- guint32 uid_validity;
+ guint32 uid_next, uid_validity;
gint ok;
- g_return_if_fail(folder != NULL);
- g_return_if_fail(item != NULL);
+ g_return_val_if_fail(folder != NULL, -1);
+ g_return_val_if_fail(item != NULL, -1);
session = imap_session_get(folder);
- if (!session) return;
+ if (!session) return -1;
ok = imap_status(session, IMAP_FOLDER(folder), item->path,
- &messages, &recent, &unseen, &uid_validity);
+ &messages, &recent, &uid_next, &uid_validity, &unseen);
statusbar_pop_all();
- if (ok != IMAP_SUCCESS) return;
+ if (ok != IMAP_SUCCESS) return -1;
- item->new = recent;
+ item->new = unseen > 0 ? recent : 0;
item->unread = unseen;
item->total = messages;
+ item->last_num = (messages > 0 && uid_next > 0) ? uid_next - 1 : 0;
/* item->mtime = uid_validity; */
+
+ return 0;
}
void imap_scan_tree(Folder *folder)
new_item = folder_item_new(loc_name, loc_path);
if (strcasestr(flags, "\\Noinferiors") != NULL)
new_item->no_sub = TRUE;
- if (strcasestr(flags, "\\Noselect") != NULL)
+ if (strcmp(buf, "INBOX") != 0 &&
+ strcasestr(flags, "\\Noselect") != NULL)
new_item->no_select = TRUE;
item_list = g_slist_append(item_list, new_item);
if (!folder->inbox)
folder->inbox = imap_create_special_folder
(folder, F_INBOX, "INBOX");
+#if 0
if (!folder->outbox)
folder->outbox = imap_create_special_folder
(folder, F_OUTBOX, "Sent");
if (!folder->queue)
folder->queue = imap_create_special_folder
(folder, F_QUEUE, "Queue");
+#endif
if (!folder->trash)
folder->trash = imap_create_special_folder
(folder, F_TRASH, "Trash");
new_item = imap_create_folder(folder, folder->inbox, name);
if (!new_item)
g_warning(_("Can't create '%s' under INBOX\n"), name);
+ else
+ new_item->stype = stype;
} else
new_item->stype = stype;
real_oldpath = imap_get_real_path(IMAP_FOLDER(folder), item->path);
+ g_free(session->mbox);
+ session->mbox = NULL;
ok = imap_cmd_examine(SESSION(session)->sock, "INBOX",
&exists, &recent, &unseen, &uid_validity);
statusbar_pop_all();
g_free(tmp);
break;
}
+ if (strstr(tmp, "FETCH") == NULL) {
+ g_free(tmp);
+ continue;
+ }
g_string_assign(str, tmp);
g_free(tmp);
SockInfo *sock;
if ((sock = sock_connect_cmd(server, tunnelcmd)) == NULL)
+ log_warning(_("Can't establish IMAP4 session with: %s\n"),
+ server);
return NULL;
return imap_init_sock(sock);
#if USE_SSL
if (use_ssl && !ssl_init_socket(sock)) {
+ log_warning(_("Can't establish IMAP4 session with: %s:%d\n"),
+ server, port);
sock_close(sock);
return NULL;
}
imap_cmd_count = 0;
if (imap_cmd_noop(sock) != IMAP_SUCCESS) {
+ log_warning(_("Can't establish IMAP4 session\n"));
sock_close(sock);
return NULL;
}
return sock;
}
-
-
#define THROW goto catch
static void imap_parse_namespace(IMAPSession *session, IMAPFolder *folder)
gchar *dest, gint dest_len, GString *str)
{
gchar *cur_pos = src;
+ gchar *nextline;
g_return_val_if_fail(str != NULL, cur_pos);
- while (*cur_pos == ' ') cur_pos++;
+ /* read the next line if the current response buffer is empty */
+ while (isspace(*cur_pos)) cur_pos++;
+ while (*cur_pos == '\0') {
+ if ((nextline = sock_getline(sock)) == NULL)
+ return cur_pos;
+ g_string_assign(str, nextline);
+ cur_pos = str->str;
+ strretchomp(nextline);
+ log_print("IMAP4< %s\n", nextline);
+ g_free(nextline);
+
+ while (isspace(*cur_pos)) cur_pos++;
+ }
if (!strncmp(cur_pos, "NIL", 3)) {
*dest = '\0';
} else if (*cur_pos == '{') {
gchar buf[32];
gint len;
- gchar *nextline;
+ gint line_len = 0;
cur_pos = strchr_cpy(cur_pos + 1, '}', buf, sizeof(buf));
len = atoi(buf);
- if ((nextline = sock_getline(sock)) == NULL)
- return cur_pos;
- strretchomp(nextline);
- log_print("IMAP4< %s\n", nextline);
- g_string_assign(str, nextline);
-
- len = MIN(len, strlen(nextline));
- memcpy(dest, nextline, MIN(len, dest_len - 1));
+ g_string_truncate(str, 0);
+ cur_pos = str->str;
+
+ do {
+ if ((nextline = sock_getline(sock)) == NULL)
+ return cur_pos;
+ line_len += strlen(nextline);
+ g_string_append(str, nextline);
+ cur_pos = str->str;
+ strretchomp(nextline);
+ log_print("IMAP4< %s\n", nextline);
+ g_free(nextline);
+ } while (line_len < len);
+
+ memcpy(dest, cur_pos, MIN(len, dest_len - 1));
dest[MIN(len, dest_len - 1)] = '\0';
- cur_pos = str->str + len;
+ cur_pos += len;
}
return cur_pos;
while ((p = strchr(p, '\\')) != NULL) {
p++;
- if (g_strncasecmp(p, "Recent", 6) == 0) {
- MSG_SET_PERM_FLAGS(flags, MSG_NEW|MSG_UNREAD);
+ if (g_strncasecmp(p, "Recent", 6) == 0 && MSG_IS_UNREAD(flags)) {
+ MSG_SET_PERM_FLAGS(flags, MSG_NEW);
} else if (g_strncasecmp(p, "Seen", 4) == 0) {
MSG_UNSET_PERM_FLAGS(flags, MSG_NEW|MSG_UNREAD);
} else if (g_strncasecmp(p, "Deleted", 7) == 0) {
{
gchar *real_path;
gint ok;
+ gint exists_, recent_, unseen_, uid_validity_;
+
+ if (!exists || !recent || !unseen || !uid_validity) {
+ if (session->mbox && strcmp(session->mbox, path) == 0)
+ return IMAP_SUCCESS;
+ exists = &exists_;
+ recent = &recent_;
+ unseen = &unseen_;
+ uid_validity = &uid_validity_;
+ }
+
+ g_free(session->mbox);
+ session->mbox = NULL;
real_path = imap_get_real_path(folder, path);
ok = imap_cmd_select(SESSION(session)->sock, real_path,
exists, recent, unseen, uid_validity);
if (ok != IMAP_SUCCESS)
log_warning(_("can't select folder: %s\n"), real_path);
+ else
+ session->mbox = g_strdup(path);
g_free(real_path);
return ok;
static gint imap_status(IMAPSession *session, IMAPFolder *folder,
const gchar *path,
- gint *messages, gint *recent, gint *unseen,
- guint32 *uid_validity)
+ gint *messages, gint *recent,
+ guint32 *uid_next, guint32 *uid_validity,
+ gint *unseen)
{
gchar *real_path;
gchar *real_path_;
GPtrArray *argbuf;
gchar *str;
- *messages = *recent = *unseen = *uid_validity = 0;
+ *messages = *recent = *uid_next = *uid_validity = *unseen = 0;
argbuf = g_ptr_array_new();
real_path = imap_get_real_path(folder, path);
QUOTE_IF_REQUIRED(real_path_, real_path);
imap_cmd_gen_send(SESSION(session)->sock, "STATUS %s "
- "(MESSAGES RECENT UNSEEN UIDVALIDITY)", real_path_);
+ "(MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN)",
+ real_path_);
ok = imap_cmd_ok(SESSION(session)->sock, argbuf);
if (ok != IMAP_SUCCESS) THROW(ok);
} else if (!strncmp(str, "RECENT ", 7)) {
str += 7;
*recent = strtol(str, &str, 10);
- } else if (!strncmp(str, "UNSEEN ", 7)) {
- str += 7;
- *unseen = strtol(str, &str, 10);
+ } else if (!strncmp(str, "UIDNEXT ", 8)) {
+ str += 8;
+ *uid_next = strtoul(str, &str, 10);
} else if (!strncmp(str, "UIDVALIDITY ", 12)) {
str += 12;
*uid_validity = strtoul(str, &str, 10);
+ } else if (!strncmp(str, "UNSEEN ", 7)) {
+ str += 7;
+ *unseen = strtol(str, &str, 10);
} else {
g_warning("invalid STATUS response: %s\n", str);
break;
imap_cmd_gen_send(sock, "UID FETCH %d BODY[]", uid);
- if (sock_gets(sock, buf, sizeof(buf)) < 0)
- return IMAP_ERROR;
- strretchomp(buf);
- if (buf[0] != '*' || buf[1] != ' ')
- return IMAP_ERROR;
- log_print("IMAP4< %s\n", buf);
+ while ((ok = imap_cmd_gen_recv(sock, buf, sizeof(buf)))
+ == IMAP_SUCCESS) {
+ if (buf[0] != '*' || buf[1] != ' ')
+ return IMAP_ERROR;
+ if (strstr(buf, "FETCH") != NULL)
+ break;
+ }
+ if (ok != IMAP_SUCCESS)
+ return ok;
cur_pos = strchr(buf, '{');
g_return_val_if_fail(cur_pos != NULL, IMAP_ERROR);