[PATCH v2 5/6] cli: move config open/close to main() from subcommands
authorJani Nikula <jani@nikula.org>
Sun, 3 Mar 2013 21:55:09 +0000 (23:55 +0200)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:53:54 +0000 (09:53 -0800)
ab/d1dd00e06314199c2ed213a4210320b2840e6f [new file with mode: 0644]

diff --git a/ab/d1dd00e06314199c2ed213a4210320b2840e6f b/ab/d1dd00e06314199c2ed213a4210320b2840e6f
new file mode 100644 (file)
index 0000000..b6def15
--- /dev/null
@@ -0,0 +1,884 @@
+Return-Path: <jani@nikula.org>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id C4130429E36\r
+       for <notmuch@notmuchmail.org>; Sun,  3 Mar 2013 13:55:42 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References"\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.7\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
+       tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id ywBCbdX2FNZV for <notmuch@notmuchmail.org>;\r
+       Sun,  3 Mar 2013 13:55:35 -0800 (PST)\r
+Received: from mail-la0-f51.google.com (mail-la0-f51.google.com\r
+       [209.85.215.51]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
+       (No client certificate requested)\r
+       by olra.theworths.org (Postfix) with ESMTPS id C7C37431FC4\r
+       for <notmuch@notmuchmail.org>; Sun,  3 Mar 2013 13:55:28 -0800 (PST)\r
+Received: by mail-la0-f51.google.com with SMTP id fo13so4452375lab.38\r
+       for <notmuch@notmuchmail.org>; Sun, 03 Mar 2013 13:55:27 -0800 (PST)\r
+X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;\r
+       d=google.com; s=20120113;\r
+       h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to\r
+       :references:in-reply-to:references:x-gm-message-state;\r
+       bh=O+JcirM1yFTlgiq9i/P1lfsmc7YoUJ92yBY8yiKiecg=;\r
+       b=jjmA21zLq2DXcRoKxCTFxgK5ZlmU+ft8SJ16pW23sXm4igeMzarAdgKxDWopKujZaz\r
+       DF9C437ZSc/kjYUIOLCU8hyg3YbxcO/ugseR0Z0txQsFjdzFAXCmqYxGYq3NhewXlIx0\r
+       4Xg9qlxsLQV/c27wXu4NrwGZbsFBNATqdCNYh6cjQCBQ2JXzvq339xvpb5YGd0lX5TGr\r
+       TbWNnguuQWCkn+tm5VXeXlxJe3R+JcoIoZY0EvOwQThqR7wOvYLiaRZ7TEteYALR3IVp\r
+       m0SJAZpvlGLosrrXUQASWle5PW+7r+TJAi+N4fKLjmu8YVsyGLITCvs4Zz/94OKdCfv0\r
+       uW5w==\r
+X-Received: by 10.112.23.232 with SMTP id p8mr3714912lbf.38.1362347727087;\r
+       Sun, 03 Mar 2013 13:55:27 -0800 (PST)\r
+Received: from localhost (dsl-hkibrasgw4-50df51-27.dhcp.inet.fi.\r
+       [80.223.81.27])\r
+       by mx.google.com with ESMTPS id gm20sm10730463lab.7.2013.03.03.13.55.25\r
+       (version=TLSv1.2 cipher=RC4-SHA bits=128/128);\r
+       Sun, 03 Mar 2013 13:55:26 -0800 (PST)\r
+From: Jani Nikula <jani@nikula.org>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH v2 5/6] cli: move config open/close to main() from subcommands\r
+Date: Sun,  3 Mar 2013 23:55:09 +0200\r
+Message-Id:\r
+ <75b8b04e4d63d67ec79ffe2379829add96b37be0.1362347362.git.jani@nikula.org>\r
+X-Mailer: git-send-email 1.7.10.4\r
+In-Reply-To: <cover.1362347362.git.jani@nikula.org>\r
+References: <cover.1362347362.git.jani@nikula.org>\r
+In-Reply-To: <cover.1362347362.git.jani@nikula.org>\r
+References: <cover.1362347362.git.jani@nikula.org>\r
+X-Gm-Message-State:\r
+ ALoCoQlzeLlLN4cbh8oEbSglSr32TjWfYsb8rIhIiVoprRoQPrNb6l1pNlICR64Pi6ZP9lHZW9Ci\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Sun, 03 Mar 2013 21:55:43 -0000\r
+\r
+This allows specifying config file as a top level argument to notmuch,\r
+and generally makes it possible to override config file options in\r
+main(), without having to touch the subcommands.\r
+\r
+If the config file does not exist, one will be created for the notmuch\r
+main command and setup and help subcommands. Help is special in this\r
+regard; the config is created just to avoid errors about missing\r
+config, but it will not be saved.\r
+\r
+This also makes notmuch config the talloc context for subcommands.\r
+---\r
+ notmuch-client.h  |   30 +++++++++++---------------\r
+ notmuch-config.c  |   40 +++++++----------------------------\r
+ notmuch-count.c   |   11 +++-------\r
+ notmuch-dump.c    |    7 +-----\r
+ notmuch-new.c     |   17 ++++++---------\r
+ notmuch-reply.c   |   15 +++++--------\r
+ notmuch-restore.c |   11 +++-------\r
+ notmuch-search.c  |   15 +++++--------\r
+ notmuch-setup.c   |   17 ++++++---------\r
+ notmuch-show.c    |   15 +++++--------\r
+ notmuch-tag.c     |   15 +++++--------\r
+ notmuch.c         |   61 +++++++++++++++++++++++++++--------------------------\r
+ 12 files changed, 91 insertions(+), 163 deletions(-)\r
+\r
+diff --git a/notmuch-client.h b/notmuch-client.h\r
+index b3dcb21..45749a6 100644\r
+--- a/notmuch-client.h\r
++++ b/notmuch-client.h\r
+@@ -150,6 +150,8 @@ chomp_newline (char *str)\r
+  */\r
+ extern int notmuch_format_version;\r
\r
++typedef struct _notmuch_config notmuch_config_t;\r
++\r
+ /* Commands that support structured output should support the\r
+  * following argument\r
+  *  { NOTMUCH_OPT_INT, &notmuch_format_version, "format-version", 0, 0 }\r
+@@ -169,40 +171,34 @@ int\r
+ notmuch_crypto_cleanup (notmuch_crypto_t *crypto);\r
\r
+ int\r
+-notmuch_count_command (void *ctx, int argc, char *argv[]);\r
+-\r
+-int\r
+-notmuch_dump_command (void *ctx, int argc, char *argv[]);\r
++notmuch_count_command (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ int\r
+-notmuch_new_command (void *ctx, int argc, char *argv[]);\r
++notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ int\r
+-notmuch_reply_command (void *ctx, int argc, char *argv[]);\r
++notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ int\r
+-notmuch_restore_command (void *ctx, int argc, char *argv[]);\r
++notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ int\r
+-notmuch_search_command (void *ctx, int argc, char *argv[]);\r
++notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ int\r
+-notmuch_setup_command (void *ctx, int argc, char *argv[]);\r
++notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ int\r
+-notmuch_show_command (void *ctx, int argc, char *argv[]);\r
++notmuch_setup_command (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ int\r
+-notmuch_tag_command (void *ctx, int argc, char *argv[]);\r
++notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ int\r
+-notmuch_search_tags_command (void *ctx, int argc, char *argv[]);\r
++notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ int\r
+-notmuch_cat_command (void *ctx, int argc, char *argv[]);\r
+-\r
+-int\r
+-notmuch_config_command (void *ctx, int argc, char *argv[]);\r
++notmuch_config_command (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ const char *\r
+ notmuch_time_relative_date (const void *ctx, time_t then);\r
+@@ -243,8 +239,6 @@ json_quote_str (const void *ctx, const char *str);\r
\r
+ /* notmuch-config.c */\r
\r
+-typedef struct _notmuch_config notmuch_config_t;\r
+-\r
+ notmuch_config_t *\r
+ notmuch_config_open (void *ctx,\r
+                    const char *filename,\r
+diff --git a/notmuch-config.c b/notmuch-config.c\r
+index 247fbe4..48312e3 100644\r
+--- a/notmuch-config.c\r
++++ b/notmuch-config.c\r
+@@ -705,14 +705,8 @@ _item_split (char *item, char **group, char **key)\r
+ }\r
\r
+ static int\r
+-notmuch_config_command_get (void *ctx, char *item)\r
++notmuch_config_command_get (notmuch_config_t *config, char *item)\r
+ {\r
+-    notmuch_config_t *config;\r
+-\r
+-    config = notmuch_config_open (ctx, NULL, FALSE);\r
+-    if (config == NULL)\r
+-      return 1;\r
+-\r
+     if (strcmp(item, "database.path") == 0) {\r
+       printf ("%s\n", notmuch_config_get_database_path (config));\r
+     } else if (strcmp(item, "user.name") == 0) {\r
+@@ -756,25 +750,17 @@ notmuch_config_command_get (void *ctx, char *item)\r
+       g_strfreev (value);\r
+     }\r
\r
+-    notmuch_config_close (config);\r
+-\r
+     return 0;\r
+ }\r
\r
+ static int\r
+-notmuch_config_command_set (void *ctx, char *item, int argc, char *argv[])\r
++notmuch_config_command_set (notmuch_config_t *config, char *item, int argc, char *argv[])\r
+ {\r
+-    notmuch_config_t *config;\r
+     char *group, *key;\r
+-    int ret;\r
\r
+     if (_item_split (item, &group, &key))\r
+       return 1;\r
\r
+-    config = notmuch_config_open (ctx, NULL, FALSE);\r
+-    if (config == NULL)\r
+-      return 1;\r
+-\r
+     /* With only the name of an item, we clear it from the\r
+      * configuration file.\r
+      *\r
+@@ -795,23 +781,15 @@ notmuch_config_command_set (void *ctx, char *item, int argc, char *argv[])\r
+       break;\r
+     }\r
\r
+-    ret = notmuch_config_save (config);\r
+-    notmuch_config_close (config);\r
+-\r
+-    return ret;\r
++    return notmuch_config_save (config);\r
+ }\r
\r
+ static int\r
+-notmuch_config_command_list (void *ctx)\r
++notmuch_config_command_list (notmuch_config_t *config)\r
+ {\r
+-    notmuch_config_t *config;\r
+     char **groups;\r
+     size_t g, groups_length;\r
\r
+-    config = notmuch_config_open (ctx, NULL, FALSE);\r
+-    if (config == NULL)\r
+-      return 1;\r
+-\r
+     groups = g_key_file_get_groups (config->key_file, &groups_length);\r
+     if (groups == NULL)\r
+       return 1;\r
+@@ -841,13 +819,11 @@ notmuch_config_command_list (void *ctx)\r
\r
+     g_strfreev (groups);\r
\r
+-    notmuch_config_close (config);\r
+-\r
+     return 0;\r
+ }\r
\r
+ int\r
+-notmuch_config_command (void *ctx, int argc, char *argv[])\r
++notmuch_config_command (notmuch_config_t *config, int argc, char *argv[])\r
+ {\r
+     argc--; argv++; /* skip subcommand argument */\r
\r
+@@ -862,16 +838,16 @@ notmuch_config_command (void *ctx, int argc, char *argv[])\r
+                    "one argument.\n");\r
+           return 1;\r
+       }\r
+-      return notmuch_config_command_get (ctx, argv[1]);\r
++      return notmuch_config_command_get (config, argv[1]);\r
+     } else if (strcmp (argv[0], "set") == 0) {\r
+       if (argc < 2) {\r
+           fprintf (stderr, "Error: notmuch config set requires at least "\r
+                    "one argument.\n");\r
+           return 1;\r
+       }\r
+-      return notmuch_config_command_set (ctx, argv[1], argc - 2, argv + 2);\r
++      return notmuch_config_command_set (config, argv[1], argc - 2, argv + 2);\r
+     } else if (strcmp (argv[0], "list") == 0) {\r
+-      return notmuch_config_command_list (ctx);\r
++      return notmuch_config_command_list (config);\r
+     }\r
\r
+     fprintf (stderr, "Unrecognized argument for notmuch config: %s\n",\r
+diff --git a/notmuch-count.c b/notmuch-count.c\r
+index 61722ed..390794f 100644\r
+--- a/notmuch-count.c\r
++++ b/notmuch-count.c\r
+@@ -33,9 +33,8 @@ enum {\r
+ };\r
\r
+ int\r
+-notmuch_count_command (void *ctx, int argc, char *argv[])\r
++notmuch_count_command (notmuch_config_t *config, int argc, char *argv[])\r
+ {\r
+-    notmuch_config_t *config;\r
+     notmuch_database_t *notmuch;\r
+     notmuch_query_t *query;\r
+     char *query_str;\r
+@@ -62,22 +61,18 @@ notmuch_count_command (void *ctx, int argc, char *argv[])\r
+       return 1;\r
+     }\r
\r
+-    config = notmuch_config_open (ctx, NULL, FALSE);\r
+-    if (config == NULL)\r
+-      return 1;\r
+-\r
+     if (notmuch_database_open (notmuch_config_get_database_path (config),\r
+                              NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))\r
+       return 1;\r
\r
+-    query_str = query_string_from_args (ctx, argc-opt_index, argv+opt_index);\r
++    query_str = query_string_from_args (config, argc-opt_index, argv+opt_index);\r
+     if (query_str == NULL) {\r
+       fprintf (stderr, "Out of memory.\n");\r
+       return 1;\r
+     }\r
\r
+     if (*query_str == '\0') {\r
+-      query_str = talloc_strdup (ctx, "");\r
++      query_str = talloc_strdup (config, "");\r
+     }\r
\r
+     query = notmuch_query_create (notmuch, query_str);\r
+diff --git a/notmuch-dump.c b/notmuch-dump.c\r
+index 845a67e..2024e30 100644\r
+--- a/notmuch-dump.c\r
++++ b/notmuch-dump.c\r
+@@ -23,9 +23,8 @@\r
+ #include "string-util.h"\r
\r
+ int\r
+-notmuch_dump_command (unused (void *ctx), int argc, char *argv[])\r
++notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])\r
+ {\r
+-    notmuch_config_t *config;\r
+     notmuch_database_t *notmuch;\r
+     notmuch_query_t *query;\r
+     FILE *output = stdout;\r
+@@ -34,10 +33,6 @@ notmuch_dump_command (unused (void *ctx), int argc, char *argv[])\r
+     notmuch_tags_t *tags;\r
+     const char *query_str = "";\r
\r
+-    config = notmuch_config_open (ctx, NULL, FALSE);\r
+-    if (config == NULL)\r
+-      return 1;\r
+-\r
+     if (notmuch_database_open (notmuch_config_get_database_path (config),\r
+                              NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))\r
+       return 1;\r
+diff --git a/notmuch-new.c b/notmuch-new.c\r
+index 4915418..faa33f1 100644\r
+--- a/notmuch-new.c\r
++++ b/notmuch-new.c\r
+@@ -840,9 +840,8 @@ _remove_directory (void *ctx,\r
+ }\r
\r
+ int\r
+-notmuch_new_command (void *ctx, int argc, char *argv[])\r
++notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])\r
+ {\r
+-    notmuch_config_t *config;\r
+     notmuch_database_t *notmuch;\r
+     add_files_state_t add_files_state;\r
+     double elapsed;\r
+@@ -875,10 +874,6 @@ notmuch_new_command (void *ctx, int argc, char *argv[])\r
+       return 1;\r
+     }\r
\r
+-    config = notmuch_config_open (ctx, NULL, FALSE);\r
+-    if (config == NULL)\r
+-      return 1;\r
+-\r
+     add_files_state.new_tags = notmuch_config_get_new_tags (config, &add_files_state.new_tags_length);\r
+     add_files_state.new_ignore = notmuch_config_get_new_ignore (config, &add_files_state.new_ignore_length);\r
+     add_files_state.synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);\r
+@@ -890,7 +885,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[])\r
+           return ret;\r
+     }\r
\r
+-    dot_notmuch_path = talloc_asprintf (ctx, "%s/%s", db_path, ".notmuch");\r
++    dot_notmuch_path = talloc_asprintf (config, "%s/%s", db_path, ".notmuch");\r
\r
+     if (stat (dot_notmuch_path, &st)) {\r
+       int count;\r
+@@ -941,9 +936,9 @@ notmuch_new_command (void *ctx, int argc, char *argv[])\r
+     add_files_state.removed_messages = add_files_state.renamed_messages = 0;\r
+     gettimeofday (&add_files_state.tv_start, NULL);\r
\r
+-    add_files_state.removed_files = _filename_list_create (ctx);\r
+-    add_files_state.removed_directories = _filename_list_create (ctx);\r
+-    add_files_state.directory_mtimes = _filename_list_create (ctx);\r
++    add_files_state.removed_files = _filename_list_create (config);\r
++    add_files_state.removed_directories = _filename_list_create (config);\r
++    add_files_state.directory_mtimes = _filename_list_create (config);\r
\r
+     if (! debugger_is_active () && add_files_state.output_is_a_tty\r
+       && ! add_files_state.verbose) {\r
+@@ -970,7 +965,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[])\r
\r
+     gettimeofday (&tv_start, NULL);\r
+     for (f = add_files_state.removed_directories->head, i = 0; f && !interrupted; f = f->next, i++) {\r
+-      ret = _remove_directory (ctx, notmuch, f->filename, &add_files_state);\r
++      ret = _remove_directory (config, notmuch, f->filename, &add_files_state);\r
+       if (ret)\r
+           goto DONE;\r
+       if (do_print_progress) {\r
+diff --git a/notmuch-reply.c b/notmuch-reply.c\r
+index 9da42b9..e151f78 100644\r
+--- a/notmuch-reply.c\r
++++ b/notmuch-reply.c\r
+@@ -702,9 +702,8 @@ enum {\r
+ };\r
\r
+ int\r
+-notmuch_reply_command (void *ctx, int argc, char *argv[])\r
++notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])\r
+ {\r
+-    notmuch_config_t *config;\r
+     notmuch_database_t *notmuch;\r
+     notmuch_query_t *query;\r
+     char *query_string;\r
+@@ -752,21 +751,17 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])\r
+       reply_format_func = notmuch_reply_format_headers_only;\r
+     } else if (format == FORMAT_JSON) {\r
+       reply_format_func = notmuch_reply_format_sprinter;\r
+-      sp = sprinter_json_create (ctx, stdout);\r
++      sp = sprinter_json_create (config, stdout);\r
+     } else if (format == FORMAT_SEXP) {\r
+       reply_format_func = notmuch_reply_format_sprinter;\r
+-      sp = sprinter_sexp_create (ctx, stdout);\r
++      sp = sprinter_sexp_create (config, stdout);\r
+     } else {\r
+       reply_format_func = notmuch_reply_format_default;\r
+     }\r
\r
+     notmuch_exit_if_unsupported_format ();\r
\r
+-    config = notmuch_config_open (ctx, NULL, FALSE);\r
+-    if (config == NULL)\r
+-      return 1;\r
+-\r
+-    query_string = query_string_from_args (ctx, argc-opt_index, argv+opt_index);\r
++    query_string = query_string_from_args (config, argc-opt_index, argv+opt_index);\r
+     if (query_string == NULL) {\r
+       fprintf (stderr, "Out of memory\n");\r
+       return 1;\r
+@@ -787,7 +782,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])\r
+       return 1;\r
+     }\r
\r
+-    if (reply_format_func (ctx, config, query, &params, reply_all, sp) != 0)\r
++    if (reply_format_func (config, config, query, &params, reply_all, sp) != 0)\r
+       return 1;\r
\r
+     notmuch_crypto_cleanup (&params.crypto);\r
+diff --git a/notmuch-restore.c b/notmuch-restore.c\r
+index dd2507f..1419621 100644\r
+--- a/notmuch-restore.c\r
++++ b/notmuch-restore.c\r
+@@ -120,9 +120,8 @@ parse_sup_line (void *ctx, char *line,\r
+ }\r
\r
+ int\r
+-notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
++notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])\r
+ {\r
+-    notmuch_config_t *config;\r
+     notmuch_database_t *notmuch;\r
+     notmuch_bool_t accumulate = FALSE;\r
+     tag_op_flag_t flags = 0;\r
+@@ -139,10 +138,6 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
+     int opt_index;\r
+     int input_format = DUMP_FORMAT_AUTO;\r
\r
+-    config = notmuch_config_open (ctx, NULL, FALSE);\r
+-    if (config == NULL)\r
+-      return 1;\r
+-\r
+     if (notmuch_database_open (notmuch_config_get_database_path (config),\r
+                              NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch))\r
+       return 1;\r
+@@ -187,7 +182,7 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
+       return 1;\r
+     }\r
\r
+-    tag_ops = tag_op_list_create (ctx);\r
++    tag_ops = tag_op_list_create (config);\r
+     if (tag_ops == NULL) {\r
+       fprintf (stderr, "Out of memory.\n");\r
+       return 1;\r
+@@ -226,7 +221,7 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
+       if (line_ctx != NULL)\r
+           talloc_free (line_ctx);\r
\r
+-      line_ctx = talloc_new (ctx);\r
++      line_ctx = talloc_new (config);\r
+       if (input_format == DUMP_FORMAT_SUP) {\r
+           ret = parse_sup_line (line_ctx, line, &query_string, tag_ops);\r
+       } else {\r
+diff --git a/notmuch-search.c b/notmuch-search.c\r
+index fac6663..e658639 100644\r
+--- a/notmuch-search.c\r
++++ b/notmuch-search.c\r
+@@ -290,9 +290,8 @@ enum {\r
+ };\r
\r
+ int\r
+-notmuch_search_command (void *ctx, int argc, char *argv[])\r
++notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])\r
+ {\r
+-    notmuch_config_t *config;\r
+     notmuch_database_t *notmuch;\r
+     notmuch_query_t *query;\r
+     char *query_str;\r
+@@ -349,20 +348,20 @@ notmuch_search_command (void *ctx, int argc, char *argv[])\r
\r
+     switch (format_sel) {\r
+     case NOTMUCH_FORMAT_TEXT:\r
+-      format = sprinter_text_create (ctx, stdout);\r
++      format = sprinter_text_create (config, stdout);\r
+       break;\r
+     case NOTMUCH_FORMAT_TEXT0:\r
+       if (output == OUTPUT_SUMMARY) {\r
+           fprintf (stderr, "Error: --format=text0 is not compatible with --output=summary.\n");\r
+           return 1;\r
+       }\r
+-      format = sprinter_text0_create (ctx, stdout);\r
++      format = sprinter_text0_create (config, stdout);\r
+       break;\r
+     case NOTMUCH_FORMAT_JSON:\r
+-      format = sprinter_json_create (ctx, stdout);\r
++      format = sprinter_json_create (config, stdout);\r
+       break;\r
+     case NOTMUCH_FORMAT_SEXP:\r
+-      format = sprinter_sexp_create (ctx, stdout);\r
++      format = sprinter_sexp_create (config, stdout);\r
+       break;\r
+     default:\r
+       /* this should never happen */\r
+@@ -371,10 +370,6 @@ notmuch_search_command (void *ctx, int argc, char *argv[])\r
\r
+     notmuch_exit_if_unsupported_format ();\r
\r
+-    config = notmuch_config_open (ctx, NULL, FALSE);\r
+-    if (config == NULL)\r
+-      return 1;\r
+-\r
+     if (notmuch_database_open (notmuch_config_get_database_path (config),\r
+                              NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))\r
+       return 1;\r
+diff --git a/notmuch-setup.c b/notmuch-setup.c\r
+index 72d862a..475248b 100644\r
+--- a/notmuch-setup.c\r
++++ b/notmuch-setup.c\r
+@@ -120,12 +120,11 @@ parse_tag_list (void *ctx, char *response)\r
+ }\r
\r
+ int\r
+-notmuch_setup_command (unused (void *ctx),\r
++notmuch_setup_command (notmuch_config_t *config,\r
+                      unused (int argc), unused (char *argv[]))\r
+ {\r
+     char *response = NULL;\r
+     size_t response_size = 0;\r
+-    notmuch_config_t *config;\r
+     const char **old_other_emails;\r
+     size_t old_other_emails_len;\r
+     GPtrArray *other_emails;\r
+@@ -146,8 +145,6 @@ notmuch_setup_command (unused (void *ctx),\r
+       chomp_newline (response);                               \\r
+     } while (0)\r
\r
+-    config = notmuch_config_open (ctx, NULL, TRUE);\r
+-\r
+     if (notmuch_config_is_new (config))\r
+       welcome_message_pre_setup ();\r
\r
+@@ -167,16 +164,16 @@ notmuch_setup_command (unused (void *ctx),\r
+     for (i = 0; i < old_other_emails_len; i++) {\r
+       prompt ("Additional email address [%s]: ", old_other_emails[i]);\r
+       if (strlen (response))\r
+-          g_ptr_array_add (other_emails, talloc_strdup (ctx, response));\r
++          g_ptr_array_add (other_emails, talloc_strdup (config, response));\r
+       else\r
+-          g_ptr_array_add (other_emails, talloc_strdup (ctx,\r
++          g_ptr_array_add (other_emails, talloc_strdup (config,\r
+                                                        old_other_emails[i]));\r
+     }\r
\r
+     do {\r
+       prompt ("Additional email address [Press 'Enter' if none]: ");\r
+       if (strlen (response))\r
+-          g_ptr_array_add (other_emails, talloc_strdup (ctx, response));\r
++          g_ptr_array_add (other_emails, talloc_strdup (config, response));\r
+     } while (strlen (response));\r
+     if (other_emails->len)\r
+       notmuch_config_set_user_other_email (config,\r
+@@ -190,7 +187,7 @@ notmuch_setup_command (unused (void *ctx),\r
+     if (strlen (response)) {\r
+       const char *absolute_path;\r
\r
+-      absolute_path = make_path_absolute (ctx, response);\r
++      absolute_path = make_path_absolute (config, response);\r
+       notmuch_config_set_database_path (config, absolute_path);\r
+     }\r
\r
+@@ -201,7 +198,7 @@ notmuch_setup_command (unused (void *ctx),\r
+     prompt ("]: ");\r
\r
+     if (strlen (response)) {\r
+-      GPtrArray *tags = parse_tag_list (ctx, response);\r
++      GPtrArray *tags = parse_tag_list (config, response);\r
\r
+       notmuch_config_set_new_tags (config, (const char **) tags->pdata,\r
+                                    tags->len);\r
+@@ -217,7 +214,7 @@ notmuch_setup_command (unused (void *ctx),\r
+     prompt ("]: ");\r
\r
+     if (strlen (response)) {\r
+-      GPtrArray *tags = parse_tag_list (ctx, response);\r
++      GPtrArray *tags = parse_tag_list (config, response);\r
\r
+       notmuch_config_set_search_exclude_tags (config,\r
+                                               (const char **) tags->pdata,\r
+diff --git a/notmuch-show.c b/notmuch-show.c\r
+index 5ae5d7d..c2ec122 100644\r
+--- a/notmuch-show.c\r
++++ b/notmuch-show.c\r
+@@ -1056,9 +1056,8 @@ enum {\r
+ };\r
\r
+ int\r
+-notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))\r
++notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])\r
+ {\r
+-    notmuch_config_t *config;\r
+     notmuch_database_t *notmuch;\r
+     notmuch_query_t *query;\r
+     char *query_string;\r
+@@ -1176,11 +1175,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))\r
+     else\r
+       params.entire_thread = FALSE;\r
\r
+-    config = notmuch_config_open (ctx, NULL, FALSE);\r
+-    if (config == NULL)\r
+-      return 1;\r
+-\r
+-    query_string = query_string_from_args (ctx, argc-opt_index, argv+opt_index);\r
++    query_string = query_string_from_args (config, argc-opt_index, argv+opt_index);\r
+     if (query_string == NULL) {\r
+       fprintf (stderr, "Out of memory\n");\r
+       return 1;\r
+@@ -1202,11 +1197,11 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))\r
+     }\r
\r
+     /* Create structure printer. */\r
+-    sprinter = format->new_sprinter(ctx, stdout);\r
++    sprinter = format->new_sprinter(config, stdout);\r
\r
+     /* If a single message is requested we do not use search_excludes. */\r
+     if (params.part >= 0)\r
+-      ret = do_show_single (ctx, query, format, sprinter, &params);\r
++      ret = do_show_single (config, query, format, sprinter, &params);\r
+     else {\r
+       /* We always apply set the exclude flag. The\r
+        * exclude=true|false option controls whether or not we return\r
+@@ -1225,7 +1220,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))\r
+           params.omit_excluded = FALSE;\r
+       }\r
\r
+-      ret = do_show (ctx, query, format, sprinter, &params);\r
++      ret = do_show (config, query, format, sprinter, &params);\r
+     }\r
\r
+     notmuch_crypto_cleanup (&params.crypto);\r
+diff --git a/notmuch-tag.c b/notmuch-tag.c\r
+index 148e856..0e73197 100644\r
+--- a/notmuch-tag.c\r
++++ b/notmuch-tag.c\r
+@@ -178,11 +178,10 @@ tag_file (void *ctx, notmuch_database_t *notmuch, tag_op_flag_t flags,\r
+ }\r
\r
+ int\r
+-notmuch_tag_command (void *ctx, int argc, char *argv[])\r
++notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[])\r
+ {\r
+     tag_op_list_t *tag_ops = NULL;\r
+     char *query_string = NULL;\r
+-    notmuch_config_t *config;\r
+     notmuch_database_t *notmuch;\r
+     struct sigaction action;\r
+     tag_op_flag_t tag_flags = TAG_FLAG_NONE;\r
+@@ -225,21 +224,17 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])\r
+           return 1;\r
+       }\r
+     } else {\r
+-      tag_ops = tag_op_list_create (ctx);\r
++      tag_ops = tag_op_list_create (config);\r
+       if (tag_ops == NULL) {\r
+           fprintf (stderr, "Out of memory.\n");\r
+           return 1;\r
+       }\r
\r
+-      if (parse_tag_command_line (ctx, argc - opt_index, argv + opt_index,\r
++      if (parse_tag_command_line (config, argc - opt_index, argv + opt_index,\r
+                                   &query_string, tag_ops))\r
+           return 1;\r
+     }\r
\r
+-    config = notmuch_config_open (ctx, NULL, FALSE);\r
+-    if (config == NULL)\r
+-      return 1;\r
+-\r
+     if (notmuch_database_open (notmuch_config_get_database_path (config),\r
+                              NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch))\r
+       return 1;\r
+@@ -248,9 +243,9 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])\r
+       tag_flags |= TAG_FLAG_MAILDIR_SYNC;\r
\r
+     if (batch)\r
+-      ret = tag_file (ctx, notmuch, tag_flags, input);\r
++      ret = tag_file (config, notmuch, tag_flags, input);\r
+     else\r
+-      ret = tag_query (ctx, notmuch, query_string, tag_ops, tag_flags);\r
++      ret = tag_query (config, notmuch, query_string, tag_ops, tag_flags);\r
\r
+     notmuch_database_destroy (notmuch);\r
\r
+diff --git a/notmuch.c b/notmuch.c\r
+index e434d03..3241e23 100644\r
+--- a/notmuch.c\r
++++ b/notmuch.c\r
+@@ -22,56 +22,57 @@\r
\r
+ #include "notmuch-client.h"\r
\r
+-typedef int (*command_function_t) (void *ctx, int argc, char *argv[]);\r
++typedef int (*command_function_t) (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ typedef struct command {\r
+     const char *name;\r
+     command_function_t function;\r
++    notmuch_bool_t create_config;\r
+     const char *arguments;\r
+     const char *summary;\r
+ } command_t;\r
\r
+ static int\r
+-notmuch_help_command (void *ctx, int argc, char *argv[]);\r
++notmuch_help_command (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ static int\r
+-notmuch_command (void *ctx, int argc, char *argv[]);\r
++notmuch_command (notmuch_config_t *config, int argc, char *argv[]);\r
\r
+ static command_t commands[] = {\r
+-    { NULL, notmuch_command,\r
++    { NULL, notmuch_command, TRUE,\r
+       NULL,\r
+       "Notmuch main command." },\r
+-    { "setup", notmuch_setup_command,\r
++    { "setup", notmuch_setup_command, TRUE,\r
+       NULL,\r
+       "Interactively setup notmuch for first use." },\r
+-    { "new", notmuch_new_command,\r
++    { "new", notmuch_new_command, FALSE,\r
+       "[options...]",\r
+       "Find and import new messages to the notmuch database." },\r
+-    { "search", notmuch_search_command,\r
++    { "search", notmuch_search_command, FALSE,\r
+       "[options...] <search-terms> [...]",\r
+       "Search for messages matching the given search terms." },\r
+-    { "show", notmuch_show_command,\r
++    { "show", notmuch_show_command, FALSE,\r
+       "<search-terms> [...]",\r
+       "Show all messages matching the search terms." },\r
+-    { "count", notmuch_count_command,\r
++    { "count", notmuch_count_command, FALSE,\r
+       "[options...] <search-terms> [...]",\r
+       "Count messages matching the search terms." },\r
+-    { "reply", notmuch_reply_command,\r
++    { "reply", notmuch_reply_command, FALSE,\r
+       "[options...] <search-terms> [...]",\r
+       "Construct a reply template for a set of messages." },\r
+-    { "tag", notmuch_tag_command,\r
++    { "tag", notmuch_tag_command, FALSE,\r
+       "+<tag>|-<tag> [...] [--] <search-terms> [...]" ,\r
+       "Add/remove tags for all messages matching the search terms." },\r
+-    { "dump", notmuch_dump_command,\r
++    { "dump", notmuch_dump_command, FALSE,\r
+       "[<filename>] [--] [<search-terms>]",\r
+       "Create a plain-text dump of the tags for each message." },\r
+-    { "restore", notmuch_restore_command,\r
++    { "restore", notmuch_restore_command, FALSE,\r
+       "[--accumulate] [<filename>]",\r
+       "Restore the tags from the given dump file (see 'dump')." },\r
+-    { "config", notmuch_config_command,\r
++    { "config", notmuch_config_command, FALSE,\r
+       "[get|set] <section>.<item> [value ...]",\r
+       "Get or set settings in the notmuch configuration file." },\r
+-    { "help", notmuch_help_command,\r
++    { "help", notmuch_help_command, TRUE, /* create but don't save config */\r
+       "[<command>]",\r
+       "This message, or more detailed help for the named command." }\r
+ };\r
+@@ -155,7 +156,7 @@ exec_man (const char *page)\r
+ }\r
\r
+ static int\r
+-notmuch_help_command (void *ctx, int argc, char *argv[])\r
++notmuch_help_command (notmuch_config_t *config, int argc, char *argv[])\r
+ {\r
+     command_t *command;\r
\r
+@@ -178,7 +179,7 @@ notmuch_help_command (void *ctx, int argc, char *argv[])\r
\r
+     command = find_command (argv[0]);\r
+     if (command) {\r
+-      char *page = talloc_asprintf (ctx, "notmuch-%s", command->name);\r
++      char *page = talloc_asprintf (config, "notmuch-%s", command->name);\r
+       exec_man (page);\r
+     }\r
\r
+@@ -199,28 +200,23 @@ notmuch_help_command (void *ctx, int argc, char *argv[])\r
+  * to be more clever about this in the future.\r
+  */\r
+ static int\r
+-notmuch_command (void *ctx, unused(int argc), unused(char *argv[]))\r
++notmuch_command (notmuch_config_t *config,\r
++               unused(int argc), unused(char *argv[]))\r
+ {\r
+-    notmuch_config_t *config;\r
+     char *db_path;\r
+     struct stat st;\r
\r
+-    config = notmuch_config_open (ctx, NULL, TRUE);\r
+-\r
+     /* If the user has never configured notmuch, then run\r
+      * notmuch_setup_command which will give a nice welcome message,\r
+      * and interactively guide the user through the configuration. */\r
+-    if (notmuch_config_is_new (config)) {\r
+-      notmuch_config_close (config);\r
+-      return notmuch_setup_command (ctx, 0, NULL);\r
+-    }\r
++    if (notmuch_config_is_new (config))\r
++      return notmuch_setup_command (config, 0, NULL);\r
\r
+     /* Notmuch is already configured, but is there a database? */\r
+-    db_path = talloc_asprintf (ctx, "%s/%s",\r
++    db_path = talloc_asprintf (config, "%s/%s",\r
+                              notmuch_config_get_database_path (config),\r
+                              ".notmuch");\r
+     if (stat (db_path, &st)) {\r
+-      notmuch_config_close (config);\r
+       if (errno != ENOENT) {\r
+           fprintf (stderr, "Error looking for notmuch database at %s: %s\n",\r
+                    db_path, strerror (errno));\r
+@@ -252,8 +248,6 @@ notmuch_command (void *ctx, unused(int argc), unused(char *argv[]))\r
+           notmuch_config_get_user_name (config),\r
+           notmuch_config_get_user_primary_email (config));\r
\r
+-    notmuch_config_close (config);\r
+-\r
+     return 0;\r
+ }\r
\r
+@@ -264,6 +258,7 @@ main (int argc, char *argv[])\r
+     char *talloc_report;\r
+     const char *command_name = NULL;\r
+     command_t *command;\r
++    notmuch_config_t *config;\r
+     notmuch_bool_t print_help=FALSE, print_version=FALSE;\r
+     int opt_index;\r
+     int ret = 0;\r
+@@ -308,7 +303,13 @@ main (int argc, char *argv[])\r
+       return 1;\r
+     }\r
\r
+-    ret = (command->function)(local, argc - opt_index, argv + opt_index);\r
++    config = notmuch_config_open (local, NULL, command->create_config);\r
++    if (!config)\r
++      return 1;\r
++\r
++    ret = (command->function)(config, argc - opt_index, argv + opt_index);\r
++\r
++    notmuch_config_close (config);\r
\r
+     talloc_report = getenv ("NOTMUCH_TALLOC_REPORT");\r
+     if (talloc_report && strcmp (talloc_report, "") != 0) {\r
+-- \r
+1.7.10.4\r
+\r