From d19d2c5d8874b947abc80b7aa29c7b19909006f7 Mon Sep 17 00:00:00 2001 From: hiro Date: Fri, 7 Oct 2005 08:37:31 +0000 Subject: support literals in IMAP response. git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@627 ee746299-78ed-0310-b773-934348b2243d --- ChangeLog | 6 ++++++ ChangeLog.ja | 6 ++++++ libsylph/imap.c | 60 +++++++++++++++++++++++++++++++++++++++++++-------------- libsylph/recv.c | 41 ++++++++++++++++++++++++++------------- libsylph/recv.h | 3 +++ 5 files changed, 89 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index ee73831e..f75bf665 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-10-07 + + * libsylph/recv.[ch] + libsylph/imap.c: imap_cmd_ok(): support literals in response + (fixed out of sync when literals appeared). + 2005-10-06 * libsylph/codeconv.c: diff --git a/ChangeLog.ja b/ChangeLog.ja index 28a2517c..232e137c 100644 --- a/ChangeLog.ja +++ b/ChangeLog.ja @@ -1,3 +1,9 @@ +2005-10-07 + + * libsylph/recv.[ch] + libsylph/imap.c: imap_cmd_ok(): 応答中のリテラルに対応 + (リテラルが現われた際に同期がとれなくなるのを修正)。 + 2005-10-06 * libsylph/codeconv.c: diff --git a/libsylph/imap.c b/libsylph/imap.c index ead5d4c3..92926d3e 100644 --- a/libsylph/imap.c +++ b/libsylph/imap.c @@ -3109,6 +3109,8 @@ static gint imap_status(IMAPSession *session, IMAPFolder *folder, real_path_); ok = imap_cmd_ok(session, argbuf); + if (ok != IMAP_SUCCESS) + log_warning(_("error on imap command: STATUS\n")); if (ok != IMAP_SUCCESS || !argbuf) THROW(ok); str = search_array_str(argbuf, "STATUS"); @@ -3727,34 +3729,64 @@ static gint imap_cmd_ok(IMAPSession *session, GPtrArray *argbuf) gchar *buf; gint cmd_num; gchar cmd_status[IMAPBUFSIZE + 1]; + GString *str; + gchar *p; + gchar obuf[32]; + gint len; + gchar *literal; + + str = g_string_sized_new(256); while ((ok = imap_cmd_gen_recv(session, &buf)) == IMAP_SUCCESS) { - if (buf[0] == '*' && buf[1] == ' ') { - if (argbuf) { - g_memmove(buf, buf + 2, strlen(buf + 2) + 1); - g_ptr_array_add(argbuf, buf); - } else + g_string_append(str, buf); + + if ((p = strrchr(buf, '{'))) { + /* literal */ + p = strchr_cpy(p + 1, '}', obuf, sizeof(obuf)); + len = atoi(obuf); + if (len < 0 || p != '\0') { g_free(buf); + ok = IMAP_ERROR; + break; + } + + literal = recv_bytes(SESSION(session)->sock, len); + if (!literal) { + g_free(buf); + ok = IMAP_SOCKET; + break; + } + + g_string_append(str, "\r\n"); + g_string_append_len(str, literal, len); + g_free(literal); + g_free(buf); continue; } - if (sscanf(buf, "%d %" Xstr(IMAPBUFSIZE) "s", + g_free(buf); + + if (str->str[0] == '*' && str->str[1] == ' ') { + if (argbuf) + g_ptr_array_add(argbuf, g_strdup(str->str + 2)); + + g_string_truncate(str, 0); + continue; + } else if (sscanf(str->str, "%d %" Xstr(IMAPBUFSIZE) "s", &cmd_num, cmd_status) < 2) { - g_free(buf); - return IMAP_ERROR; + ok = IMAP_ERROR; } else if (cmd_num == session->cmd_count && !strcmp(cmd_status, "OK")) { if (argbuf) - g_ptr_array_add(argbuf, buf); - else - g_free(buf); - return IMAP_SUCCESS; + g_ptr_array_add(argbuf, g_strdup(str->str)); } else { - g_free(buf); - return IMAP_ERROR; + ok = IMAP_ERROR; } + + break; } + g_string_free(str, TRUE); return ok; } diff --git a/libsylph/recv.c b/libsylph/recv.c index d01d49b8..0b71545c 100644 --- a/libsylph/recv.c +++ b/libsylph/recv.c @@ -36,6 +36,31 @@ static RecvUIFunc recv_ui_func; static gpointer recv_ui_func_data; + +gchar *recv_bytes(SockInfo *sock, glong size) +{ + gchar *buf; + glong count = 0; + + if (size == 0) + return NULL; + + buf = g_malloc(size); + + do { + gint read_count; + + read_count = sock_read(sock, buf + count, size - count); + if (read_count < 0) { + g_free(buf); + return NULL; + } + count += read_count; + } while (count < size); + + return buf; +} + gint recv_write_to_file(SockInfo *sock, const gchar *filename) { FILE *fp; @@ -164,24 +189,14 @@ gint recv_write(SockInfo *sock, FILE *fp) gint recv_bytes_write(SockInfo *sock, glong size, FILE *fp) { gchar *buf; - glong count = 0; gchar *prev, *cur; if (size == 0) return 0; - buf = g_malloc(size); - - do { - gint read_count; - - read_count = sock_read(sock, buf + count, size - count); - if (read_count < 0) { - g_free(buf); - return -2; - } - count += read_count; - } while (count < size); + buf = recv_bytes(sock, size); + if (!buf) + return -2; /* +------------------+----------------+--------------------------+ * * ^buf ^prev ^cur buf+size-1^ */ diff --git a/libsylph/recv.h b/libsylph/recv.h index 251bef56..bc31b9c7 100644 --- a/libsylph/recv.h +++ b/libsylph/recv.h @@ -29,6 +29,9 @@ typedef gboolean (*RecvUIFunc) (SockInfo *sock, gint read_bytes, gpointer data); +gchar *recv_bytes (SockInfo *sock, + glong size); + gint recv_write_to_file (SockInfo *sock, const gchar *filename); gint recv_bytes_write_to_file (SockInfo *sock, -- cgit v1.2.3