1 Return-Path: <amdragon@mit.edu>
\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 15DBA431FBD
\r
6 for <notmuch@notmuchmail.org>; Thu, 10 Apr 2014 06:24:53 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5
\r
12 tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled
\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 keNYugqGW-o2 for <notmuch@notmuchmail.org>;
\r
16 Thu, 10 Apr 2014 06:24:44 -0700 (PDT)
\r
17 Received: from dmz-mailsec-scanner-7.mit.edu (dmz-mailsec-scanner-7.mit.edu
\r
19 (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
\r
20 (No client certificate requested)
\r
21 by olra.theworths.org (Postfix) with ESMTPS id 9854D431FBC
\r
22 for <notmuch@notmuchmail.org>; Thu, 10 Apr 2014 06:24:44 -0700 (PDT)
\r
23 X-AuditID: 12074424-f79e26d000000c70-8b-53469b9a40a1
\r
24 Received: from mailhub-auth-3.mit.edu ( [18.9.21.43])
\r
25 (using TLS with cipher AES256-SHA (256/256 bits))
\r
26 (Client did not present a certificate)
\r
27 by dmz-mailsec-scanner-7.mit.edu (Symantec Messaging Gateway) with SMTP
\r
28 id A8.8B.03184.A9B96435; Thu, 10 Apr 2014 09:24:42 -0400 (EDT)
\r
29 Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11])
\r
30 by mailhub-auth-3.mit.edu (8.13.8/8.9.2) with ESMTP id s3ADOfiS028048;
\r
31 Thu, 10 Apr 2014 09:24:42 -0400
\r
32 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])
\r
33 (authenticated bits=0)
\r
34 (User authenticated as amdragon@ATHENA.MIT.EDU)
\r
35 by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id s3ADOcn9015845
\r
36 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT);
\r
37 Thu, 10 Apr 2014 09:24:40 -0400
\r
38 Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.80)
\r
39 (envelope-from <amdragon@mit.edu>)
\r
40 id 1WYEy6-0003DR-Kb; Thu, 10 Apr 2014 09:24:38 -0400
\r
41 From: Austin Clements <amdragon@MIT.EDU>
\r
42 To: David Bremner <david@tethera.net>, notmuch@notmuchmail.org
\r
43 Subject: Re: [Patch v7 4/6] restore: transparently support gzipped input
\r
44 In-Reply-To: <1396712636-10640-5-git-send-email-david@tethera.net>
\r
45 References: <1396712636-10640-1-git-send-email-david@tethera.net>
\r
46 <1396712636-10640-5-git-send-email-david@tethera.net>
\r
47 User-Agent: Notmuch/0.17+167~g3863755 (http://notmuchmail.org) Emacs/23.4.1
\r
49 Date: Thu, 10 Apr 2014 09:24:38 -0400
\r
50 Message-ID: <8761mhxqp5.fsf@awakening.csail.mit.edu>
\r
52 Content-Type: text/plain; charset=us-ascii
\r
53 X-Brightmail-Tracker:
\r
54 H4sIAAAAAAAAA+NgFrrHIsWRmVeSWpSXmKPExsUixCmqrTtrtluwwd+tphY3WrsZLa7fnMns
\r
55 wOTxbNUtZo8th94zBzBFcdmkpOZklqUW6dslcGXcmLCAqeCWScW9k8uZGxjvqXcxcnJICJhI
\r
56 LN54lh3CFpO4cG89WxcjF4eQwGwmiUVNc1hBEkICGxkl+icUQiROM0lMWryIHcJZwiix5PwV
\r
57 sCo2AQ2JbfuXM4LYIgJ2Ej0XzgMVcXAIC3hIzH7qBmJyCjhJfFigAmIKCZRLvLmrCVIsKhAv
\r
58 0doP0cgioCqxfvZMsHt4gW47tf81E4QtKHFy5hMWEJtZQEvixr+XTBMYBWYhSc1CklrAyLSK
\r
59 UTYlt0o3NzEzpzg1Wbc4OTEvL7VI11wvN7NELzWldBMjKBjZXVR2MDYfUjrEKMDBqMTDe3CZ
\r
60 a7AQa2JZcWXuIUZJDiYlUV61SW7BQnxJ+SmVGYnFGfFFpTmpxYcYJTiYlUR4N04FyvGmJFZW
\r
61 pRblw6SkOViUxHnfWlsFCwmkJ5akZqemFqQWwWRlODiUJHiXzAJqFCxKTU+tSMvMKUFIM3Fw
\r
62 ggznARq+CKSGt7ggMbc4Mx0if4pRUUqc1wwkIQCSyCjNg+uFJYtXjOJArwjz7gCp4gEmGrju
\r
63 V0CDmYAGp9q5gAwuSURISTUw7t50hoOjQFGiXlmwuHZLsZSAr7SgQkuZ/VrPTfUr3/h0bXnY
\r
64 ZtZYUPd52oolMVpX5Tas9+jnE4tVDLrJJf41rHWN4sk3t9yzFI66XBGImFv6dfuWnzff9V1Y
\r
65 uFHyp1TBCUaLlrq86mB3zllrq6afOma1MNti3s6yu/uzN7zosAmb+Gif0NMKJZbijERDLeai
\r
67 X-BeenThere: notmuch@notmuchmail.org
\r
68 X-Mailman-Version: 2.1.13
\r
70 List-Id: "Use and development of the notmuch mail system."
\r
71 <notmuch.notmuchmail.org>
\r
72 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
73 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
74 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
75 List-Post: <mailto:notmuch@notmuchmail.org>
\r
76 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
77 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
78 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
79 X-List-Received-Date: Thu, 10 Apr 2014 13:24:53 -0000
\r
81 On Sat, 05 Apr 2014, David Bremner <david@tethera.net> wrote:
\r
82 > We rely completely on zlib to do the right thing in detecting gzipped
\r
83 > input. Since our dump format is chosen to be 7 bit ascii, this should
\r
86 > doc/man1/notmuch-restore.rst | 8 ++++
\r
87 > notmuch-restore.c | 93 +++++++++++++++++++++++++++++++++-----------
\r
88 > test/T240-dump-restore.sh | 14 +++++++
\r
89 > 3 files changed, 92 insertions(+), 23 deletions(-)
\r
91 > diff --git a/doc/man1/notmuch-restore.rst b/doc/man1/notmuch-restore.rst
\r
92 > index d6cf19a..936b138 100644
\r
93 > --- a/doc/man1/notmuch-restore.rst
\r
94 > +++ b/doc/man1/notmuch-restore.rst
\r
95 > @@ -50,6 +50,14 @@ Supported options for **restore** include
\r
96 > format, this heuristic, based the fact that batch-tag format
\r
97 > contains no parentheses, should be accurate.
\r
102 > +\ **notmuch restore** will detect if the input is compressed in
\r
103 > +**gzip(1)** format and automatically decompress it while reading. This
\r
104 > +detection does not depend on file naming and in particular works for
\r
110 > diff --git a/notmuch-restore.c b/notmuch-restore.c
\r
111 > index c54d513..7abee0a 100644
\r
112 > --- a/notmuch-restore.c
\r
113 > +++ b/notmuch-restore.c
\r
114 > @@ -22,6 +22,7 @@
\r
115 > #include "hex-escape.h"
\r
116 > #include "tag-util.h"
\r
117 > #include "string-util.h"
\r
118 > +#include "zlib-extra.h"
\r
120 > static regex_t regex;
\r
122 > @@ -128,10 +129,10 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
\r
123 > tag_op_list_t *tag_ops;
\r
125 > char *input_file_name = NULL;
\r
126 > - FILE *input = stdin;
\r
127 > + const char *name_for_error = NULL;
\r
128 > + gzFile input = NULL;
\r
129 > char *line = NULL;
\r
130 > void *line_ctx = NULL;
\r
131 > - size_t line_size;
\r
132 > ssize_t line_len;
\r
135 > @@ -157,39 +158,69 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
\r
138 > opt_index = parse_arguments (argc, argv, options, 1);
\r
139 > - if (opt_index < 0)
\r
140 > - return EXIT_FAILURE;
\r
141 > + if (opt_index < 0) {
\r
142 > + ret = EXIT_FAILURE;
\r
146 > + name_for_error = input_file_name ? input_file_name : "stdin";
\r
148 > if (! accumulate)
\r
149 > flags |= TAG_FLAG_REMOVE_ALL;
\r
151 > - if (input_file_name) {
\r
152 > - input = fopen (input_file_name, "r");
\r
153 > - if (input == NULL) {
\r
154 > - fprintf (stderr, "Error opening %s for reading: %s\n",
\r
155 > - input_file_name, strerror (errno));
\r
156 > - return EXIT_FAILURE;
\r
158 > + if (input_file_name)
\r
159 > + input = gzopen (input_file_name, "r");
\r
161 > + int infd = dup (STDIN_FILENO);
\r
162 > + if (infd < 0) {
\r
163 > + fprintf (stderr, "Error duping stdin: %s\n",
\r
164 > + strerror (errno));
\r
165 > + ret = EXIT_FAILURE;
\r
168 > + input = gzdopen (infd, "r");
\r
173 > + if (input == NULL) {
\r
174 > + fprintf (stderr, "Error opening %s for (gzip) reading: %s\n",
\r
175 > + name_for_error, strerror (errno));
\r
176 > + ret = EXIT_FAILURE;
\r
180 > if (opt_index < argc) {
\r
181 > fprintf (stderr, "Unused positional parameter: %s\n", argv[opt_index]);
\r
182 > - return EXIT_FAILURE;
\r
183 > + ret = EXIT_FAILURE;
\r
187 > tag_ops = tag_op_list_create (config);
\r
188 > if (tag_ops == NULL) {
\r
189 > fprintf (stderr, "Out of memory.\n");
\r
190 > - return EXIT_FAILURE;
\r
191 > + ret = EXIT_FAILURE;
\r
196 > - line_len = getline (&line, &line_size, input);
\r
197 > + util_status_t status;
\r
199 > + status = gz_getline (line_ctx, &line, &line_len, input);
\r
201 > /* empty input file not considered an error */
\r
202 > - if (line_len < 0)
\r
203 > - return EXIT_SUCCESS;
\r
204 > + if (status == UTIL_EOF) {
\r
205 > + ret = EXIT_SUCCESS;
\r
210 > + fprintf (stderr, "Error reading (gzipped) input: %s\n",
\r
211 > + gz_error_string(status, input));
\r
212 > + ret = EXIT_FAILURE;
\r
215 > } while ((line_len == 0) ||
\r
216 > (line[0] == '#') ||
\r
217 > /* the cast is safe because we checked about for line_len < 0 */
\r
218 > @@ -254,21 +285,37 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
\r
222 > - } while ((line_len = getline (&line, &line_size, input)) != -1);
\r
223 > + } while (! (ret = gz_getline (line_ctx, &line, &line_len, input)));
\r
226 > - if (line_ctx != NULL)
\r
227 > - talloc_free (line_ctx);
\r
228 > + /* EOF is normal loop termination condition, UTIL_SUCCESS is
\r
229 > + * impossible here */
\r
230 > + if (ret == UTIL_EOF) {
\r
231 > + ret = UTIL_SUCCESS;
\r
233 > + fprintf (stderr, "Error reading (gzipped) input: %s\n",
\r
234 > + gz_error_string (ret, input));
\r
236 ret = EXIT_FAILURE; here?
\r
240 > + /* currently this should not be after DONE: since we don't
\r
241 > + * know if the xregcomp was reached
\r
244 > if (input_format == DUMP_FORMAT_SUP)
\r
245 > regfree (®ex);
\r
250 > + if (line_ctx != NULL)
\r
251 > + talloc_free (line_ctx);
\r
253 > - notmuch_database_destroy (notmuch);
\r
255 > + notmuch_database_destroy (notmuch);
\r
257 > - if (input != stdin)
\r
258 > - fclose (input);
\r
259 > + if (input && gzclose_r (input)) {
\r
260 > + fprintf (stderr, "Error closing %s: %s\n",
\r
261 > + name_for_error, gzerror (input, NULL));
\r
262 > + ret = EXIT_FAILURE;
\r
265 > return ret ? EXIT_FAILURE : EXIT_SUCCESS;
\r
267 > diff --git a/test/T240-dump-restore.sh b/test/T240-dump-restore.sh
\r
268 > index b6d8602..efe463e 100755
\r
269 > --- a/test/T240-dump-restore.sh
\r
270 > +++ b/test/T240-dump-restore.sh
\r
271 > @@ -80,6 +80,20 @@ notmuch dump --gzip --output=dump-gzip-outfile.gz
\r
272 > gunzip dump-gzip-outfile.gz
\r
273 > test_expect_equal_file dump.expected dump-gzip-outfile
\r
275 > +test_begin_subtest "restoring gzipped stdin"
\r
276 > +notmuch dump --gzip --output=backup.gz
\r
277 > +notmuch tag +new_tag '*'
\r
278 > +notmuch restore < backup.gz
\r
279 > +notmuch dump --output=dump.actual
\r
280 > +test_expect_equal_file dump.expected dump.actual
\r
282 > +test_begin_subtest "restoring gzipped file"
\r
283 > +notmuch dump --gzip --output=backup.gz
\r
284 > +notmuch tag +new_tag '*'
\r
285 > +notmuch restore --input=backup.gz
\r
286 > +notmuch dump --output=dump.actual
\r
287 > +test_expect_equal_file dump.expected dump.actual
\r
289 > # Note, we assume all messages from cworth have a message-id
\r
290 > # containing cworth.org
\r
295 > _______________________________________________
\r
296 > notmuch mailing list
\r
297 > notmuch@notmuchmail.org
\r
298 > http://notmuchmail.org/mailman/listinfo/notmuch
\r