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 E7E82414395
\r
6 for <notmuch@notmuchmail.org>; Sat, 14 Jan 2012 17:40:48 -0800 (PST)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=-2.3 tagged_above=-999 required=5
\r
12 tests=[RCVD_IN_DNSWL_MED=-2.3] 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 jlu1ZaOmkDuZ for <notmuch@notmuchmail.org>;
\r
16 Sat, 14 Jan 2012 17:40:46 -0800 (PST)
\r
17 Received: from tempo.its.unb.ca (tempo.its.unb.ca [131.202.1.21])
\r
18 (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
\r
19 (No client certificate requested)
\r
20 by olra.theworths.org (Postfix) with ESMTPS id 8B87F40441F
\r
21 for <notmuch@notmuchmail.org>; Sat, 14 Jan 2012 17:40:46 -0800 (PST)
\r
22 Received: from zancas.localnet
\r
23 (fctnnbsc36w-156034076032.pppoe-dynamic.High-Speed.nb.bellaliant.net
\r
24 [156.34.76.32]) (authenticated bits=0)
\r
25 by tempo.its.unb.ca (8.13.8/8.13.8) with ESMTP id q0F1efva008572
\r
26 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO);
\r
27 Sat, 14 Jan 2012 21:40:44 -0400
\r
28 Received: from bremner by zancas.localnet with local (Exim 4.77)
\r
29 (envelope-from <bremner@tethera.net>)
\r
30 id 1RmF5N-00042v-Eu; Sat, 14 Jan 2012 21:40:41 -0400
\r
31 From: David Bremner <david@tethera.net>
\r
32 To: notmuch@notmuchmail.org
\r
33 Subject: [PATCH v3 06/10] notmuch-restore: add 'notmuch format' support,
\r
35 Date: Sat, 14 Jan 2012 21:40:20 -0400
\r
36 Message-Id: <1326591624-15493-7-git-send-email-david@tethera.net>
\r
37 X-Mailer: git-send-email 1.7.7.3
\r
38 In-Reply-To: <1326591624-15493-1-git-send-email-david@tethera.net>
\r
39 References: <874nwxbkhr.fsf@zancas.localnet>
\r
40 <1326591624-15493-1-git-send-email-david@tethera.net>
\r
41 Cc: David Bremner <bremner@debian.org>
\r
42 X-BeenThere: notmuch@notmuchmail.org
\r
43 X-Mailman-Version: 2.1.13
\r
45 List-Id: "Use and development of the notmuch mail system."
\r
46 <notmuch.notmuchmail.org>
\r
47 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
48 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
49 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
50 List-Post: <mailto:notmuch@notmuchmail.org>
\r
51 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
52 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
53 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
54 X-List-Received-Date: Sun, 15 Jan 2012 01:40:49 -0000
\r
56 From: David Bremner <bremner@debian.org>
\r
58 This is format is whitespace separated tokens, encoded by
\r
61 The format detection heuristic relies on the fact that '(' is not part
\r
62 of the character set used by hex-escape. Since hex-escape is designed
\r
63 to be OK for pathnames (and shells), this seems like a reasonable
\r
66 In principle the --format argument to notmuch-restore is notmuch
\r
67 needed at this point, but it adds literally 5 lines of argument
\r
68 description, so I left it.
\r
70 dump-restore-private.h | 5 +-
\r
71 notmuch-restore.c | 111 ++++++++++++++++++++++++++++++++++++++---------
\r
72 2 files changed, 92 insertions(+), 24 deletions(-)
\r
74 diff --git a/dump-restore-private.h b/dump-restore-private.h
\r
75 index 34a5022..67795e5 100644
\r
76 --- a/dump-restore-private.h
\r
77 +++ b/dump-restore-private.h
\r
79 #include "command-line-arguments.h"
\r
81 typedef enum dump_formats {
\r
83 - DUMP_FORMAT_NOTMUCH
\r
85 + DUMP_FORMAT_NOTMUCH,
\r
90 diff --git a/notmuch-restore.c b/notmuch-restore.c
\r
91 index 87d9772..3fdfecc 100644
\r
92 --- a/notmuch-restore.c
\r
93 +++ b/notmuch-restore.c
\r
97 #include "notmuch-client.h"
\r
98 +#include "dump-restore-private.h"
\r
101 notmuch_restore_command (unused (void *ctx), int argc, char *argv[])
\r
102 @@ -35,6 +36,7 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])
\r
106 + int input_format = DUMP_FORMAT_AUTO;
\r
108 config = notmuch_config_open (ctx, NULL, NULL);
\r
109 if (config == NULL)
\r
110 @@ -48,6 +50,11 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])
\r
111 synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);
\r
113 notmuch_opt_desc_t options[] = {
\r
114 + { NOTMUCH_OPT_KEYWORD, &input_format, "format", 'f',
\r
115 + (notmuch_keyword_t []){ { "auto", DUMP_FORMAT_AUTO },
\r
116 + { "notmuch", DUMP_FORMAT_NOTMUCH },
\r
117 + { "sup", DUMP_FORMAT_SUP },
\r
119 { NOTMUCH_OPT_POSITION, &input_file_name, 0, 0, 0 },
\r
120 { NOTMUCH_OPT_BOOLEAN, &accumulate, "accumulate", 'a', 0 },
\r
122 @@ -77,37 +84,85 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])
\r
126 - /* Dump output is one line per message. We match a sequence of
\r
127 - * non-space characters for the message-id, then one or more
\r
128 - * spaces, then a list of space-separated tags as a sequence of
\r
129 - * characters within literal '(' and ')'. */
\r
130 - if ( xregcomp (®ex,
\r
131 - "^([^ ]+) \\(([^)]*)\\)$",
\r
133 - INTERNAL_ERROR("compile time constant regex failed.");
\r
135 + /* These are out here to re-use the buffers with hex_decode */
\r
137 + char *message_id = NULL;
\r
138 + size_t message_id_size = 0;
\r
139 + char *tag = NULL;
\r
140 + size_t tag_size = 0;
\r
141 + notmuch_bool_t first_line = TRUE;
\r
143 while ((line_len = getline (&line, &line_size, input)) != -1) {
\r
144 regmatch_t match[3];
\r
145 - char *message_id, *file_tags, *tag, *next;
\r
146 + char *file_tags, *next;
\r
147 notmuch_message_t *message = NULL;
\r
149 notmuch_status_t status;
\r
150 notmuch_tags_t *db_tags;
\r
153 chomp_newline (line);
\r
154 + if (first_line && input_format == DUMP_FORMAT_AUTO) {
\r
157 - rerr = xregexec (®ex, line, 3, match, 0);
\r
158 - if (rerr == REG_NOMATCH)
\r
160 - fprintf (stderr, "Warning: Ignoring invalid input line: %s\n",
\r
162 + for (p = line; *p; p++) {
\r
164 + input_format = DUMP_FORMAT_SUP;
\r
167 + if (input_format == DUMP_FORMAT_AUTO)
\r
168 + input_format = DUMP_FORMAT_NOTMUCH;
\r
172 + /* sup dump output is one line per message. We match a
\r
173 + * sequence of non-space characters for the message-id, then
\r
174 + * one or more spaces, then a list of space-separated tags as
\r
175 + * a sequence of characters within literal '(' and ')'. */
\r
176 + if (first_line && input_format == DUMP_FORMAT_SUP) {
\r
177 + if ( xregcomp (®ex,
\r
178 + "^([^ ]+) \\(([^)]*)\\)$",
\r
180 + INTERNAL_ERROR("compile time constant regex failed.");
\r
184 + /* Silently ignore blank lines */
\r
186 + if (line[0] == '\0') {
\r
190 - message_id = xstrndup (line + match[1].rm_so,
\r
191 - match[1].rm_eo - match[1].rm_so);
\r
192 - file_tags = xstrndup (line + match[2].rm_so,
\r
193 - match[2].rm_eo - match[2].rm_so);
\r
194 + if (input_format == DUMP_FORMAT_SUP) {
\r
195 + rerr = xregexec (®ex, line, 3, match, 0);
\r
196 + if (rerr == REG_NOMATCH)
\r
198 + fprintf (stderr, "Warning: Ignoring invalid input line: %s\n",
\r
202 + message_id = talloc_strndup (notmuch, line + match[1].rm_so,
\r
203 + match[1].rm_eo - match[1].rm_so);
\r
204 + file_tags = talloc_strndup (notmuch, line + match[2].rm_so,
\r
205 + match[2].rm_eo - match[2].rm_so);
\r
210 + raw_mid = strsep (&p, " \t");
\r
212 + if (hex_decode (notmuch, raw_mid,
\r
213 + &message_id, &message_id_size) != HEX_SUCCESS)
\r
217 + file_tags = xstrdup (p);
\r
219 + file_tags = NULL;
\r
222 + first_line = FALSE;
\r
224 status = notmuch_database_find_message (notmuch, message_id, &message);
\r
225 if (status || message == NULL) {
\r
226 @@ -153,7 +208,16 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])
\r
230 - tag = strsep (&next, " ");
\r
231 + char *raw_tag = strsep (&next, " ");
\r
233 + if (input_format == DUMP_FORMAT_NOTMUCH) {
\r
234 + if (hex_decode (notmuch, raw_tag,
\r
235 + &tag, &tag_size) != HEX_SUCCESS)
\r
238 + tag = talloc_strdup (notmuch, raw_tag);
\r
243 status = notmuch_message_add_tag (message, tag);
\r
244 @@ -175,11 +239,14 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])
\r
246 notmuch_message_destroy (message);
\r
248 - free (message_id);
\r
249 - free (file_tags);
\r
250 + if (input_format == DUMP_FORMAT_SUP) {
\r
251 + talloc_free (message_id);
\r
252 + talloc_free (file_tags);
\r
256 - regfree (®ex);
\r
257 + if (input_format == DUMP_FORMAT_SUP)
\r
258 + regfree (®ex);
\r