[balsa] Add COMPRESS=DEFLATE IMAP extension support.
- From: Pawel Salek <pawels src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [balsa] Add COMPRESS=DEFLATE IMAP extension support.
- Date: Sun, 3 Jan 2010 20:09:15 +0000 (UTC)
commit 49ce71edbc0cd63d092d5262d75e5057c50c9519
Author: Pawel Salek <pawsa damage localdomain>
Date: Sun Jan 3 21:08:28 2010 +0100
Add COMPRESS=DEFLATE IMAP extension support.
* libbalsa/imap-server.c: enable compression by default.
* libbalsa/imap/Makefile.am: add imap_compress.[hc]
* libbalsa/imap/imap-commands.c: imap_cmd_exec returns ImapResponse.
* libbalsa/imap/imap-handle.c: add COMPRESS=DEFLATE capability
* libbalsa/imap/imap_compress.[ch]: support the extension.
* libbalsa/imap/imap_tst.c: allow compression testing.
* configure.in: zlib.h is unconditionally required.
ChangeLog | 9 ++
configure.in | 1 +
libbalsa/imap-server.c | 20 +++++
libbalsa/imap/Makefile.am | 2 +
libbalsa/imap/imap-commands.c | 4 +-
libbalsa/imap/imap-handle.c | 37 +++++++--
libbalsa/imap/imap-handle.h | 11 ++-
libbalsa/imap/imap_compress.c | 184 +++++++++++++++++++++++++++++++++++++++++
libbalsa/imap/imap_compress.h | 40 +++++++++
libbalsa/imap/imap_private.h | 11 ++-
libbalsa/imap/imap_tst.c | 47 +++++++++--
11 files changed, 342 insertions(+), 24 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index cac92a0..b69322b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2010-01-03 Pawel Salek
+
+ * libbalsa/imap-server.c: enable compression by default.
+ * libbalsa/imap/Makefile.am: add imap_compress.[hc]
+ * libbalsa/imap/imap-commands.c: imap_cmd_exec returns ImapResponse.
+ * libbalsa/imap/imap-handle.c: add COMPRESS=DEFLATE capability
+ * libbalsa/imap/imap_compress.[ch]: support the extension.
+ * libbalsa/imap/imap_tst.c: allow compression testing.
+
2010-01-02 Peter Bloomfield
* src/balsa-mime-widget-text.c (balsa_mime_widget_new_text),
diff --git a/configure.in b/configure.in
index 8789b61..032d875 100644
--- a/configure.in
+++ b/configure.in
@@ -862,6 +862,7 @@ AC_STDC_HEADERS
AC_DEFINE([_XOPEN_SOURCE],[500],[We strive for XOPEN compliance])
AC_CHECK_DECLS([localtime_r, gmtime_r, ctime_r], [], [], [[#include <time.h>]])
AC_CHECK_FUNCS([localtime_r gmtime_r ctime_r])
+AC_CHECK_HEADER([zlib.h],,AC_MSG_ERROR([zlib library required]))
# more warnings.
#
diff --git a/libbalsa/imap-server.c b/libbalsa/imap-server.c
index d43b954..77b303e 100644
--- a/libbalsa/imap-server.c
+++ b/libbalsa/imap-server.c
@@ -1,4 +1,23 @@
/* -*-mode:c; c-basic-offset:4; -*- */
+/* Balsa E-Mail Client
+ * Copyright (C) 1997-2010 Stuart Parmenter and others,
+ * See the file AUTHORS for a list.
+ *
+ * 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, 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.
+ */
/*
LibBalsaImapServer is a class for managing connections to one IMAP
server. Idle connections are disconnected after a timeout, or when
@@ -353,6 +372,7 @@ lb_imap_server_info_new(LibBalsaServer *server)
#else
imap_handle_set_option(handle, IMAP_OPT_BINARY, TRUE);
#endif
+ imap_handle_set_option(handle, IMAP_OPT_COMPRESS, TRUE);
imap_handle_set_option(handle, IMAP_OPT_IDLE,
LIBBALSA_IMAP_SERVER(server)->use_idle);
return info;
diff --git a/libbalsa/imap/Makefile.am b/libbalsa/imap/Makefile.am
index 6d8a3e2..cb7f780 100644
--- a/libbalsa/imap/Makefile.am
+++ b/libbalsa/imap/Makefile.am
@@ -21,6 +21,8 @@ libimap_a_SOURCES = \
imap-auth.h \
imap-commands.c \
imap-commands.h \
+ imap_compress.c \
+ imap_compress.h \
imap-handle.c \
imap-handle.h \
imap_search.c \
diff --git a/libbalsa/imap/imap-commands.c b/libbalsa/imap/imap-commands.c
index 16591f6..f8a4f52 100644
--- a/libbalsa/imap/imap-commands.c
+++ b/libbalsa/imap/imap-commands.c
@@ -1,5 +1,5 @@
/* libimap library.
- * Copyright (C) 2003-2004 Pawel Salek.
+ * Copyright (C) 2003-2010 Pawel Salek.
*
* 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
@@ -119,7 +119,7 @@ imap_check_capability(ImapMboxHandle* handle)
{
IMAP_REQUIRED_STATE3(handle, IMHS_CONNECTED, IMHS_AUTHENTICATED,
IMHS_SELECTED, FALSE);
- if (imap_cmd_exec(handle, "CAPABILITY") != 0)
+ if (imap_cmd_exec(handle, "CAPABILITY") != IMR_OK)
return FALSE;
if (!(imap_mbox_handle_can_do(handle, IMCAP_IMAP4) ||
diff --git a/libbalsa/imap/imap-handle.c b/libbalsa/imap/imap-handle.c
index 7ae8b63..3e10d7b 100644
--- a/libbalsa/imap/imap-handle.c
+++ b/libbalsa/imap/imap-handle.c
@@ -1,5 +1,5 @@
/* libimap library.
- * Copyright (C) 2003-2004 Pawel Salek.
+ * Copyright (C) 2003-2010 Pawel Salek.
*
* 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
@@ -166,6 +166,8 @@ imap_mbox_handle_init(ImapMboxHandle *handle)
handle->enable_binary = 0;
handle->enable_idle = 1;
mbox_view_init(&handle->mbox_view);
+
+ imap_compress_init(&handle->compress);
#if defined(BALSA_USE_THREADS)
pthread_mutex_init(&handle->mutex, NULL);
#endif
@@ -234,10 +236,11 @@ void
imap_handle_set_option(ImapMboxHandle *h, ImapOption opt, gboolean state)
{
switch(opt) {
- case IMAP_OPT_ANONYMOUS: h->enable_anonymous = !!state; break;
+ case IMAP_OPT_ANONYMOUS: h->enable_anonymous = !!state; break;
+ case IMAP_OPT_BINARY: h->enable_binary = !!state; break;
case IMAP_OPT_CLIENT_SORT: h->enable_client_sort = !!state; break;
- case IMAP_OPT_BINARY: h->enable_binary = !!state; break;
- case IMAP_OPT_IDLE: h->enable_idle = !!state; break;
+ case IMAP_OPT_COMPRESS: h->enable_compress = !!state; break;
+ case IMAP_OPT_IDLE: h->enable_idle = !!state; break;
default: g_warning("imap_set_option: invalid option\n");
}
}
@@ -599,6 +602,11 @@ imap_mbox_handle_connect(ImapMboxHandle* ret, const char *host, int over_ssl)
if( (rc=imap_mbox_connect(ret)) == IMAP_SUCCESS) {
rc = imap_authenticate(ret);
+ if (rc == IMAP_SUCCESS) {
+ ImapResponse response = imap_compress(ret);
+ if ( !(response == IMR_NO || response == IMR_OK))
+ rc = IMAP_PROTOCOL_ERROR;
+ }
}
HANDLE_UNLOCK(ret);
@@ -635,13 +643,23 @@ imap_mbox_handle_reconnect(ImapMboxHandle* h, gboolean *readonly)
if( (rc=imap_mbox_connect(h)) == IMAP_SUCCESS) {
if( (rc = imap_authenticate(h)) == IMAP_SUCCESS) {
+ ImapResponse response;
imap_mbox_resize_cache(h, 0); /* invalidate cache */
mbox_view_dispose(&h->mbox_view); /* FIXME: recreate it here? */
- if(h->mbox &&
- imap_mbox_select_unlocked(h, h->mbox, readonly) != IMR_OK) {
- rc = IMAP_SELECT_FAILED;
+ response = imap_compress(h);
+ if (response == IMR_OK || response == IMR_NO) {
+ rc = IMAP_SUCCESS;
+ if(h->mbox &&
+ imap_mbox_select_unlocked(h, h->mbox, readonly) != IMR_OK) {
+ rc = IMAP_SELECT_FAILED;
+ }
+
+ } else {
+ /* compression was apparently attempted but failed. */
+ rc = IMAP_PROTOCOL_ERROR;
}
+
}
}
HANDLE_UNLOCK(h);
@@ -1000,6 +1018,7 @@ imap_mbox_handle_finalize(GObject* gobject)
g_free(handle->msg_cache); handle->msg_cache = NULL;
g_array_free(handle->flag_cache, TRUE);
+ imap_compress_release(&handle->compress);
HANDLE_UNLOCK(handle);
#if defined(BALSA_USE_THREADS)
pthread_mutex_destroy(&handle->mutex);
@@ -2285,7 +2304,9 @@ ir_capability_data(ImapMboxHandle *handle)
static const char* capabilities[] = {
"IMAP4", "IMAP4rev1", "STATUS",
"AUTH=ANONYMOUS", "AUTH=CRAM-MD5", "AUTH=GSSAPI", "AUTH=PLAIN",
- "ACL", "BINARY", "CHILDREN", "ESEARCH", "IDLE", "LITERAL+",
+ "ACL", "BINARY", "CHILDREN",
+ "COMPRESS=DEFLATE",
+ "ESEARCH", "IDLE", "LITERAL+",
"LOGINDISABLED", "MULTIAPPEND", "NAMESPACE", "SASL-IR",
"SCAN", "STARTTLS",
"SORT", "THREAD=ORDEREDSUBJECT", "THREAD=REFERENCES",
diff --git a/libbalsa/imap/imap-handle.h b/libbalsa/imap/imap-handle.h
index 0e84bb0..02d94c0 100644
--- a/libbalsa/imap/imap-handle.h
+++ b/libbalsa/imap/imap-handle.h
@@ -65,19 +65,19 @@ typedef enum
IMCAP_ACL, /* RFC 2086: IMAP4 ACL extension */
IMCAP_BINARY, /* RFC 3516 */
IMCAP_CHILDREN, /* RFC 3348 */
+ IMCAP_COMPRESS_DEFLATE, /* RFC 4978 */
IMCAP_ESEARCH, /* RFC 4731 */
IMCAP_IDLE, /* RFC 2177 */
IMCAP_LITERAL, /* RFC 2088 */
IMCAP_LOGINDISABLED, /* RFC 2595 */
IMCAP_MULTIAPPEND, /* RFC 3502 */
IMCAP_NAMESPACE, /* RFC 2342: IMAP4 Namespace */
- IMCAP_SASLIR, /* imap-sasl-initial-response: SASL-IR */
+ IMCAP_SASLIR, /* RFC 4959 */
IMCAP_SCAN, /* FIXME: RFC? */
IMCAP_STARTTLS, /* RFC 2595: STARTTLS */
IMCAP_SORT, /* SORT and THREAD described at: */
- IMCAP_THREAD_ORDEREDSUBJECT,
- IMCAP_THREAD_REFERENCES,
- /* http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-13.txt */
+ IMCAP_THREAD_ORDEREDSUBJECT, /* RFC 5256 */
+ IMCAP_THREAD_REFERENCES,
IMCAP_UIDPLUS, /* RFC 4315 */
IMCAP_UNSELECT, /* RFC 3691 */
IMCAP_FETCHBODY, /* basic imap implemented correctly by
@@ -90,7 +90,8 @@ typedef enum {
IMAP_OPT_ANONYMOUS, /**< try anonymous authentication */
IMAP_OPT_CLIENT_SORT, /**< allow client-side sorting */
IMAP_OPT_BINARY, /**< enable binary=no-transfer-encoding msg transfer */
- IMAP_OPT_IDLE /**< enable IDLE */
+ IMAP_OPT_IDLE, /**< enable IDLE */
+ IMAP_OPT_COMPRESS, /**< enable COMPRESS */
} ImapOption;
typedef struct _ImapMboxHandleClass ImapMboxHandleClass;
diff --git a/libbalsa/imap/imap_compress.c b/libbalsa/imap/imap_compress.c
new file mode 100644
index 0000000..06f1723
--- /dev/null
+++ b/libbalsa/imap/imap_compress.c
@@ -0,0 +1,184 @@
+/* libimap library.
+ * Copyright (C) 2003-2010 Pawel Salek.
+ *
+ * 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, 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.
+ */
+
+#include <stdio.h>
+#include <zlib.h>
+#include "siobuf.h"
+#include "imap-handle.h"
+#include "imap_private.h"
+
+/** Arbitrary - not really a useful one. */
+static const unsigned IMAP_COMPRESS_BUFFER_SIZE = 65536;
+
+static void
+imap_compress_cb(char **dstbuf, int *dstlen,
+ const char *srcbuf, int srclen, void *arg)
+{
+ struct ImapCompressContext *icb = &((ImapMboxHandle*)arg)->compress;
+ int err;
+
+ *dstbuf = icb->out_buffer;
+
+ icb->out_stream.next_in = (Bytef*)srcbuf;
+ icb->out_stream.avail_in = srclen;
+
+ icb->out_stream.next_out = (Byte*)*dstbuf;
+ icb->out_stream.avail_out = IMAP_COMPRESS_BUFFER_SIZE;
+
+ do {
+ if (icb->out_stream.avail_out ==0){
+ printf("Buffer reallocation not implemented, aborting.\n");
+ /* FIXME1 */
+ break;
+ }
+ /* check sizes here */
+ err = deflate(&icb->out_stream, Z_SYNC_FLUSH);
+ if ( !(err == Z_OK || err == Z_STREAM_END || err == Z_BUF_ERROR) ) {
+ fprintf(stderr, "deflate error1 %d\n", err);
+ /* FIXME - break the connection here, no point in continuing. */
+ }
+ } while (icb->out_stream.avail_out == 0);
+
+ *dstlen = IMAP_COMPRESS_BUFFER_SIZE - icb->out_stream.avail_out;
+ /* printf("imap_compress_cb %d bytes to %d\n", srclen, *dstlen); */
+ icb->out_uncompressed += srclen;
+ icb->out_compressed += *dstlen;
+}
+
+static void
+imap_decompress_cb(char **dstbuf, int *dstlen,
+ const char *srcbuf, int srclen, void *arg)
+{
+ struct ImapCompressContext *icb = &((ImapMboxHandle*)arg)->compress;
+ int err;
+
+ *dstbuf = icb->in_buffer;
+
+ icb->in_stream.next_in = (Bytef*)srcbuf;
+ icb->in_stream.avail_in = srclen;
+
+ icb->in_stream.next_out = (Byte*)*dstbuf;
+ icb->in_stream.avail_out = IMAP_COMPRESS_BUFFER_SIZE;
+ err = inflate(&icb->in_stream, Z_SYNC_FLUSH);
+
+ if (!(err == Z_OK || err == Z_BUF_ERROR || err == Z_STREAM_END)) {
+ fprintf(stderr, "inflate error %d\n", err);
+ /* FIXME break the connection. */
+ }
+
+ *dstlen = IMAP_COMPRESS_BUFFER_SIZE - icb->in_stream.avail_out;
+ /* printf("imap_decompress_cb %d bytes to %d\n", srclen, *dstlen); */
+ icb->in_compressed += srclen;
+ icb->in_uncompressed += *dstlen;
+}
+
+/** Enables COMPRESS extension if available. Assumes that the handle
+ is already locked. */
+ImapResponse
+imap_compress(ImapMboxHandle *handle)
+{
+ struct ImapCompressContext *icb;
+ int err;
+
+ if (!handle->enable_compress ||
+ !imap_mbox_handle_can_do(handle, IMCAP_COMPRESS_DEFLATE))
+ return IMR_NO;
+
+ if (imap_cmd_exec(handle, "COMPRESS DEFLATE") != IMR_OK)
+ return IMR_NO;
+
+ icb = &handle->compress;
+ icb->in_buffer = malloc(IMAP_COMPRESS_BUFFER_SIZE);
+ icb->out_buffer = malloc(IMAP_COMPRESS_BUFFER_SIZE);
+
+ if (!icb->in_buffer || !icb->out_buffer)
+ return IMR_NO;
+
+ /* Compression enabled. Everything that we send and receive now must
+ go through compression/decompression routines enabled in sio. */
+
+ icb->out_stream.zalloc = Z_NULL;
+ icb->out_stream.zfree = Z_NULL;
+ icb->out_stream.opaque = (voidpf)0;
+
+ /* amazingly enough, deflateInit() won't do */
+ err = deflateInit2(&icb->out_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
+ -15, 8, Z_DEFAULT_STRATEGY);
+ if (err != Z_OK) {
+ fprintf(stderr, "deflateInit error: %d\n", err);
+ return IMR_NO;
+ }
+
+ icb->in_stream.next_in = Z_NULL;
+ icb->in_stream.avail_in = 0;
+ icb->in_stream.zalloc = Z_NULL;
+ icb->in_stream.zfree = Z_NULL;
+ icb->in_stream.opaque = (voidpf)0;
+
+ /* amazingly enough, inflateInit() won't do */
+ err = inflateInit2(&icb->in_stream, -15);
+ if (err != Z_OK) {
+ fprintf(stderr, "inflateInit error: %d\n", err);
+ return IMR_NO;
+ }
+
+ if (handle->sio) {
+ sio_set_securitycb(handle->sio, imap_compress_cb, imap_decompress_cb,
+ handle);
+ return IMR_OK;
+ } else {
+ fprintf(stderr, "SIO not set!\n");
+ return IMR_NO;
+ }
+}
+
+void
+imap_compress_init(struct ImapCompressContext *buf)
+{
+ memset(buf, 0, sizeof(buf));
+}
+
+/** releases any data that might have been allocated by compression routines. */
+
+void
+imap_compress_release(struct ImapCompressContext *buf)
+{
+
+ if (buf->in_buffer) {
+ inflateEnd(&buf->in_stream);
+ free(buf->in_buffer);
+ }
+
+ if (buf->out_buffer) {
+ deflateEnd(&buf->out_stream);
+ free(buf->out_buffer);
+ }
+ if (buf->in_uncompressed) {
+ printf("IMAP server compression %lu -> %lu sent %5.1f %% over wire\n",
+ buf->in_compressed, buf->in_uncompressed,
+ 100.0*(buf->in_compressed/(float)buf->in_uncompressed));
+ }
+ if (buf->in_uncompressed) {
+ printf("IMAP client compression %lu -> %lu sent %5.1f %% over wire\n",
+ buf->out_uncompressed, buf->out_compressed,
+ 100.0*(buf->out_compressed/(float)buf->out_uncompressed));
+ }
+}
+
+
diff --git a/libbalsa/imap/imap_compress.h b/libbalsa/imap/imap_compress.h
new file mode 100644
index 0000000..47c4256
--- /dev/null
+++ b/libbalsa/imap/imap_compress.h
@@ -0,0 +1,40 @@
+#ifndef __IMAP_COMPRESS_H__
+#define __IMAP_COMPRESS_H__ 1
+/* libimap library.
+ * Copyright (C) 2003-2010 Pawel Salek.
+ *
+ * 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, 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.
+ */
+
+#include <zlib.h>
+
+#include "imap-handle.h"
+
+struct ImapCompressContext {
+ z_stream out_stream;
+ z_stream in_stream;
+ char *in_buffer;
+ char *out_buffer;
+ unsigned long in_uncompressed, in_compressed;
+ unsigned long out_uncompressed, out_compressed;
+};
+
+ImapResponse imap_compress(ImapMboxHandle* h);
+
+void imap_compress_init(struct ImapCompressContext *buf);
+void imap_compress_release(struct ImapCompressContext *buf);
+
+#endif /* __IMAP_COMPRESS_H__ */
diff --git a/libbalsa/imap/imap_private.h b/libbalsa/imap/imap_private.h
index 2e5f66b..cb748a6 100644
--- a/libbalsa/imap/imap_private.h
+++ b/libbalsa/imap/imap_private.h
@@ -35,6 +35,7 @@
#endif
#include "imap-commands.h"
+#include "imap_compress.h"
typedef enum {
IMAP_BODY_TYPE_RFC822, /**< as fetched with RFC822 */
@@ -92,6 +93,9 @@ struct _ImapMboxHandle {
* processing of current line is finished. */
GNode *thread_root; /* deprecated! */
+ /** Compression data */
+ struct ImapCompressContext compress;
+
struct {
GList* src; /**< returned by COPY */
GList* dst; /**< returned by APPEND and COPY */
@@ -134,10 +138,11 @@ struct _ImapMboxHandle {
unsigned can_fetch_body:1; /* set for servers that always respond
* correctly to FETCH x BODY[y]
* requests. */
- unsigned enable_anonymous:1; /* try anonymous if possible */
+ unsigned enable_anonymous:1; /**< try anonymous if possible */
+ unsigned enable_binary:1; /**< enable binary extension */
unsigned enable_client_sort:1; /**< client side sorting allowed */
- unsigned enable_idle:1; /**< use IDLE - no problem with firewalls */
- unsigned enable_binary:1; /* enable binary extension */
+ unsigned enable_compress:1; /**< enable compress extension */
+ unsigned enable_idle:1; /**< use IDLE - no problem with firewalls */
/* conditional stuff at the end for the safety. */
#ifdef USE_TLS
diff --git a/libbalsa/imap/imap_tst.c b/libbalsa/imap/imap_tst.c
index e59193b..8f6767b 100644
--- a/libbalsa/imap/imap_tst.c
+++ b/libbalsa/imap/imap_tst.c
@@ -1,3 +1,21 @@
+/* libimap library.
+ * Copyright (C) 2003-2010 Pawel Salek.
+ *
+ * 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, 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.
+ */
/** @file imap_tst.c tests some IMAP capabilities. It is very useful
for stress-testing the imap part of balsa. */
@@ -26,7 +44,8 @@ struct {
gboolean over_ssl;
gboolean monitor;
gboolean anonymous;
-} TestContext = { NULL, NULL, IMAP_TLS_ENABLED, FALSE, FALSE, FALSE };
+ gboolean compress;
+} TestContext = { NULL, NULL, IMAP_TLS_ENABLED, FALSE, FALSE, FALSE, FALSE };
static void
monitor_cb(const char *buffer, int length, int direction, void *arg)
@@ -49,8 +68,8 @@ get_user(const char* method) {
printf("Login with method %s as user: %s\n", method, TestContext.user);
return g_strdup(TestContext.user);
} else {
- printf("Login with method %s as user: ", method);
- fflush(stdout);
+ fprintf(stderr, "Login with method %s as user: ", method);
+ fflush(stderr);
if(!fgets(buf, sizeof(buf), stdin))
return NULL;
@@ -151,6 +170,8 @@ get_handle(const char *host)
if(TestContext.anonymous)
imap_handle_set_option(h, IMAP_OPT_ANONYMOUS, TRUE);
+ if(TestContext.compress)
+ imap_handle_set_option(h, IMAP_OPT_COMPRESS, TRUE);
if(TestContext.monitor)
imap_handle_set_monitorcb(h, monitor_cb, NULL);
@@ -274,7 +295,7 @@ dump_mbox(const char *host, const char *mailbox,
}
if(imap_mbox_select(h, mailbox, &read_only) == IMR_OK) {
- unsigned cnt = imap_mbox_handle_get_exists(h);
+ unsigned cnt = imap_mbox_handle_get_exists(h);
unsigned i;
#define FETCH_AT_ONCE 300
for(i=0; i<cnt; i+= FETCH_AT_ONCE) {
@@ -339,6 +360,7 @@ test_mbox_dumpfile(int argc, char *argv[])
struct DumpdirState {
const char *dst_directory;
int error;
+ unsigned last_seqno;
};
static void
@@ -351,7 +373,8 @@ dumpdir_cb(unsigned seqno, const char *buf, size_t buflen, void *arg)
g_snprintf(num, sizeof(num), "%u", seqno);
fname = g_build_filename(dds->dst_directory, num, NULL);
- f = fopen(fname, "wt");
+ f = fopen(fname, seqno == dds->last_seqno ? "at" : "wt");
+ dds->last_seqno = seqno;
if(!f) {
fprintf(stderr, "Cannot open %s for writing.\n", fname);
dds->error = 1;
@@ -387,7 +410,7 @@ test_mbox_dumpdir(int argc, char *argv[])
fprintf(stderr, "%s is not a directory\n", state.dst_directory);
return 1;
}
-
+ state.last_seqno = 0;
return dump_mbox(argv[0], argv[1], dumpdir_cb, &state);
}
@@ -613,6 +636,8 @@ process_options(int argc, char *argv[])
TestContext.over_ssl = TRUE;
} else if( strcmp(argv[first_arg], "-a") == 0) {
TestContext.anonymous = TRUE;
+ } else if( strcmp(argv[first_arg], "-c") == 0) {
+ TestContext.compress = TRUE;
} else {
break; /* break the loop - non-option encountered. */
}
@@ -651,6 +676,16 @@ main(int argc, char *argv[]) {
argv[first_arg]);
for(i=0; i<sizeof(cmds)/sizeof(cmds[0]); i++)
fprintf(stderr, "%s %s\n", cmds[i].cmd, cmds[i].help);
+ fprintf(stderr, "Known options:\n"
+ "-u USER specify user\n"
+ "-p PASSWORD specify password\n"
+ "-m enable monitor\n"
+ "-T tls required\n"
+ "-t tls disabled\n"
+ "-s over ssl\n"
+ "-a anonymous\n"
+ "-c compress\n");
+
return 1;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]