[Patch v3 08/11] CLI: optionally restore config data.

David Bremner david at tethera.net
Sat Apr 30 18:24:36 PDT 2016


The default to restore config data seems safest, especially since
currently we have no config data to mess up.
---
 doc/man1/notmuch-restore.rst | 18 +++++++++++++++
 notmuch-restore.c            | 53 ++++++++++++++++++++++++++++++++++++++++++++
 test/T590-libconfig.sh       | 11 +++++++++
 3 files changed, 82 insertions(+)

diff --git a/doc/man1/notmuch-restore.rst b/doc/man1/notmuch-restore.rst
index 362e262..87fa22e 100644
--- a/doc/man1/notmuch-restore.rst
+++ b/doc/man1/notmuch-restore.rst
@@ -50,6 +50,24 @@ Supported options for **restore** include
             format, this heuristic, based the fact that batch-tag format
             contains no parentheses, should be accurate.
 
+    ``--include=(config|tags)``
+
+      Control what kind of metadata is restored.
+
+	**config**
+
+	  Restore configuration data to the database. Each configuration line starts
+	  with "#@ ", followed by a space seperated key-value pair.
+	  Both key and value are hex encoded if needed.
+
+	**tags**
+
+	  Output per-message metadata, namely tags. See *format* above
+	  for more details.
+
+      The default is to restore both tags and configuration
+      information
+
     ``--input=``\ <filename>
         Read input from given file instead of stdin.
 
diff --git a/notmuch-restore.c b/notmuch-restore.c
index 9abc64f..e06fbde 100644
--- a/notmuch-restore.c
+++ b/notmuch-restore.c
@@ -24,6 +24,38 @@
 #include "string-util.h"
 #include "zlib-extra.h"
 
+static int
+process_config_line(notmuch_database_t *notmuch, const char* line){
+    const char *key_p, *val_p;
+    char *key, *val;
+    size_t key_len,val_len;
+    const char *delim=" \t\n";
+    int ret = EXIT_FAILURE;
+
+    void *local = talloc_new(NULL);
+
+    key_p = strtok_len_c(line, delim, &key_len);
+    val_p = strtok_len_c(key_p+key_len, delim, &val_len);
+
+    key = talloc_strndup(local, key_p, key_len);
+    val = talloc_strndup(local, val_p, val_len);
+    if (hex_decode_inplace (key) != HEX_SUCCESS ||
+	hex_decode_inplace (val) != HEX_SUCCESS ) {
+	fprintf (stderr, "hex decoding failure on line %s\n", line);
+	goto DONE;
+    }
+
+    if (print_status_database ("notmuch restore", notmuch,
+			       notmuch_database_set_config (notmuch, key, val)))
+	goto DONE;
+
+    ret = EXIT_SUCCESS;
+
+ DONE:
+    talloc_free (local);
+    return ret;
+}
+
 static regex_t regex;
 
 /* Non-zero return indicates an error in retrieving the message,
@@ -137,6 +169,7 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
 
     int ret = 0;
     int opt_index;
+    int include=0;
     int input_format = DUMP_FORMAT_AUTO;
 
     if (notmuch_database_open (notmuch_config_get_database_path (config),
@@ -152,6 +185,10 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
 				  { "batch-tag", DUMP_FORMAT_BATCH_TAG },
 				  { "sup", DUMP_FORMAT_SUP },
 				  { 0, 0 } } },
+	{ NOTMUCH_OPT_KEYWORD_FLAGS, &include, "include", 'I',
+	  (notmuch_keyword_t []){ { "config", DUMP_INCLUDE_CONFIG },
+				  { "tags", DUMP_INCLUDE_TAGS} } },
+
 	{ NOTMUCH_OPT_STRING, &input_file_name, "input", 'i', 0 },
 	{ NOTMUCH_OPT_BOOLEAN,  &accumulate, "accumulate", 'a', 0 },
 	{ NOTMUCH_OPT_INHERIT, (void *) &notmuch_shared_options, NULL, 0, 0 },
@@ -167,6 +204,10 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
     notmuch_process_shared_options (argv[0]);
     notmuch_exit_if_unmatched_db_uuid (notmuch);
 
+    if (include == 0) {
+	include = DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_TAGS;
+    }
+
     name_for_error = input_file_name ? input_file_name : "stdin";
 
     if (! accumulate)
@@ -225,11 +266,23 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
 	    ret = EXIT_FAILURE;
 	    goto DONE;
 	}
+
+	if ((include & DUMP_INCLUDE_CONFIG) && line_len >= 2 && line[0] == '#' && line[1] == '@') {
+	    ret = process_config_line(notmuch, line+2);
+	    if (ret)
+		goto DONE;
+	}
+
     } while ((line_len == 0) ||
 	     (line[0] == '#') ||
 	     /* the cast is safe because we checked about for line_len < 0 */
 	     (strspn (line, " \t\n") == (unsigned)line_len));
 
+    if (! (include & DUMP_INCLUDE_TAGS)) {
+	ret = EXIT_SUCCESS;
+	goto DONE;
+    }
+
     char *p;
     for (p = line; (input_format == DUMP_FORMAT_AUTO) && *p; p++) {
 	if (*p == '(')
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 5ea5300..9c1e566 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -132,4 +132,15 @@ cat <<'EOF' >EXPECTED
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "restore config"
+notmuch dump --include=config >EXPECTED
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+{
+    RUN(notmuch_database_set_config (db, "testkey1", "mutatedvalue"));
+}
+EOF
+notmuch restore --include=config <EXPECTED
+notmuch dump --include=config >OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+
 test_done
-- 
2.8.0.rc3



More information about the notmuch mailing list