diff options
Diffstat (limited to 'camel/providers')
-rw-r--r-- | camel/providers/imap/camel-imap-folder.c | 4 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-store.c | 116 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-store.h | 3 |
3 files changed, 115 insertions, 8 deletions
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index 5a157a037c..89604b5cac 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -601,8 +601,8 @@ imap_append_message (CamelFolder *folder, CamelMimeMessage *message, const Camel g_free (folder_path); /* send the rest of our data - the mime message */ - status = camel_imap_command_continuation (CAMEL_IMAP_STORE (folder->parent_store), - &result, cmdid, memstream); + status = camel_imap_command_continuation_with_stream (CAMEL_IMAP_STORE (folder->parent_store), + &result, cmdid, memstream); if (status != CAMEL_IMAP_OK) { CamelService *service = CAMEL_SERVICE (folder->parent_store); diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index 07d13396d3..0a2be4f326 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -1049,7 +1049,7 @@ camel_imap_command_preliminary (CamelImapStore *store, char **ret, char **cmdid, * @store: the IMAP store * @cmdid: The command identifier returned from camel_imap_command_preliminary * @ret: a pointer to return the full server response in - * @cstream: a CamelStream containing a continuation response. + * @cmdbuf: buffer containing the response/request data * * This method is for sending continuing responses to the IMAP server. Meant * to be used as a followup to camel_imap_command_preliminary. @@ -1065,7 +1065,116 @@ camel_imap_command_preliminary (CamelImapStore *store, char **ret, char **cmdid, * of the result of the command.) **/ gint -camel_imap_command_continuation (CamelImapStore *store, char **ret, char *cmdid, CamelStream *cstream) +camel_imap_command_continuation (CamelImapStore *store, char **ret, char *cmdid, char *cmdbuf) +{ + gint len = 0, status = CAMEL_IMAP_OK; + gchar *respbuf; + GPtrArray *data; + int i; + + d(fprintf (stderr, "sending : %s\r\n", cmdbuf)); + + if (camel_stream_printf (store->ostream, "%s\r\n", cmdbuf) == -1) { + *ret = g_strdup (strerror (errno)); + + return CAMEL_IMAP_FAIL; + } + + data = g_ptr_array_new (); + + while (1) { + CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream); + + respbuf = camel_stream_buffer_read_line (stream); + if (!respbuf || *respbuf == '+' || !strncmp (respbuf, cmdid, strlen (cmdid))) { + /* IMAP's last response starts with our command id or a continuation request */ + d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)")); + + break; + } + + d(fprintf (stderr, "received: %s\n", respbuf)); + + g_ptr_array_add (data, respbuf); + len += strlen (respbuf) + 1; + } + + if (respbuf) { + g_ptr_array_add (data, respbuf); + len += strlen (respbuf) + 1; + + switch (*respbuf) { + case '+': + status = CAMEL_IMAP_PLUS; + break; + default: + status = camel_imap_status (cmdid, respbuf); + } + } else { + status = CAMEL_IMAP_FAIL; + } + + if (status == CAMEL_IMAP_OK || status == CAMEL_IMAP_PLUS) { + char *p; + + *ret = g_malloc0 (len + 1); + + for (i = 0, p = *ret; i < data->len; i++) { + char *ptr, *datap; + + datap = (char *) data->pdata[i]; + ptr = (*datap == '.') ? datap + 1 : datap; + len = strlen (ptr); + memcpy (p, ptr, len); + p += len; + *p++ = '\n'; + } + *p = '\0'; + } else { + if (status != CAMEL_IMAP_FAIL && respbuf) { + char *word; + + word = imap_next_word (respbuf); + + if (*respbuf == '-') + *ret = g_strdup (word); + else + *ret = g_strdup (imap_next_word (word)); + } else { + *ret = NULL; + } + } + + for (i = 0; i < data->len; i++) + g_free (data->pdata[i]); + g_ptr_array_free (data, TRUE); + + return status; +} + +/** + * camel_imap_command_continuation_with_stream: Handle another transaction with the IMAP + * server and possibly get a multi-line response. + * @store: the IMAP store + * @cmdid: The command identifier returned from camel_imap_command_preliminary + * @ret: a pointer to return the full server response in + * @cstream: a CamelStream containing a continuation response. + * + * This method is for sending continuing responses to the IMAP server. Meant + * to be used as a followup to camel_imap_command_preliminary. + * camel_imap_command_continuation will set @ret to point to a buffer + * containing the rest of the response from the IMAP server. The + * caller function is responsible for freeing @ret. + * + * Return value: one of CAMEL_IMAP_PLUS (command requires additional data), + * CAMEL_IMAP_OK (command executed successfully), + * CAMEL_IMAP_NO (operational error message), + * CAMEL_IMAP_BAD (error message from the server), or + * CAMEL_IMAP_FAIL (a protocol-level error occurred, and Camel is uncertain + * of the result of the command.) + **/ +gint +camel_imap_command_continuation_with_stream (CamelImapStore *store, char **ret, char *cmdid, CamelStream *cstream) { gint len = 0, status = CAMEL_IMAP_OK; gchar *respbuf; @@ -1075,14 +1184,11 @@ camel_imap_command_continuation (CamelImapStore *store, char **ret, char *cmdid, d(fprintf (stderr, "sending continuation stream\r\n")); if (camel_stream_write_to_stream (cstream, store->ostream) == -1) { - d(fprintf (stderr, "failed to send continuation stream\r\n")); - *ret = g_strdup (strerror (errno)); return CAMEL_IMAP_FAIL; } - d(fprintf (stderr, "okie dokie...\r\n")); data = g_ptr_array_new (); while (1) { diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h index 678cf83a1d..fcf0bcaf39 100644 --- a/camel/providers/imap/camel-imap-store.h +++ b/camel/providers/imap/camel-imap-store.h @@ -88,7 +88,8 @@ gint camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, ch /* multi-transactional commands... */ gint camel_imap_command_preliminary (CamelImapStore *store, char **ret, char **cmdid, char *fmt, ...); -gint camel_imap_command_continuation (CamelImapStore *store, char **ret, char *cmdid, CamelStream *cstream); +gint camel_imap_command_continuation (CamelImapStore *store, char **ret, char *cmdid, char *cmdbuf); +gint camel_imap_command_continuation_with_stream (CamelImapStore *store, char **ret, char *cmdid, CamelStream *cstream); /* Standard Camel function */ CamelType camel_imap_store_get_type (void); |