aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog122
-rw-r--r--camel/providers/imap/camel-imap-folder.c44
-rw-r--r--camel/providers/imap/camel-imap-store.c98
-rw-r--r--camel/providers/imap/camel-imap-store.h2
4 files changed, 159 insertions, 107 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index bd79988c7d..d174136f6a 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,88 +1,104 @@
+2000-07-23 Jeffrey Stedfast <fejj@helixcode.com>
+
+ * providers/imap/camel-imap-store.c (imap_disconnect): Made it a
+ little more forgiving. Also set current_folder to NULL as there is
+ no selected folder after a disconnect.
+ (stream_is_alive): Detects whether or not a socket is "alive"
+ (camel_imap_command_extended): Use stream_is_alive() to aid in the
+ detection of a disconnected state.
+
2000-07-22 Jeffrey Stedfast <fejj@helixcode.com>
- * providers/imap/camel-imap-store.c (get_folder): Clear CamelExceptions when
- appropriate (eg when folder is marked as \NoSelect). Still needs some
- cleanup and perhaps Dan will have a better way of doing this as this seems
- like a messy way of handling this.
+ * providers/imap/camel-imap-store.c (get_folder): Clear
+ CamelExceptions when appropriate (eg when folder is marked as
+ \NoSelect). Still needs some cleanup and perhaps Dan will have a
+ better way of doing this as this seems like a messy way of
+ handling this.
- * providers/imap/camel-imap-folder.c (imap_get_uids): Took out some debug
- statements as they are no longer needed.
+ * providers/imap/camel-imap-folder.c (imap_get_uids): Took out
+ some debug statements as they are no longer needed.
2000-07-21 Jeffrey Stedfast <fejj@helixcode.com>
- * providers/imap/camel-imap-folder.c (imap_get_subfolder_names): Updated to
- not strip out subfolders that are marked as \NoSelect because this will be
- correctly handled in store->get_folder from now on.
+ * providers/imap/camel-imap-folder.c (imap_get_subfolder_names):
+ Updated to not strip out subfolders that are marked as \NoSelect
+ because this will be correctly handled in store->get_folder from
+ now on.
- * providers/imap/camel-imap-store.c (folder_is_selectable): New convenience
- function for use in get_folder().
- (parse_list_response): Now takes a char **flags argument which is needed by
- folder_is_selectable().
- (imap_connect): Updated to reflect changes to parse_list_response().
+ * providers/imap/camel-imap-store.c (folder_is_selectable): New
+ convenience function for use in get_folder().
+ (parse_list_response): Now takes a char **flags argument which is
+ needed by folder_is_selectable().
+ (imap_connect): Updated to reflect changes to
+ parse_list_response().
2000-07-21 Jeffrey Stedfast <fejj@helixcode.com>
- * providers/imap/camel-imap-stream.c (stream_read): Updated with some of the
- same fixes I've made to camel-imap-folder.c like recalculating message part
- lengths.
+ * providers/imap/camel-imap-stream.c (stream_read): Updated with
+ some of the same fixes I've made to camel-imap-folder.c like
+ recalculating message part lengths.
- * providers/imap/camel-imap-store.c (camel_imap_command_extended): Rewrote
- the code to check for "* %d RECENT". Still needs to be modified, but should
- no longer cause an infinite loop by detecting mis-detecting RECENT messages.
+ * providers/imap/camel-imap-store.c (camel_imap_command_extended):
+ Rewrote the code to check for "* %d RECENT". Still needs to be
+ modified, but should no longer cause an infinite loop by detecting
+ mis-detecting RECENT messages.
2000-07-20 Jeffrey Stedfast <fejj@helixcode.com>
- * providers/imap/camel-imap-folder.c (imap_get_summary):
- (imap_get_message_info): Oops. Fix UID parser to allow 0 and 9 to be in
- the range of valid UID chars.
+ * providers/imap/camel-imap-folder.c (imap_get_summary):
+ (imap_get_message_info): Oops. Fix UID parser to allow 0 and 9 to
+ be in the range of valid UID chars.
2000-07-19 Jeffrey Stedfast <fejj@helixcode.com>
- * providers/imap/camel-imap-folder.c: General cleanup working towards
- getting Actions->Expunge working correctly.
+ * providers/imap/camel-imap-folder.c: General cleanup working
+ towards getting Actions->Expunge working correctly.
- * providers/imap/camel-imap-store.c (cammel_imap_command_extended): Added
- code to look for "* %d RECENT" and to emit the folder_changed signal if
- there are any recent messages. Note: this is a hack and needs to be rewritten
+ * providers/imap/camel-imap-store.c
+ (cammel_imap_command_extended): Added code to look for "* %d
+ RECENT" and to emit the folder_changed signal if there are any
+ recent messages. Note: this is a hack and needs to be rewritten
badly.
2000-07-19 Jeffrey Stedfast <fejj@helixcode.com>
- * providers/imap/camel-imap-folder.c (imap_get_summary): If the folder's
- message count is not the same as the number of summaries, free the old
- summary and create a new summary.
+ * providers/imap/camel-imap-folder.c (imap_get_summary): If the
+ folder's message count is not the same as the number of summaries,
+ free the old summary and create a new summary.
2000-07-18 Jeffrey Stedfast <fejj@helixcode.com>
- * providers/imap/camel-imap-folder.c (camel_imap_folder_class_init): Added
- in imap_[g,s]et_message_user_flag() methods
+ * providers/imap/camel-imap-folder.c
+ (camel_imap_folder_class_init): Added in
+ imap_[g,s]et_message_user_flag() methods
(imap_get_message_info): Rewrote to use the more efficient way of
- downloading summary information and also added a UID comparison so that
- if the UID requested doesn't match the UID received, it returns NULL.
- FIXME: When the mailer gets NULL when it requested message info, it
- seems that it displays a row for that message and when you try and select
- the blank row, it segfaults.
+ downloading summary information and also added a UID comparison so
+ that if the UID requested doesn't match the UID received, it
+ returns NULL. FIXME: When the mailer gets NULL when it requested
+ message info, it seems that it displays a row for that message and
+ when you try and select the blank row, it segfaults.
- * providers/imap/camel-imap-store.c (get_folder): Oops, this should not be
- checking against "/", it should be checking against dir_sep.
+ * providers/imap/camel-imap-store.c (get_folder): Oops, this
+ should not be checking against "/", it should be checking against
+ dir_sep.
- * providers/imap/camel-imap-folder.c (imap_parse_subfolder_line): Updated
- to trim out the leading namespace.
- (imap_get_subfolder_names): Let the subfolder parser trim the namespace
- off the folder name.
+ * providers/imap/camel-imap-folder.c (imap_parse_subfolder_line):
+ Updated to trim out the leading namespace.
+ (imap_get_subfolder_names): Let the subfolder parser trim the
+ namespace off the folder name.
2000-07-17 Jeffrey Stedfast <fejj@helixcode.com>
- * providers/imap/camel-imap-store.c (imap_disconnect): Send a "LOGOUT"
- command.
+ * providers/imap/camel-imap-store.c (imap_disconnect): Send a
+ "LOGOUT" command.
- * providers/imap/camel-imap-folder.c (imap_get_message): Hacks to get
- IMAP code to work with CommunigatePro and MS Exchange (and any other
- servers that send back a UID at the end of each FETCH inside of the main
- body of the message part).
- (imap_sync): Un-#if 0 the code that sets the flags on the IMAP server
- for messages that have changed. Oops, don't mask with DELETED to find out
- if the message has been answered ;-)
+ * providers/imap/camel-imap-folder.c (imap_get_message): Hacks to
+ get IMAP code to work with CommunigatePro and MS Exchange (and any
+ other servers that send back a UID at the end of each FETCH inside
+ of the main body of the message part).
+ (imap_sync): Un-#if 0 the code that sets the flags on the IMAP
+ server for messages that have changed. Oops, don't mask with
+ DELETED to find out if the message has been answered ;-)
(imap_expunge): sync before expunging.
2000-07-16 Jeffrey Stedfast <fejj@helixcode.com>
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index 28cf4a848d..1093005376 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -786,14 +786,14 @@ imap_delete_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
static CamelMimeMessage *
imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
{
- CamelStream *msgstream;
+ CamelStream *msgstream = NULL;
/*CamelStreamFilter *f_stream;*/
/*CamelMimeFilter *filter;*/
- CamelMimeMessage *msg;
+ CamelMimeMessage *msg = NULL;
/*CamelMimePart *part;*/
- gchar *result, *header, *body, *mesg, *p, *q;
- int status, part_len;
-
+ gchar *result, *header = NULL, *body = NULL, *mesg = NULL, *p = NULL, *q = NULL;
+ int status = 0, part_len = 0;
+
status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder,
&result, "UID FETCH %s BODY.PEEK[HEADER]", uid);
@@ -808,20 +808,20 @@ imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
g_free (result);
return camel_mime_message_new ();
}
-
+
for (p = result; *p && *p != '{' && *p != '\n'; p++);
if (*p != '{') {
g_free (result);
return camel_mime_message_new ();
}
-
- part_len = atoi (p + 1);
+
+ part_len = atoi (p + 1);
for ( ; *p && *p != '\n'; p++);
if (*p != '\n') {
g_free (result);
return camel_mime_message_new ();
}
-
+
/* calculate the new part-length */
for (q = p; *q && (q - p) <= part_len; q++) {
if (*q == '\n')
@@ -829,15 +829,15 @@ imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
}
/* FIXME: This is a hack for IMAP daemons that send us a UID at the end of each FETCH */
for (q--, part_len--; q > p && *(q-1) != '\n'; q--, part_len--);
-
- header = g_strndup (p, part_len + 1);
+ header = g_strndup (p, part_len + 1);
+
g_free (result);
d(fprintf (stderr, "*** We got the header ***\n"));
-
+
status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder,
&result, "UID FETCH %s BODY[TEXT]", uid);
-
+
if (!result || status != CAMEL_IMAP_OK) {
CamelService *service = CAMEL_SERVICE (folder->parent_store);
@@ -850,14 +850,14 @@ imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
g_free (header);
return camel_mime_message_new ();
}
-
+
for (p = result; *p && *p != '{' && *p != '\n'; p++);
if (*p != '{') {
g_free (result);
g_free (header);
return camel_mime_message_new ();
}
-
+
part_len = atoi (p + 1);
for ( ; *p && *p != '\n'; p++);
if (*p != '\n') {
@@ -865,7 +865,7 @@ imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
g_free (header);
return camel_mime_message_new ();
}
-
+
/* calculate the new part-length */
for (q = p; *q && (q - p) <= part_len; q++) {
if (*q == '\n')
@@ -873,19 +873,19 @@ imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
}
/* FIXME: This is a hack for IMAP daemons that send us a UID at the end of each FETCH */
for ( ; q > p && *(q-1) != '\n'; q--, part_len--);
-
+
body = g_strndup (p, part_len + 1);
-
+
g_free (result);
d(fprintf (stderr, "*** We got the body ***\n"));
-
+
mesg = g_strdup_printf ("%s\n%s", header, body);
g_free (header);
g_free (body);
d(fprintf (stderr, "*** We got the mesg ***\n"));
-
+
d(fprintf (stderr, "Message:\n%s\n", mesg));
-
+
msgstream = camel_stream_mem_new_with_buffer (mesg, strlen (mesg) + 1);
#if 0
f_stream = camel_stream_filter_new_with_stream (msgstream);
@@ -902,7 +902,7 @@ imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
#endif
gtk_object_unref (GTK_OBJECT (msgstream));
/*gtk_object_unref (GTK_OBJECT (f_stream));*/
-
+
d(fprintf (stderr, "*** We're returning... ***\n"));
return msg;
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index cf2de4b304..777dc26e25 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -436,13 +436,21 @@ imap_disconnect (CamelService *service, CamelException *ex)
if (!service_class->disconnect (service, ex))
return FALSE;
- gtk_object_unref (GTK_OBJECT (store->ostream));
- gtk_object_unref (GTK_OBJECT (store->istream));
- store->ostream = NULL;
- store->istream = NULL;
+ if (store->istream) {
+ gtk_object_unref (GTK_OBJECT (store->istream));
+ store->istream = NULL;
+ }
+
+ if (store->ostream) {
+ gtk_object_unref (GTK_OBJECT (store->ostream));
+ store->ostream = NULL;
+ }
+
g_free (store->dir_sep);
store->dir_sep = NULL;
+ store->current_folder = NULL;
+
return TRUE;
}
@@ -609,6 +617,23 @@ get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex)
return g_strdup (folder_name);
}
+static gboolean
+stream_is_alive (CamelStream *istream)
+{
+ CamelStreamFs *fs_stream;
+ char buf;
+
+ g_return_val_if_fail (istream != NULL, FALSE);
+
+ fs_stream = CAMEL_STREAM_FS (CAMEL_STREAM_BUFFER (istream)->stream);
+ g_return_val_if_fail (fs_stream->fd != -1, FALSE);
+
+ if (read (fs_stream->fd, (void *) &buf, 0) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
static int
camel_imap_status (char *cmdid, char *respbuf)
{
@@ -693,7 +718,6 @@ camel_imap_command (CamelImapStore *store, CamelFolder *folder, char **ret, char
va_end (ap);
d(fprintf (stderr, "sending : %s %s\r\n", cmdid, cmdbuf));
- fflush (stderr);
if (camel_stream_printf (store->ostream, "%s %s\r\n", cmdid, cmdbuf) == -1) {
g_free (cmdbuf);
@@ -763,32 +787,34 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
{
CamelService *service = CAMEL_SERVICE (store);
CamelURL *url = service->url;
- CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream);
gint len = 0, recent = 0, status = CAMEL_IMAP_OK;
gchar *cmdid, *cmdbuf, *respbuf;
GPtrArray *data;
va_list app;
-
+
/* First make sure we're connected... */
- if (!service->connected) {
+ if (!service->connected || !stream_is_alive (store->istream)) {
CamelException *ex;
-
+
ex = camel_exception_new ();
if (!imap_disconnect (service, ex) || !imap_connect (service, ex)) {
camel_exception_free (ex);
+
+ *ret = NULL;
+
return CAMEL_IMAP_FAIL;
}
service->connected = TRUE;
-
+
camel_exception_free (ex);
}
-
+
if (folder && store->current_folder != folder && strncmp (fmt, "CREATE", 6)) {
/* We need to select the correct mailbox first */
char *r, *folder_path, *dir_sep;
int s;
-
+
dir_sep = store->dir_sep;
if (url && url->path && *(url->path + 1) && strcmp (folder->full_name, "INBOX"))
@@ -804,9 +830,9 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
return s;
}
-
+
g_free (r);
-
+
store->current_folder = folder;
}
@@ -815,45 +841,55 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
va_start (app, fmt);
cmdbuf = g_strdup_vprintf (fmt, app);
va_end (app);
-
+
d(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);
-
+
data = g_ptr_array_new ();
-
+
while (1) {
+ CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream);
char *ptr;
respbuf = camel_stream_buffer_read_line (stream);
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 (!respbuf && strcmp (fmt, "LOGOUT")) {
+ /* we need to force a disconnect here? */
+ CamelException *ex;
+
+ ex = camel_exception_new ();
+ imap_disconnect (service, ex);
+ camel_exception_free (ex);
+ }
break;
}
-
+
d(fprintf (stderr, "received: %s\n", respbuf));
-
+
g_ptr_array_add (data, respbuf);
len += strlen (respbuf) + 1;
-
+
/* If recent was somehow set and this response doesn't begin with a '*'
then recent must have been misdetected */
if (recent && *respbuf != '*')
recent = 0;
-
+
if (*respbuf == '*' && (ptr = strstr (respbuf, "RECENT"))) {
char *rcnt, *ercnt;
- d(fprintf (stderr, "*** We may have found a 'RECENT' flag: %s", respbuf));
+ d(fprintf (stderr, "*** We may have found a 'RECENT' flag: %s\n", respbuf));
/* Make sure it's in the form: "* %d RECENT" */
rcnt = respbuf + 2;
if (*rcnt > '0' || *rcnt < '9') {
@@ -863,7 +899,7 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
}
}
}
-
+
if (respbuf) {
g_ptr_array_add (data, respbuf);
len += strlen (respbuf) + 1;
@@ -873,16 +909,16 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
status = CAMEL_IMAP_FAIL;
}
g_free (cmdid);
-
+
if (status == CAMEL_IMAP_OK) {
char *p;
int i;
*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);
@@ -897,9 +933,9 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
else
*ret = NULL;
}
-
+
g_ptr_array_free (data, TRUE);
-
+
if (folder && recent > 0)
gtk_signal_emit_by_name (GTK_OBJECT (folder), "folder_changed", 0);
diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h
index b38ed769c9..aeabdaa96d 100644
--- a/camel/providers/imap/camel-imap-store.h
+++ b/camel/providers/imap/camel-imap-store.h
@@ -68,7 +68,7 @@ void camel_imap_store_close (CamelImapStore *store, gboolean expunge, CamelExcep
/* support functions */
-enum { CAMEL_IMAP_OK, CAMEL_IMAP_NO, CAMEL_IMAP_BAD, CAMEL_IMAP_FAIL };
+enum { CAMEL_IMAP_OK = 0, CAMEL_IMAP_NO, CAMEL_IMAP_BAD, CAMEL_IMAP_FAIL };
gint camel_imap_command (CamelImapStore *store, CamelFolder *folder, char **ret, char *fmt, ...);
gint camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **ret, char *fmt, ...);