Config files are currently read using glib's g_key_file_load_from_file function which is very inconvenient because it's limited by design to read only from "regular data files" in a filesystem. Because of this limitation notmuch can't read configs from pipes, fifos, sockets, stdin, etc. Not even "notmuch --config=/dev/stdin" works:
Error reading configuration file /dev/stdin: Not a regular file So replace g_key_file_load_from_file with g_key_file_load_from_data which gives us much more freedom to read configs from multiple sources. This also helps the more security sensitive users: If someone has private information in the config file, it can be encrypted on disk, then decrypted in RAM and passed through a pipe directly to notmuch without the use of intermediate plain text files. Signed-off-by: Ioan-Adrian Ratiu <a...@adirat.com> --- notmuch-config.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/notmuch-config.c b/notmuch-config.c index e5d42a0..8435815 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -202,6 +202,64 @@ get_username_from_passwd_file (void *ctx) return name; } +static gboolean +get_config_from_file (notmuch_config_t *config, GError **error) +{ + #define BUF_SIZE 4096 + char buffer[BUF_SIZE]; + size_t content_size = 1; // includes NULL + + FILE *fp = fopen(config->filename, "r"); + if (fp == NULL) { + *error = g_error_new(G_FILE_ERROR, + G_FILE_ERROR_NOENT, + "Couldn't open config file '%s': %s.\n", + config->filename, + strerror(errno)); + return FALSE; + } + + char *config_str = talloc_zero_array (config, char, BUF_SIZE); + if (config_str == NULL) + { + *error = g_error_new(G_FILE_ERROR, + G_FILE_ERROR_NOMEM, + "Out of memory while reading config.\n"); + return FALSE; + } + + while (fgets (buffer, BUF_SIZE, fp)) + { + content_size += strlen(buffer); + config_str = talloc_realloc(config, config_str, char, content_size); + if (config_str == NULL) + { + *error = g_error_new(G_FILE_ERROR, + G_FILE_ERROR_NOMEM, + "Failed to reallocate config memory.\n"); + return FALSE; + } + strcat (config_str, buffer); + } + + if (ferror (fp)) + { + *error = g_error_new(G_FILE_ERROR, + G_FILE_ERROR_IO, + "I/O error reading configuration from '%s'.\n", + config->filename); + return FALSE; + } + + fclose(fp); + + return g_key_file_load_from_data (config->key_file, + config_str, + strlen(config_str), + G_KEY_FILE_KEEP_COMMENTS, + error); +} + /* Open the named notmuch configuration file. If the filename is NULL, * the value of the environment variable $NOTMUCH_CONFIG will be used. * If $NOTMUCH_CONFIG is unset, the default configuration file @@ -289,10 +347,7 @@ notmuch_config_open (void *ctx, config->search_exclude_tags_length = 0; config->crypto_gpg_path = NULL; - if (! g_key_file_load_from_file (config->key_file, - config->filename, - G_KEY_FILE_KEEP_COMMENTS, - &error)) + if (! get_config_from_file (config, &error)) { if (error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT) { /* If create_new is true, then the caller is prepared for a -- 2.10.2 _______________________________________________ notmuch mailing list notmuch@notmuchmail.org https://notmuchmail.org/mailman/listinfo/notmuch