aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers')
-rw-r--r--camel/providers/imap/camel-imap-folder.c96
-rw-r--r--camel/providers/imap/camel-imap-folder.h2
-rw-r--r--camel/providers/imap/camel-imap-store.c230
-rw-r--r--camel/providers/imap/camel-imap-store.h5
4 files changed, 191 insertions, 142 deletions
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index 9664dab008..96236d2374 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -93,7 +93,6 @@ static const CamelMessageInfo *imap_get_message_info (CamelFolder *folder, const
static GPtrArray *imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex);
/* flag methods */
-/*static guint32 imap_get_permanent_flags (CamelFolder *folder, CamelException *ex);*/
static guint32 imap_get_message_flags (CamelFolder *folder, const char *uid);
static void imap_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set);
static gboolean imap_get_message_user_flag (CamelFolder *folder, const char *uid, const char *name);
@@ -306,6 +305,7 @@ imap_get_message_count_internal (CamelFolder *folder, CamelException *ex)
{
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
gchar *result, *msg_count, *folder_path;
+ GPtrArray *response;
gint status, count = 0;
g_return_val_if_fail (folder->can_hold_messages, 0);
@@ -313,10 +313,10 @@ imap_get_message_count_internal (CamelFolder *folder, CamelException *ex)
folder_path = camel_imap_store_folder_path (store, folder->full_name);
if (store->has_status_capability)
- status = camel_imap_command_extended (store, folder, &result, ex,
+ status = camel_imap_command_extended (store, folder, &response, ex,
"STATUS \"%s\" (MESSAGES)", folder_path);
else
- status = camel_imap_command_extended (store, folder, &result, ex,
+ status = camel_imap_command_extended (store, folder, &response, ex,
"EXAMINE \"%s\"", folder_path);
g_free (folder_path);
@@ -325,17 +325,22 @@ imap_get_message_count_internal (CamelFolder *folder, CamelException *ex)
return 0;
/* parse out the message count */
- if (result && *result == '*') {
- if (store->has_status_capability) {
- /* should come in the form: "* STATUS <folder> (MESSAGES <count>)" */
+ if (store->has_status_capability) {
+ /* should come in the form: "* STATUS <folder> (MESSAGES <count>)" */
+ result = camel_imap_response_extract (response, "STATUS", NULL);
+ if (result) {
if ((msg_count = strstr (result, "MESSAGES")) != NULL) {
msg_count = imap_next_word (msg_count);
/* we should now be pointing to the message count */
count = atoi (msg_count);
}
- } else {
- /* should come in the form: "* <count> EXISTS" */
+ g_free (result);
+ }
+ } else {
+ /* should come in the form: "* <count> EXISTS" */
+ result = camel_imap_response_extract (response, "EXISTS", NULL);
+ if (result) {
if ((msg_count = strstr (result, "EXISTS")) != NULL) {
for ( ; msg_count > result && *msg_count != '*'; msg_count--);
@@ -344,9 +349,9 @@ imap_get_message_count_internal (CamelFolder *folder, CamelException *ex)
/* we should now be pointing to the message count */
count = atoi (msg_count);
}
+ g_free (result);
}
}
- g_free (result);
return count;
}
@@ -501,16 +506,16 @@ imap_get_subfolder_info_internal (CamelFolder *folder, CamelException *ex)
{
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- GPtrArray *listing;
+ GPtrArray *response, *listing;
gboolean found_inbox = FALSE;
- gint status;
- gchar *result, *namespace;
+ gint status, i;
+ gchar *namespace;
CamelFolderInfo *fi;
g_return_val_if_fail (folder != NULL, g_ptr_array_new ());
namespace = camel_imap_store_folder_path (store, folder->full_name);
- status = camel_imap_command_extended (store, NULL, &result, ex,
+ status = camel_imap_command_extended (store, NULL, &response, ex,
"LIST \"\" \"%s%s*\"", namespace,
*namespace ? store->dir_sep : "");
@@ -523,31 +528,20 @@ imap_get_subfolder_info_internal (CamelFolder *folder, CamelException *ex)
/* parse out the subfolders */
listing = g_ptr_array_new ();
- if (result) {
- char *ptr = result;
-
- while (ptr && *ptr == '*') {
- gchar *flags, *sep, *dir, *buf, *end;
-
- for (end = ptr; *end && *end != '\n'; end++);
- buf = g_strndup (ptr, (gint)(end - ptr));
- ptr = end;
-
- if (!imap_parse_list_response (buf, namespace, &flags, &sep, &dir)) {
- g_free (buf);
+ if (response) {
+ for (i = 0; i < response->len; i++) {
+ gchar *resp, *flags, *sep, *dir;
+
+ resp = response->pdata[i];
+ if (!imap_parse_list_response (resp, namespace, &flags, &sep, &dir)) {
g_free (flags);
g_free (sep);
g_free (dir);
-
- if (*ptr == '\n')
- ptr++;
-
continue;
}
-
- g_free (buf);
+
g_free (flags);
-
+
if (*dir) {
d(fprintf (stderr, "adding folder: %s\n", dir));
fi = g_new0 (CamelFolderInfo, 1);
@@ -563,12 +557,10 @@ imap_get_subfolder_info_internal (CamelFolder *folder, CamelException *ex)
found_inbox = TRUE;
g_ptr_array_add (listing, fi);
}
-
+
g_free (sep);
-
- if (*ptr == '\n')
- ptr++;
}
+ camel_imap_response_free (response);
}
if (!*folder->name && !found_inbox) {
@@ -580,7 +572,6 @@ imap_get_subfolder_info_internal (CamelFolder *folder, CamelException *ex)
g_ptr_array_add (listing, fi);
}
- g_free (result);
g_free (namespace);
imap_folder->lsub = listing;
@@ -821,13 +812,12 @@ imap_get_summary_internal (CamelFolder *folder, CamelException *ex)
summary_specifier = imap_protocol_get_summary_specifier (store);
- /* We use camel_imap_command_extended here because it's safe */
if (num == 1) {
- status = camel_imap_command_extended (store, folder, &result, ex,
- "FETCH 1 (%s)", summary_specifier);
+ status = camel_imap_fetch_command (store, folder, &result, ex,
+ "FETCH 1 (%s)", summary_specifier);
} else {
- status = camel_imap_command_extended (store, folder, &result, ex,
- "FETCH 1:%d (%s)", num, summary_specifier);
+ status = camel_imap_fetch_command (store, folder, &result, ex,
+ "FETCH 1:%d (%s)", num, summary_specifier);
}
g_free (summary_specifier);
@@ -986,9 +976,8 @@ imap_get_message_info_internal (CamelFolder *folder, guint id, CamelException *e
/* we don't have a cached copy, so fetch it */
summary_specifier = imap_protocol_get_summary_specifier (store);
- /* again, we use camel_imap_command_extended here because it's safe to do so */
- status = camel_imap_command_extended (store, folder, &result, ex,
- "FETCH %d (%s)", id, summary_specifier);
+ status = camel_imap_fetch_command (store, folder, &result, ex,
+ "FETCH %d (%s)", id, summary_specifier);
g_free (summary_specifier);
@@ -1093,7 +1082,7 @@ imap_get_message_info (CamelFolder *folder, const char *uid)
static GPtrArray *
imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex)
{
- GPtrArray *uids = NULL;
+ GPtrArray *response, *uids = NULL;
char *result, *sexp, *p;
int status;
@@ -1109,12 +1098,14 @@ imap_search_by_expression (CamelFolder *folder, const char *expression, CamelExc
}
status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder,
- &result, ex, "UID SEARCH %s", sexp);
+ &response, NULL, "UID SEARCH %s", sexp);
+ g_free (sexp);
- if (status != CAMEL_IMAP_OK) {
- g_free (sexp);
+ if (status != CAMEL_IMAP_OK)
+ return uids;
+ result = camel_imap_response_extract (response, "SEARCH", NULL);
+ if (!result)
return uids;
- }
if ((p = strstr (result, "* SEARCH"))) {
char *word;
@@ -1136,7 +1127,6 @@ imap_search_by_expression (CamelFolder *folder, const char *expression, CamelExc
}
g_free (result);
- g_free (sexp);
return uids;
}
@@ -1178,7 +1168,7 @@ imap_set_message_user_flag (CamelFolder *folder, const char *uid, const char *na
}
void
-camel_imap_folder_changed (CamelFolder *folder, gint recent, GPtrArray *expunged, CamelException *ex)
+camel_imap_folder_changed (CamelFolder *folder, gint recent, GArray *expunged, CamelException *ex)
{
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
@@ -1186,7 +1176,7 @@ camel_imap_folder_changed (CamelFolder *folder, gint recent, GPtrArray *expunged
gint i, id;
for (i = 0; i < expunged->len; i++) {
- id = atoi (expunged->pdata[i]);
+ id = g_array_index (expunged, int, i);
d(fprintf (stderr, "Expunging message %d from the summary (i = %d)\n", id + i, i));
if (id <= imap_folder->summary->len) {
diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h
index 2589ab4d50..d4d960b2a8 100644
--- a/camel/providers/imap/camel-imap-folder.h
+++ b/camel/providers/imap/camel-imap-folder.h
@@ -64,7 +64,7 @@ typedef struct {
/* public methods */
CamelFolder *camel_imap_folder_new (CamelStore *parent, const char *folder_name);
-void camel_imap_folder_changed (CamelFolder *folder, gint recent, GPtrArray *expunged,
+void camel_imap_folder_changed (CamelFolder *folder, gint recent, GArray *expunged,
CamelException *ex);
/* Standard Camel function */
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index b6748f62cc..698b2ed732 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -180,7 +180,8 @@ imap_connect (CamelService *service, CamelException *ex)
{
CamelImapStore *store = CAMEL_IMAP_STORE (service);
CamelSession *session = camel_service_get_session (CAMEL_SERVICE (store));
- gchar *buf, *result, *errbuf = NULL;
+ gchar *result, *buf, *errbuf = NULL;
+ GPtrArray *response;
gboolean authenticated = FALSE;
gint status;
@@ -244,12 +245,14 @@ imap_connect (CamelService *service, CamelException *ex)
}
/* Now lets find out the IMAP capabilities */
- status = camel_imap_command_extended (store, NULL, &result, ex, "CAPABILITY");
-
- if (status != CAMEL_IMAP_OK) {
- /* Non-fatal error... (ex is set) */
- }
-
+ status = camel_imap_command_extended (store, NULL, &response, ex, "CAPABILITY");
+ if (status != CAMEL_IMAP_OK)
+ return FALSE;
+
+ result = camel_imap_response_extract (response, "CAPABILITY", ex);
+ if (!result)
+ return FALSE;
+
/* parse for capabilities here. */
if (e_strstrcase (result, "IMAP4REV1"))
store->server_level = IMAP_LEVEL_IMAP4REV1;
@@ -257,20 +260,22 @@ imap_connect (CamelService *service, CamelException *ex)
store->server_level = IMAP_LEVEL_IMAP4;
else
store->server_level = IMAP_LEVEL_UNKNOWN;
-
- if ((store->server_level >= IMAP_LEVEL_IMAP4REV1) || (e_strstrcase (result, "STATUS")))
+
+ if ((store->server_level >= IMAP_LEVEL_IMAP4REV1) ||
+ (e_strstrcase (result, "STATUS")))
store->has_status_capability = TRUE;
else
store->has_status_capability = FALSE;
-
g_free (result);
-
+
/* We now need to find out which directory separator this daemon uses */
- status = camel_imap_command_extended (store, NULL, &result, ex, "LIST \"\" \"\"");
-
- if (status != CAMEL_IMAP_OK) {
- /* Again, this is non-fatal */
- } else {
+ status = camel_imap_command_extended (store, NULL, &response, ex, "LIST \"\" \"\"");
+ if (status != CAMEL_IMAP_OK)
+ return FALSE;
+ result = camel_imap_response_extract (response, "LIST", ex);
+ if (!result)
+ return FALSE;
+ else {
char *flags, *sep, *folder;
if (imap_parse_list_response (result, "", &flags, &sep, &folder)) {
@@ -283,9 +288,8 @@ imap_connect (CamelService *service, CamelException *ex)
g_free (flags);
g_free (sep);
g_free (folder);
+ g_free (result);
}
-
- g_free (result);
camel_remote_store_refresh_folders (CAMEL_REMOTE_STORE (store), ex);
@@ -330,8 +334,8 @@ camel_imap_store_folder_path (CamelImapStore *store, const char *name)
static gboolean
imap_folder_exists (CamelImapStore *store, const char *folder_path, gboolean *selectable, CamelException *ex)
{
- gchar *result;
- char *flags, *sep, *dirname;
+ GPtrArray *response;
+ char *result, *flags, *sep, *dirname;
gint status;
if (!g_strcasecmp (folder_path, "INBOX")) {
@@ -345,12 +349,13 @@ imap_folder_exists (CamelImapStore *store, const char *folder_path, gboolean *se
*selectable = FALSE;
status = camel_imap_command_extended (CAMEL_IMAP_STORE (store), NULL,
- &result, ex, "LIST \"\" \"%s\"", folder_path);
- if (status != CAMEL_IMAP_OK) {
- g_free (result);
+ &response, ex, "LIST \"\" \"%s\"", folder_path);
+ if (status != CAMEL_IMAP_OK)
return FALSE;
- }
-
+ result = camel_imap_response_extract (response, "LIST", ex);
+ if (!result)
+ return FALSE;
+
if (imap_parse_list_response (result, "", &flags, &sep, &dirname)) {
if (selectable)
*selectable = !e_strstrcase (flags, "NoSelect");
@@ -358,9 +363,11 @@ imap_folder_exists (CamelImapStore *store, const char *folder_path, gboolean *se
g_free (flags);
g_free (sep);
g_free (dirname);
+ g_free (result);
return TRUE;
}
+ g_free (result);
g_free (flags);
g_free (sep);
@@ -630,12 +637,12 @@ camel_imap_command (CamelImapStore *store, CamelFolder *folder, CamelException *
**/
gint
-camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **ret, CamelException *ex, char *fmt, ...)
+camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, GPtrArray **ret, CamelException *ex, char *fmt, ...)
{
gint status = CAMEL_IMAP_OK;
- GPtrArray *data, *expunged;
+ GPtrArray *data;
+ GArray *expunged;
gchar *respbuf, *cmdid;
- guint32 len = 0;
gint recent = 0;
va_list ap;
gint i;
@@ -653,27 +660,24 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
}
va_end (ap);
- data = g_ptr_array_new ();
- expunged = g_ptr_array_new ();
+ expunged = g_array_new (FALSE, FALSE, sizeof (int));
+ if (ret)
+ data = g_ptr_array_new ();
/* read multi-line response */
while (1) {
if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &respbuf, ex) < 0) {
/* cleanup */
- for (i = 0; i < data->len; i++)
- g_free (data->pdata[i]);
- g_ptr_array_free (data, TRUE);
-
- for (i = 0; i < expunged->len; i++)
- g_free (expunged->pdata[i]);
- g_ptr_array_free (expunged, TRUE);
+ if (ret) {
+ for (i = 0; i < data->len; i++)
+ g_free (data->pdata[i]);
+ g_ptr_array_free (data, TRUE);
+ }
+ g_array_free (expunged, TRUE);
return CAMEL_IMAP_FAIL;
}
- g_ptr_array_add (data, respbuf);
- len += strlen (respbuf) + 1;
-
/* IMAPs multi-line response ends with the cmdid string at the beginning of the line */
if (!strncmp (respbuf, cmdid, strlen (cmdid))) {
status = camel_imap_status (cmdid, respbuf);
@@ -690,6 +694,8 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
rcnt = imap_next_word (respbuf);
if (*rcnt >= '0' && *rcnt <= '9' && !strncmp ("RECENT", imap_next_word (rcnt), 6))
recent = atoi (rcnt);
+ g_free (respbuf);
+ continue;
} else if (strstr (respbuf, "EXPUNGE")) {
char *id_str;
int id;
@@ -699,33 +705,22 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
id_str = imap_next_word (respbuf);
if (*id_str >= '0' && *id_str <= '9' && !strncmp ("EXPUNGE", imap_next_word (id_str), 7)) {
id = atoi (id_str);
- g_ptr_array_add (expunged, g_strdup_printf ("%d", id));
+ g_array_append_val (expunged, id);
}
+ g_free (respbuf);
+ continue;
}
}
+ if (ret)
+ g_ptr_array_add (data, respbuf);
+ else
+ g_free (respbuf);
}
- if (status == CAMEL_IMAP_OK && ret) {
- gchar *p;
-
- /* populate the return buffer with the server response */
- *ret = g_new (char, len + 1);
- p = *ret;
-
- for (i = 0; i < data->len; i++) {
- char *datap;
-
- datap = (char *) data->pdata[i];
- if (*datap == '.')
- datap++;
- len = strlen (datap);
- memcpy (p, datap, len);
- p += len;
- *p++ = '\n';
- }
-
- *p = '\0';
- } else if (status != CAMEL_IMAP_OK) {
+ if (status == CAMEL_IMAP_OK) {
+ if (ret)
+ *ret = data;
+ } else {
/* command failed */
if (respbuf) {
char *word;
@@ -741,10 +736,16 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
"IMAP command failed: Unknown");
}
- if (ret)
- *ret = NULL;
+ if (ret) {
+ for (i = 0; i < data->len; i++)
+ g_free (data->pdata[i]);
+ g_ptr_array_free (data, TRUE);
+ }
}
+ if (respbuf)
+ g_free (respbuf);
+
/* Update the summary */
if (folder && (recent > 0 || expunged->len > 0)) {
CamelException dex;
@@ -753,19 +754,81 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
camel_imap_folder_changed (folder, recent, expunged, &dex);
camel_exception_clear (&dex);
}
-
- for (i = 0; i < data->len; i++)
- g_free (data->pdata[i]);
- g_ptr_array_free (data, TRUE);
-
- for (i = 0; i < expunged->len; i++)
- g_free (expunged->pdata[i]);
- g_ptr_array_free (expunged, TRUE);
+ g_array_free (expunged, TRUE);
return status;
}
/**
+ * camel_imap_response_free:
+ * @response: the result data returned from camel_imap_command_extended
+ *
+ * Frees the data.
+ **/
+void
+camel_imap_response_free (GPtrArray *response)
+{
+ int i;
+
+ for (i = 0; i < response->len; i++)
+ g_free (response->pdata[i]);
+ g_ptr_array_free (response, TRUE);
+}
+
+/**
+ * camel_imap_response_extract:
+ * @response: the result data returned from camel_imap_command_extended
+ * @type: the response type to extract
+ * @ex: a CamelException
+ *
+ * This checks that @response contains a single untagged response of
+ * type @type and returns just that response data. If @response
+ * doesn't contain the right information, the function will set @ex and
+ * return %NULL. Either way, @response will be freed.
+ *
+ * Return value: the desired response string, which the caller must free.
+ **/
+char *
+camel_imap_response_extract (GPtrArray *response, const char *type,
+ CamelException *ex)
+{
+ int len = strlen (type), i;
+ char *resp;
+
+ for (i = 0; i < response->len; i++) {
+ resp = response->pdata[i];
+ if (strncmp (resp, "* ", 2) != 0) {
+ g_free (resp);
+ continue;
+ }
+
+ /* Skip inititial sequence number, if present */
+ strtoul (resp + 2, &resp, 10);
+ if (*resp == ' ')
+ resp++;
+
+ if (!g_strncasecmp (resp, type, len))
+ break;
+
+ g_free (resp);
+ }
+
+ if (i < response->len) {
+ resp = response->pdata[i];
+ for (i++; i < response->len; i++)
+ g_free (response->pdata[i]);
+ } else {
+ resp = NULL;
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ "IMAP server response did not contain "
+ "%s information", type);
+ }
+
+ g_ptr_array_free (response, TRUE);
+ return resp;
+}
+
+/**
* camel_imap_fetch_command: Send a FETCH request to an IMAP server and get
* a multi-line response.
* @store: the IMAP store
@@ -800,7 +863,8 @@ camel_imap_fetch_command (CamelImapStore *store, CamelFolder *folder, char **ret
* determine whether we are actually reading server responses.
*/
gint status = CAMEL_IMAP_OK;
- GPtrArray *data, *expunged;
+ GPtrArray *data;
+ GArray *expunged;
gboolean is_notification;
gchar *respbuf, *cmdid;
guint32 len = 0;
@@ -862,7 +926,7 @@ camel_imap_fetch_command (CamelImapStore *store, CamelFolder *folder, char **ret
return CAMEL_IMAP_FAIL;
}
- expunged = g_ptr_array_new ();
+ expunged = g_array_new (FALSE, FALSE, sizeof (int));
/* read multi-line response */
while (1) {
@@ -871,10 +935,7 @@ camel_imap_fetch_command (CamelImapStore *store, CamelFolder *folder, char **ret
for (i = 0; i < data->len; i++)
g_free (data->pdata[i]);
g_ptr_array_free (data, TRUE);
-
- for (i = 0; i < expunged->len; i++)
- g_free (expunged->pdata[i]);
- g_ptr_array_free (expunged, TRUE);
+ g_array_free (expunged, TRUE);
return CAMEL_IMAP_FAIL;
}
@@ -897,10 +958,8 @@ camel_imap_fetch_command (CamelImapStore *store, CamelFolder *folder, char **ret
recent = 0;
- for (i = 0; i < expunged->len; i++) {
- g_free (expunged->pdata[i]);
- g_ptr_array_remove_index (expunged, i);
- }
+ for (i = 0; i < expunged->len; i++)
+ g_array_remove_index (expunged, i);
}
/* Check for a RECENT in the untagged response */
@@ -922,7 +981,7 @@ camel_imap_fetch_command (CamelImapStore *store, CamelFolder *folder, char **ret
id_str = imap_next_word (respbuf);
if (*id_str >= '0' && *id_str <= '9' && !strncmp ("EXPUNGE", imap_next_word (id_str), 7)) {
id = atoi (id_str);
- g_ptr_array_add (expunged, g_strdup_printf ("%d", id));
+ g_array_append_val (expunged, id);
}
}
}
@@ -986,10 +1045,7 @@ camel_imap_fetch_command (CamelImapStore *store, CamelFolder *folder, char **ret
for (i = 0; i < data->len; i++)
g_free (data->pdata[i]);
g_ptr_array_free (data, TRUE);
-
- for (i = 0; i < expunged->len; i++)
- g_free (expunged->pdata[i]);
- g_ptr_array_free (expunged, TRUE);
+ g_array_free (expunged, TRUE);
return status;
}
diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h
index fe7b9f2f78..1d9a07ff96 100644
--- a/camel/providers/imap/camel-imap-store.h
+++ b/camel/providers/imap/camel-imap-store.h
@@ -84,7 +84,10 @@ gint camel_imap_command (CamelImapStore *store, CamelFolder *folder,
CamelException *ex, char *fmt, ...);
gint camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder,
- char **ret, CamelException *ex, char *fmt, ...);
+ GPtrArray **ret, CamelException *ex, char *fmt, ...);
+void camel_imap_response_free (GPtrArray *response);
+char *camel_imap_response_extract (GPtrArray *response, const char *type,
+ CamelException *ex);
gint camel_imap_fetch_command (CamelImapStore *store, CamelFolder *folder,
char **ret, CamelException *ex, char *fmt, ...);