aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2001-02-08 09:42:53 +0800
committerMichael Zucci <zucchi@src.gnome.org>2001-02-08 09:42:53 +0800
commit49f8a687a41e635cd83807d33c74afe8e55fb3df (patch)
tree4162f19a2db18ff787386c7c97a98e5e8a5e7744
parent1290da3f286a31745b1814610c16918c2e84e140 (diff)
downloadgsoc2013-evolution-49f8a687a41e635cd83807d33c74afe8e55fb3df.tar
gsoc2013-evolution-49f8a687a41e635cd83807d33c74afe8e55fb3df.tar.gz
gsoc2013-evolution-49f8a687a41e635cd83807d33c74afe8e55fb3df.tar.bz2
gsoc2013-evolution-49f8a687a41e635cd83807d33c74afe8e55fb3df.tar.lz
gsoc2013-evolution-49f8a687a41e635cd83807d33c74afe8e55fb3df.tar.xz
gsoc2013-evolution-49f8a687a41e635cd83807d33c74afe8e55fb3df.tar.zst
gsoc2013-evolution-49f8a687a41e635cd83807d33c74afe8e55fb3df.zip
Changed to push the operation into a status stack.
2001-02-07 Not Zed <NotZed@Ximian.com> * camel-operation.c (camel_operation_start): Changed to push the operation into a status stack. (camel_operation_progress): Changed to only accept % complete. (camel_operation_reset): Free status stack as well. * providers/pop3/camel-pop3-folder.c (pop3_get_message): Get the octect count from the return line, and pass it to get_additional_data(). (pop3_refresh_info): Added status stuff. * providers/pop3/camel-pop3-store.c (camel_pop3_command_get_additional_data): Added a total bytes expected argument for progress reporting & fixed callers. (camel_pop3_command_get_additional_data): Added progress reporting. * providers/local/camel-mbox-summary.c (mbox_summary_sync_full): (mbox_summary_sync_quick): (summary_rebuild): Added progress reporting stuff. svn path=/trunk/; revision=8095
-rw-r--r--camel/ChangeLog35
-rw-r--r--camel/Makefile.am2
-rw-r--r--camel/camel-operation.c540
-rw-r--r--camel/camel-operation.h66
-rw-r--r--camel/camel-remote-store.c9
-rw-r--r--camel/camel-session.c254
-rw-r--r--camel/camel-session.h18
-rw-r--r--camel/camel-stream-fs.c10
-rw-r--r--camel/providers/local/camel-mbox-summary.c42
-rw-r--r--camel/providers/pop3/camel-pop3-folder.c31
-rw-r--r--camel/providers/pop3/camel-pop3-store.c15
-rw-r--r--camel/providers/pop3/camel-pop3-store.h3
12 files changed, 729 insertions, 296 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 0dca380b40..059966a30c 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,25 @@
+2001-02-07 Not Zed <NotZed@Ximian.com>
+
+ * camel-operation.c (camel_operation_start): Changed to push the
+ operation into a status stack.
+ (camel_operation_progress): Changed to only accept % complete.
+ (camel_operation_reset): Free status stack as well.
+
+ * providers/pop3/camel-pop3-folder.c (pop3_get_message): Get the
+ octect count from the return line, and pass it to
+ get_additional_data().
+ (pop3_refresh_info): Added status stuff.
+
+ * providers/pop3/camel-pop3-store.c
+ (camel_pop3_command_get_additional_data): Added a total bytes
+ expected argument for progress reporting & fixed callers.
+ (camel_pop3_command_get_additional_data): Added progress
+ reporting.
+
+ * providers/local/camel-mbox-summary.c (mbox_summary_sync_full):
+ (mbox_summary_sync_quick):
+ (summary_rebuild): Added progress reporting stuff.
+
2001-02-07 Jeffrey Stedfast <fejj@ximian.com>
* camel-search-private.c (CAMEL_SEARCH_COMPARE): Macro for making
@@ -27,6 +49,19 @@
2001-02-06 Not Zed <NotZed@Ximian.com>
+ * camel-session.c: Removed all the camel_cancel stuff.
+
+ * camel-stream-fs.c (stream_read): Change to use camel_operation.
+ (stream_write): "
+
+ * camel-remote-store.c (socket_connect): Change to use
+ camel_operation rather than camel_cancel stuff.
+ Removed gal include, WTF is that doing there anyway?
+
+ * Makefile.am (libcamel_la_SOURCES):
+ (libcamelinclude_HEADERS): Added camel-operation.[ch], stuff to
+ handle notification and cancellation.
+
* camel-search-private.c: Removed unwanted header. It was never
put in for a reason. Stop fixing irrelevant warnings.
diff --git a/camel/Makefile.am b/camel/Makefile.am
index 063ec03f08..55d28f48fc 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -46,6 +46,7 @@ libcamel_la_SOURCES = \
camel-movemail.c \
camel-multipart.c \
camel-object.c \
+ camel-operation.c \
camel-provider.c \
camel-remote-store.c \
camel-search-private.c \
@@ -102,6 +103,7 @@ libcamelinclude_HEADERS = \
camel-movemail.h \
camel-multipart.h \
camel-object.h \
+ camel-operation.h \
camel-provider.h \
camel-remote-store.h \
camel-seekable-stream.h \
diff --git a/camel/camel-operation.c b/camel/camel-operation.c
new file mode 100644
index 0000000000..9d631fca7b
--- /dev/null
+++ b/camel/camel-operation.c
@@ -0,0 +1,540 @@
+
+#include "config.h"
+
+#include <stdio.h>
+#ifdef ENABLE_THREADS
+#include <pthread.h>
+#endif
+
+#include <glib.h>
+#include "camel-operation.h"
+#include "e-util/e-msgport.h"
+
+#define d(x)
+
+/* ********************************************************************** */
+
+struct _CamelOperation {
+ pthread_t id; /* id of running thread */
+ guint32 flags; /* cancelled ? */
+ int blocked; /* cancellation blocked depth */
+ int refcount;
+
+ CamelOperationStatusFunc status;
+ void *status_data;
+ time_t status_update;
+
+ /* stack of status messages (char *) */
+ GSList *status_stack;
+
+#ifdef ENABLE_THREADS
+ EMsgPort *cancel_port;
+ int cancel_fd;
+ pthread_mutex_t lock;
+#endif
+};
+
+#define CAMEL_OPERATION_CANCELLED (1<<0)
+
+#ifdef ENABLE_THREADS
+#define CAMEL_OPERATION_LOCK(cc) pthread_mutex_lock(&cc->lock)
+#define CAMEL_OPERATION_UNLOCK(cc) pthread_mutex_unlock(&cc->lock)
+#define CAMEL_ACTIVE_LOCK() pthread_mutex_lock(&operation_active_lock)
+#define CAMEL_ACTIVE_UNLOCK() pthread_mutex_unlock(&operation_active_lock)
+static pthread_mutex_t operation_active_lock = PTHREAD_MUTEX_INITIALIZER;
+#else
+#define CAMEL_OPERATION_LOCK(cc)
+#define CAMEL_OPERATION_UNLOCK(cc)
+#define CAMEL_ACTIVE_LOCK()
+#define CAMEL_ACTIVE_UNLOCK()
+#endif
+
+static GHashTable *operation_active;
+
+typedef struct _CamelOperationMsg {
+ EMsg msg;
+} CamelOperationMsg ;
+
+/**
+ * camel_operation_new:
+ * @status: Callback for receiving status messages.
+ * @status_data: User data.
+ *
+ * Create a new camel operation handle. Camel operation handles can
+ * be used in a multithreaded application (or a single operation
+ * handle can be used in a non threaded appliation) to cancel running
+ * operations and to obtain notification messages of the internal
+ * status of messages.
+ *
+ * Return value: A new operation handle.
+ **/
+CamelOperation *camel_operation_new(CamelOperationStatusFunc status, void *status_data)
+{
+ CamelOperation *cc;
+
+ cc = g_malloc0(sizeof(*cc));
+
+ cc->flags = 0;
+ cc->blocked = 0;
+ cc->refcount = 1;
+ cc->status = status;
+ cc->status_data = status_data;
+#ifdef ENABLE_THREADS
+ cc->id = ~0;
+ cc->cancel_port = e_msgport_new();
+ cc->cancel_fd = e_msgport_fd(cc->cancel_port);
+ pthread_mutex_init(&cc->lock, NULL);
+#endif
+
+ return cc;
+}
+
+/**
+ * camel_operation_reset:
+ * @cc:
+ *
+ * Resets an operation cancel state and message.
+ **/
+void camel_operation_reset(CamelOperation *cc)
+{
+ GSList *n;
+
+#ifdef ENABLE_THREADS
+ CamelOperationMsg *msg;
+
+ while ((msg = (CamelOperationMsg *)e_msgport_get(cc->cancel_port)))
+ g_free(msg);
+#endif
+
+ n = cc->status_stack;
+ while (n) {
+ g_free(n->data);
+ n = n->next;
+ }
+ g_slist_free(cc->status_stack);
+ cc->status_stack = NULL;
+
+ cc->flags = 0;
+ cc->blocked = 0;
+}
+
+/**
+ * camel_operation_ref:
+ * @cc:
+ *
+ * Add a reference to the CamelOperation @cc.
+ **/
+void camel_operation_ref(CamelOperation *cc)
+{
+ CAMEL_OPERATION_LOCK(cc);
+ cc->refcount++;
+ CAMEL_OPERATION_UNLOCK(cc);
+}
+
+/**
+ * camel_operation_unref:
+ * @cc:
+ *
+ * Unref and potentially free @cc.
+ **/
+void camel_operation_unref(CamelOperation *cc)
+{
+ GSList *n;
+#ifdef ENABLE_THREADS
+ CamelOperationMsg *msg;
+
+ if (cc->refcount == 1) {
+ while ((msg = (CamelOperationMsg *)e_msgport_get(cc->cancel_port)))
+ g_free(msg);
+
+ e_msgport_destroy(cc->cancel_port);
+#endif
+ n = cc->status_stack;
+ while (n) {
+ g_warning("Camel operation status stack non empty: %s", (char *)n->data);
+ g_free(n->data);
+ n = n->next;
+ }
+ g_slist_free(cc->status_stack);
+
+ g_free(cc);
+ } else {
+ CAMEL_OPERATION_LOCK(cc);
+ cc->refcount--;
+ CAMEL_OPERATION_UNLOCK(cc);
+ }
+}
+
+/**
+ * camel_operation_cancel_block:
+ * @cc:
+ *
+ * Block cancellation for this operation. If @cc is NULL, then the
+ * current thread is blocked.
+ **/
+void camel_operation_cancel_block(CamelOperation *cc)
+{
+ CAMEL_ACTIVE_LOCK();
+ if (operation_active == NULL)
+ operation_active = g_hash_table_new(NULL, NULL);
+
+ if (cc == NULL)
+ cc = g_hash_table_lookup(operation_active, (void *)pthread_self());
+ CAMEL_ACTIVE_UNLOCK();
+
+ if (cc) {
+ CAMEL_OPERATION_LOCK(cc);
+ cc->blocked++;
+ CAMEL_OPERATION_UNLOCK(cc);
+ }
+}
+
+/**
+ * camel_operation_cancel_unblock:
+ * @cc:
+ *
+ * Unblock cancellation, when the unblock count reaches the block
+ * count, then this operation can be cancelled. If @cc is NULL, then
+ * the current thread is unblocked.
+ **/
+void camel_operation_cancel_unblock(CamelOperation *cc)
+{
+ CAMEL_ACTIVE_LOCK();
+ if (operation_active == NULL)
+ operation_active = g_hash_table_new(NULL, NULL);
+
+ if (cc == NULL)
+ cc = g_hash_table_lookup(operation_active, (void *)pthread_self());
+ CAMEL_ACTIVE_UNLOCK();
+
+ if (cc) {
+ CAMEL_OPERATION_LOCK(cc);
+ cc->blocked--;
+ CAMEL_OPERATION_UNLOCK(cc);
+ }
+}
+
+static void
+cancel_thread(void *key, CamelOperation *cc, void *data)
+{
+ if (cc)
+ camel_operation_cancel(cc);
+}
+
+/**
+ * camel_operation_cancel:
+ * @cc:
+ *
+ * Cancel a given operation. If @cc is NULL then all outstanding
+ * operations are cancelled.
+ **/
+void camel_operation_cancel(CamelOperation *cc)
+{
+ CamelOperationMsg *msg;
+
+ if (cc == NULL) {
+ if (operation_active) {
+ CAMEL_ACTIVE_LOCK();
+ g_hash_table_foreach(operation_active, (GHFunc)cancel_thread, NULL);
+ CAMEL_ACTIVE_UNLOCK();
+ }
+ } else if ((cc->flags & CAMEL_OPERATION_CANCELLED) == 0) {
+ d(printf("cancelling thread %d\n", cc->id));
+
+ CAMEL_OPERATION_LOCK(cc);
+ msg = g_malloc0(sizeof(*msg));
+ e_msgport_put(cc->cancel_port, (EMsg *)msg);
+ cc->flags |= CAMEL_OPERATION_CANCELLED;
+ CAMEL_OPERATION_UNLOCK(cc);
+ }
+}
+
+/**
+ * camel_operation_register:
+ * @cc:
+ *
+ * Register a thread or the main thread for cancellation through @cc.
+ * If @cc is NULL, then a new cancellation is created for this thread,
+ * but may only be cancelled from the same thread.
+ *
+ * All calls to operation_register() should be matched with calls to
+ * operation_unregister(), or resources will be lost.
+ **/
+void camel_operation_register(CamelOperation *cc)
+{
+ pthread_t id = pthread_self();
+
+ CAMEL_ACTIVE_LOCK();
+
+ if (operation_active == NULL)
+ operation_active = g_hash_table_new(NULL, NULL);
+
+ if (cc == NULL) {
+ cc = g_hash_table_lookup(operation_active, (void *)id);
+ if (cc == NULL) {
+ cc = camel_operation_new(NULL, NULL);
+ }
+ }
+
+ cc->id = id;
+ g_hash_table_insert(operation_active, (void *)id, cc);
+
+ d(printf("registering thread %ld for cancellation\n", id));
+
+ CAMEL_ACTIVE_UNLOCK();
+
+ camel_operation_ref(cc);
+}
+
+/**
+ * camel_operation_unregister:
+ * @cc:
+ *
+ * Unregister a given operation from being cancelled. If @cc is NULL,
+ * then the current thread is used.
+ **/
+void camel_operation_unregister(CamelOperation *cc)
+{
+ CAMEL_ACTIVE_LOCK();
+
+ if (operation_active == NULL)
+ operation_active = g_hash_table_new(NULL, NULL);
+
+ if (cc == NULL) {
+ cc = g_hash_table_lookup(operation_active, (void *)pthread_self());
+ if (cc == NULL) {
+ g_warning("Trying to unregister a thread that was never registered for cancellation");
+ }
+ }
+
+ if (cc)
+ g_hash_table_remove(operation_active, (void *)cc->id);
+
+ CAMEL_ACTIVE_UNLOCK();
+
+ d({if (cc) printf("unregistering thread %d for cancellation\n", cc->id);});
+
+ if (cc)
+ camel_operation_unref(cc);
+}
+
+/**
+ * camel_operation_cancel_check:
+ * @cc:
+ *
+ * Check if cancellation has been applied to @cc. If @cc is NULL,
+ * then the CamelOperation registered for the current thread is used.
+ *
+ * Return value: TRUE if the operation has been cancelled.
+ **/
+gboolean camel_operation_cancel_check(CamelOperation *cc)
+{
+ CamelOperationMsg *msg;
+
+ d(printf("checking for cancel in thread %d\n", pthread_self()));
+
+ if (cc == NULL) {
+ if (operation_active) {
+ CAMEL_ACTIVE_LOCK();
+ cc = g_hash_table_lookup(operation_active, (void *)pthread_self());
+ CAMEL_ACTIVE_UNLOCK();
+ }
+ if (cc == NULL)
+ return FALSE;
+ }
+
+ if (cc->blocked > 0) {
+ d(printf("ahah! cancellation is blocked\n"));
+ return FALSE;
+ }
+
+ if (cc->flags & CAMEL_OPERATION_CANCELLED) {
+ d(printf("previously cancelled\n"));
+ return TRUE;
+ }
+
+ msg = (CamelOperationMsg *)e_msgport_get(cc->cancel_port);
+ if (msg) {
+ d(printf("Got cancellation message\n"));
+ CAMEL_OPERATION_LOCK(cc);
+ cc->flags |= CAMEL_OPERATION_CANCELLED;
+ CAMEL_OPERATION_UNLOCK(cc);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * camel_operation_cancel_fd:
+ * @cc:
+ *
+ * Retrieve a file descriptor that can be waited on (select, or poll)
+ * for read, to asynchronously detect cancellation.
+ *
+ * Return value: The fd, or -1 if cancellation is not available
+ * (blocked, or has not been registered for this thread).
+ **/
+int camel_operation_cancel_fd(CamelOperation *cc)
+{
+ if (cc == NULL) {
+ if (operation_active) {
+ CAMEL_ACTIVE_LOCK();
+ cc = g_hash_table_lookup(operation_active, (void *)pthread_self());
+ CAMEL_ACTIVE_UNLOCK();
+ }
+ if (cc == NULL)
+ return -1;
+ }
+ if (cc->blocked)
+ return -1;
+
+ return cc->cancel_fd;
+}
+
+/**
+ * camel_operation_start:
+ * @cc:
+ * @what:
+ * @:
+ *
+ * Report the start of an operation. All start operations should have
+ * similar end operations.
+ **/
+void camel_operation_start(CamelOperation *cc, char *what, ...)
+{
+ va_list ap;
+ char *msg;
+
+ if (operation_active == NULL)
+ return;
+
+ if (cc == NULL) {
+ CAMEL_ACTIVE_LOCK();
+ cc = g_hash_table_lookup(operation_active, (void *)pthread_self());
+ CAMEL_ACTIVE_UNLOCK();
+ if (cc == NULL)
+ return;
+ }
+
+ if (cc->status == NULL)
+ return;
+
+ va_start(ap, what);
+ msg = g_strdup_vprintf(what, ap);
+ va_end(ap);
+ cc->status(cc, msg, CAMEL_OPERATION_START, cc->status_data);
+ cc->status_update = 0;
+ cc->status_stack = g_slist_prepend(cc->status_stack, msg);
+ d(printf("start '%s'\n", msg, pc));
+}
+
+/**
+ * camel_operation_progress:
+ * @cc: Operation to report to.
+ * @pc: Percent complete, 0 to 100.
+ *
+ * Report progress on the current operation. If @cc is NULL, then the
+ * currently registered operation is used. @pc reports the current
+ * percentage of completion, which should be in the range of 0 to 100.
+ *
+ * If the total percentage is not know, then use
+ * camel_operation_progress_count().
+ **/
+void camel_operation_progress(CamelOperation *cc, int pc)
+{
+ char *msg;
+ time_t now;
+
+ if (operation_active == NULL)
+ return;
+
+ if (cc == NULL) {
+ CAMEL_ACTIVE_LOCK();
+ cc = g_hash_table_lookup(operation_active, (void *)pthread_self());
+ CAMEL_ACTIVE_UNLOCK();
+ if (cc == NULL)
+ return;
+ }
+
+ if (cc->status == NULL)
+ return;
+
+ if (cc->status_stack == NULL)
+ return;
+
+ now = time(0);
+ if (cc->status_update != now) {
+ msg =cc->status_stack->data;
+ cc->status(cc, msg, pc, cc->status_data);
+ d(printf("progress '%s' %d %%\n", msg, pc));
+ cc->status_update = now;
+ }
+}
+
+void camel_operation_progress_count(CamelOperation *cc, int sofar)
+{
+ char *msg;
+ time_t now;
+
+ if (operation_active == NULL)
+ return;
+
+ if (cc == NULL) {
+ CAMEL_ACTIVE_LOCK();
+ cc = g_hash_table_lookup(operation_active, (void *)pthread_self());
+ CAMEL_ACTIVE_UNLOCK();
+ if (cc == NULL)
+ return;
+ }
+
+ if (cc->status == NULL)
+ return;
+
+ if (cc->status_stack == NULL)
+ return;
+
+ /* FIXME: generate some meaningful pc value */
+ now = time(0);
+ if (cc->status_update != now) {
+ msg =cc->status_stack->data;
+ cc->status(cc, msg, sofar, cc->status_data);
+ d(printf("progress '%s' %d done\n", msg, sofar));
+ cc->status_update = now;
+ }
+}
+
+/**
+ * camel_operation_end:
+ * @cc:
+ * @what: Format string.
+ * @:
+ *
+ * Report the end of an operation. If @cc is NULL, then the currently
+ * registered operation is notified.
+ **/
+void camel_operation_end(CamelOperation *cc)
+{
+ char *msg;
+
+ if (operation_active == NULL)
+ return;
+
+ if (cc == NULL) {
+ CAMEL_ACTIVE_LOCK();
+ cc = g_hash_table_lookup(operation_active, (void *)pthread_self());
+ CAMEL_ACTIVE_UNLOCK();
+ if (cc == NULL)
+ return;
+ }
+
+ if (cc->status == NULL)
+ return;
+
+ if (cc->status_stack == NULL)
+ return;
+
+ msg = cc->status_stack->data;
+ cc->status(cc, msg, CAMEL_OPERATION_END, cc->status_data);
+ g_free(msg);
+ cc->status_stack = g_slist_remove_link(cc->status_stack, cc->status_stack);
+}
diff --git a/camel/camel-operation.h b/camel/camel-operation.h
new file mode 100644
index 0000000000..4a61b40dfc
--- /dev/null
+++ b/camel/camel-operation.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Authors: Michael Zucchi <NotZed@Ximian.com>
+ *
+ * Copyright 2001 Ximian, Inc. (http://www.ximian.com/)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#ifndef CAMEL_OPERATION_H
+#define CAMEL_OPERATION_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus }*/
+
+/* cancellation helper stuff, not yet finalised */
+
+typedef struct _CamelOperation CamelOperation;
+
+typedef void (*CamelOperationStatusFunc)(struct _CamelOperation *op, const char *what, int pc, void *data);
+
+enum _camel_operation_status_t {
+ CAMEL_OPERATION_START = -1,
+ CAMEL_OPERATION_END = -2,
+};
+
+/* main thread functions */
+CamelOperation *camel_operation_new(CamelOperationStatusFunc status, void *status_data);
+void camel_operation_ref(CamelOperation *cc);
+void camel_operation_unref(CamelOperation *cc);
+void camel_operation_reset(CamelOperation *cc);
+void camel_operation_cancel(CamelOperation *cc);
+/* subthread functions */
+void camel_operation_register(CamelOperation *cc);
+void camel_operation_unregister(CamelOperation *cc);
+/* called internally by camel, for the current thread */
+void camel_operation_cancel_block(CamelOperation *cc);
+void camel_operation_cancel_unblock(CamelOperation *cc);
+int camel_operation_cancel_check(CamelOperation *cc);
+int camel_operation_cancel_fd(CamelOperation *cc);
+
+void camel_operation_start(CamelOperation *cc, char *what, ...);
+void camel_operation_progress(CamelOperation *cc, int pc);
+void camel_operation_progress_count(CamelOperation *cc, int sofar);
+void camel_operation_end(CamelOperation *cc);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CAMEL_OPERATION_H */
diff --git a/camel/camel-remote-store.c b/camel/camel-remote-store.c
index e81ef5e91e..d1352300b7 100644
--- a/camel/camel-remote-store.c
+++ b/camel/camel-remote-store.c
@@ -36,8 +36,6 @@
#include <unistd.h>
#include <errno.h>
-#include <gal/util/e-util.h>
-
#include "camel-remote-store.h"
#include "camel-folder.h"
#include "camel-exception.h"
@@ -49,6 +47,7 @@
#include "string-utils.h"
#include "camel-private.h"
+#include "camel-operation.h"
#define d(x) x
#if d(!)0
@@ -202,7 +201,7 @@ timeout_cb (gpointer data)
return TRUE;
}
-/* this is a 'cancellable' connect, cancellable from camel_cancel etc */
+/* this is a 'cancellable' connect, cancellable from camel_operation_cancel etc */
/* returns -1 & errno == EINTR if the connection was cancelled */
static int socket_connect(struct hostent *h, int port)
{
@@ -214,7 +213,7 @@ static int socket_connect(struct hostent *h, int port)
int cancel_fd;
/* see if we're cancelled yet */
- if (camel_cancel_check(NULL)) {
+ if (camel_operation_cancel_check(NULL)) {
errno = EINTR;
return -1;
}
@@ -226,7 +225,7 @@ static int socket_connect(struct hostent *h, int port)
fd = socket (h->h_addrtype, SOCK_STREAM, 0);
- cancel_fd = camel_cancel_fd(NULL);
+ cancel_fd = camel_operation_cancel_fd(NULL);
if (cancel_fd == -1) {
ret = connect(fd, (struct sockaddr *)&sin, sizeof (sin));
if (ret == -1) {
diff --git a/camel/camel-session.c b/camel/camel-session.c
index 8f97c507b9..a8ca5983ec 100644
--- a/camel/camel-session.c
+++ b/camel/camel-session.c
@@ -32,7 +32,6 @@
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
-#include <gal/util/e-util.h>
#include "camel-session.h"
#include "camel-store.h"
#include "camel-transport.h"
@@ -509,256 +508,3 @@ camel_session_remove_timeout (CamelSession *session, guint handle)
{
return session->remover (handle);
}
-
-/* ********************************************************************** */
-
-struct _CamelCancel {
- pthread_t id; /* id of running thread */
- guint32 flags; /* cancelled ? */
- int blocked; /* cancellation blocked depth */
- int refcount;
-#ifdef ENABLE_THREADS
- EMsgPort *cancel_port;
- int cancel_fd;
- pthread_mutex_t lock;
-#endif
-};
-
-#define CAMEL_CANCEL_CANCELLED (1<<0)
-
-#ifdef ENABLE_THREADS
-#define CAMEL_CANCEL_LOCK(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_unlock(&cancel_active_lock)
-static pthread_mutex_t cancel_active_lock = PTHREAD_MUTEX_INITIALIZER;
-#else
-#define CAMEL_CANCEL_LOCK(cc)
-#define CAMEL_CANCEL_UNLOCK(cc)
-#define CAMEL_ACTIVE_LOCK()
-#define CAMEL_ACTIVE_UNLOCK()
-#endif
-
-static GHashTable *cancel_active;
-
-typedef struct _CamelCancelMsg {
- EMsg msg;
-} CamelCancelMsg ;
-
-/* creates a new cancel handle */
-CamelCancel *camel_cancel_new(void)
-{
- CamelCancel *cc;
-
- cc = g_malloc0(sizeof(*cc));
-
- cc->flags = 0;
- cc->blocked = 0;
- cc->refcount = 1;
-#ifdef ENABLE_THREADS
- cc->id = ~0;
- cc->cancel_port = e_msgport_new();
- cc->cancel_fd = e_msgport_fd(cc->cancel_port);
- pthread_mutex_init(&cc->lock, NULL);
-#endif
-
- return cc;
-}
-
-void camel_cancel_reset(CamelCancel *cc)
-{
-#ifdef ENABLE_THREADS
- CamelCancelMsg *msg;
-
- while ((msg = (CamelCancelMsg *)e_msgport_get(cc->cancel_port)))
- g_free(msg);
-#endif
-
- cc->flags = 0;
- cc->blocked = 0;
-}
-
-void camel_cancel_ref(CamelCancel *cc)
-{
- CAMEL_CANCEL_LOCK(cc);
- cc->refcount++;
- CAMEL_CANCEL_UNLOCK(cc);
-}
-
-void camel_cancel_unref(CamelCancel *cc)
-{
-#ifdef ENABLE_THREADS
- CamelCancelMsg *msg;
-
- if (cc->refcount == 1) {
- while ((msg = (CamelCancelMsg *)e_msgport_get(cc->cancel_port)))
- g_free(msg);
-
- e_msgport_destroy(cc->cancel_port);
-#endif
- g_free(cc);
- } else {
- CAMEL_CANCEL_LOCK(cc);
- cc->refcount--;
- CAMEL_CANCEL_UNLOCK(cc);
- }
-}
-
-/* block cancellation */
-void camel_cancel_block(CamelCancel *cc)
-{
- CAMEL_CANCEL_LOCK(cc);
-
- cc->blocked++;
-
- CAMEL_CANCEL_UNLOCK(cc);
-}
-
-/* unblock cancellation */
-void camel_cancel_unblock(CamelCancel *cc)
-{
- CAMEL_CANCEL_LOCK(cc);
-
- cc->blocked--;
-
- 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 == NULL) {
- if (cancel_active) {
- CAMEL_ACTIVE_LOCK();
- g_hash_table_foreach(cancel_active, (GHFunc)cancel_thread, NULL);
- CAMEL_ACTIVE_UNLOCK();
- }
- } else if ((cc->flags & CAMEL_CANCEL_CANCELLED) == 0) {
- d(printf("cancelling thread %d\n", cc->id));
-
- CAMEL_CANCEL_LOCK(cc);
- msg = g_malloc0(sizeof(*msg));
- e_msgport_put(cc->cancel_port, (EMsg *)msg);
- cc->flags |= CAMEL_CANCEL_CANCELLED;
- CAMEL_CANCEL_UNLOCK(cc);
- }
-}
-
-/* register a thread for cancellation */
-void camel_cancel_register(CamelCancel *cc)
-{
- pthread_t id = pthread_self();
-
- CAMEL_ACTIVE_LOCK();
-
- if (cancel_active == NULL)
- cancel_active = g_hash_table_new(NULL, NULL);
-
- if (cc == NULL) {
- cc = g_hash_table_lookup(cancel_active, (void *)id);
- if (cc == NULL) {
- cc = camel_cancel_new();
- }
- }
-
- cc->id = id;
- g_hash_table_insert(cancel_active, (void *)id, cc);
-
- d(printf("registering thread %d for cancellation\n", id));
-
- CAMEL_ACTIVE_UNLOCK();
-
- camel_cancel_ref(cc);
-}
-
-/* remove a thread from being able to be cancelled */
-void camel_cancel_unregister(CamelCancel *cc)
-{
- CAMEL_ACTIVE_LOCK();
-
- if (cancel_active == NULL)
- cancel_active = g_hash_table_new(NULL, NULL);
-
- if (cc == NULL) {
- 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");
- }
- }
-
- if (cc)
- g_hash_table_remove(cancel_active, (void *)cc->id);
-
- CAMEL_ACTIVE_UNLOCK();
-
- d({if (cc) printf("unregistering thread %d for cancellation\n", cc->id)});
-
- if (cc)
- camel_cancel_unref(cc);
-}
-
-/* test for cancellation */
-gboolean camel_cancel_check(CamelCancel *cc)
-{
- CamelCancelMsg *msg;
-
- d(printf("checking for cancel in thread %d\n", pthread_self()));
-
- if (cc == NULL) {
- if (cancel_active) {
- CAMEL_ACTIVE_LOCK();
- cc = g_hash_table_lookup(cancel_active, (void *)pthread_self());
- CAMEL_ACTIVE_UNLOCK();
- }
- if (cc == NULL)
- return FALSE;
- }
-
- if (cc->blocked > 0) {
- d(printf("ahah! cancellation is blocked\n"));
- return FALSE;
- }
-
- if (cc->flags & CAMEL_CANCEL_CANCELLED) {
- d(printf("previously cancelled\n"));
- return TRUE;
- }
-
- msg = (CamelCancelMsg *)e_msgport_get(cc->cancel_port);
- if (msg) {
- d(printf("Got cancellation message\n"));
- CAMEL_CANCEL_LOCK(cc);
- cc->flags |= CAMEL_CANCEL_CANCELLED;
- CAMEL_CANCEL_UNLOCK(cc);
- return TRUE;
- }
- return FALSE;
-}
-
-/* get the fd for cancellation waiting */
-int camel_cancel_fd(CamelCancel *cc)
-{
- if (cc == NULL) {
- if (cancel_active) {
- CAMEL_ACTIVE_LOCK();
- cc = g_hash_table_lookup(cancel_active, (void *)pthread_self());
- CAMEL_ACTIVE_UNLOCK();
- }
- if (cc == NULL)
- return -1;
- }
- if (cc->blocked)
- return -1;
-
- return cc->cancel_fd;
-}
-
diff --git a/camel/camel-session.h b/camel/camel-session.h
index d740830d7e..c530c6ffe6 100644
--- a/camel/camel-session.h
+++ b/camel/camel-session.h
@@ -140,24 +140,6 @@ guint camel_session_register_timeout (CamelSession *session,
gboolean camel_session_remove_timeout (CamelSession *session,
guint handle);
-
-/* cancellation helper stuff, not yet finalised */
-typedef struct _CamelCancel CamelCancel;
-/* main thread functions */
-CamelCancel *camel_cancel_new(void);
-void camel_cancel_ref(CamelCancel *cc);
-void camel_cancel_unref(CamelCancel *cc);
-void camel_cancel_reset(CamelCancel *cc);
-void camel_cancel_cancel(CamelCancel *cc);
-/* subthread functions */
-void camel_cancel_register(CamelCancel *cc);
-void camel_cancel_unregister(CamelCancel *cc);
-/* called internally by camel, for the current thread */
-void camel_cancel_block(CamelCancel *cc);
-void camel_cancel_unblock(CamelCancel *cc);
-gboolean camel_cancel_check(CamelCancel *cc);
-int camel_cancel_fd(CamelCancel *cc);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c
index 1e2a6bdf55..d19000b37e 100644
--- a/camel/camel-stream-fs.c
+++ b/camel/camel-stream-fs.c
@@ -33,7 +33,7 @@
#include <errno.h>
#include <string.h>
-#include "camel-session.h" /* for camel_cancel_* */
+#include "camel-operation.h"
static CamelSeekableStreamClass *parent_class = NULL;
@@ -214,7 +214,7 @@ stream_read (CamelStream *stream, char *buffer, size_t n)
ssize_t nread;
int cancel_fd;
- if (camel_cancel_check(NULL)) {
+ if (camel_operation_cancel_check(NULL)) {
errno = EINTR;
return -1;
}
@@ -222,7 +222,7 @@ stream_read (CamelStream *stream, char *buffer, size_t n)
if (seekable->bound_end != CAMEL_STREAM_UNBOUND)
n = MIN (seekable->bound_end - seekable->position, n);
- cancel_fd = camel_cancel_fd(NULL);
+ cancel_fd = camel_operation_cancel_fd(NULL);
if (cancel_fd == -1) {
do {
nread = read (stream_fs->fd, buffer, n);
@@ -263,7 +263,7 @@ stream_write (CamelStream *stream, const char *buffer, size_t n)
ssize_t v, written = 0;
int cancel_fd;
- if (camel_cancel_check(NULL)) {
+ if (camel_operation_cancel_check(NULL)) {
errno = EINTR;
return -1;
}
@@ -271,7 +271,7 @@ stream_write (CamelStream *stream, const char *buffer, size_t n)
if (seekable->bound_end != CAMEL_STREAM_UNBOUND)
n = MIN (seekable->bound_end - seekable->position, n);
- cancel_fd = camel_cancel_fd(NULL);
+ cancel_fd = camel_operation_cancel_fd(NULL);
if (cancel_fd == -1) {
do {
v = write (stream_fs->fd, buffer+written, n-written);
diff --git a/camel/providers/local/camel-mbox-summary.c b/camel/providers/local/camel-mbox-summary.c
index ab42e10df7..b8219b4c78 100644
--- a/camel/providers/local/camel-mbox-summary.c
+++ b/camel/providers/local/camel-mbox-summary.c
@@ -21,7 +21,8 @@
*/
#include "camel-mbox-summary.h"
-#include <camel/camel-mime-message.h>
+#include "camel/camel-mime-message.h"
+#include "camel/camel-operation.h"
#include <sys/stat.h>
#include <sys/uio.h>
@@ -230,18 +231,26 @@ summary_rebuild(CamelMboxSummary *mbs, off_t offset, CamelException *ex)
CamelMimeParser *mp;
int fd;
int ok = 0;
+ struct stat st;
+ off_t size = 0;
/* FIXME: If there is a failure, it shouldn't clear the summary and restart,
it should try and merge the summary info's. This is a bit tricky. */
+ camel_operation_start(NULL, _("Summarising folder"));
+
fd = open(cls->folder_path, O_RDONLY);
if (fd == -1) {
printf("%s failed to open: %s", cls->folder_path, strerror(errno));
camel_exception_setv(ex, 1, _("Could not open folder: %s: summarising from position %ld: %s"),
cls->folder_path, offset, strerror(errno));
+ camel_operation_end(NULL);
return -1;
}
+ if (fstat(fd, &st) == 0)
+ size = st.st_size;
+
mp = camel_mime_parser_new();
camel_mime_parser_init_with_fd(mp, fd);
camel_mime_parser_scan_from(mp, TRUE);
@@ -262,12 +271,16 @@ summary_rebuild(CamelMboxSummary *mbs, off_t offset, CamelException *ex)
d(printf("mime parser state ran out? state is %d\n", camel_mime_parser_state(mp)));
camel_object_unref(CAMEL_OBJECT(mp));
/* end of file - no content? no error either */
+ camel_operation_end(NULL);
return 0;
}
}
while (camel_mime_parser_step(mp, NULL, NULL) == HSCAN_FROM) {
CamelMessageInfo *info;
+ int pc = (camel_mime_parser_tell(mp)+1) * 100/size;
+
+ camel_operation_progress(NULL, pc);
info = camel_folder_summary_add_from_parser(s, mp);
if (info == NULL) {
@@ -284,8 +297,6 @@ summary_rebuild(CamelMboxSummary *mbs, off_t offset, CamelException *ex)
/* update the file size/mtime in the summary */
if (ok != -1) {
- struct stat st;
-
if (stat(cls->folder_path, &st) == 0) {
camel_folder_summary_touch(s);
mbs->folder_size = st.st_size;
@@ -293,6 +304,8 @@ summary_rebuild(CamelMboxSummary *mbs, off_t offset, CamelException *ex)
}
}
+ camel_operation_end(NULL);
+
return ok;
}
@@ -477,11 +490,14 @@ mbox_summary_sync_full(CamelLocalSummary *cls, gboolean expunge, CamelFolderChan
d(printf("performing full summary/sync\n"));
+ camel_operation_start(NULL, _("Synchronising folder"));
+
fd = open(cls->folder_path, O_RDONLY);
if (fd == -1) {
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
_("Could not open folder to summarise: %s: %s"),
cls->folder_path, strerror(errno));
+ camel_operation_end(NULL);
return -1;
}
@@ -502,6 +518,10 @@ mbox_summary_sync_full(CamelLocalSummary *cls, gboolean expunge, CamelFolderChan
count = camel_folder_summary_count(s);
for (i = 0; i < count; i++) {
+ int pc = (i+1)*100/count;
+
+ camel_operation_progress(NULL, pc);
+
info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
g_assert(info);
@@ -630,7 +650,8 @@ mbox_summary_sync_full(CamelLocalSummary *cls, gboolean expunge, CamelFolderChan
tmpname = NULL;
camel_object_unref((CamelObject *)mp);
-
+ camel_operation_end(NULL);
+
return 0;
error:
if (fd != -1)
@@ -648,6 +669,8 @@ mbox_summary_sync_full(CamelLocalSummary *cls, gboolean expunge, CamelFolderChan
if (info)
camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
+ camel_operation_end(NULL);
+
return -1;
}
@@ -668,11 +691,15 @@ mbox_summary_sync_quick(CamelLocalSummary *cls, gboolean expunge, CamelFolderCha
d(printf("Performing quick summary sync\n"));
+ camel_operation_start(NULL, _("Synchronising folder"));
+
fd = open(cls->folder_path, O_RDWR);
if (fd == -1) {
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
_("Could not open folder to summarise: %s: %s"),
cls->folder_path, strerror(errno));
+
+ camel_operation_end(NULL);
return -1;
}
@@ -684,6 +711,9 @@ mbox_summary_sync_quick(CamelLocalSummary *cls, gboolean expunge, CamelFolderCha
count = camel_folder_summary_count(s);
for (i = 0; i < count; i++) {
int xevoffset;
+ int pc = (i+1)*100/count;
+
+ camel_operation_progress(NULL, pc);
info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
@@ -769,6 +799,8 @@ mbox_summary_sync_quick(CamelLocalSummary *cls, gboolean expunge, CamelFolderCha
}
camel_object_unref((CamelObject *)mp);
+
+ camel_operation_end(NULL);
return 0;
error:
@@ -779,6 +811,8 @@ mbox_summary_sync_quick(CamelLocalSummary *cls, gboolean expunge, CamelFolderCha
if (info)
camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
+ camel_operation_end(NULL);
+
return -1;
}
diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c
index cf55a95661..810faed846 100644
--- a/camel/providers/pop3/camel-pop3-folder.c
+++ b/camel/providers/pop3/camel-pop3-folder.c
@@ -29,6 +29,7 @@
#include "camel-stream-mem.h"
#include "camel-stream-filter.h"
#include "camel-mime-message.h"
+#include "camel-operation.h"
#include <stdlib.h>
#include <string.h>
@@ -141,9 +142,13 @@ pop3_refresh_info (CamelFolder *folder, CamelException *ex)
CamelPop3Folder *pop3_folder = (CamelPop3Folder *) folder;
CamelPop3Store *pop3_store = CAMEL_POP3_STORE (folder->parent_store);
+ camel_operation_start(NULL, _("Retrieving POP summary"));
+
status = camel_pop3_command (pop3_store, &data, ex, "STAT");
- if (status != CAMEL_POP3_OK)
+ if (status != CAMEL_POP3_OK) {
+ camel_operation_end(NULL);
return;
+ }
count = atoi (data);
g_free (data);
@@ -155,6 +160,7 @@ pop3_refresh_info (CamelFolder *folder, CamelException *ex)
pop3_store->supports_uidl = FALSE;
break;
case CAMEL_POP3_FAIL:
+ camel_operation_end(NULL);
return;
}
}
@@ -167,8 +173,10 @@ pop3_refresh_info (CamelFolder *folder, CamelException *ex)
for (i = 0; i < count; i++)
uids->pdata[i] = g_strdup_printf ("%d", i + 1);
+ camel_operation_end(NULL);
} else {
- data = camel_pop3_command_get_additional_data (pop3_store, ex);
+ data = camel_pop3_command_get_additional_data (pop3_store, 0, ex);
+ camel_operation_end(NULL);
if (camel_exception_is_set (ex))
return;
@@ -263,7 +271,7 @@ uid_to_number (CamelPop3Folder *pop3_folder, const char *uid)
static CamelMimeMessage *
pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
{
- int status, num;
+ int status, num, total;
char *result, *body;
CamelStream *msgstream;
CamelMimeMessage *msg;
@@ -275,19 +283,28 @@ pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
return NULL;
}
+ camel_operation_start(NULL, _("Retrieving POP message %d"), num);
+
status = camel_pop3_command (CAMEL_POP3_STORE (folder->parent_store),
&result, ex, "RETR %d", num);
- if (status != CAMEL_POP3_OK)
+ if (status != CAMEL_POP3_OK) {
+ camel_operation_end(NULL);
return NULL;
- g_free (result);
+ }
+
+ /* this should be "nnn octets" ? */
+ if (sscanf(result, "%d", &total) != 1)
+ total = 0;
- body = camel_pop3_command_get_additional_data (CAMEL_POP3_STORE (folder->parent_store), ex);
+ g_free (result);
+ body = camel_pop3_command_get_additional_data (CAMEL_POP3_STORE (folder->parent_store), total, ex);
if (!body) {
CamelService *service = CAMEL_SERVICE (folder->parent_store);
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
_("Could not retrieve message from POP "
"server %s: %s"), service->url->host,
camel_exception_get_description (ex));
+ camel_operation_end(NULL);
return NULL;
}
@@ -300,6 +317,8 @@ pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
camel_object_unref (CAMEL_OBJECT (msgstream));
+ camel_operation_end(NULL);
+
return msg;
}
diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c
index aefabebfa4..f0338a8584 100644
--- a/camel/providers/pop3/camel-pop3-store.c
+++ b/camel/providers/pop3/camel-pop3-store.c
@@ -35,6 +35,8 @@
#include <unistd.h>
#include <errno.h>
+#include "camel-operation.h"
+
#ifdef HAVE_KRB4
/* Specified nowhere */
#define KPOP_PORT 1109
@@ -250,7 +252,7 @@ connect_to_server (CamelService *service, /*gboolean real, */CamelException *ex)
char *p;
int len;
- buf = camel_pop3_command_get_additional_data (store, ex);
+ buf = camel_pop3_command_get_additional_data (store, 0, ex);
if (camel_exception_is_set (ex))
return FALSE;
@@ -632,6 +634,7 @@ pop3_get_response (CamelPop3Store *store, char **ret, CamelException *ex)
* camel_pop3_command_get_additional_data: get "additional data" from
* a POP3 command.
* @store: the POP3 store
+ * @total: Total bytes expected (for progress reporting), use 0 for 'unknown'.
*
* This command gets the additional data returned by "multi-line" POP
* commands, such as LIST, RETR, TOP, and UIDL. This command _must_
@@ -643,11 +646,12 @@ pop3_get_response (CamelPop3Store *store, char **ret, CamelException *ex)
* Return value: the data, which the caller must free.
**/
char *
-camel_pop3_command_get_additional_data (CamelPop3Store *store, CamelException *ex)
+camel_pop3_command_get_additional_data (CamelPop3Store *store, int total, CamelException *ex)
{
GPtrArray *data;
char *buf, *p;
int i, len = 0, status = CAMEL_POP3_OK;
+ int pc = 0;
data = g_ptr_array_new ();
while (1) {
@@ -661,6 +665,13 @@ camel_pop3_command_get_additional_data (CamelPop3Store *store, CamelException *e
g_ptr_array_add (data, buf);
len += strlen (buf) + 1;
+
+ if (total) {
+ pc = (len+1) * 100 / total;
+ camel_operation_progress(NULL, pc);
+ } else {
+ camel_operation_progress_count(NULL, len);
+ }
}
if (buf)
diff --git a/camel/providers/pop3/camel-pop3-store.h b/camel/providers/pop3/camel-pop3-store.h
index 65bf1cbdba..078a317a14 100644
--- a/camel/providers/pop3/camel-pop3-store.h
+++ b/camel/providers/pop3/camel-pop3-store.h
@@ -65,8 +65,7 @@ void camel_pop3_store_expunge (CamelPop3Store *store, CamelException *ex);
/* support functions */
enum { CAMEL_POP3_OK, CAMEL_POP3_ERR, CAMEL_POP3_FAIL };
int camel_pop3_command (CamelPop3Store *store, char **ret, CamelException *ex, char *fmt, ...);
-char *camel_pop3_command_get_additional_data (CamelPop3Store *store,
- CamelException *ex);
+char *camel_pop3_command_get_additional_data (CamelPop3Store *store, int total, CamelException *ex);
/* Standard Camel function */
CamelType camel_pop3_store_get_type (void);