mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-28 13:44:12 +01:00
Merge branch 'release'
Conflicts: doc/man1/notmuch-reply.rst doc/man1/notmuch-show.rst Conflicts taken from release (dkg's doc changes)
This commit is contained in:
commit
99407db25c
20 changed files with 230 additions and 80 deletions
59
NEWS
59
NEWS
|
@ -24,6 +24,17 @@ Support for re-indexing existing messages
|
||||||
archive, the recorded Subject: of may change upon reindexing,
|
archive, the recorded Subject: of may change upon reindexing,
|
||||||
depending on the order in which the variants are indexed.
|
depending on the order in which the variants are indexed.
|
||||||
|
|
||||||
|
Improved error reporting in notmuch new
|
||||||
|
|
||||||
|
Give more details when reporting certain Xapian exceptions.
|
||||||
|
|
||||||
|
Support maildir synced tags in `new.tags`
|
||||||
|
|
||||||
|
Tags `draft`, `flagged`, `passed`, and `replied` are now supported
|
||||||
|
in `new.tags`. The tag `unread` is still special in the presence of
|
||||||
|
maildir syncing, and will be added for files in `new/` regardless of
|
||||||
|
the setting of `new.tags`.
|
||||||
|
|
||||||
Encrypted Mail
|
Encrypted Mail
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
@ -41,6 +52,54 @@ Indexing cleartext of encrypted e-mails
|
||||||
that the notmuch index itself is adequately protected. DO NOT USE
|
that the notmuch index itself is adequately protected. DO NOT USE
|
||||||
this feature without considering the security of your index.
|
this feature without considering the security of your index.
|
||||||
|
|
||||||
|
Library Changes
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Indexing files with duplicate message-id
|
||||||
|
|
||||||
|
Files with duplicate message-id's are now indexed, and searchable
|
||||||
|
via terms and phrases. There are known issues related to
|
||||||
|
presentation of results and regular-expression search, but in
|
||||||
|
principle no mail file should be completely unsearchable now.
|
||||||
|
|
||||||
|
New functions to count files
|
||||||
|
|
||||||
|
Two new functions in the libnotmuch API:
|
||||||
|
`notmuch_message_count_files`, and `notmuch_thread_get_total_files`.
|
||||||
|
|
||||||
|
Change of return value of `notmuch_thread_get_authors`
|
||||||
|
|
||||||
|
In certain corner cases, `notmuch_thread_get_authors` previously
|
||||||
|
returned NULL. This has been replaced by an empty string, since the
|
||||||
|
possibility of NULL was not documented.
|
||||||
|
|
||||||
|
Python Bindings
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Python bindings specific Debian packaging is removed
|
||||||
|
|
||||||
|
The bindings have been build by the top level Debian packaging for a
|
||||||
|
long time, and `bindings/python/debian` has bit-rotted.
|
||||||
|
|
||||||
|
Open mail files in binary mode when using Python 3
|
||||||
|
|
||||||
|
This avoids certain encoding related crashes under Python 3.
|
||||||
|
|
||||||
|
Add python bindings for notmuch_database_{get,set}_config*
|
||||||
|
|
||||||
|
nmbug
|
||||||
|
-----
|
||||||
|
|
||||||
|
nmbug's internal version increases to 0.3 in this notmuch release.
|
||||||
|
User-facing changes with this notmuch release:
|
||||||
|
|
||||||
|
* Accept failures to unset `core.worktree` in `clone`, which allows
|
||||||
|
nmbug to be used with Git 2.11.0 and later.
|
||||||
|
* Auto-checkout in `clone` if it wouldn't clobber existing content,
|
||||||
|
which makes the initial clone more convenient.
|
||||||
|
* Only error for invalid diff lines in `tags/`, which allows for
|
||||||
|
`README`s and similar in nmbug repositories.
|
||||||
|
|
||||||
Notmuch 0.25.3 (2017-12-08)
|
Notmuch 0.25.3 (2017-12-08)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# this file should be kept in sync with ../../../version
|
# this file should be kept in sync with ../../../version
|
||||||
__VERSION__ = '0.26~rc0'
|
__VERSION__ = '0.26~rc1'
|
||||||
SOVERSION = '5'
|
SOVERSION = '5'
|
||||||
|
|
|
@ -4,13 +4,19 @@
|
||||||
#include "error_util.h"
|
#include "error_util.h"
|
||||||
#include "command-line-arguments.h"
|
#include "command-line-arguments.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OPT_FAILED, /* false */
|
||||||
|
OPT_OK, /* good */
|
||||||
|
OPT_GIVEBACK, /* pop one of the arguments you thought you were getting off the stack */
|
||||||
|
} opt_handled;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Search the array of keywords for a given argument, assigning the
|
Search the array of keywords for a given argument, assigning the
|
||||||
output variable to the corresponding value. Return false if nothing
|
output variable to the corresponding value. Return false if nothing
|
||||||
matches.
|
matches.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static opt_handled
|
||||||
_process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next,
|
_process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next,
|
||||||
const char *arg_str, bool negate)
|
const char *arg_str, bool negate)
|
||||||
{
|
{
|
||||||
|
@ -32,16 +38,32 @@ _process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next,
|
||||||
else
|
else
|
||||||
*arg_desc->opt_keyword = keywords->value;
|
*arg_desc->opt_keyword = keywords->value;
|
||||||
|
|
||||||
return true;
|
return OPT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arg_desc->opt_keyword && arg_desc->keyword_no_arg_value && next != ':' && next != '=') {
|
||||||
|
for (keywords = arg_desc->keywords; keywords->name; keywords++) {
|
||||||
|
if (strcmp (arg_desc->keyword_no_arg_value, keywords->name) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*arg_desc->opt_keyword = keywords->value;
|
||||||
|
fprintf (stderr, "Warning: No known keyword option given for \"%s\", choosing value \"%s\"."
|
||||||
|
" Please specify the argument explicitly!\n", arg_desc->name, arg_desc->keyword_no_arg_value);
|
||||||
|
|
||||||
|
return OPT_GIVEBACK;
|
||||||
|
}
|
||||||
|
fprintf (stderr, "No matching keyword for option \"%s\" and default value \"%s\" is invalid.\n", arg_str, arg_desc->name);
|
||||||
|
return OPT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if (next != '\0')
|
if (next != '\0')
|
||||||
fprintf (stderr, "Unknown keyword argument \"%s\" for option \"%s\".\n", arg_str, arg_desc->name);
|
fprintf (stderr, "Unknown keyword argument \"%s\" for option \"%s\".\n", arg_str, arg_desc->name);
|
||||||
else
|
else
|
||||||
fprintf (stderr, "Option \"%s\" needs a keyword argument.\n", arg_desc->name);
|
fprintf (stderr, "Option \"%s\" needs a keyword argument.\n", arg_desc->name);
|
||||||
return false;
|
return OPT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static opt_handled
|
||||||
_process_boolean_arg (const notmuch_opt_desc_t *arg_desc, char next,
|
_process_boolean_arg (const notmuch_opt_desc_t *arg_desc, char next,
|
||||||
const char *arg_str, bool negate)
|
const char *arg_str, bool negate)
|
||||||
{
|
{
|
||||||
|
@ -53,45 +75,45 @@ _process_boolean_arg (const notmuch_opt_desc_t *arg_desc, char next,
|
||||||
value = false;
|
value = false;
|
||||||
} else {
|
} else {
|
||||||
fprintf (stderr, "Unknown argument \"%s\" for (boolean) option \"%s\".\n", arg_str, arg_desc->name);
|
fprintf (stderr, "Unknown argument \"%s\" for (boolean) option \"%s\".\n", arg_str, arg_desc->name);
|
||||||
return false;
|
return OPT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
*arg_desc->opt_bool = negate ? !value : value;
|
*arg_desc->opt_bool = negate ? !value : value;
|
||||||
|
|
||||||
return true;
|
return OPT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static opt_handled
|
||||||
_process_int_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
|
_process_int_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
|
||||||
|
|
||||||
char *endptr;
|
char *endptr;
|
||||||
if (next == '\0' || arg_str[0] == '\0') {
|
if (next == '\0' || arg_str[0] == '\0') {
|
||||||
fprintf (stderr, "Option \"%s\" needs an integer argument.\n", arg_desc->name);
|
fprintf (stderr, "Option \"%s\" needs an integer argument.\n", arg_desc->name);
|
||||||
return false;
|
return OPT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
*arg_desc->opt_int = strtol (arg_str, &endptr, 10);
|
*arg_desc->opt_int = strtol (arg_str, &endptr, 10);
|
||||||
if (*endptr == '\0')
|
if (*endptr == '\0')
|
||||||
return true;
|
return OPT_OK;
|
||||||
|
|
||||||
fprintf (stderr, "Unable to parse argument \"%s\" for option \"%s\" as an integer.\n",
|
fprintf (stderr, "Unable to parse argument \"%s\" for option \"%s\" as an integer.\n",
|
||||||
arg_str, arg_desc->name);
|
arg_str, arg_desc->name);
|
||||||
return false;
|
return OPT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static opt_handled
|
||||||
_process_string_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
|
_process_string_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
|
||||||
|
|
||||||
if (next == '\0') {
|
if (next == '\0') {
|
||||||
fprintf (stderr, "Option \"%s\" needs a string argument.\n", arg_desc->name);
|
fprintf (stderr, "Option \"%s\" needs a string argument.\n", arg_desc->name);
|
||||||
return false;
|
return OPT_FAILED;
|
||||||
}
|
}
|
||||||
if (arg_str[0] == '\0' && ! arg_desc->allow_empty) {
|
if (arg_str[0] == '\0' && ! arg_desc->allow_empty) {
|
||||||
fprintf (stderr, "String argument for option \"%s\" must be non-empty.\n", arg_desc->name);
|
fprintf (stderr, "String argument for option \"%s\" must be non-empty.\n", arg_desc->name);
|
||||||
return false;
|
return OPT_FAILED;
|
||||||
}
|
}
|
||||||
*arg_desc->opt_string = arg_str;
|
*arg_desc->opt_string = arg_str;
|
||||||
return true;
|
return OPT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return number of non-NULL opt_* fields in opt_desc. */
|
/* Return number of non-NULL opt_* fields in opt_desc. */
|
||||||
|
@ -212,13 +234,15 @@ parse_option (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_
|
||||||
if (next != '=' && next != ':' && next != '\0')
|
if (next != '=' && next != ':' && next != '\0')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (next == '\0' && next_arg != NULL && ! try->opt_bool) {
|
bool lookahead = (next == '\0' && next_arg != NULL && ! try->opt_bool);
|
||||||
|
|
||||||
|
if (lookahead) {
|
||||||
next = ' ';
|
next = ' ';
|
||||||
value = next_arg;
|
value = next_arg;
|
||||||
opt_index ++;
|
opt_index ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool opt_status = false;
|
opt_handled opt_status = OPT_FAILED;
|
||||||
if (try->opt_keyword || try->opt_flags)
|
if (try->opt_keyword || try->opt_flags)
|
||||||
opt_status = _process_keyword_arg (try, next, value, negate);
|
opt_status = _process_keyword_arg (try, next, value, negate);
|
||||||
else if (try->opt_bool)
|
else if (try->opt_bool)
|
||||||
|
@ -230,9 +254,12 @@ parse_option (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_
|
||||||
else
|
else
|
||||||
INTERNAL_ERROR ("unknown or unhandled option \"%s\"", try->name);
|
INTERNAL_ERROR ("unknown or unhandled option \"%s\"", try->name);
|
||||||
|
|
||||||
if (! opt_status)
|
if (opt_status == OPT_FAILED)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (lookahead && opt_status == OPT_GIVEBACK)
|
||||||
|
opt_index --;
|
||||||
|
|
||||||
if (try->present)
|
if (try->present)
|
||||||
*try->present = true;
|
*try->present = true;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,10 @@ typedef struct notmuch_opt_desc {
|
||||||
const char **opt_string;
|
const char **opt_string;
|
||||||
const char **opt_position;
|
const char **opt_position;
|
||||||
|
|
||||||
|
/* for opt_keyword only: if no matching arguments were found, and
|
||||||
|
* keyword_no_arg_value is set, then use keyword_no_arg_value instead. */
|
||||||
|
const char *keyword_no_arg_value;
|
||||||
|
|
||||||
/* Must be set except for opt_inherit and opt_position. */
|
/* Must be set except for opt_inherit and opt_position. */
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
|
|
|
@ -351,7 +351,7 @@ _notmuch_reply()
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
--decrypt)
|
--decrypt)
|
||||||
COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
|
COMPREPLY=( $( compgen -W "true auto false" -- "${cur}" ) )
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -517,10 +517,14 @@ _notmuch_show()
|
||||||
COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
|
COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
--exclude|--body|--decrypt)
|
--exclude|--body)
|
||||||
COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
|
COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
|
--decrypt)
|
||||||
|
COMPREPLY=( $( compgen -W "true auto false" -- "${cur}" ) )
|
||||||
|
return
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
! $split &&
|
! $split &&
|
||||||
|
|
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -1,3 +1,9 @@
|
||||||
|
notmuch (0.26~rc1-1) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Second upstream release candidate
|
||||||
|
|
||||||
|
-- David Bremner <bremner@debian.org> Fri, 29 Dec 2017 16:49:37 -0400
|
||||||
|
|
||||||
notmuch (0.26~rc0-1) experimental; urgency=medium
|
notmuch (0.26~rc0-1) experimental; urgency=medium
|
||||||
|
|
||||||
* Upstream release candidate
|
* Upstream release candidate
|
||||||
|
|
|
@ -51,7 +51,7 @@ except ImportError: # Python 2
|
||||||
from urllib import unquote as _unquote
|
from urllib import unquote as _unquote
|
||||||
|
|
||||||
|
|
||||||
__version__ = '0.2'
|
__version__ = '0.3'
|
||||||
|
|
||||||
_LOG = _logging.getLogger('nmbug')
|
_LOG = _logging.getLogger('nmbug')
|
||||||
_LOG.setLevel(_logging.WARNING)
|
_LOG.setLevel(_logging.WARNING)
|
||||||
|
|
|
@ -70,20 +70,26 @@ Supported options for **reply** include
|
||||||
order, and copy values from the first that contains something
|
order, and copy values from the first that contains something
|
||||||
other than only the user's addresses.
|
other than only the user's addresses.
|
||||||
|
|
||||||
``--decrypt``
|
``--decrypt=(false|auto|true)``
|
||||||
Decrypt any MIME encrypted parts found in the selected content
|
|
||||||
(ie. "multipart/encrypted" parts). Status of the decryption will
|
|
||||||
be reported (currently only supported with --format=json and
|
|
||||||
--format=sexp) and on successful decryption the
|
|
||||||
multipart/encrypted part will be replaced by the decrypted
|
|
||||||
content.
|
|
||||||
|
|
||||||
If a session key is already known for the message, then it will be
|
If ``true``, decrypt any MIME encrypted parts found in the
|
||||||
decrypted automatically unless the user explicitly sets
|
selected content (i.e., "multipart/encrypted" parts). Status
|
||||||
``--decrypt=false``.
|
of the decryption will be reported (currently only supported
|
||||||
|
with --format=json and --format=sexp), and on successful
|
||||||
|
decryption the multipart/encrypted part will be replaced by
|
||||||
|
the decrypted content.
|
||||||
|
|
||||||
Decryption expects a functioning **gpg-agent(1)** to provide any
|
If ``auto``, and a session key is already known for the
|
||||||
needed credentials. Without one, the decryption will likely fail.
|
message, then it will be decrypted, but notmuch will not try
|
||||||
|
to access the user's secret keys.
|
||||||
|
|
||||||
|
Use ``false`` to avoid even automatic decryption.
|
||||||
|
|
||||||
|
Non-automatic decryption expects a functioning
|
||||||
|
**gpg-agent(1)** to provide any needed credentials. Without
|
||||||
|
one, the decryption will likely fail.
|
||||||
|
|
||||||
|
Default: ``auto``
|
||||||
|
|
||||||
See **notmuch-search-terms(7)** for details of the supported syntax for
|
See **notmuch-search-terms(7)** for details of the supported syntax for
|
||||||
<search-terms>.
|
<search-terms>.
|
||||||
|
|
|
@ -110,22 +110,27 @@ Supported options for **show** include
|
||||||
supported with --format=json and --format=sexp), and the
|
supported with --format=json and --format=sexp), and the
|
||||||
multipart/signed part will be replaced by the signed data.
|
multipart/signed part will be replaced by the signed data.
|
||||||
|
|
||||||
``--decrypt``
|
``--decrypt=(false|auto|true)``
|
||||||
Decrypt any MIME encrypted parts found in the selected content
|
If ``true``, decrypt any MIME encrypted parts found in the
|
||||||
(ie. "multipart/encrypted" parts). Status of the decryption will
|
selected content (i.e. "multipart/encrypted" parts). Status of
|
||||||
be reported (currently only supported with --format=json and
|
the decryption will be reported (currently only supported
|
||||||
--format=sexp) and on successful decryption the
|
with --format=json and --format=sexp) and on successful
|
||||||
multipart/encrypted part will be replaced by the decrypted
|
decryption the multipart/encrypted part will be replaced by
|
||||||
content.
|
the decrypted content.
|
||||||
|
|
||||||
If a session key is already known for the message, then it will be
|
If ``auto``, and a session key is already known for the
|
||||||
decrypted automatically unless the user explicitly sets
|
message, then it will be decrypted, but notmuch will not try
|
||||||
``--decrypt=false``.
|
to access the user's keys.
|
||||||
|
|
||||||
Decryption expects a functioning **gpg-agent(1)** to provide any
|
Use ``false`` to avoid even automatic decryption.
|
||||||
needed credentials. Without one, the decryption will fail.
|
|
||||||
|
|
||||||
Implies --verify.
|
Non-automatic decryption expects a functioning
|
||||||
|
**gpg-agent(1)** to provide any needed credentials. Without
|
||||||
|
one, the decryption will fail.
|
||||||
|
|
||||||
|
Note: ``true`` implies --verify.
|
||||||
|
|
||||||
|
Default: ``auto``
|
||||||
|
|
||||||
``--exclude=(true|false)``
|
``--exclude=(true|false)``
|
||||||
Specify whether to omit threads only matching search.tag\_exclude
|
Specify whether to omit threads only matching search.tag\_exclude
|
||||||
|
|
|
@ -593,7 +593,7 @@ the given type."
|
||||||
(set-buffer-multibyte nil))
|
(set-buffer-multibyte nil))
|
||||||
(let ((args `("show" "--format=raw"
|
(let ((args `("show" "--format=raw"
|
||||||
,(format "--part=%s" (plist-get part :id))
|
,(format "--part=%s" (plist-get part :id))
|
||||||
,@(when process-crypto '("--decrypt"))
|
,@(when process-crypto '("--decrypt=true"))
|
||||||
,(notmuch-id-to-query (plist-get msg :id))))
|
,(notmuch-id-to-query (plist-get msg :id))))
|
||||||
(coding-system-for-read
|
(coding-system-for-read
|
||||||
(if binaryp 'no-conversion
|
(if binaryp 'no-conversion
|
||||||
|
|
|
@ -181,7 +181,7 @@ mutiple parts get a header."
|
||||||
reply
|
reply
|
||||||
original)
|
original)
|
||||||
(when process-crypto
|
(when process-crypto
|
||||||
(setq args (append args '("--decrypt"))))
|
(setq args (append args '("--decrypt=true"))))
|
||||||
|
|
||||||
(if reply-all
|
(if reply-all
|
||||||
(setq args (append args '("--reply-to=all")))
|
(setq args (append args '("--reply-to=all")))
|
||||||
|
|
|
@ -32,7 +32,7 @@ is a possibly empty forest of replies.
|
||||||
"
|
"
|
||||||
(let ((args '("show" "--format=sexp" "--format-version=4")))
|
(let ((args '("show" "--format=sexp" "--format-version=4")))
|
||||||
(if notmuch-show-process-crypto
|
(if notmuch-show-process-crypto
|
||||||
(setq args (append args '("--decrypt"))))
|
(setq args (append args '("--decrypt=true"))))
|
||||||
(setq args (append args search-terms))
|
(setq args (append args search-terms))
|
||||||
(apply #'notmuch-call-notmuch-sexp args)))
|
(apply #'notmuch-call-notmuch-sexp args)))
|
||||||
|
|
||||||
|
|
|
@ -704,8 +704,6 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
|
||||||
};
|
};
|
||||||
int format = FORMAT_DEFAULT;
|
int format = FORMAT_DEFAULT;
|
||||||
int reply_all = true;
|
int reply_all = true;
|
||||||
bool decrypt = false;
|
|
||||||
bool decrypt_set = false;
|
|
||||||
|
|
||||||
notmuch_opt_desc_t options[] = {
|
notmuch_opt_desc_t options[] = {
|
||||||
{ .opt_keyword = &format, .name = "format", .keywords =
|
{ .opt_keyword = &format, .name = "format", .keywords =
|
||||||
|
@ -719,7 +717,12 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
|
||||||
(notmuch_keyword_t []){ { "all", true },
|
(notmuch_keyword_t []){ { "all", true },
|
||||||
{ "sender", false },
|
{ "sender", false },
|
||||||
{ 0, 0 } } },
|
{ 0, 0 } } },
|
||||||
{ .opt_bool = &decrypt, .name = "decrypt", .present = &decrypt_set },
|
{ .opt_keyword = (int*)(¶ms.crypto.decrypt), .name = "decrypt",
|
||||||
|
.keyword_no_arg_value = "true", .keywords =
|
||||||
|
(notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE },
|
||||||
|
{ "auto", NOTMUCH_DECRYPT_AUTO },
|
||||||
|
{ "true", NOTMUCH_DECRYPT_NOSTASH },
|
||||||
|
{ 0, 0 } } },
|
||||||
{ .opt_inherit = notmuch_shared_options },
|
{ .opt_inherit = notmuch_shared_options },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
@ -729,8 +732,6 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
notmuch_process_shared_options (argv[0]);
|
notmuch_process_shared_options (argv[0]);
|
||||||
if (decrypt_set)
|
|
||||||
params.crypto.decrypt = decrypt ? NOTMUCH_DECRYPT_NOSTASH : NOTMUCH_DECRYPT_FALSE;
|
|
||||||
|
|
||||||
notmuch_exit_if_unsupported_format ();
|
notmuch_exit_if_unsupported_format ();
|
||||||
|
|
||||||
|
|
|
@ -1085,8 +1085,6 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
|
||||||
bool exclude = true;
|
bool exclude = true;
|
||||||
bool entire_thread_set = false;
|
bool entire_thread_set = false;
|
||||||
bool single_message;
|
bool single_message;
|
||||||
bool decrypt = false;
|
|
||||||
bool decrypt_set = false;
|
|
||||||
|
|
||||||
notmuch_opt_desc_t options[] = {
|
notmuch_opt_desc_t options[] = {
|
||||||
{ .opt_keyword = &format, .name = "format", .keywords =
|
{ .opt_keyword = &format, .name = "format", .keywords =
|
||||||
|
@ -1101,7 +1099,12 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
|
||||||
{ .opt_bool = ¶ms.entire_thread, .name = "entire-thread",
|
{ .opt_bool = ¶ms.entire_thread, .name = "entire-thread",
|
||||||
.present = &entire_thread_set },
|
.present = &entire_thread_set },
|
||||||
{ .opt_int = ¶ms.part, .name = "part" },
|
{ .opt_int = ¶ms.part, .name = "part" },
|
||||||
{ .opt_bool = &decrypt, .name = "decrypt", .present = &decrypt_set },
|
{ .opt_keyword = (int*)(¶ms.crypto.decrypt), .name = "decrypt",
|
||||||
|
.keyword_no_arg_value = "true", .keywords =
|
||||||
|
(notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE },
|
||||||
|
{ "auto", NOTMUCH_DECRYPT_AUTO },
|
||||||
|
{ "true", NOTMUCH_DECRYPT_NOSTASH },
|
||||||
|
{ 0, 0 } } },
|
||||||
{ .opt_bool = ¶ms.crypto.verify, .name = "verify" },
|
{ .opt_bool = ¶ms.crypto.verify, .name = "verify" },
|
||||||
{ .opt_bool = ¶ms.output_body, .name = "body" },
|
{ .opt_bool = ¶ms.output_body, .name = "body" },
|
||||||
{ .opt_bool = ¶ms.include_html, .name = "include-html" },
|
{ .opt_bool = ¶ms.include_html, .name = "include-html" },
|
||||||
|
@ -1115,16 +1118,9 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
|
||||||
|
|
||||||
notmuch_process_shared_options (argv[0]);
|
notmuch_process_shared_options (argv[0]);
|
||||||
|
|
||||||
if (decrypt_set) {
|
/* explicit decryption implies verification */
|
||||||
if (decrypt) {
|
if (params.crypto.decrypt == NOTMUCH_DECRYPT_NOSTASH)
|
||||||
/* we do not need or want to ask for session keys */
|
|
||||||
params.crypto.decrypt = NOTMUCH_DECRYPT_NOSTASH;
|
|
||||||
/* decryption implies verification */
|
|
||||||
params.crypto.verify = true;
|
params.crypto.verify = true;
|
||||||
} else {
|
|
||||||
params.crypto.decrypt = NOTMUCH_DECRYPT_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* specifying a part implies single message display */
|
/* specifying a part implies single message display */
|
||||||
single_message = params.part >= 0;
|
single_message = params.part >= 0;
|
||||||
|
|
|
@ -223,7 +223,7 @@ output=$(notmuch search mimetype:multipart/encrypted and mimetype:application/pg
|
||||||
test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; test encrypted message 001 (encrypted inbox)"
|
test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; test encrypted message 001 (encrypted inbox)"
|
||||||
|
|
||||||
test_begin_subtest "decryption, --format=text"
|
test_begin_subtest "decryption, --format=text"
|
||||||
output=$(notmuch show --format=text --decrypt subject:"test encrypted message 001" \
|
output=$(notmuch show --format=text --decrypt=true subject:"test encrypted message 001" \
|
||||||
| notmuch_show_sanitize_all \
|
| notmuch_show_sanitize_all \
|
||||||
| sed -e 's|"created": [1234567890]*|"created": 946728000|')
|
| sed -e 's|"created": [1234567890]*|"created": 946728000|')
|
||||||
expected='message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX
|
expected='message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX
|
||||||
|
@ -255,7 +255,7 @@ test_expect_equal \
|
||||||
"$expected"
|
"$expected"
|
||||||
|
|
||||||
test_begin_subtest "decryption, --format=json"
|
test_begin_subtest "decryption, --format=json"
|
||||||
output=$(notmuch show --format=json --decrypt subject:"test encrypted message 001" \
|
output=$(notmuch show --format=json --decrypt=true subject:"test encrypted message 001" \
|
||||||
| notmuch_json_show_sanitize \
|
| notmuch_json_show_sanitize \
|
||||||
| sed -e 's|"created": [1234567890]*|"created": 946728000|')
|
| sed -e 's|"created": [1234567890]*|"created": 946728000|')
|
||||||
expected='[[[{"id": "XXXXX",
|
expected='[[[{"id": "XXXXX",
|
||||||
|
@ -293,7 +293,7 @@ test_expect_equal_json \
|
||||||
"$expected"
|
"$expected"
|
||||||
|
|
||||||
test_begin_subtest "decryption, --format=json, --part=4"
|
test_begin_subtest "decryption, --format=json, --part=4"
|
||||||
output=$(notmuch show --format=json --part=4 --decrypt subject:"test encrypted message 001" \
|
output=$(notmuch show --format=json --part=4 --decrypt=true subject:"test encrypted message 001" \
|
||||||
| notmuch_json_show_sanitize \
|
| notmuch_json_show_sanitize \
|
||||||
| sed -e 's|"created": [1234567890]*|"created": 946728000|')
|
| sed -e 's|"created": [1234567890]*|"created": 946728000|')
|
||||||
expected='{"id": 4,
|
expected='{"id": 4,
|
||||||
|
@ -307,13 +307,13 @@ test_begin_subtest "decrypt attachment (--part=5 --format=raw)"
|
||||||
notmuch show \
|
notmuch show \
|
||||||
--format=raw \
|
--format=raw \
|
||||||
--part=5 \
|
--part=5 \
|
||||||
--decrypt \
|
--decrypt=true \
|
||||||
subject:"test encrypted message 001" >OUTPUT
|
subject:"test encrypted message 001" >OUTPUT
|
||||||
test_expect_equal_file TESTATTACHMENT OUTPUT
|
test_expect_equal_file TESTATTACHMENT OUTPUT
|
||||||
|
|
||||||
test_begin_subtest "decryption failure with missing key"
|
test_begin_subtest "decryption failure with missing key"
|
||||||
mv "${GNUPGHOME}"{,.bak}
|
mv "${GNUPGHOME}"{,.bak}
|
||||||
output=$(notmuch show --format=json --decrypt subject:"test encrypted message 001" \
|
output=$(notmuch show --format=json --decrypt=true subject:"test encrypted message 001" \
|
||||||
| notmuch_json_show_sanitize \
|
| notmuch_json_show_sanitize \
|
||||||
| sed -e 's|"created": [1234567890]*|"created": 946728000|')
|
| sed -e 's|"created": [1234567890]*|"created": 946728000|')
|
||||||
expected='[[[{"id": "XXXXX",
|
expected='[[[{"id": "XXXXX",
|
||||||
|
@ -351,7 +351,7 @@ test_expect_success \
|
||||||
|
|
||||||
test_begin_subtest "decryption + signature verification"
|
test_begin_subtest "decryption + signature verification"
|
||||||
test_subtest_broken_gmime_2
|
test_subtest_broken_gmime_2
|
||||||
output=$(notmuch show --format=json --decrypt subject:"test encrypted message 002" \
|
output=$(notmuch show --format=json --decrypt=true subject:"test encrypted message 002" \
|
||||||
| notmuch_json_show_sanitize \
|
| notmuch_json_show_sanitize \
|
||||||
| sed -e 's|"created": [1234567890]*|"created": 946728000|')
|
| sed -e 's|"created": [1234567890]*|"created": 946728000|')
|
||||||
expected='[[[{"id": "XXXXX",
|
expected='[[[{"id": "XXXXX",
|
||||||
|
@ -384,7 +384,7 @@ test_expect_equal_json \
|
||||||
"$expected"
|
"$expected"
|
||||||
|
|
||||||
test_begin_subtest "reply to encrypted message"
|
test_begin_subtest "reply to encrypted message"
|
||||||
output=$(notmuch reply --decrypt subject:"test encrypted message 002" \
|
output=$(notmuch reply --decrypt=true subject:"test encrypted message 002" \
|
||||||
| notmuch_drop_mail_headers In-Reply-To References)
|
| notmuch_drop_mail_headers In-Reply-To References)
|
||||||
expected='From: Notmuch Test Suite <test_suite@notmuchmail.org>
|
expected='From: Notmuch Test Suite <test_suite@notmuchmail.org>
|
||||||
Subject: Re: test encrypted message 002
|
Subject: Re: test encrypted message 002
|
||||||
|
|
|
@ -197,14 +197,14 @@ test_expect_equal \
|
||||||
"$output" \
|
"$output" \
|
||||||
"$expected"
|
"$expected"
|
||||||
|
|
||||||
test_begin_subtest "show one of the messages with --decrypt"
|
test_begin_subtest "show one of the messages with --decrypt=true"
|
||||||
output=$(notmuch show --decrypt thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }')
|
output=$(notmuch show --decrypt=true thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }')
|
||||||
expected='This is a test encrypted message with a wumpus.'
|
expected='This is a test encrypted message with a wumpus.'
|
||||||
test_expect_equal \
|
test_expect_equal \
|
||||||
"$output" \
|
"$output" \
|
||||||
"$expected"
|
"$expected"
|
||||||
|
|
||||||
test_begin_subtest "Ensure that we cannot show the message without --decrypt"
|
test_begin_subtest "Ensure that we cannot show the message with --decrypt=auto"
|
||||||
output=$(notmuch show thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }')
|
output=$(notmuch show thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }')
|
||||||
expected='Non-text part: application/octet-stream'
|
expected='Non-text part: application/octet-stream'
|
||||||
test_expect_equal \
|
test_expect_equal \
|
||||||
|
|
|
@ -65,4 +65,36 @@ flags 1
|
||||||
EOF
|
EOF
|
||||||
test_expect_equal_file EXPECTED OUTPUT
|
test_expect_equal_file EXPECTED OUTPUT
|
||||||
|
|
||||||
|
test_begin_subtest "test keyword arguments without value"
|
||||||
|
$TEST_DIRECTORY/arg-test --boolkeyword bananas > OUTPUT
|
||||||
|
cat <<EOF > EXPECTED
|
||||||
|
boolkeyword 1
|
||||||
|
positional arg 1 bananas
|
||||||
|
EOF
|
||||||
|
test_expect_equal_file EXPECTED OUTPUT
|
||||||
|
|
||||||
|
test_begin_subtest "test keyword arguments with non-default value separted by a space"
|
||||||
|
$TEST_DIRECTORY/arg-test --boolkeyword false bananas > OUTPUT
|
||||||
|
cat <<EOF > EXPECTED
|
||||||
|
boolkeyword 0
|
||||||
|
positional arg 1 bananas
|
||||||
|
EOF
|
||||||
|
test_expect_equal_file EXPECTED OUTPUT
|
||||||
|
|
||||||
|
test_begin_subtest "test keyword arguments without value at the end"
|
||||||
|
$TEST_DIRECTORY/arg-test bananas --boolkeyword > OUTPUT
|
||||||
|
cat <<EOF > EXPECTED
|
||||||
|
boolkeyword 1
|
||||||
|
positional arg 1 bananas
|
||||||
|
EOF
|
||||||
|
test_expect_equal_file EXPECTED OUTPUT
|
||||||
|
|
||||||
|
test_begin_subtest "test keyword arguments without value but with = (should be an error)"
|
||||||
|
$TEST_DIRECTORY/arg-test bananas --boolkeyword= > OUTPUT 2>&1
|
||||||
|
cat <<EOF > EXPECTED
|
||||||
|
Unknown keyword argument "" for option "boolkeyword".
|
||||||
|
Unrecognized option: --boolkeyword=
|
||||||
|
EOF
|
||||||
|
test_expect_equal_file EXPECTED OUTPUT
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
|
@ -191,7 +191,7 @@ This is an error (see *Notmuch errors* for more details)
|
||||||
=== ERROR ===
|
=== ERROR ===
|
||||||
[XXX]
|
[XXX]
|
||||||
This is an error
|
This is an error
|
||||||
command: YYY/notmuch_fail show --format\\=sexp --format-version\\=4 --decrypt --exclude\\=false \\' \\* \\'
|
command: YYY/notmuch_fail show --format\\=sexp --format-version\\=4 --decrypt\\=true --exclude\\=false \\' \\* \\'
|
||||||
exit status: 1
|
exit status: 1
|
||||||
stderr:
|
stderr:
|
||||||
This is an error
|
This is an error
|
||||||
|
|
|
@ -7,13 +7,14 @@ int main(int argc, char **argv){
|
||||||
int opt_index=1;
|
int opt_index=1;
|
||||||
|
|
||||||
int kw_val=0;
|
int kw_val=0;
|
||||||
|
int kwb_val=0;
|
||||||
int fl_val=0;
|
int fl_val=0;
|
||||||
int int_val=0;
|
int int_val=0;
|
||||||
const char *pos_arg1=NULL;
|
const char *pos_arg1=NULL;
|
||||||
const char *pos_arg2=NULL;
|
const char *pos_arg2=NULL;
|
||||||
const char *string_val=NULL;
|
const char *string_val=NULL;
|
||||||
bool bool_val = false;
|
bool bool_val = false;
|
||||||
bool fl_set = false, int_set = false, bool_set = false,
|
bool fl_set = false, int_set = false, bool_set = false, kwb_set = false,
|
||||||
kw_set = false, string_set = false, pos1_set = false, pos2_set = false;
|
kw_set = false, string_set = false, pos1_set = false, pos2_set = false;
|
||||||
|
|
||||||
notmuch_opt_desc_t parent_options[] = {
|
notmuch_opt_desc_t parent_options[] = {
|
||||||
|
@ -33,6 +34,12 @@ int main(int argc, char **argv){
|
||||||
{ "one", 1 },
|
{ "one", 1 },
|
||||||
{ "two", 2 },
|
{ "two", 2 },
|
||||||
{ 0, 0 } } },
|
{ 0, 0 } } },
|
||||||
|
{ .opt_keyword = &kwb_val, .name = "boolkeyword", .present = &kwb_set,
|
||||||
|
.keyword_no_arg_value = "true", .keywords =
|
||||||
|
(notmuch_keyword_t []){ { "false", 0 },
|
||||||
|
{ "true", 1 },
|
||||||
|
{ "auto", 2 },
|
||||||
|
{ 0, 0 } } },
|
||||||
{ .opt_inherit = parent_options },
|
{ .opt_inherit = parent_options },
|
||||||
{ .opt_string = &string_val, .name = "string", .present = &string_set },
|
{ .opt_string = &string_val, .name = "string", .present = &string_set },
|
||||||
{ .opt_position = &pos_arg1, .present = &pos1_set },
|
{ .opt_position = &pos_arg1, .present = &pos1_set },
|
||||||
|
@ -51,6 +58,9 @@ int main(int argc, char **argv){
|
||||||
if (kw_set)
|
if (kw_set)
|
||||||
printf("keyword %d\n", kw_val);
|
printf("keyword %d\n", kw_val);
|
||||||
|
|
||||||
|
if (kwb_set)
|
||||||
|
printf("boolkeyword %d\n", kwb_val);
|
||||||
|
|
||||||
if (fl_set)
|
if (fl_set)
|
||||||
printf("flags %d\n", fl_val);
|
printf("flags %d\n", fl_val);
|
||||||
|
|
||||||
|
|
2
version
2
version
|
@ -1 +1 @@
|
||||||
0.26~rc0
|
0.26~rc1
|
||||||
|
|
Loading…
Reference in a new issue