+ _notmuch_search_cleanup (ctx);
+
+ return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+int
+notmuch_address_command (notmuch_database_t *notmuch, int argc, char *argv[])
+{
+ search_context_t *ctx = &search_context;
+ int opt_index, ret;
+
+ notmuch_opt_desc_t options[] = {
+ { .opt_flags = &ctx->output, .name = "output", .keywords =
+ (notmuch_keyword_t []){ { "sender", OUTPUT_SENDER },
+ { "recipients", OUTPUT_RECIPIENTS },
+ { "count", OUTPUT_COUNT },
+ { "address", OUTPUT_ADDRESS },
+ { 0, 0 } } },
+ { .opt_keyword = &ctx->exclude, .name = "exclude", .keywords =
+ (notmuch_keyword_t []){ { "true", NOTMUCH_EXCLUDE_TRUE },
+ { "false", NOTMUCH_EXCLUDE_FALSE },
+ { 0, 0 } } },
+ { .opt_keyword = &ctx->dedup, .name = "deduplicate", .keywords =
+ (notmuch_keyword_t []){ { "no", DEDUP_NONE },
+ { "mailbox", DEDUP_MAILBOX },
+ { "address", DEDUP_ADDRESS },
+ { 0, 0 } } },
+ { .opt_inherit = common_options },
+ { .opt_inherit = notmuch_shared_options },
+ { }
+ };
+
+ ctx->notmuch = notmuch;
+
+ opt_index = parse_arguments (argc, argv, options, 1);
+ if (opt_index < 0)
+ return EXIT_FAILURE;
+
+ notmuch_process_shared_options (argv[0]);
+
+ if (! (ctx->output & (OUTPUT_SENDER | OUTPUT_RECIPIENTS)))
+ ctx->output |= OUTPUT_SENDER;
+
+ if (ctx->output & OUTPUT_COUNT && ctx->dedup == DEDUP_NONE) {
+ fprintf (stderr, "--output=count is not applicable with --deduplicate=no\n");
+ return EXIT_FAILURE;
+ }
+
+ if (_notmuch_search_prepare (ctx, argc - opt_index, argv + opt_index))
+ return EXIT_FAILURE;
+
+ ctx->addresses = g_hash_table_new_full (strcase_hash, strcase_equal,
+ _talloc_free_for_g_hash,
+ _list_free_for_g_hash);
+
+ /* The order is not guaranteed if a full pass is required, so go
+ * for fastest. */
+ if (ctx->output & OUTPUT_COUNT || ctx->dedup == DEDUP_ADDRESS)
+ notmuch_query_set_sort (ctx->query, NOTMUCH_SORT_UNSORTED);
+
+ ret = do_search_messages (ctx);
+
+ g_hash_table_unref (ctx->addresses);
+
+