aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers')
-rw-r--r--camel/providers/imap/camel-imap-folder.c4
-rw-r--r--camel/providers/imap/camel-imap-store.c116
-rw-r--r--camel/providers/imap/camel-imap-store.h3
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);