aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog28
-rw-r--r--camel/camel-folder-summary.c4
-rw-r--r--camel/camel-remote-store.c6
-rw-r--r--camel/camel-session.c42
-rw-r--r--camel/camel-stream-fs.c8
-rw-r--r--camel/providers/imap/camel-imap-command.c9
-rw-r--r--camel/providers/imap/camel-imap-private.h6
-rw-r--r--camel/providers/imap/camel-imap-store.c28
8 files changed, 114 insertions, 17 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 85e4ddef27..036bb75729 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,31 @@
+2001-01-16 Not Zed <NotZed@Ximian.com>
+
+ * camel-folder-summary.c (camel_folder_summary_decode_string):
+ Chganged len back to be unsigned. And do a simple range check on
+ the string value to try and detect corrupted summary files.
+
+ * providers/imap/camel-imap-command.c (imap_read_untagged): Handle
+ cancelled stream reads with an appropriate exception.
+
+ * providers/imap/camel-imap-private.h: Fix the include-once
+ macro. Doh, confliced with camel-private.h.
+
+ * providers/imap/camel-imap-store.c (imap_store_refresh_folders):
+ A copy of camel_remote_store_refresh_folders. We avoid locking
+ each folder when we call it though. This should be removed when i
+ can work out how to remove the folder lock from this function
+ easily.
+
+ * camel-stream-fs.c (stream_write): Fix n' argument of select.
+ (stream_read): Likewise.
+
+ * camel-remote-store.c (socket_connect): Bump the connect timeout
+ upto 4 minutes.
+ (socket_connect): Oops, fix the 'n' argument of select.
+
+ * camel-session.c (camel_cancel_cancel): If we are given no
+ cancellation node, then do it for all active ones.
+
2001-01-15 Jeffrey Stedfast <fejj@ximian.com>
* camel-stream-fs.c (stream_close): If the close() is successful,
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 89b18e5141..8cea0a4666 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -1375,7 +1375,7 @@ camel_folder_summary_encode_string(FILE *out, const char *str)
int
camel_folder_summary_decode_string(FILE *in, char **str)
{
- gint32 len;
+ guint32 len;
register char *ret;
io(printf("Decode string ...\n", str));
@@ -1386,7 +1386,7 @@ camel_folder_summary_decode_string(FILE *in, char **str)
}
len--;
- if (len < 0) {
+ if (len > 65536) {
*str = NULL;
io(printf("String = '%s'\n", *str));
return -1;
diff --git a/camel/camel-remote-store.c b/camel/camel-remote-store.c
index 9e7a60e378..993d9b5778 100644
--- a/camel/camel-remote-store.c
+++ b/camel/camel-remote-store.c
@@ -241,6 +241,7 @@ static int socket_connect(struct hostent *h, int port)
} else {
fd_set rdset, wrset;
long flags;
+ int fdmax;
fcntl(fd, F_GETFL, &flags);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
@@ -258,9 +259,10 @@ static int socket_connect(struct hostent *h, int port)
FD_ZERO(&wrset);
FD_SET(fd, &wrset);
FD_SET(cancel_fd, &rdset);
+ fdmax = MAX(fd, cancel_fd)+1;
tv.tv_usec = 0;
- tv.tv_sec = 30;
- if (select((fd+cancel_fd)/2+1, &rdset, &wrset, 0, &tv) == 0) {
+ tv.tv_sec = 60*4;
+ if (select(fdmax, &rdset, &wrset, 0, &tv) == 0) {
close(fd);
errno = ETIMEDOUT;
return -1;
diff --git a/camel/camel-session.c b/camel/camel-session.c
index 67d58a1e67..d834bad54c 100644
--- a/camel/camel-session.c
+++ b/camel/camel-session.c
@@ -501,9 +501,9 @@ struct _CamelCancel {
#ifdef ENABLE_THREADS
#define CAMEL_CANCEL_LOCK(cc) pthread_mutex_lock(&cc->lock)
-#define CAMEL_CANCEL_UNLOCK(cc) pthread_mutex_lock(&cc->lock)
+#define CAMEL_CANCEL_UNLOCK(cc) pthread_mutex_unlock(&cc->lock)
#define CAMEL_ACTIVE_LOCK() pthread_mutex_lock(&cancel_active_lock)
-#define CAMEL_ACTIVE_UNLOCK() pthread_mutex_lock(&cancel_active_lock)
+#define CAMEL_ACTIVE_UNLOCK() pthread_mutex_unlock(&cancel_active_lock)
static pthread_mutex_t cancel_active_lock = PTHREAD_MUTEX_INITIALIZER;
#else
#define CAMEL_CANCEL_LOCK(cc)
@@ -597,12 +597,27 @@ void camel_cancel_unblock(CamelCancel *cc)
CAMEL_CANCEL_UNLOCK(cc);
}
+static void
+cancel_thread(void *key, CamelCancel *cc, void *data)
+{
+ if (cc)
+ camel_cancel_cancel(cc);
+}
+
/* cancels an operation */
void camel_cancel_cancel(CamelCancel *cc)
{
CamelCancelMsg *msg;
- if ((cc->flags & CAMEL_CANCEL_CANCELLED) == 0) {
+ if (cc == NULL) {
+ if (cancel_active) {
+ CAMEL_ACTIVE_LOCK();
+ g_hash_table_foreach(cancel_active, (GHRFunc)cancel_thread, NULL);
+ CAMEL_ACTIVE_UNLOCK();
+ }
+ } else if ((cc->flags & CAMEL_CANCEL_CANCELLED) == 0) {
+ printf("cancelling thread %d\n", cc->id);
+
CAMEL_CANCEL_LOCK(cc);
msg = g_malloc0(sizeof(*msg));
e_msgport_put(cc->cancel_port, (EMsg *)msg);
@@ -630,9 +645,12 @@ void camel_cancel_register(CamelCancel *cc)
cc->id = id;
g_hash_table_insert(cancel_active, (void *)id, cc);
- camel_cancel_ref(cc);
+
+ printf("registering thread %d for cancellation\n", id);
CAMEL_ACTIVE_UNLOCK();
+
+ camel_cancel_ref(cc);
}
/* remove a thread from being able to be cancelled */
@@ -644,7 +662,7 @@ void camel_cancel_unregister(CamelCancel *cc)
cancel_active = g_hash_table_new(NULL, NULL);
if (cc == NULL) {
- cc = g_hash_table_lookup(cancel_active, (void *)cc->id);
+ cc = g_hash_table_lookup(cancel_active, (void *)pthread_self());
if (cc == NULL) {
g_warning("Trying to unregister a thread that was never registered for cancellation");
}
@@ -656,6 +674,9 @@ void camel_cancel_unregister(CamelCancel *cc)
CAMEL_ACTIVE_UNLOCK();
if (cc)
+ printf("unregistering thread %d for cancellation\n", cc->id);
+
+ if (cc)
camel_cancel_unref(cc);
}
@@ -664,6 +685,8 @@ gboolean camel_cancel_check(CamelCancel *cc)
{
CamelCancelMsg *msg;
+ printf("checking for cancel in thread %d\n", pthread_self());
+
if (cc == NULL) {
if (cancel_active) {
CAMEL_ACTIVE_LOCK();
@@ -674,14 +697,19 @@ gboolean camel_cancel_check(CamelCancel *cc)
return FALSE;
}
- if (cc->blocked > 0)
+ if (cc->blocked > 0) {
+ printf("ahah! cancellation is blocked\n");
return FALSE;
+ }
- if (cc->flags & CAMEL_CANCEL_CANCELLED)
+ if (cc->flags & CAMEL_CANCEL_CANCELLED) {
+ printf("previously cancelled\n");
return TRUE;
+ }
msg = (CamelCancelMsg *)e_msgport_get(cc->cancel_port);
if (msg) {
+ printf("Got cancellation message\n");
CAMEL_CANCEL_LOCK(cc);
cc->flags |= CAMEL_CANCEL_CANCELLED;
CAMEL_CANCEL_UNLOCK(cc);
diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c
index 7047670832..92c11435fa 100644
--- a/camel/camel-stream-fs.c
+++ b/camel/camel-stream-fs.c
@@ -227,13 +227,15 @@ stream_read (CamelStream *stream, char *buffer, size_t n)
} else {
fd_set rdset;
long flags;
+ int fdmax;
fcntl(stream_fs->fd, F_GETFL, &flags);
fcntl(stream_fs->fd, F_SETFL, flags | O_NONBLOCK);
FD_ZERO(&rdset);
FD_SET(stream_fs->fd, &rdset);
FD_SET(cancel_fd, &rdset);
- select((stream_fs->fd+cancel_fd)/2+1, &rdset, 0, 0, NULL);
+ fdmax = MAX(stream_fs->fd, cancel_fd)+1;
+ select(fdmax, &rdset, 0, 0, NULL);
if (FD_ISSET(cancel_fd, &rdset)) {
fcntl(stream_fs->fd, F_SETFL, flags);
errno = EINTR;
@@ -277,6 +279,7 @@ stream_write (CamelStream *stream, const char *buffer, size_t n)
} else {
fd_set rdset, wrset;
long flags;
+ int fdmax;
fcntl(stream_fs->fd, F_GETFL, &flags);
fcntl(stream_fs->fd, F_SETFL, flags | O_NONBLOCK);
@@ -284,7 +287,8 @@ stream_write (CamelStream *stream, const char *buffer, size_t n)
FD_ZERO(&wrset);
FD_SET(stream_fs->fd, &wrset);
FD_SET(cancel_fd, &rdset);
- select((stream_fs->fd+cancel_fd)/2+1, &rdset, &wrset, 0, NULL);
+ fdmax = MAX(stream_fs->fd, cancel_fd)+1;
+ select(fdmax, &rdset, &wrset, 0, NULL);
if (FD_ISSET(cancel_fd, &rdset)) {
fcntl(stream_fs->fd, F_SETFL, flags);
errno = EINTR;
diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c
index af61ed0981..db8cdd29dd 100644
--- a/camel/providers/imap/camel-imap-command.c
+++ b/camel/providers/imap/camel-imap-command.c
@@ -30,6 +30,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#include <errno.h>
#include "camel-imap-command.h"
#include "camel-imap-utils.h"
@@ -283,6 +284,14 @@ imap_read_untagged (CamelImapStore *store, char *line, CamelException *ex)
str->str[0] = '\n';
nread = camel_stream_read (CAMEL_REMOTE_STORE (store)->istream,
str->str + 1, length);
+ if (nread == -1) {
+ if (errno == EINTR)
+ camel_exception_set(ex, CAMEL_EXCEPTION_USER_CANCEL, _("Operation cancelled"));
+ else
+ camel_exception_set(ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, strerror(errno));
+ camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+ goto lose;
+ }
if (nread < length) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
_("Server response ended too soon."));
diff --git a/camel/providers/imap/camel-imap-private.h b/camel/providers/imap/camel-imap-private.h
index 95ec3a5a0b..abcb3f8dd7 100644
--- a/camel/providers/imap/camel-imap-private.h
+++ b/camel/providers/imap/camel-imap-private.h
@@ -21,8 +21,8 @@
* USA
*/
-#ifndef CAMEL_PRIVATE_H
-#define CAMEL_PRIVATE_H 1
+#ifndef CAMEL_IMAP_PRIVATE_H
+#define CAMEL_IMAP_PRIVATE_H 1
#ifdef __cplusplus
extern "C" {
@@ -70,5 +70,5 @@ struct _CamelImapFolderPrivate {
}
#endif /* __cplusplus */
-#endif /* CAMEL_H */
+#endif /* CAMEL_IMAP_PRIVATE_H */
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index ca4ca2e0d7..275270ecb6 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -48,6 +48,7 @@
#include "string-utils.h"
#include "camel-imap-private.h"
+#include "camel-private.h"
#define d(x) x
@@ -283,6 +284,31 @@ query_auth_types (CamelService *service, CamelException *ex)
return g_list_prepend (types, &password_authtype);
}
+/* call refresh folder directly, bypassing the folder lock */
+static void
+refresh_folder_info (gpointer key, gpointer value, gpointer data)
+{
+ CamelFolder *folder = CAMEL_FOLDER (value);
+
+ CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(folder))->refresh_info(folder, data);
+}
+
+/* This is a little 'hack' to avoid the deadlock conditions that would otherwise
+ ensue when calling camel_folder_refresh_info from inside a lock */
+/* NB: on second thougts this is probably not entirely safe, but it'll do for now */
+/* the alternative is to:
+ make the camel folder->lock recursive (which should probably be done)
+ or remove it from camel_folder_refresh_info, and use another locking mechanism */
+static void
+imap_store_refresh_folders (CamelRemoteStore *store, CamelException *ex)
+{
+ CAMEL_STORE_LOCK(store, cache_lock);
+
+ g_hash_table_foreach (CAMEL_STORE (store)->folders, refresh_folder_info, ex);
+
+ CAMEL_STORE_UNLOCK(store, cache_lock);
+}
+
static gboolean
imap_connect (CamelService *service, CamelException *ex)
{
@@ -476,7 +502,7 @@ imap_connect (CamelService *service, CamelException *ex)
return FALSE;
}
- camel_remote_store_refresh_folders (CAMEL_REMOTE_STORE (store), ex);
+ imap_store_refresh_folders (CAMEL_REMOTE_STORE (store), ex);
return !camel_exception_is_set (ex);
}