From e1b7d32db00ea8afaa1f2ae31bdaa5cb423dda96 Mon Sep 17 00:00:00 2001 From: David Bremner Date: Sat, 3 Jun 2017 14:47:34 -0300 Subject: [PATCH] cli: implement structured output version 4 Since the error field is unused by the emacs front end, no changes are needed other than bumping the format version number. As it is, this is a bit overengineered, but it will reduce duplication when we support gmime 3.0 --- emacs/notmuch-query.el | 2 +- notmuch-client.h | 2 +- notmuch-show.c | 54 ++++++++++++++++++++++++++++++++++++++--- test/T350-crypto.sh | 4 +-- test/T355-smime.sh | 4 +-- test/T450-emacs-show.sh | 2 +- 6 files changed, 57 insertions(+), 11 deletions(-) diff --git a/emacs/notmuch-query.el b/emacs/notmuch-query.el index 48acb551..592fd8f1 100644 --- a/emacs/notmuch-query.el +++ b/emacs/notmuch-query.el @@ -30,7 +30,7 @@ A thread is a forest or list of trees. A tree is a two element list where the first element is a message, and the second element is a possibly empty forest of replies. " - (let ((args '("show" "--format=sexp" "--format-version=3"))) + (let ((args '("show" "--format=sexp" "--format-version=4"))) (if notmuch-show-process-crypto (setq args (append args '("--decrypt")))) (setq args (append args search-terms)) diff --git a/notmuch-client.h b/notmuch-client.h index 62d4bcec..77b34184 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -145,7 +145,7 @@ chomp_newline (char *str) * this. New (required) map fields can be added without increasing * this. */ -#define NOTMUCH_FORMAT_CUR 3 +#define NOTMUCH_FORMAT_CUR 4 /* The minimum supported structured output format version. Requests * for format versions below this will return an error. */ #define NOTMUCH_FORMAT_MIN 1 diff --git a/notmuch-show.c b/notmuch-show.c index 3ce4b63c..5c2d56e8 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -340,6 +340,48 @@ signature_status_to_string (GMimeSignatureStatus x) return "unknown"; } + +/* Print signature flags */ +struct key_map_struct { + GMimeSignatureError bit; + const char * string; +}; + +static void +do_format_signature_errors (sprinter_t *sp, struct key_map_struct *key_map, + unsigned int array_map_len, GMimeSignatureError errors) { + sp->map_key (sp, "errors"); + sp->begin_map (sp); + + for (unsigned int i = 0; i < array_map_len; i++) { + if (errors & key_map[i].bit) { + sp->map_key (sp, key_map[i].string); + sp->boolean (sp, TRUE); + } + } + + sp->end (sp); +} + +static void +format_signature_errors (sprinter_t *sp, GMimeSignature *signature) +{ + GMimeSignatureError errors = g_mime_signature_get_errors (signature); + + if (errors == GMIME_SIGNATURE_ERROR_NONE) + return; + + struct key_map_struct key_map[] = { + { GMIME_SIGNATURE_ERROR_EXPSIG, "sig-expired" }, + { GMIME_SIGNATURE_ERROR_NO_PUBKEY, "key-missing"}, + { GMIME_SIGNATURE_ERROR_EXPKEYSIG, "key-expired"}, + { GMIME_SIGNATURE_ERROR_REVKEYSIG, "key-revoked"}, + { GMIME_SIGNATURE_ERROR_UNSUPP_ALGO, "alg-unsupported"}, + }; + + do_format_signature_errors (sp, key_map, ARRAY_SIZE(key_map), errors); +} + /* Signature status sprinter (GMime 2.6) */ static void format_part_sigstatus_sprinter (sprinter_t *sp, mime_node_t *node) @@ -404,10 +446,14 @@ format_part_sigstatus_sprinter (sprinter_t *sp, mime_node_t *node) } } - GMimeSignatureError errors = g_mime_signature_get_errors (signature); - if (errors != GMIME_SIGNATURE_ERROR_NONE) { - sp->map_key (sp, "errors"); - sp->integer (sp, errors); + if (notmuch_format_version <= 3) { + GMimeSignatureError errors = g_mime_signature_get_errors (signature); + if (errors != GMIME_SIGNATURE_ERROR_NONE) { + sp->map_key (sp, "errors"); + sp->integer (sp, errors); + } + } else { + format_signature_errors (sp, signature); } sp->end (sp); diff --git a/test/T350-crypto.sh b/test/T350-crypto.sh index d21cad14..0753acf3 100755 --- a/test/T350-crypto.sh +++ b/test/T350-crypto.sh @@ -123,7 +123,7 @@ expected='[[[{"id": "XXXXX", "body": [{"id": 1, "sigstatus": [{"status": "error", "keyid": "'$(echo $FINGERPRINT | cut -c 25-)'", - "errors": 2}], + "errors": {"key-missing": true}}], "content-type": "multipart/signed", "content": [{"id": 2, "content-type": "text/plain", @@ -367,7 +367,7 @@ expected='[[[{"id": "XXXXX", "body": [{"id": 1, "sigstatus": [{"status": "error", "keyid": "6D92612D94E46381", - "errors": 8}], + "errors": {"key-revoked": true}}], "content-type": "multipart/signed", "content": [{"id": 2, "content-type": "text/plain", diff --git a/test/T355-smime.sh b/test/T355-smime.sh index 0f39bc69..03d24581 100755 --- a/test/T355-smime.sh +++ b/test/T355-smime.sh @@ -64,8 +64,8 @@ expected='[[[{"id": "XXXXX", "To": "test_suite@notmuchmail.org", "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, "body": [{"id": 1, - "sigstatus": [{"status": "good", - "fingerprint": "'$FINGERPRINT'", + "sigstatus": [{"fingerprint": "'$FINGERPRINT'", + "status": "good", "expires": 424242424, "created": 946728000}], "content-type": "multipart/signed", diff --git a/test/T450-emacs-show.sh b/test/T450-emacs-show.sh index d302efb6..c4bc5ce0 100755 --- a/test/T450-emacs-show.sh +++ b/test/T450-emacs-show.sh @@ -191,7 +191,7 @@ This is an error (see *Notmuch errors* for more details) === ERROR === [XXX] This is an error -command: YYY/notmuch_fail show --format\\=sexp --format-version\\=3 --exclude\\=false \\' \\* \\' +command: YYY/notmuch_fail show --format\\=sexp --format-version\\=4 --exclude\\=false \\' \\* \\' exit status: 1 stderr: This is an error -- 2.26.2