aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/imap/camel-imap-store.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers/imap/camel-imap-store.c')
-rw-r--r--camel/providers/imap/camel-imap-store.c100
1 files changed, 75 insertions, 25 deletions
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index b5d5f71ccc..0d35e971b2 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -367,7 +367,7 @@ static gchar
* (a protocol-level error occurred, and Camel is uncertain of the
* result of the command.)
**/
-int
+gint
camel_imap_command (CamelImapStore *store, char **ret, char *fmt, ...)
{
gchar *cmdbuf, *respbuf;
@@ -403,9 +403,10 @@ camel_imap_command (CamelImapStore *store, char **ret, char *fmt, ...)
fprintf(stderr, "received: %s\n", respbuf);
+ /* TODO: We should really check the command id, da? */
if (!strncmp (respbuf + 11, "OK", 2))
status = CAMEL_IMAP_OK;
- else if (!strncmp (respbuf + 11, "BAD", 3))
+ else if (!strncmp (respbuf + 11, "NO", 2))
status = CAMEL_IMAP_ERR;
else
status = CAMEL_IMAP_FAIL;
@@ -424,41 +425,81 @@ camel_imap_command (CamelImapStore *store, char **ret, char *fmt, ...)
}
/**
- * camel_imap_command_get_additional_data: get "additional data" from
- * an IMAP command.
+ * camel_imap_command_extended: Send a command to a IMAP server and get
+ * a multi-line response.
* @store: the IMAP store
+ * @ret: a pointer to return the full server response in
+ * @fmt: a printf-style format string, followed by arguments
+ *
+ * This command sends the command specified by @fmt and the following
+ * arguments to the connected IMAP store specified by @store. It then
+ * reads the server's response and parses out the status code.
+ * Camel_imap_command_extended will set it to point to a buffer containing the
+ * response from the IMAP server. (If @ret was passed but there was The caller
+ * must free this buffer when it is done with it.
*
* This command gets the additional data returned by "multi-line" IMAP
- * commands, such as LIST, RETR, TOP, and UIDL. This command _must_
- * be called after a successful (CAMEL_IMAP_OK) call to
- * camel_imap_command for a command that has a multi-line response.
+ * commands, such as SELECT, LIST, LSUB, and various other commands.
* The returned data is un-byte-stuffed, and has lines termined by
* newlines rather than CR/LF pairs.
*
- * Return value: the data, which the caller must free.
+ * Return value: one of CAMEL_IMAP_OK (command executed successfully),
+ * CAMEL_IMAP_ERR (command encounted an error), or CAMEL_IMAP_FAIL
+ * (a protocol-level error occurred, and Camel is uncertain of the
+ * result of the command.)
**/
-char *
-camel_imap_command_get_additional_data (CamelImapStore *store,
- CamelException *ex)
+
+gint
+camel_imap_command_extended (CamelImapStore *store, char **ret, char *fmt, ...)
{
CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream);
GPtrArray *data;
- char *buf;
- int i, status = CAMEL_IMAP_OK;
+ gchar *cmdid, *cmdbuf, *respbuf, *code;
+ va_list app;
+ gint i, status = CAMEL_IMAP_OK;
+
+ /* Create the command */
+ cmdid = g_strdup_printf("A%.5d", store->command++);
+ va_start (ap, fmt);
+ cmdbuf = g_strdup_vprintf (fmt, ap);
+ va_end (ap);
+
+ fprintf(stderr, "sending : %s %s\r\n", cmdid, cmdbuf);
+
+ if (camel_stream_printf (store->ostream, "%s %s\r\n", cmdid, cmdbuf) == -1) {
+ g_free(cmdbuf);
+ g_free(cmdid);
+
+ *ret = g_strdup(strerror(errno));
+
+ return CAMEL_IMAP_FAIL;
+ }
+ g_free(cmdbuf);
+ g_free(cmdid);
data = g_ptr_array_new ();
while (1) {
- buf = camel_stream_buffer_read_line (stream);
- if (!buf) {
- status = CAMEL_IMAP_FAIL;
+ respbuf = camel_stream_buffer_read_line (stream);
+ if (!respbuf || !strncmp(respbuf, cmdid, strlen(cmdid)) ) {
+ /* IMAP's last response starts with our command id */
break;
}
- if (!strcmp (buf, "."))
- break;
- if (*buf == '.')
- memmove (buf, buf + 1, strlen (buf));
- g_ptr_array_add (data, buf);
+ fprintf(stderr, "received: %s\n", respbuf);
+
+ g_ptr_array_add (data, respbuf);
+ }
+
+ if (respbuf) {
+ code = respbuf + strlen(cmdid) + 1;
+ if (!strncmp(code, "OK", 2))
+ status = CAMEL_IMAP_OK;
+ else if (!strncmp(code, "NO", 2))
+ status = CAMEL_IMAP_ERR;
+ else
+ status = CAMEL_IMAP_FAIL;
+ } else {
+ status = CAMEL_IMAP_FAIL;
}
if (status == CAMEL_IMAP_OK) {
@@ -468,14 +509,23 @@ camel_imap_command_get_additional_data (CamelImapStore *store,
*/
g_ptr_array_add (data, "");
g_ptr_array_add (data, NULL);
- buf = g_strjoinv ("\n", (char **)data->pdata);
- } else
- buf = NULL;
+ *ret = g_strjoinv ("\n", (gchar **)data->pdata);
+ } else {
+ if (status != CAMEL_IMAP_FAIL)
+ *ret = g_strdup (strchr (respbuf, ' ' + 1);
+ else
+ *ret = NULL;
+ }
for (i = 0; i < data->len - 2; i++)
g_free (data->pdata[i]);
g_ptr_array_free (data, TRUE);
- return buf;
+ return status;
}
+
+
+
+
+