1 Return-Path: <bremner@tethera.net>
\r
2 X-Original-To: notmuch@notmuchmail.org
\r
3 Delivered-To: notmuch@notmuchmail.org
\r
4 Received: from localhost (localhost [127.0.0.1])
\r
5 by olra.theworths.org (Postfix) with ESMTP id 81E6D431FB6
\r
6 for <notmuch@notmuchmail.org>; Sun, 30 Mar 2014 10:32:06 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]
\r
13 Received: from olra.theworths.org ([127.0.0.1])
\r
14 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
15 with ESMTP id ikef-XPKpE7D for <notmuch@notmuchmail.org>;
\r
16 Sun, 30 Mar 2014 10:31:59 -0700 (PDT)
\r
17 Received: from yantan.tethera.net (yantan.tethera.net [199.188.72.155])
\r
18 (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits))
\r
19 (No client certificate requested)
\r
20 by olra.theworths.org (Postfix) with ESMTPS id 44CC2431FBD
\r
21 for <notmuch@notmuchmail.org>; Sun, 30 Mar 2014 10:31:56 -0700 (PDT)
\r
22 Received: from remotemail by yantan.tethera.net with local (Exim 4.80)
\r
23 (envelope-from <bremner@tethera.net>)
\r
24 id 1WUJaM-0004Ad-J1; Sun, 30 Mar 2014 14:31:54 -0300
\r
25 Received: (nullmailer pid 29598 invoked by uid 1000); Sun, 30 Mar 2014
\r
27 From: David Bremner <david@tethera.net>
\r
28 To: notmuch@notmuchmail.org
\r
29 Subject: [Patch v4 1/3] dump: support gzipped output
\r
30 Date: Sun, 30 Mar 2014 14:31:38 -0300
\r
31 Message-Id: <1396200700-29361-2-git-send-email-david@tethera.net>
\r
32 X-Mailer: git-send-email 1.9.0
\r
33 In-Reply-To: <1396200700-29361-1-git-send-email-david@tethera.net>
\r
34 References: <1396200700-29361-1-git-send-email-david@tethera.net>
\r
35 X-BeenThere: notmuch@notmuchmail.org
\r
36 X-Mailman-Version: 2.1.13
\r
38 List-Id: "Use and development of the notmuch mail system."
\r
39 <notmuch.notmuchmail.org>
\r
40 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
41 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
42 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
43 List-Post: <mailto:notmuch@notmuchmail.org>
\r
44 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
45 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
46 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
47 X-List-Received-Date: Sun, 30 Mar 2014 17:32:06 -0000
\r
49 The main goal is to support gzipped output for future internal
\r
50 calls (e.g. from notmuch-new) to notmuch_database_dump.
\r
52 The additional dependency is not very heavy since xapian already pulls
\r
55 INSTALL | 17 ++++++++++----
\r
56 Makefile.local | 2 +-
\r
57 configure | 28 ++++++++++++++++++++---
\r
58 doc/man1/notmuch-dump.rst | 3 +++
\r
59 notmuch-client.h | 4 +++-
\r
60 notmuch-dump.c | 57 ++++++++++++++++++++++++++++++-----------------
\r
61 test/T240-dump-restore.sh | 12 ++++++++++
\r
62 7 files changed, 94 insertions(+), 29 deletions(-)
\r
64 diff --git a/INSTALL b/INSTALL
\r
65 index 690b0ef..df318fa 100644
\r
68 @@ -20,8 +20,8 @@ configure stage.
\r
72 -Notmuch depends on three libraries: Xapian, GMime 2.4 or 2.6, and
\r
73 -Talloc which are each described below:
\r
74 +Notmuch depends on four libraries: Xapian, GMime 2.4 or 2.6,
\r
75 +Talloc, and zlib which are each described below:
\r
79 @@ -60,6 +60,15 @@ Talloc which are each described below:
\r
81 Talloc is available from http://talloc.samba.org/
\r
86 + zlib is an extremely popular compression library. It is used
\r
87 + by Xapian, so if you installed that you will already have
\r
88 + zlib. You may need to install the zlib headers separately.
\r
90 + zlib is available from http://zlib.net
\r
92 Building Documentation
\r
93 ----------------------
\r
95 @@ -79,11 +88,11 @@ dependencies with a simple simple command line. For example:
\r
97 For Debian and similar:
\r
99 - sudo apt-get install libxapian-dev libgmime-2.6-dev libtalloc-dev python-sphinx
\r
100 + sudo apt-get install libxapian-dev libgmime-2.6-dev libtalloc-dev zlib1g-dev python-sphinx
\r
102 For Fedora and similar:
\r
104 - sudo yum install xapian-core-devel gmime-devel libtalloc-devel python-sphinx
\r
105 + sudo yum install xapian-core-devel gmime-devel libtalloc-devel zlib-devel python-sphinx
\r
107 On other systems, a similar command can be used, but the details of
\r
108 the package names may be different.
\r
109 diff --git a/Makefile.local b/Makefile.local
\r
110 index cb7b106..e5a20a7 100644
\r
111 --- a/Makefile.local
\r
112 +++ b/Makefile.local
\r
113 @@ -41,7 +41,7 @@ PV_FILE=bindings/python/notmuch/version.py
\r
114 # Smash together user's values with our extra values
\r
115 FINAL_CFLAGS = -DNOTMUCH_VERSION=$(VERSION) $(CPPFLAGS) $(CFLAGS) $(WARN_CFLAGS) $(extra_cflags) $(CONFIGURE_CFLAGS)
\r
116 FINAL_CXXFLAGS = $(CPPFLAGS) $(CXXFLAGS) $(WARN_CXXFLAGS) $(extra_cflags) $(extra_cxxflags) $(CONFIGURE_CXXFLAGS)
\r
117 -FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Lutil -lutil -Llib -lnotmuch $(AS_NEEDED_LDFLAGS) $(GMIME_LDFLAGS) $(TALLOC_LDFLAGS)
\r
118 +FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Lutil -lutil -Llib -lnotmuch $(AS_NEEDED_LDFLAGS) $(GMIME_LDFLAGS) $(TALLOC_LDFLAGS) $(ZLIB_LDFLAGS)
\r
119 FINAL_NOTMUCH_LINKER = CC
\r
120 ifneq ($(LINKER_RESOLVES_LIBRARY_DEPENDENCIES),1)
\r
121 FINAL_NOTMUCH_LDFLAGS += $(CONFIGURE_LDFLAGS)
\r
122 diff --git a/configure b/configure
\r
123 index 1d430b9..d685ab3 100755
\r
126 @@ -340,6 +340,18 @@ else
\r
127 errors=$((errors + 1))
\r
130 +printf "Checking for zlib development files... "
\r
132 +if pkg-config --exists zlib; then
\r
135 + zlib_cflags=$(pkg-config --cflags zlib)
\r
136 + zlib_ldflags=$(pkg-config --libs zlib)
\r
139 + errors=$((errors + 1))
\r
142 printf "Checking for talloc development files... "
\r
143 if pkg-config --exists talloc; then
\r
145 @@ -496,6 +508,11 @@ EOF
\r
146 echo " Xapian library (including development files such as headers)"
\r
147 echo " http://xapian.org/"
\r
149 + if [ $have_zlib -eq 0 ]; then
\r
150 + echo " zlib library (including development files such as headers)"
\r
151 + echo " http://zlib.net/"
\r
154 if [ $have_gmime -eq 0 ]; then
\r
155 echo " Either GMime 2.4 library" $GMIME_24_VERSION_CTR "or GMime 2.6 library" $GMIME_26_VERSION_CTR
\r
156 echo " (including development files such as headers)"
\r
157 @@ -519,11 +536,11 @@ case a simple command will install everything you need. For example:
\r
159 On Debian and similar systems:
\r
161 - sudo apt-get install libxapian-dev libgmime-2.6-dev libtalloc-dev
\r
162 + sudo apt-get install libxapian-dev libgmime-2.6-dev libtalloc-dev zlib1g-dev
\r
164 Or on Fedora and similar systems:
\r
166 - sudo yum install xapian-core-devel gmime-devel libtalloc-devel
\r
167 + sudo yum install xapian-core-devel gmime-devel libtalloc-devel zlib-devel
\r
169 On other systems, similar commands can be used, but the details of the
\r
170 package names may be different.
\r
171 @@ -844,6 +861,10 @@ XAPIAN_LDFLAGS = ${xapian_ldflags}
\r
172 GMIME_CFLAGS = ${gmime_cflags}
\r
173 GMIME_LDFLAGS = ${gmime_ldflags}
\r
175 +# Flags needed to compile and link against zlib
\r
176 +ZLIB_CFLAGS = ${zlib_cflags}
\r
177 +ZLIB_LDFLAGS = ${zlib_ldflags}
\r
179 # Flags needed to compile and link against talloc
\r
180 TALLOC_CFLAGS = ${talloc_cflags}
\r
181 TALLOC_LDFLAGS = ${talloc_ldflags}
\r
182 @@ -882,6 +903,7 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
\r
183 -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER)
\r
185 CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
\r
186 + \$(ZLIB_CFLAGS) \\
\r
187 \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\
\r
188 \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\
\r
189 -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\
\r
190 @@ -892,5 +914,5 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
\r
191 -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT) \\
\r
192 -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER)
\r
194 -CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS)
\r
195 +CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(ZLIB_LDFLAGS) \$(XAPIAN_LDFLAGS)
\r
197 diff --git a/doc/man1/notmuch-dump.rst b/doc/man1/notmuch-dump.rst
\r
198 index 17d1da5..d94cb4f 100644
\r
199 --- a/doc/man1/notmuch-dump.rst
\r
200 +++ b/doc/man1/notmuch-dump.rst
\r
201 @@ -19,6 +19,9 @@ recreated from the messages themselves. The output of notmuch dump is
\r
202 therefore the only critical thing to backup (and much more friendly to
\r
203 incremental backup than the native database files.)
\r
206 + Compress the output in a format compatible with **gzip(1)**.
\r
208 ``--format=(sup|batch-tag)``
\r
209 Notmuch restore supports two plain text dump formats, both with one
\r
210 message-id per line, followed by a list of tags.
\r
211 diff --git a/notmuch-client.h b/notmuch-client.h
\r
212 index d110648..e1efbe0 100644
\r
213 --- a/notmuch-client.h
\r
214 +++ b/notmuch-client.h
\r
215 @@ -450,7 +450,9 @@ typedef enum dump_formats {
\r
217 notmuch_database_dump (notmuch_database_t *notmuch,
\r
218 const char *output_file_name,
\r
219 - const char *query_str, dump_format_t output_format);
\r
220 + const char *query_str,
\r
221 + dump_format_t output_format,
\r
222 + notmuch_bool_t gzip_output);
\r
224 #include "command-line-arguments.h"
\r
226 diff --git a/notmuch-dump.c b/notmuch-dump.c
\r
227 index 21702d7..4875aba 100644
\r
228 --- a/notmuch-dump.c
\r
229 +++ b/notmuch-dump.c
\r
230 @@ -21,10 +21,12 @@
\r
231 #include "notmuch-client.h"
\r
232 #include "hex-escape.h"
\r
233 #include "string-util.h"
\r
238 -database_dump_file (notmuch_database_t *notmuch, FILE *output,
\r
239 - const char *query_str, int output_format)
\r
240 +database_dump_file (notmuch_database_t *notmuch, gzFile output,
\r
241 + const char *query_str, int output_format)
\r
243 notmuch_query_t *query;
\r
244 notmuch_messages_t *messages;
\r
245 @@ -69,7 +71,7 @@ database_dump_file (notmuch_database_t *notmuch, FILE *output,
\r
248 if (output_format == DUMP_FORMAT_SUP) {
\r
249 - fprintf (output, "%s (", message_id);
\r
250 + gzprintf (output, "%s (", message_id);
\r
253 for (tags = notmuch_message_get_tags (message);
\r
254 @@ -78,12 +80,12 @@ database_dump_file (notmuch_database_t *notmuch, FILE *output,
\r
255 const char *tag_str = notmuch_tags_get (tags);
\r
258 - fputs (" ", output);
\r
259 + gzputs (output, " ");
\r
263 if (output_format == DUMP_FORMAT_SUP) {
\r
264 - fputs (tag_str, output);
\r
265 + gzputs (output, tag_str);
\r
267 if (hex_encode (notmuch, tag_str,
\r
268 &buffer, &buffer_size) != HEX_SUCCESS) {
\r
269 @@ -91,12 +93,12 @@ database_dump_file (notmuch_database_t *notmuch, FILE *output,
\r
271 return EXIT_FAILURE;
\r
273 - fprintf (output, "+%s", buffer);
\r
274 + gzprintf (output, "+%s", buffer);
\r
278 if (output_format == DUMP_FORMAT_SUP) {
\r
279 - fputs (")\n", output);
\r
280 + gzputs (output, ")\n");
\r
282 if (make_boolean_term (notmuch, "id", message_id,
\r
283 &buffer, &buffer_size)) {
\r
284 @@ -104,7 +106,7 @@ database_dump_file (notmuch_database_t *notmuch, FILE *output,
\r
285 message_id, strerror (errno));
\r
286 return EXIT_FAILURE;
\r
288 - fprintf (output, " -- %s\n", buffer);
\r
289 + gzprintf (output, " -- %s\n", buffer);
\r
292 notmuch_message_destroy (message);
\r
293 @@ -121,24 +123,37 @@ database_dump_file (notmuch_database_t *notmuch, FILE *output,
\r
295 notmuch_database_dump (notmuch_database_t *notmuch,
\r
296 const char *output_file_name,
\r
297 - const char *query_str, dump_format_t output_format)
\r
298 + const char *query_str,
\r
299 + dump_format_t output_format,
\r
300 + notmuch_bool_t gzip_output)
\r
302 - FILE *output = stdout;
\r
304 + const char *mode = gzip_output ? "w9" : "wT";
\r
308 - if (output_file_name) {
\r
309 - output = fopen (output_file_name, "w");
\r
310 - if (output == NULL) {
\r
311 - fprintf (stderr, "Error opening %s for writing: %s\n",
\r
312 - output_file_name, strerror (errno));
\r
313 - return EXIT_FAILURE;
\r
315 + if (output_file_name)
\r
316 + output = gzopen (output_file_name, mode);
\r
318 + output = gzdopen (fileno (stdout), mode);
\r
320 + if (output == NULL) {
\r
321 + fprintf (stderr, "Error opening %s for (gzip) writing: %s\n",
\r
322 + output_file_name ? output_file_name : "stdout", strerror (errno));
\r
323 + return EXIT_FAILURE;
\r
326 ret = database_dump_file (notmuch, output, query_str, output_format);
\r
328 - if (output != stdout)
\r
330 + /* unlike stdio, zlib needs explicit flushing */
\r
331 + if (gzflush (output, Z_FINISH)) {
\r
332 + fprintf (stderr, "Error flushing output: %s\n",
\r
333 + gzerror (output, NULL));
\r
334 + return EXIT_FAILURE;
\r
337 + if (output_file_name)
\r
338 + gzclose_w (output);
\r
342 @@ -158,6 +173,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
\r
345 int output_format = DUMP_FORMAT_BATCH_TAG;
\r
346 + notmuch_bool_t gzip_output = 0;
\r
348 notmuch_opt_desc_t options[] = {
\r
349 { NOTMUCH_OPT_KEYWORD, &output_format, "format", 'f',
\r
350 @@ -165,6 +181,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
\r
351 { "batch-tag", DUMP_FORMAT_BATCH_TAG },
\r
353 { NOTMUCH_OPT_STRING, &output_file_name, "output", 'o', 0 },
\r
354 + { NOTMUCH_OPT_BOOLEAN, &gzip_output, "gzip", 'z', 0 },
\r
358 @@ -181,7 +198,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
\r
361 ret = notmuch_database_dump (notmuch, output_file_name, query_str,
\r
363 + output_format, gzip_output);
\r
365 notmuch_database_destroy (notmuch);
\r
367 diff --git a/test/T240-dump-restore.sh b/test/T240-dump-restore.sh
\r
368 index 0004438..d79aca8 100755
\r
369 --- a/test/T240-dump-restore.sh
\r
370 +++ b/test/T240-dump-restore.sh
\r
371 @@ -68,6 +68,18 @@ test_begin_subtest "dump --output=outfile --"
\r
372 notmuch dump --output=dump-1-arg-dash.actual --
\r
373 test_expect_equal_file dump.expected dump-1-arg-dash.actual
\r
377 +test_begin_subtest "dump --gzip"
\r
378 +notmuch dump --gzip > dump-gzip.gz
\r
379 +gunzip dump-gzip.gz
\r
380 +test_expect_equal_file dump.expected dump-gzip
\r
382 +test_begin_subtest "dump --gzip --output=outfile"
\r
383 +notmuch dump --gzip --output=dump-gzip-outfile.gz
\r
384 +gunzip dump-gzip-outfile.gz
\r
385 +test_expect_equal_file dump.expected dump-gzip-outfile
\r
387 # Note, we assume all messages from cworth have a message-id
\r
388 # containing cworth.org
\r