1 Return-Path: <bremner@tesseract.cs.unb.ca>
\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 2BA62431FDA
\r
6 for <notmuch@notmuchmail.org>; Fri, 27 Mar 2015 15:13:22 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=2.438 tagged_above=-999 required=5
\r
12 tests=[DNS_FROM_AHBL_RHSBL=2.438] 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 3lF5hEF9fxYZ for <notmuch@notmuchmail.org>;
\r
16 Fri, 27 Mar 2015 15:13:20 -0700 (PDT)
\r
17 Received: from mx.xen14.node3324.gplhost.com (gitolite.debian.net
\r
19 (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits))
\r
20 (No client certificate requested)
\r
21 by olra.theworths.org (Postfix) with ESMTPS id F2561431FC9
\r
22 for <notmuch@notmuchmail.org>; Fri, 27 Mar 2015 15:13:19 -0700 (PDT)
\r
23 Received: from remotemail by mx.xen14.node3324.gplhost.com with local (Exim
\r
24 4.80) (envelope-from <bremner@tesseract.cs.unb.ca>)
\r
25 id 1YbcUV-0000EQ-ME; Fri, 27 Mar 2015 22:12:35 +0000
\r
26 Received: (nullmailer pid 1813 invoked by uid 1000); Fri, 27 Mar 2015
\r
28 From: David Bremner <david@tethera.net>
\r
29 To: notmuch@notmuchmail.org
\r
30 Subject: [Patch v6 4/8] lib: add "verbose" versions of
\r
31 notmuch_database_{open,create}
\r
32 Date: Fri, 27 Mar 2015 23:11:56 +0100
\r
33 Message-Id: <1427494320-1483-5-git-send-email-david@tethera.net>
\r
34 X-Mailer: git-send-email 2.1.4
\r
35 In-Reply-To: <1427494320-1483-1-git-send-email-david@tethera.net>
\r
36 References: <1427494320-1483-1-git-send-email-david@tethera.net>
\r
37 X-BeenThere: notmuch@notmuchmail.org
\r
38 X-Mailman-Version: 2.1.13
\r
40 List-Id: "Use and development of the notmuch mail system."
\r
41 <notmuch.notmuchmail.org>
\r
42 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
43 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
44 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
45 List-Post: <mailto:notmuch@notmuchmail.org>
\r
46 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
47 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
48 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
49 X-List-Received-Date: Fri, 27 Mar 2015 22:13:22 -0000
\r
51 The compatibility wrapper ensures that clients calling
\r
52 notmuch_database_open will receive consistent output for now.
\r
54 The changes to notmuch-{new,search} and test/symbol-test are just to
\r
55 make the test suite pass.
\r
57 The use of IGNORE_RESULT is justified by two things. 1) I don't know
\r
58 what else to do. 2) asprintf guarantees the output string is NULL if
\r
59 an error occurs, so at least we are not passing garbage back.
\r
61 lib/database.cc | 109 ++++++++++++++++++++++++++++++++++++++--------------
\r
62 lib/notmuch.h | 21 ++++++++++
\r
63 notmuch-new.c | 11 +++++-
\r
64 notmuch-search.c | 13 ++++++-
\r
65 test/symbol-test.cc | 9 ++++-
\r
66 5 files changed, 130 insertions(+), 33 deletions(-)
\r
68 diff --git a/lib/database.cc b/lib/database.cc
\r
69 index 3974e2e..5d973b9 100644
\r
70 --- a/lib/database.cc
\r
71 +++ b/lib/database.cc
\r
72 @@ -608,29 +608,50 @@ parse_references (void *ctx,
\r
74 notmuch_database_create (const char *path, notmuch_database_t **database)
\r
76 + char *status_string = NULL;
\r
77 + notmuch_status_t status;
\r
79 + status = notmuch_database_create_verbose (path, database,
\r
82 + if (status_string) {
\r
83 + fputs (status_string, stderr);
\r
84 + free (status_string);
\r
91 +notmuch_database_create_verbose (const char *path,
\r
92 + notmuch_database_t **database,
\r
93 + char **status_string)
\r
95 notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
\r
96 notmuch_database_t *notmuch = NULL;
\r
97 char *notmuch_path = NULL;
\r
98 + char *message = NULL;
\r
102 if (path == NULL) {
\r
103 - fprintf (stderr, "Error: Cannot create a database for a NULL path.\n");
\r
104 + message = strdup ("Error: Cannot create a database for a NULL path.\n");
\r
105 status = NOTMUCH_STATUS_NULL_POINTER;
\r
109 err = stat (path, &st);
\r
111 - fprintf (stderr, "Error: Cannot create database at %s: %s.\n",
\r
112 - path, strerror (errno));
\r
113 + IGNORE_RESULT (asprintf (&message, "Error: Cannot create database at %s: %s.\n",
\r
114 + path, strerror (errno)));
\r
115 status = NOTMUCH_STATUS_FILE_ERROR;
\r
119 if (! S_ISDIR (st.st_mode)) {
\r
120 - fprintf (stderr, "Error: Cannot create database at %s: Not a directory.\n",
\r
122 + IGNORE_RESULT (asprintf (&message, "Error: Cannot create database at %s: "
\r
123 + "Not a directory.\n",
\r
125 status = NOTMUCH_STATUS_FILE_ERROR;
\r
128 @@ -640,15 +661,15 @@ notmuch_database_create (const char *path, notmuch_database_t **database)
\r
129 err = mkdir (notmuch_path, 0755);
\r
132 - fprintf (stderr, "Error: Cannot create directory %s: %s.\n",
\r
133 - notmuch_path, strerror (errno));
\r
134 + IGNORE_RESULT (asprintf (&message, "Error: Cannot create directory %s: %s.\n",
\r
135 + notmuch_path, strerror (errno)));
\r
136 status = NOTMUCH_STATUS_FILE_ERROR;
\r
140 - status = notmuch_database_open (path,
\r
141 - NOTMUCH_DATABASE_MODE_READ_WRITE,
\r
143 + status = notmuch_database_open_verbose (path,
\r
144 + NOTMUCH_DATABASE_MODE_READ_WRITE,
\r
145 + ¬much, &message);
\r
149 @@ -667,6 +688,9 @@ notmuch_database_create (const char *path, notmuch_database_t **database)
\r
151 talloc_free (notmuch_path);
\r
153 + if (status_string && message)
\r
154 + *status_string = message;
\r
157 *database = notmuch;
\r
159 @@ -767,37 +791,58 @@ notmuch_database_open (const char *path,
\r
160 notmuch_database_mode_t mode,
\r
161 notmuch_database_t **database)
\r
163 + char *status_string = NULL;
\r
164 + notmuch_status_t status;
\r
166 + status = notmuch_database_open_verbose (path, mode, database,
\r
169 + if (status_string) {
\r
170 + fputs (status_string, stderr);
\r
171 + free (status_string);
\r
178 +notmuch_database_open_verbose (const char *path,
\r
179 + notmuch_database_mode_t mode,
\r
180 + notmuch_database_t **database,
\r
181 + char **status_string)
\r
183 notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
\r
184 void *local = talloc_new (NULL);
\r
185 notmuch_database_t *notmuch = NULL;
\r
186 char *notmuch_path, *xapian_path, *incompat_features;
\r
187 + char *message = NULL;
\r
190 unsigned int i, version;
\r
191 static int initialized = 0;
\r
193 if (path == NULL) {
\r
194 - fprintf (stderr, "Error: Cannot open a database for a NULL path.\n");
\r
195 + message = strdup ("Error: Cannot open a database for a NULL path.\n");
\r
196 status = NOTMUCH_STATUS_NULL_POINTER;
\r
200 if (! (notmuch_path = talloc_asprintf (local, "%s/%s", path, ".notmuch"))) {
\r
201 - fprintf (stderr, "Out of memory\n");
\r
202 + message = strdup ("Out of memory\n");
\r
203 status = NOTMUCH_STATUS_OUT_OF_MEMORY;
\r
207 err = stat (notmuch_path, &st);
\r
209 - fprintf (stderr, "Error opening database at %s: %s\n",
\r
210 - notmuch_path, strerror (errno));
\r
211 + IGNORE_RESULT (asprintf (&message, "Error opening database at %s: %s\n",
\r
212 + notmuch_path, strerror (errno)));
\r
213 status = NOTMUCH_STATUS_FILE_ERROR;
\r
217 if (! (xapian_path = talloc_asprintf (local, "%s/%s", notmuch_path, "xapian"))) {
\r
218 - fprintf (stderr, "Out of memory\n");
\r
219 + message = strdup ("Out of memory\n");
\r
220 status = NOTMUCH_STATUS_OUT_OF_MEMORY;
\r
223 @@ -837,11 +882,11 @@ notmuch_database_open (const char *path,
\r
224 * means a dramatically incompatible change. */
\r
225 version = notmuch_database_get_version (notmuch);
\r
226 if (version > NOTMUCH_DATABASE_VERSION) {
\r
228 - "Error: Notmuch database at %s\n"
\r
229 - " has a newer database format version (%u) than supported by this\n"
\r
230 - " version of notmuch (%u).\n",
\r
231 - notmuch_path, version, NOTMUCH_DATABASE_VERSION);
\r
232 + IGNORE_RESULT (asprintf (&message,
\r
233 + "Error: Notmuch database at %s\n"
\r
234 + " has a newer database format version (%u) than supported by this\n"
\r
235 + " version of notmuch (%u).\n",
\r
236 + notmuch_path, version, NOTMUCH_DATABASE_VERSION));
\r
237 notmuch->mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
\r
238 notmuch_database_destroy (notmuch);
\r
240 @@ -856,11 +901,11 @@ notmuch_database_open (const char *path,
\r
241 version, mode == NOTMUCH_DATABASE_MODE_READ_WRITE ? 'w' : 'r',
\r
242 &incompat_features);
\r
243 if (incompat_features) {
\r
245 - "Error: Notmuch database at %s\n"
\r
246 - " requires features (%s)\n"
\r
247 - " not supported by this version of notmuch.\n",
\r
248 - notmuch_path, incompat_features);
\r
249 + IGNORE_RESULT (asprintf (&message,
\r
250 + "Error: Notmuch database at %s\n"
\r
251 + " requires features (%s)\n"
\r
252 + " not supported by this version of notmuch.\n",
\r
253 + notmuch_path, incompat_features));
\r
254 notmuch->mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
\r
255 notmuch_database_destroy (notmuch);
\r
257 @@ -906,8 +951,8 @@ notmuch_database_open (const char *path,
\r
258 notmuch->query_parser->add_prefix (prefix->name, prefix->prefix);
\r
260 } catch (const Xapian::Error &error) {
\r
261 - fprintf (stderr, "A Xapian exception occurred opening database: %s\n",
\r
262 - error.get_msg().c_str());
\r
263 + IGNORE_RESULT (asprintf (&message, "A Xapian exception occurred opening database: %s\n",
\r
264 + error.get_msg().c_str()));
\r
265 notmuch_database_destroy (notmuch);
\r
267 status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
\r
268 @@ -916,6 +961,9 @@ notmuch_database_open (const char *path,
\r
270 talloc_free (local);
\r
272 + if (status_string && message)
\r
273 + *status_string = message;
\r
276 *database = notmuch;
\r
278 @@ -1039,13 +1087,18 @@ notmuch_database_compact (const char *path,
\r
279 notmuch_database_t *notmuch = NULL;
\r
280 struct stat statbuf;
\r
281 notmuch_bool_t keep_backup;
\r
282 + char *message = NULL;
\r
284 local = talloc_new (NULL);
\r
286 return NOTMUCH_STATUS_OUT_OF_MEMORY;
\r
288 - ret = notmuch_database_open (path, NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much);
\r
289 + ret = notmuch_database_open_verbose (path,
\r
290 + NOTMUCH_DATABASE_MODE_READ_WRITE,
\r
294 + if (status_cb) status_cb (message, closure);
\r
298 diff --git a/lib/notmuch.h b/lib/notmuch.h
\r
299 index f066245..c671d82 100644
\r
300 --- a/lib/notmuch.h
\r
301 +++ b/lib/notmuch.h
\r
302 @@ -230,6 +230,16 @@ notmuch_status_t
\r
303 notmuch_database_create (const char *path, notmuch_database_t **database);
\r
306 + * Like notmuch_database_create, except optionally return an error
\r
307 + * message. This message is allocated by malloc and should be freed by
\r
311 +notmuch_database_create_verbose (const char *path,
\r
312 + notmuch_database_t **database,
\r
313 + char **error_message);
\r
316 * Database open mode for notmuch_database_open.
\r
319 @@ -279,6 +289,17 @@ notmuch_status_t
\r
320 notmuch_database_open (const char *path,
\r
321 notmuch_database_mode_t mode,
\r
322 notmuch_database_t **database);
\r
324 + * Like notmuch_database_open, except optionally return an error
\r
325 + * message. This message is allocated by malloc and should be freed by
\r
330 +notmuch_database_open_verbose (const char *path,
\r
331 + notmuch_database_mode_t mode,
\r
332 + notmuch_database_t **database,
\r
333 + char **error_message);
\r
336 * Commit changes and close the given notmuch database.
\r
337 diff --git a/notmuch-new.c b/notmuch-new.c
\r
338 index ddf42c1..e6c283e 100644
\r
339 --- a/notmuch-new.c
\r
340 +++ b/notmuch-new.c
\r
341 @@ -985,9 +985,16 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
\r
342 return EXIT_FAILURE;
\r
343 add_files_state.total_files = count;
\r
345 - if (notmuch_database_open (db_path, NOTMUCH_DATABASE_MODE_READ_WRITE,
\r
347 + char *status_string = NULL;
\r
348 + if (notmuch_database_open_verbose (db_path, NOTMUCH_DATABASE_MODE_READ_WRITE,
\r
349 + ¬much, &status_string)) {
\r
350 + if (status_string) {
\r
351 + fputs (status_string, stderr);
\r
352 + free (status_string);
\r
355 return EXIT_FAILURE;
\r
358 if (notmuch_database_needs_upgrade (notmuch)) {
\r
359 time_t now = time (NULL);
\r
360 diff --git a/notmuch-search.c b/notmuch-search.c
\r
361 index a591d45..b81ac01 100644
\r
362 --- a/notmuch-search.c
\r
363 +++ b/notmuch-search.c
\r
364 @@ -545,6 +545,7 @@ _notmuch_search_prepare (search_context_t *ctx, notmuch_config_t *config, int ar
\r
368 + char *status_string = NULL;
\r
370 switch (ctx->format_sel) {
\r
371 case NOTMUCH_FORMAT_TEXT:
\r
372 @@ -570,9 +571,17 @@ _notmuch_search_prepare (search_context_t *ctx, notmuch_config_t *config, int ar
\r
374 notmuch_exit_if_unsupported_format ();
\r
376 - if (notmuch_database_open (notmuch_config_get_database_path (config),
\r
377 - NOTMUCH_DATABASE_MODE_READ_ONLY, &ctx->notmuch))
\r
378 + if (notmuch_database_open_verbose (
\r
379 + notmuch_config_get_database_path (config),
\r
380 + NOTMUCH_DATABASE_MODE_READ_ONLY, &ctx->notmuch, &status_string)) {
\r
382 + if (status_string) {
\r
383 + fputs (status_string, stderr);
\r
384 + free (status_string);
\r
387 return EXIT_FAILURE;
\r
390 query_str = query_string_from_args (ctx->notmuch, argc, argv);
\r
391 if (query_str == NULL) {
\r
392 diff --git a/test/symbol-test.cc b/test/symbol-test.cc
\r
393 index 3e96c03..d979f83 100644
\r
394 --- a/test/symbol-test.cc
\r
395 +++ b/test/symbol-test.cc
\r
398 +#include <stdlib.h>
\r
399 #include <xapian.h>
\r
400 #include <notmuch.h>
\r
404 notmuch_database_t *notmuch;
\r
405 - notmuch_database_open("fakedb", NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much);
\r
406 + char *message = NULL;
\r
408 + if (notmuch_database_open_verbose ("fakedb", NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much, &message))
\r
410 + fputs (message, stderr);
\r
415 (void) new Xapian::WritableDatabase("./nonexistant", Xapian::DB_OPEN);
\r