aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2005-10-07 08:37:31 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2005-10-07 08:37:31 +0000
commitd19d2c5d8874b947abc80b7aa29c7b19909006f7 (patch)
tree7f9b3f1b7095b12da753df3fb0fd28b6fef7476c
parent5f667d42f46f4735b0e23c00467055fc7d93df8e (diff)
support literals in IMAP response.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@627 ee746299-78ed-0310-b773-934348b2243d
-rw-r--r--ChangeLog6
-rw-r--r--ChangeLog.ja6
-rw-r--r--libsylph/imap.c60
-rw-r--r--libsylph/recv.c41
-rw-r--r--libsylph/recv.h3
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,