From e9112cf496ef8dd380ac030624b1fbda2b0d8c3d Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Mon, 24 Jul 2000 01:37:43 +0000 Subject: Made it a little more forgiving. Also set current_folder to NULL as there 2000-07-23 Jeffrey Stedfast * 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. svn path=/trunk/; revision=4288 --- camel/providers/imap/camel-imap-folder.c | 44 +++++++------- camel/providers/imap/camel-imap-store.c | 98 ++++++++++++++++++++++---------- camel/providers/imap/camel-imap-store.h | 2 +- 3 files changed, 90 insertions(+), 54 deletions(-) (limited to 'camel/providers') 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, ...); -- cgit v1.2.3