summaryrefslogtreecommitdiffstats
path: root/notmuch-restore.c
diff options
context:
space:
mode:
authorDavid Bremner <david@tethera.net>2016-06-12 22:05:55 -0300
committerDavid Bremner <david@tethera.net>2016-09-21 18:14:25 -0300
commit651da30c0941081cf730930fc1a7cac34954ca0e (patch)
tree645886643d9ba06a17714c60fe5d1161156aad2c /notmuch-restore.c
parentb7345d277ec5f562000c0e740e6515c2a84f9c76 (diff)
cli: optionally restore message properties from dump file
This somewhat mimics the config line parsing, except there can be arbitrarily many key value pairs, so one more level of looping is required.
Diffstat (limited to 'notmuch-restore.c')
-rw-r--r--notmuch-restore.c85
1 files changed, 82 insertions, 3 deletions
diff --git a/notmuch-restore.c b/notmuch-restore.c
index 371237c5..d6429efb 100644
--- a/notmuch-restore.c
+++ b/notmuch-restore.c
@@ -57,6 +57,72 @@ process_config_line (notmuch_database_t *notmuch, const char* line)
return ret;
}
+static int
+process_properties_line (notmuch_database_t *notmuch, const char* line)
+
+{
+ const char *id_p, *tok;
+ size_t id_len = 0, tok_len = 0;
+ char *id;
+
+ notmuch_message_t *message = NULL;
+ const char *delim = " \t\n";
+ int ret = EXIT_FAILURE;
+
+ void *local = talloc_new (NULL);
+
+ id_p = strtok_len_c (line, delim, &id_len);
+ id = talloc_strndup (local, id_p, id_len);
+ if (hex_decode_inplace (id) != HEX_SUCCESS) {
+ fprintf (stderr, "hex decoding failure on line %s\n", line);
+ goto DONE;
+ }
+
+ if (print_status_database ("notmuch restore", notmuch,
+ notmuch_database_find_message (notmuch, id, &message)))
+ goto DONE;
+
+ if (print_status_database ("notmuch restore", notmuch,
+ notmuch_message_remove_all_properties (message, NULL)))
+ goto DONE;
+
+ tok = id_p + id_len;
+
+ while ((tok = strtok_len_c (tok + tok_len, delim, &tok_len)) != NULL) {
+ char *key, *value;
+ size_t off = strcspn (tok, "=");
+ if (off > tok_len) {
+ fprintf (stderr, "unparsable token %s\n", tok);
+ goto DONE;
+ }
+
+ key = talloc_strndup (local, tok, off);
+ value = talloc_strndup (local, tok + off + 1, tok_len - off - 1);
+
+ if (hex_decode_inplace (key) != HEX_SUCCESS) {
+ fprintf (stderr, "hex decoding failure on key %s\n", key);
+ goto DONE;
+ }
+
+ if (hex_decode_inplace (value) != HEX_SUCCESS) {
+ fprintf (stderr, "hex decoding failure on value %s\n", value);
+ goto DONE;
+ }
+
+ if (print_status_database ("notmuch restore", notmuch,
+ notmuch_message_add_property (message, key, value)))
+ 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,
@@ -188,6 +254,7 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
{ 0, 0 } } },
{ NOTMUCH_OPT_KEYWORD_FLAGS, &include, "include", 'I',
(notmuch_keyword_t []){ { "config", DUMP_INCLUDE_CONFIG },
+ { "properties", DUMP_INCLUDE_PROPERTIES },
{ "tags", DUMP_INCLUDE_TAGS} } },
{ NOTMUCH_OPT_STRING, &input_file_name, "input", 'i', 0 },
@@ -206,7 +273,7 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
notmuch_exit_if_unmatched_db_uuid (notmuch);
if (include == 0) {
- include = DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_TAGS;
+ include = DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_PROPERTIES | DUMP_INCLUDE_TAGS;
}
name_for_error = input_file_name ? input_file_name : "stdin";
@@ -273,13 +340,18 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
if (ret)
goto DONE;
}
+ if ((include & DUMP_INCLUDE_PROPERTIES) && line_len >= 2 && line[0] == '#' && line[1] == '=') {
+ ret = process_properties_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)) {
+ if (! ((include & DUMP_INCLUDE_TAGS) || (include & DUMP_INCLUDE_PROPERTIES))) {
ret = EXIT_SUCCESS;
goto DONE;
}
@@ -306,6 +378,13 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
talloc_free (line_ctx);
line_ctx = talloc_new (config);
+
+ if ((include & DUMP_INCLUDE_PROPERTIES) && line_len >= 2 && line[0] == '#' && line[1] == '=') {
+ ret = process_properties_line (notmuch, line + 2);
+ if (ret)
+ goto DONE;
+ }
+
if (input_format == DUMP_FORMAT_SUP) {
ret = parse_sup_line (line_ctx, line, &query_string, tag_ops);
} else {
@@ -344,7 +423,7 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
break;
} while (! (ret = gz_getline (line_ctx, &line, &line_len, input)));
-
+
/* EOF is normal loop termination condition, UTIL_SUCCESS is
* impossible here */