CLI/reply: convert to new config framework

This is messier than some of the other conversions because the
extensive use of 'config' as a talloc context.
This commit is contained in:
David Bremner 2020-11-07 21:58:32 -04:00
parent 0ab0b48be2
commit 8588719eb1
3 changed files with 108 additions and 52 deletions

View file

@ -112,25 +112,26 @@ match_address (const char *str, const char *address, address_match_t mode)
/* Match given string against user's configured "primary" and "other"
* addresses according to mode. */
static const char *
address_match (const char *str, notmuch_config_t *config, address_match_t mode)
address_match (const char *str, notmuch_database_t *notmuch, address_match_t mode)
{
const char *primary;
const char **other;
size_t i, other_len;
notmuch_config_values_t *other = NULL;
if (! str || *str == '\0')
return NULL;
primary = notmuch_config_get_user_primary_email (config);
primary = notmuch_config_get (notmuch, NOTMUCH_CONFIG_PRIMARY_EMAIL);
if (match_address (str, primary, mode))
return primary;
other = notmuch_config_get_user_other_email (config, &other_len);
for (i = 0; i < other_len; i++) {
if (match_address (str, other[i], mode))
return other[i];
}
for (other = notmuch_config_get_values (notmuch, NOTMUCH_CONFIG_OTHER_EMAIL);
notmuch_config_values_valid (other);
notmuch_config_values_move_to_next (other)) {
const char *addr = notmuch_config_values_get (other);
if (match_address (str, addr, mode))
return addr;
}
return NULL;
}
@ -138,26 +139,26 @@ address_match (const char *str, notmuch_config_t *config, address_match_t mode)
* user's "primary" or "other" addresses. If so, return the matching
* address, NULL otherwise. */
static const char *
user_address_in_string (const char *str, notmuch_config_t *config)
user_address_in_string (const char *str, notmuch_database_t *notmuch)
{
return address_match (str, config, USER_ADDRESS_IN_STRING);
return address_match (str, notmuch, USER_ADDRESS_IN_STRING);
}
/* Do any of the addresses configured as one of the user's "primary"
* or "other" addresses contain the given string. If so, return the
* matching address, NULL otherwise. */
static const char *
string_in_user_address (const char *str, notmuch_config_t *config)
string_in_user_address (const char *str, notmuch_database_t *notmuch)
{
return address_match (str, config, STRING_IN_USER_ADDRESS);
return address_match (str, notmuch, STRING_IN_USER_ADDRESS);
}
/* Is the given address configured as one of the user's "primary" or
* "other" addresses. */
static bool
address_is_users (const char *address, notmuch_config_t *config)
address_is_users (const char *address, notmuch_database_t *notmuch)
{
return address_match (address, config, STRING_IS_USER_ADDRESS) != NULL;
return address_match (address, notmuch, STRING_IS_USER_ADDRESS) != NULL;
}
/* Scan addresses in 'list'.
@ -175,7 +176,7 @@ address_is_users (const char *address, notmuch_config_t *config)
*/
static unsigned int
scan_address_list (InternetAddressList *list,
notmuch_config_t *config,
notmuch_database_t *notmuch,
GMimeMessage *message,
GMimeAddressType type,
const char **user_from)
@ -195,7 +196,7 @@ scan_address_list (InternetAddressList *list,
group = INTERNET_ADDRESS_GROUP (address);
group_list = internet_address_group_get_members (group);
n += scan_address_list (group_list, config, message, type, user_from);
n += scan_address_list (group_list, notmuch, message, type, user_from);
} else {
InternetAddressMailbox *mailbox;
const char *name;
@ -206,7 +207,7 @@ scan_address_list (InternetAddressList *list,
name = internet_address_get_name (address);
addr = internet_address_mailbox_get_addr (mailbox);
if (address_is_users (addr, config)) {
if (address_is_users (addr, notmuch)) {
if (user_from && *user_from == NULL)
*user_from = addr;
} else if (message) {
@ -324,7 +325,7 @@ get_bcc (GMimeMessage *message)
*/
static const char *
add_recipients_from_message (GMimeMessage *reply,
notmuch_config_t *config,
notmuch_database_t *notmuch,
GMimeMessage *message,
bool reply_all)
{
@ -346,7 +347,7 @@ add_recipients_from_message (GMimeMessage *reply,
recipients = reply_to_map[i].get_header (message);
n += scan_address_list (recipients, config, reply,
n += scan_address_list (recipients, notmuch, reply,
reply_to_map[i].recipient_type, &from_addr);
if (! reply_all && n) {
@ -384,7 +385,7 @@ add_recipients_from_message (GMimeMessage *reply,
* Return the address that was found, if any, and NULL otherwise.
*/
static const char *
guess_from_in_received_for (notmuch_config_t *config, const char *received)
guess_from_in_received_for (notmuch_database_t *notmuch, const char *received)
{
const char *ptr;
@ -392,7 +393,7 @@ guess_from_in_received_for (notmuch_config_t *config, const char *received)
if (! ptr)
return NULL;
return user_address_in_string (ptr, config);
return user_address_in_string (ptr, notmuch);
}
/*
@ -408,7 +409,7 @@ guess_from_in_received_for (notmuch_config_t *config, const char *received)
* Return the address that was found, if any, and NULL otherwise.
*/
static const char *
guess_from_in_received_by (notmuch_config_t *config, const char *received)
guess_from_in_received_by (notmuch_database_t *notmuch, const char *received)
{
const char *addr;
const char *by = received;
@ -446,7 +447,7 @@ guess_from_in_received_by (notmuch_config_t *config, const char *received)
*/
*(tld - 1) = '.';
addr = string_in_user_address (domain, config);
addr = string_in_user_address (domain, notmuch);
if (addr) {
free (mta);
return addr;
@ -469,12 +470,13 @@ guess_from_in_received_by (notmuch_config_t *config, const char *received)
* Return the address that was found, if any, and NULL otherwise.
*/
static const char *
guess_from_in_received_headers (notmuch_config_t *config,
notmuch_message_t *message)
guess_from_in_received_headers (notmuch_message_t *message)
{
const char *received, *addr;
char *sanitized;
notmuch_database_t *notmuch = notmuch_message_get_database (message);
received = notmuch_message_get_header (message, "received");
if (! received)
return NULL;
@ -483,9 +485,9 @@ guess_from_in_received_headers (notmuch_config_t *config,
if (! sanitized)
return NULL;
addr = guess_from_in_received_for (config, sanitized);
addr = guess_from_in_received_for (notmuch, sanitized);
if (! addr)
addr = guess_from_in_received_by (config, sanitized);
addr = guess_from_in_received_by (notmuch, sanitized);
talloc_free (sanitized);
@ -500,7 +502,7 @@ guess_from_in_received_headers (notmuch_config_t *config,
* Return the address that was found, if any, and NULL otherwise.
*/
static const char *
get_from_in_to_headers (notmuch_config_t *config, notmuch_message_t *message)
get_from_in_to_headers (notmuch_message_t *message)
{
size_t i;
const char *tohdr, *addr;
@ -510,11 +512,13 @@ get_from_in_to_headers (notmuch_config_t *config, notmuch_message_t *message)
"Delivered-To",
};
notmuch_database_t *notmuch = notmuch_message_get_database (message);
for (i = 0; i < ARRAY_SIZE (to_headers); i++) {
tohdr = notmuch_message_get_header (message, to_headers[i]);
/* Note: tohdr potentially contains a list of email addresses. */
addr = user_address_in_string (tohdr, config);
addr = user_address_in_string (tohdr, notmuch);
if (addr)
return addr;
}
@ -524,7 +528,6 @@ get_from_in_to_headers (notmuch_config_t *config, notmuch_message_t *message)
static GMimeMessage *
create_reply_message (void *ctx,
notmuch_config_t *config,
notmuch_message_t *message,
GMimeMessage *mime_message,
bool reply_all,
@ -532,7 +535,7 @@ create_reply_message (void *ctx,
{
const char *subject, *from_addr = NULL;
const char *in_reply_to, *orig_references, *references;
notmuch_database_t *notmuch = notmuch_message_get_database (message);
/*
* Use the below header order for limited headers, "pretty" order
* otherwise.
@ -558,7 +561,7 @@ create_reply_message (void *ctx,
g_mime_object_set_header (GMIME_OBJECT (reply), "References", references, NULL);
from_addr = add_recipients_from_message (reply, config,
from_addr = add_recipients_from_message (reply, notmuch,
mime_message, reply_all);
/* The above is all that is needed for limited headers. */
@ -578,7 +581,7 @@ create_reply_message (void *ctx,
* Delivered-To: headers.
*/
if (from_addr == NULL)
from_addr = get_from_in_to_headers (config, message);
from_addr = get_from_in_to_headers (message);
/*
* Check for a (for <email@add.res>) clause in Received: headers,
@ -586,14 +589,14 @@ create_reply_message (void *ctx,
* of Received: headers
*/
if (from_addr == NULL)
from_addr = guess_from_in_received_headers (config, message);
from_addr = guess_from_in_received_headers (message);
/* Default to user's primary address. */
if (from_addr == NULL)
from_addr = notmuch_config_get_user_primary_email (config);
from_addr = notmuch_config_get (notmuch, NOTMUCH_CONFIG_PRIMARY_EMAIL);
from_addr = talloc_asprintf (ctx, "%s <%s>",
notmuch_config_get_user_name (config),
notmuch_config_get (notmuch, NOTMUCH_CONFIG_USER_NAME),
from_addr);
g_mime_object_set_header (GMIME_OBJECT (reply), "From", from_addr, NULL);
@ -615,7 +618,7 @@ enum {
};
static int
do_reply (notmuch_config_t *config,
do_reply (notmuch_database_t *notmuch,
notmuch_query_t *query,
notmuch_show_params_t *params,
int format,
@ -641,9 +644,9 @@ do_reply (notmuch_config_t *config,
}
if (format == FORMAT_JSON)
sp = sprinter_json_create (config, stdout);
sp = sprinter_json_create (notmuch, stdout);
else
sp = sprinter_sexp_create (config, stdout);
sp = sprinter_sexp_create (notmuch, stdout);
}
status = notmuch_query_search_messages (query, &messages);
@ -655,10 +658,10 @@ do_reply (notmuch_config_t *config,
notmuch_messages_move_to_next (messages)) {
message = notmuch_messages_get (messages);
if (mime_node_open (config, message, &params->crypto, &node))
if (mime_node_open (notmuch, message, &params->crypto, &node))
return 1;
reply = create_reply_message (config, config, message,
reply = create_reply_message (notmuch, message,
GMIME_MESSAGE (node->part), reply_all,
format == FORMAT_HEADERS_ONLY);
if (! reply)
@ -675,7 +678,7 @@ do_reply (notmuch_config_t *config,
/* Start the original */
sp->map_key (sp, "original");
format_part_sprinter (config, sp, node, true, false);
format_part_sprinter (notmuch, sp, node, true, false);
/* End */
sp->end (sp);
@ -700,9 +703,8 @@ do_reply (notmuch_config_t *config,
}
int
notmuch_reply_command (notmuch_config_t *config, unused(notmuch_database_t *notmuch), int argc, char *argv[])
notmuch_reply_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
{
notmuch_database_t *notmuch;
notmuch_query_t *query;
char *query_string;
int opt_index;
@ -743,7 +745,7 @@ notmuch_reply_command (notmuch_config_t *config, unused(notmuch_database_t *notm
notmuch_exit_if_unsupported_format ();
query_string = query_string_from_args (config, argc - opt_index, argv + opt_index);
query_string = query_string_from_args (notmuch, argc - opt_index, argv + opt_index);
if (query_string == NULL) {
fprintf (stderr, "Out of memory\n");
return EXIT_FAILURE;
@ -754,10 +756,6 @@ notmuch_reply_command (notmuch_config_t *config, unused(notmuch_database_t *notm
return EXIT_FAILURE;
}
if (notmuch_database_open (notmuch_config_get_database_path (config),
NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))
return EXIT_FAILURE;
notmuch_exit_if_unmatched_db_uuid (notmuch);
query = notmuch_query_create (notmuch, query_string);
@ -766,7 +764,7 @@ notmuch_reply_command (notmuch_config_t *config, unused(notmuch_database_t *notm
return EXIT_FAILURE;
}
if (do_reply (config, query, &params, format, reply_all) != 0)
if (do_reply (notmuch, query, &params, format, reply_all) != 0)
return EXIT_FAILURE;
_notmuch_crypto_cleanup (&params.crypto);

View file

@ -155,7 +155,7 @@ static command_t commands[] = {
"Show all messages matching the search terms." },
{ "count", notmuch_count_command, NOTMUCH_COMMAND_DATABASE_EARLY,
"Count messages matching the search terms." },
{ "reply", notmuch_reply_command, NOTMUCH_COMMAND_CONFIG_OPEN,
{ "reply", notmuch_reply_command, NOTMUCH_COMMAND_DATABASE_EARLY,
"Construct a reply template for a set of messages." },
{ "tag", notmuch_tag_command, NOTMUCH_COMMAND_CONFIG_OPEN,
"Add/remove tags for all messages matching the search terms." },

View file

@ -210,4 +210,62 @@ count2=$(notmuch count --lastmod '*' | cut -f3)
restore_config
test_expect_success "test '$count2 -gt $count1'"
add_message '[from]="Sender <sender@example.com>"' \
[to]=test_suite@notmuchmail.org \
'[cc]="Other Parties <cc@example.com>"' \
[subject]=notmuch-reply-test \
'[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
'[body]="reply with CC"'
cat <<EOF > EXPECTED
Before:
After:
From: Notmuch Test Suite <test_suite@notmuchmail.org>
Subject: Re: notmuch-reply-test
To: Sender <sender@example.com>
Cc: Other Parties <cc@example.com>
In-Reply-To: <${gen_msg_id}>
References: <${gen_msg_id}>
On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
> reply with CC
EOF
test_begin_subtest "reply with saved query from config file"
backup_config
query_name="test${RANDOM}"
printf "Before:\n" > OUTPUT
notmuch reply query:$query_name 2>&1 >> OUTPUT
printf "\n[query]\n${query_name} = id:${gen_msg_id}\n" >> notmuch-config
printf "After:\n" >> OUTPUT
notmuch reply query:$query_name >> OUTPUT
restore_config
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "reply with saved query from config file (xdg)"
backup_config
query_name="test${RANDOM}"
xdg_config
printf "Before:\n" > OUTPUT
notmuch reply query:$query_name 2>&1 >> OUTPUT
printf "\n[query]\n${query_name} = id:${gen_msg_id}\n" >> ${CONFIG_PATH}
printf "After:\n" >> OUTPUT
notmuch reply query:$query_name >> OUTPUT
restore_config
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "reply with saved query from config file (xdg+profile)"
backup_config
query_name="test${RANDOM}"
xdg_config $query_name
printf "Before:\n" > OUTPUT
notmuch reply query:$query_name 2>&1 >> OUTPUT
printf "\n[query]\n${query_name} = id:${gen_msg_id}\n" >> ${CONFIG_PATH}
printf "After:\n" >> OUTPUT
notmuch reply query:$query_name >> OUTPUT
restore_config
test_expect_equal_file EXPECTED OUTPUT
test_done