+ return EXIT_SUCCESS;
+}
+
+static int
+_set_db_config (notmuch_database_t *notmuch, const char *key, int argc, char **argv)
+{
+ const char *val = "";
+
+ if (argc > 1) {
+ /* XXX handle lists? */
+ fprintf (stderr, "notmuch config set: at most one value expected for %s\n", key);
+ return EXIT_FAILURE;
+ }
+
+ if (argc > 0) {
+ val = argv[0];
+ }
+
+ if (print_status_database ("notmuch config", notmuch,
+ notmuch_database_reopen (notmuch,
+ NOTMUCH_DATABASE_MODE_READ_WRITE)))
+ return EXIT_FAILURE;
+
+ if (print_status_database ("notmuch config", notmuch,
+ notmuch_database_set_config (notmuch, key, val)))
+ return EXIT_FAILURE;
+
+ if (print_status_database ("notmuch config", notmuch,
+ notmuch_database_close (notmuch)))
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
+}
+
+static int
+notmuch_config_command_set (notmuch_database_t *notmuch,
+ int argc, char *argv[])
+{
+ char *group, *key;
+ const config_key_info_t *key_info;
+ notmuch_conffile_t *config;
+ bool update_database = false;
+ int opt_index, ret;
+ char *item;
+
+ notmuch_opt_desc_t options[] = {
+ { .opt_bool = &update_database, .name = "database" },
+ { }
+ };
+
+ opt_index = parse_arguments (argc, argv, options, 1);
+ if (opt_index < 0)
+ return EXIT_FAILURE;
+
+ argc -= opt_index;
+ argv += opt_index;
+
+ if (argc < 1) {
+ fprintf (stderr, "Error: notmuch config set requires at least "
+ "one argument.\n");
+ return EXIT_FAILURE;
+ }
+
+ item = argv[0];
+ argv++;
+ argc--;
+
+ if (STRNCMP_LITERAL (item, BUILT_WITH_PREFIX) == 0) {
+ fprintf (stderr, "Error: read only option: %s\n", item);
+ return 1;
+ }
+
+ key_info = _config_key_info (item);
+ if (key_info && key_info->validate && (! key_info->validate (item)))
+ return 1;
+
+ if (update_database) {
+ return _set_db_config (notmuch, item, argc, argv);
+ }
+
+ if (_item_split (item, &group, &key))
+ return 1;
+
+ config = notmuch_conffile_open (notmuch,
+ notmuch_config_path (notmuch), false);
+ if (! config)
+ return 1;
+
+ /* With only the name of an item, we clear it from the
+ * configuration file.
+ *
+ * With a single value, we set it as a string.
+ *
+ * With multiple values, we set them as a string list.
+ */
+ switch (argc) {
+ case 0:
+ g_key_file_remove_key (config->key_file, group, key, NULL);
+ break;
+ case 1:
+ g_key_file_set_string (config->key_file, group, key, argv[0]);
+ break;
+ default:
+ g_key_file_set_string_list (config->key_file, group, key,
+ (const gchar **) argv, argc);
+ break;
+ }
+
+ ret = notmuch_conffile_save (config);