aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog33
-rw-r--r--camel/providers/imap/camel-imap-folder.c220
-rw-r--r--camel/providers/imap/camel-imap-folder.h2
-rw-r--r--camel/providers/imap/camel-imap-store.c40
-rw-r--r--camel/providers/imap/camel-imap-store.h2
5 files changed, 194 insertions, 103 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 9e87b1ece4..fffa73f980 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,36 @@
+2000-07-24 Jeffrey Stedfast <fejj@helixcode.com>
+
+ * providers/imap/camel-imap-folder.c (camel_imap_folder_new):
+ Initialize the summary and subfolder listing.
+ (imap_summary_free): Now takes a GPtrArray arg rather than a
+ CamelImapFolder as it increases it's usefullness for free()'ing
+ temporary summaries.
+ (imap_get_message_count_internal): A new convenience function for
+ getting the actual message count on a server to be used by
+ imap_get_summary_internal)
+ (imap_get_message_count): Since the Camel API is on the move again,
+ the future version of this function will not be able to make a
+ call to the store, it must only access previously fetched data (thus
+ the creation of the _internal function)
+ (imap_get_subfolder_names_internal): Again, because the future version
+ of imap_get_subfolder_names will not take an exception, we must rename
+ this function which will be called by camel_imap_folder_new()
+ (imap_get_subfolder_names): We now return the previously collected
+ subfolder listing that the _internal function fetched previously
+ (imap_get_summary_internal): Again, same idea as the previous _internal
+ functions...
+ (imap_get_summary): Again... now returns a previously aquired summary
+
+ * providers/imap/camel-imap-store.c (imap_noop): This will hopefully
+ prevent the imap store from disconnecting.
+ (imap_connect): Modified to add a gtk timeout event that will call
+ imap_noop() every 10 minutes (we may want to change this time value)
+ (imap_disconnect): Modified to remove the NOOP timeout event from the
+ store.
+ (camel_imap_command_extended): Commented out the code that would try
+ and detect if the store was disconnected and then reconnect if it was
+ needed.
+
2000-07-24 Dan Winship <danw@helixcode.com>
* camel-folder.[ch]: Remove camel_folder_get_message_uid, which
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index 1093005376..cd5c8484c2 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -63,26 +63,31 @@ static void imap_init (CamelFolder *folder, CamelStore *parent_store,
gchar *separator, gboolean path_begns_with_sep,
CamelException *ex);
+static void imap_finalize (GtkObject *object);
+
static void imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
static void imap_expunge (CamelFolder *folder, CamelException *ex);
+
+static gint imap_get_message_count_internal (CamelFolder *folder, CamelException *ex);
static gint imap_get_message_count (CamelFolder *folder, CamelException *ex);
static gint imap_get_unread_message_count (CamelFolder *folder, CamelException *ex);
+
+static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex);
static void imap_append_message (CamelFolder *folder, CamelMimeMessage *message, guint32 flags, CamelException *ex);
static void imap_copy_message_to (CamelFolder *source, const char *uid, CamelFolder *destination, CamelException *ex);
static void imap_move_message_to (CamelFolder *source, const char *uid, CamelFolder *destination, CamelException *ex);
-static GPtrArray *imap_get_uids (CamelFolder *folder, CamelException *ex);
+static void imap_delete_message (CamelFolder *folder, const gchar *uid, CamelException *ex);
+
static gboolean imap_parse_subfolder_line (gchar *buf, gchar *namespace, gchar **flags, gchar **sep, gchar **folder);
+static GPtrArray *imap_get_subfolder_names_internal (CamelFolder *folder, CamelException *ex);
static GPtrArray *imap_get_subfolder_names (CamelFolder *folder, CamelException *ex);
+
+static GPtrArray *imap_get_uids (CamelFolder *folder, CamelException *ex);
+static GPtrArray *imap_get_summary_internal (CamelFolder *folder, CamelException *ex);
static GPtrArray *imap_get_summary (CamelFolder *folder, CamelException *ex);
static const CamelMessageInfo *imap_get_message_info (CamelFolder *folder, const char *uid);
-static void imap_set_message_user_flag (CamelFolder *folder, const char *uid, const char *name,
- gboolean value, CamelException *ex);
-static gboolean imap_get_message_user_flag (CamelFolder *folder, const char *uid, const char *name, CamelException *ex);
-static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex);
-static void imap_delete_message (CamelFolder *folder, const gchar *uid, CamelException *ex);
-static GPtrArray *imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex);
-static void imap_finalize (GtkObject *object);
+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);
@@ -94,6 +99,7 @@ static gboolean imap_get_message_user_flag (CamelFolder *folder, const char *uid
static void imap_set_message_user_flag (CamelFolder *folder, const char *uid, const char *name,
gboolean value, CamelException *ex);
+
static void
camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class)
{
@@ -146,10 +152,10 @@ camel_imap_folder_init (gpointer object, gpointer klass)
folder->can_hold_messages = TRUE;
folder->can_hold_folders = TRUE;
folder->has_summary_capability = TRUE;
- folder->has_search_capability = FALSE; /* default - we have to query IMAP to know for sure */
+ folder->has_search_capability = FALSE; /* this gets set in imap_init */
imap_folder->summary = NULL;
- imap_folder->count = -1;
+ imap_folder->lsub = NULL;
}
GtkType
@@ -186,19 +192,22 @@ camel_imap_folder_new (CamelStore *parent, char *folder_name, CamelException *ex
CF_CLASS (folder)->init (folder, parent, NULL, folder_name, dir_sep, FALSE, ex);
+ imap_get_subfolder_names_internal (folder, ex);
+ imap_get_summary_internal (folder, ex);
+
return folder;
}
static void
-imap_summary_free (CamelImapFolder *imap_folder)
+imap_summary_free (GPtrArray *summary)
{
CamelMessageInfo *info;
gint i, max;
-
- if (imap_folder->summary != NULL) {
- max = imap_folder->summary->len;
+
+ if (summary) {
+ max = summary->len;
for (i = 0; i < max; i++) {
- info = g_ptr_array_index (imap_folder->summary, i);
+ info = g_ptr_array_index (summary, i);
g_free (info->subject);
g_free (info->from);
g_free (info->to);
@@ -210,20 +219,30 @@ imap_summary_free (CamelImapFolder *imap_folder)
info = NULL;
}
- g_ptr_array_free (imap_folder->summary, TRUE);
- imap_folder->summary = NULL;
+ g_ptr_array_free (summary, TRUE);
+ summary = NULL;
}
-
- imap_folder->count = -1;
}
static void
imap_finalize (GtkObject *object)
{
- /* TODO: do we need to do more here? */
+ /* TODO: do we need to do more cleanup here? */
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object);
+ gint max, i;
+
+ imap_summary_free (imap_folder->summary);
- imap_summary_free (imap_folder);
+ if (imap_folder->lsub) {
+ max = imap_folder->lsub->len;
+
+ for (i = 0; i < max; i++) {
+ g_free (imap_folder->lsub->pdata[i]);
+ imap_folder->lsub->pdata[i] = NULL;
+ }
+
+ g_ptr_array_free (imap_folder->lsub, TRUE);
+ }
}
static void
@@ -372,25 +391,20 @@ imap_expunge (CamelFolder *folder, CamelException *ex)
g_free (result);
- imap_summary_free (imap_folder);
+ imap_summary_free (imap_folder->summary);
gtk_signal_emit_by_name (GTK_OBJECT (folder), "folder_changed", 0);
}
static gint
-imap_get_message_count (CamelFolder *folder, CamelException *ex)
+imap_get_message_count_internal (CamelFolder *folder, CamelException *ex)
{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
CamelStore *store = CAMEL_STORE (folder->parent_store);
CamelURL *url = CAMEL_SERVICE (store)->url;
gchar *result, *msg_count, *folder_path, *dir_sep;
- gint status;
-
- g_return_val_if_fail (folder != NULL, -1);
+ gint status, count = 0;
- /* If we already have a count, return */
- if (imap_folder->count != -1)
- return imap_folder->count;
+ g_return_val_if_fail (folder != NULL, 0);
dir_sep = CAMEL_IMAP_STORE (folder->parent_store)->dir_sep;
@@ -411,7 +425,7 @@ imap_get_message_count (CamelFolder *folder, CamelException *ex)
"Unknown error");
g_free (result);
g_free (folder_path);
- return -1;
+ return 0;
}
g_free (folder_path);
@@ -423,12 +437,23 @@ imap_get_message_count (CamelFolder *folder, CamelException *ex)
for ( ; *msg_count == ' '; msg_count++);
/* we should now be pointing to the message count */
- imap_folder->count = atoi (msg_count);
+ count = atoi (msg_count);
}
}
g_free (result);
- return imap_folder->count;
+ return count;
+}
+
+static gint
+imap_get_message_count (CamelFolder *folder, CamelException *ex)
+{
+ CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+
+ if (imap_folder->summary)
+ return imap_folder->summary->len;
+ else
+ return 0;
}
static gint
@@ -439,11 +464,11 @@ imap_get_unread_message_count (CamelFolder *folder, CamelException *ex)
GPtrArray *infolist;
gint i, count = 0;
- g_return_val_if_fail (folder != NULL, -1);
+ g_return_val_if_fail (folder != NULL, 0);
/* If we don't have a message count, return */
- if (imap_folder->count == -1)
- return -1;
+ if (!imap_folder->summary)
+ return 0;
infolist = imap_get_summary (folder, ex);
@@ -616,18 +641,18 @@ imap_get_uids (CamelFolder *folder, CamelException *ex)
CamelMessageInfo *info;
GPtrArray *array, *infolist;
gint i, count;
-
+
infolist = imap_get_summary (folder, ex);
count = infolist->len;
array = g_ptr_array_new ();
g_ptr_array_set_size (array, count);
-
+
for (i = 0; i < count; i++) {
info = (CamelMessageInfo *) g_ptr_array_index (infolist, i);
array->pdata[i] = g_strdup (info->uid);
}
-
+
return array;
}
@@ -635,14 +660,14 @@ static gboolean
imap_parse_subfolder_line (gchar *buf, gchar *namespace, gchar **flags, gchar **sep, gchar **folder)
{
gchar *ptr, *eptr, *f;
-
+
*flags = NULL;
*sep = NULL;
*folder = NULL;
-
+
if (g_strncasecmp (buf, "* LIST", 6))
return FALSE;
-
+
ptr = strstr (buf + 6, "(");
if (!ptr)
return FALSE;
@@ -653,22 +678,22 @@ imap_parse_subfolder_line (gchar *buf, gchar *namespace, gchar **flags, gchar **
return FALSE;
*flags = g_strndup (ptr, (gint)(eptr - ptr));
-
+
ptr = strstr (eptr, "\"");
if (!ptr)
return FALSE;
-
+
ptr++;
eptr = strstr (ptr, "\"");
if (!eptr)
return FALSE;
-
+
*sep = g_strndup (ptr, (gint)(eptr - ptr));
-
+
ptr = eptr + 1;
*folder = g_strdup (ptr);
g_strstrip (*folder);
-
+
/* chop out the folder prefix */
if (*namespace && !strncmp (*folder, namespace, strlen (namespace))) {
f = *folder + strlen (namespace) + strlen (*sep);
@@ -676,12 +701,12 @@ imap_parse_subfolder_line (gchar *buf, gchar *namespace, gchar **flags, gchar **
}
string_unquote (*folder); /* unquote the mailbox if it's quoted */
-
+
return TRUE;
}
static GPtrArray *
-imap_get_subfolder_names (CamelFolder *folder, CamelException *ex)
+imap_get_subfolder_names_internal (CamelFolder *folder, CamelException *ex)
{
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
CamelStore *store = CAMEL_STORE (folder->parent_store);
@@ -689,14 +714,11 @@ imap_get_subfolder_names (CamelFolder *folder, CamelException *ex)
GPtrArray *listing;
gint status;
gchar *result, *namespace, *dir_sep;
-
+
g_return_val_if_fail (folder != NULL, g_ptr_array_new ());
- if (imap_folder->count != -1)
- return g_ptr_array_new ();
-
dir_sep = CAMEL_IMAP_STORE (folder->parent_store)->dir_sep;
-
+
if (url && url->path) {
if (!strcmp (folder->full_name, "INBOX"))
namespace = g_strdup (url->path + 1);
@@ -719,7 +741,9 @@ imap_get_subfolder_names (CamelFolder *folder, CamelException *ex)
"Unknown error");
g_free (result);
g_free (namespace);
- return g_ptr_array_new ();
+
+ imap_folder->lsub = g_ptr_array_new ();
+ return imap_folder->lsub;
}
/* parse out the subfolders */
@@ -742,18 +766,18 @@ imap_get_subfolder_names (CamelFolder *folder, CamelException *ex)
g_free (flags);
g_free (sep);
g_free (folder);
-
+
if (*ptr == '\n')
ptr++;
continue;
}
g_free (flags);
-
+
d(fprintf (stderr, "adding folder: %s\n", folder));
g_ptr_array_add (listing, folder);
-
+
g_free (sep);
if (*ptr == '\n')
@@ -763,14 +787,24 @@ imap_get_subfolder_names (CamelFolder *folder, CamelException *ex)
g_free (result);
g_free (namespace);
+ imap_folder->lsub = listing;
+
return listing;
}
+static GPtrArray *
+imap_get_subfolder_names (CamelFolder *folder, CamelException *ex)
+{
+ CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+
+ return imap_folder->lsub;
+}
+
static void
imap_delete_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
{
CamelMessageInfo *info;
-
+
if (!(info = (CamelMessageInfo *)imap_get_message_info (folder, uid))) {
CamelService *service = CAMEL_SERVICE (folder->parent_store);
@@ -779,7 +813,7 @@ imap_delete_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
uid, service->url->host, "Unknown error");
return;
}
-
+
imap_set_message_flags (folder, uid, CAMEL_MESSAGE_DELETED, ~(info->flags), ex);
}
@@ -984,54 +1018,28 @@ get_header_field (gchar *header, gchar *field)
static char *header_fields[] = { "subject", "from", "to", "cc", "date",
"received", "message-id", "references",
"in-reply-to", "" };
-/*
- a2 FETCH 1:3 (UID FLAGS BODY[HEADER.FIELDS (FROM SUBJECT)])
- * 1 FETCH (UID 1469 FLAGS (\Seen) BODY[HEADER.FIELDS ("FROM" "SUBJECT")] {87}
- From: Joakim Ziegler <joakim@dna.helixcode.com>
- Subject: Helix CVS: webroot joakim
-
- )
- * 2 FETCH (UID 1470 FLAGS (\Seen) BODY[HEADER.FIELDS ("FROM" "SUBJECT")] {87}
- From: Joakim Ziegler <joakim@dna.helixcode.com>
- Subject: Helix CVS: webroot joakim
-
- )
- * 3 FETCH (UID 1471 FLAGS (\Seen) BODY[HEADER.FIELDS ("FROM" "SUBJECT")] {87}
- From: Joakim Ziegler <joakim@helixcode.com>
- Subject: Re: [HC All-hands] helix news
-
- )
- a2 OK FETCH completed
- */
static GPtrArray *
-imap_get_summary (CamelFolder *folder, CamelException *ex)
+imap_get_summary_internal (CamelFolder *folder, CamelException *ex)
{
+ /* This ALWAYS updates the summary except on fail */
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
GPtrArray *summary = NULL, *headers = NULL;
gint num, i, j, status = 0;
char *result, *q, *node;
const char *received;
struct _header_raw *h, *tail = NULL;
-
- /*if (imap_folder->summary)
- return imap_folder->summary;*/
- num = imap_get_message_count (folder, ex);
-
- if (imap_folder->summary && imap_folder->summary->len == num)
- return imap_folder->summary;
-
- /* clean up any previous summary data */
- imap_summary_free (imap_folder);
-
- summary = g_ptr_array_new ();
+ num = imap_get_message_count_internal (folder, ex);
switch (num) {
case 0:
- imap_folder->summary = summary;
+ /* clean up any previous summary data */
+ imap_summary_free (imap_folder->summary);
- return summary;
+ imap_folder->summary = g_ptr_array_new ();
+
+ return imap_folder->summary;
case 1:
status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder,
&result, "FETCH 1 (UID FLAGS BODY[HEADER.FIELDS "
@@ -1055,11 +1063,14 @@ imap_get_summary (CamelFolder *folder, CamelException *ex)
"Unknown error");
g_free (result);
- imap_folder->summary = summary;
+ g_ptr_array_free (summary, TRUE);
- return summary;
+ return imap_folder->summary;
}
+ /* initialize our new summary-to-be */
+ summary = g_ptr_array_new ();
+
/* create our array of headers from the server response */
headers = g_ptr_array_new ();
node = result;
@@ -1108,7 +1119,7 @@ imap_get_summary (CamelFolder *folder, CamelException *ex)
}
for (flags += 6; *flags && *flags != '('; flags++); /* advance to <flags> */
- for (q = flags; *q && *q != ')' /*&& *q != ' '*/; q++); /* find the end of <flags> */
+ for (q = flags; *q && *q != ')'; q++); /* find the end of <flags> */
flags = g_strndup (flags, (gint)(q - flags + 1));
d(fprintf (stderr, "*** info->flags = %s\n", flags));
@@ -1191,9 +1202,20 @@ imap_get_summary (CamelFolder *folder, CamelException *ex)
g_ptr_array_free (headers, TRUE);
+ /* clean up any previous summary data */
+ imap_summary_free (imap_folder->summary);
+
imap_folder->summary = summary;
- return summary;
+ return imap_folder->summary;
+}
+
+static GPtrArray *
+imap_get_summary (CamelFolder *folder, CamelException *ex)
+{
+ CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+
+ return imap_folder->summary;
}
/* get a single message info, by uid */
@@ -1226,7 +1248,7 @@ imap_get_message_info (CamelFolder *folder, const char *uid)
ex = camel_exception_new ();
- if (!imap_get_summary (folder, ex)) {
+ if (!imap_get_summary_internal (folder, ex)) {
camel_exception_free (ex);
return NULL;
}
diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h
index 17f6d505d2..ba2d1daa70 100644
--- a/camel/providers/imap/camel-imap-folder.h
+++ b/camel/providers/imap/camel-imap-folder.h
@@ -47,7 +47,7 @@ typedef struct {
CamelFolderSearch *search; /* used to run searches */
GPtrArray *summary;
- gint count;
+ GPtrArray *lsub;
} CamelImapFolder;
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index 777dc26e25..2554588461 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -65,6 +65,8 @@ static char *get_name (CamelService *service, gboolean brief);
static CamelFolder *get_folder (CamelStore *store, const char *folder_name, gboolean create,
CamelException *ex);
static char *get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex);
+static gboolean imap_noop (gpointer data);
+static gboolean stream_is_alive (CamelStream *istream);
static int camel_imap_status (char *cmdid, char *respbuf);
static void
@@ -105,6 +107,8 @@ camel_imap_store_init (gpointer object, gpointer klass)
store->folders = g_hash_table_new (g_str_hash, g_str_equal);
CAMEL_IMAP_STORE (store)->dir_sep = NULL;
+ CAMEL_IMAP_STORE (store)->current_folder = NULL;
+ CAMEL_IMAP_STORE (store)->timeout_id = 0;
}
GtkType
@@ -270,7 +274,12 @@ imap_connect (CamelService *service, CamelException *ex)
gchar *buf, *msg, *result, *errbuf = NULL;
gboolean authenticated = FALSE;
-
+ /* FIXME: do we really need this here? */
+ if (store->timeout_id) {
+ gtk_timeout_remove (store->timeout_id);
+ store->timeout_id = 0;
+ }
+
h = camel_service_gethost (service, ex);
if (!h)
return FALSE;
@@ -412,6 +421,9 @@ imap_connect (CamelService *service, CamelException *ex)
}
}
}
+
+ /* Lets add a timeout so that we can hopefully prevent getting disconnected */
+ store->timeout_id = gtk_timeout_add (60000, imap_noop, store);
return TRUE;
}
@@ -450,6 +462,11 @@ imap_disconnect (CamelService *service, CamelException *ex)
store->dir_sep = NULL;
store->current_folder = NULL;
+
+ if (store->timeout_id) {
+ gtk_timeout_remove (store->timeout_id);
+ store->timeout_id = 0;
+ }
return TRUE;
}
@@ -618,6 +635,20 @@ get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex)
}
static gboolean
+imap_noop (gpointer data)
+{
+ CamelImapStore *store = CAMEL_IMAP_STORE (data);
+ char *result;
+ int status;
+
+ status = camel_imap_command_extended (store, store->current_folder, &result, "NOOP");
+
+ g_free (result);
+
+ return TRUE;
+}
+
+static gboolean
stream_is_alive (CamelStream *istream)
{
CamelStreamFs *fs_stream;
@@ -791,7 +822,8 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
gchar *cmdid, *cmdbuf, *respbuf;
GPtrArray *data;
va_list app;
-
+
+#if 0
/* First make sure we're connected... */
if (!service->connected || !stream_is_alive (store->istream)) {
CamelException *ex;
@@ -809,6 +841,7 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
camel_exception_free (ex);
}
+#endif
if (folder && store->current_folder != folder && strncmp (fmt, "CREATE", 6)) {
/* We need to select the correct mailbox first */
@@ -864,7 +897,7 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
if (!respbuf || !strncmp (respbuf, cmdid, strlen (cmdid))) {
/* IMAP's last response starts with our command id */
d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
-
+#if 0
if (!respbuf && strcmp (fmt, "LOGOUT")) {
/* we need to force a disconnect here? */
CamelException *ex;
@@ -873,6 +906,7 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
imap_disconnect (service, ex);
camel_exception_free (ex);
}
+#endif
break;
}
diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h
index aeabdaa96d..e1bdc86a9c 100644
--- a/camel/providers/imap/camel-imap-store.h
+++ b/camel/providers/imap/camel-imap-store.h
@@ -52,6 +52,8 @@ typedef struct {
gboolean has_search_capability;
gchar *dir_sep;
+
+ guint timeout_id;
} CamelImapStore;