settings.c revision 7761b23ef311d4a27ed78ad864287b290d4066f2
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2002-2007 Dovecot authors, see the included COPYING file */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "lib.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "str.h"
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch#include "istream.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "strescape.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "settings.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
9dc01e0d10a61cab14867b26bf0d2d1dcf8ad978Timo Sirainen#include <stdio.h>
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include <fcntl.h>
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#define SECTION_ERRORMSG "%s (section changed at line %d)"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschsettings_section_callback_t *null_settings_section_callback = NULL;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic const char *get_bool(const char *value, bool *result)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (strcasecmp(value, "yes") == 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch *result = TRUE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch else if (strcasecmp(value, "no") == 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch *result = FALSE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch else
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return t_strconcat("Invalid boolean: ", value, NULL);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return NULL;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic const char *get_uint(const char *value, unsigned int *result)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch int num;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (!sscanf(value, "%i", &num) || num < 0)
930a2323047a5f0cdcc79a090488b72205c913f3Stephan Bosch return t_strconcat("Invalid number: ", value, NULL);
930a2323047a5f0cdcc79a090488b72205c913f3Stephan Bosch *result = num;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return NULL;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschconst char *
7384b4e78eaab44693c985192276e31322155e32Stephan Boschparse_setting_from_defs(pool_t pool, struct setting_def *defs, void *base,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const char *key, const char *value)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct setting_def *def;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch for (def = defs; def->name != NULL; def++) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (strcmp(def->name, key) == 0) {
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch void *ptr = STRUCT_MEMBER_P(base, def->offset);
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch switch (def->type) {
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch case SET_STR:
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch *((char **)ptr) = p_strdup(pool, value);
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch return NULL;
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch case SET_INT:
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch /* use %i so we can handle eg. 0600
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch as octal value with umasks */
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch return get_uint(value, (unsigned int *) ptr);
8192e6fcab193e174a3258457e967a6fcc60b05eStephan Bosch case SET_BOOL:
8192e6fcab193e174a3258457e967a6fcc60b05eStephan Bosch return get_bool(value, (bool *) ptr);
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch }
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch }
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch }
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch return t_strconcat("Unknown setting: ", key, NULL);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch}
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch#define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#undef settings_read
7384b4e78eaab44693c985192276e31322155e32Stephan Boschbool settings_read(const char *path, const char *section,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch settings_callback_t *callback,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch settings_section_callback_t *sect_callback, void *context)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct istream *input;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const char *errormsg, *next_section, *name;
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch char *line, *key, *p, quote;
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch string_t *full_line;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch size_t len;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch int fd, linenum, last_section_line = 0, skip, sections, root_section;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch fd = open(path, O_RDONLY);
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch if (fd < 0) {
8192e6fcab193e174a3258457e967a6fcc60b05eStephan Bosch i_error("Can't open configuration file %s: %m", path);
8192e6fcab193e174a3258457e967a6fcc60b05eStephan Bosch return FALSE;
8192e6fcab193e174a3258457e967a6fcc60b05eStephan Bosch }
8192e6fcab193e174a3258457e967a6fcc60b05eStephan Bosch
8192e6fcab193e174a3258457e967a6fcc60b05eStephan Bosch t_push();
8192e6fcab193e174a3258457e967a6fcc60b05eStephan Bosch
8192e6fcab193e174a3258457e967a6fcc60b05eStephan Bosch if (section == NULL) {
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch skip = 0;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch next_section = NULL;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch } else {
13bdd67aa0781d562cd2030da5092df1107d91f3Stephan Bosch skip = 1;
13bdd67aa0781d562cd2030da5092df1107d91f3Stephan Bosch next_section = t_strcut(section, '/');
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch }
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch full_line = t_str_new(512);
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch linenum = 0; sections = 0; root_section = 0; errormsg = NULL;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch input = i_stream_create_fd(fd, 2048, TRUE);
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch for (;;) {
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch line = i_stream_read_next_line(input);
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch if (line == NULL) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* EOF. Also handle the last line even if it doesn't
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch contain LF. */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const unsigned char *data;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch size_t size;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch data = i_stream_get_data(input, &size);
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch if (size == 0)
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch break;
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch line = t_strdup_noconst(t_strndup(data, size));
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch i_stream_skip(input, size);
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch }
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch linenum++;
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch /* @UNSAFE: line is modified */
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch /* skip whitespace */
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch while (IS_WHITE(*line))
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch line++;
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch /* ignore comments or empty lines */
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch if (*line == '#' || *line == '\0')
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch continue;
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch
a321ac56cfe330e3b28a4690f285419d36c3c6f4Timo Sirainen /* strip away comments. pretty kludgy way really.. */
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch for (p = line; *p != '\0'; p++) {
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch if (*p == '\'' || *p == '"') {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch quote = *p;
92e011227877493a1b6a5a38863aabde7e07bd76Timo Sirainen for (p++; *p != quote && *p != '\0'; p++) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (*p == '\\' && p[1] != '\0')
92e011227877493a1b6a5a38863aabde7e07bd76Timo Sirainen p++;
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch }
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch if (*p == '\0')
a321ac56cfe330e3b28a4690f285419d36c3c6f4Timo Sirainen break;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch } else if (*p == '#') {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch *p = '\0';
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch break;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch }
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch }
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch /* remove whitespace from end of line */
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch len = strlen(line);
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch while (IS_WHITE(line[len-1]))
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch len--;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch line[len] = '\0';
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch if (len > 0 && line[len-1] == '\\') {
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch /* continues in next line */
ebe0f5e387744621b73c4db79d5891ccbe0a1321Stephan Bosch line[len-1] = '\0';
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch str_append(full_line, line);
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch continue;
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch }
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch if (str_len(full_line) > 0) {
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch str_append(full_line, line);
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch line = str_c_modifiable(full_line);
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch }
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch /* a) key = value
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch b) section_type [section_name] {
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch c) } */
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch key = line;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch while (!IS_WHITE(*line) && *line != '\0' && *line != '=')
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch line++;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch if (IS_WHITE(*line)) {
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch *line++ = '\0';
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch while (IS_WHITE(*line)) line++;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch }
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch if (*line == '=') {
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch /* a) */
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch *line++ = '\0';
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch while (IS_WHITE(*line)) line++;
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch len = strlen(line);
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch if (len > 0 &&
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch ((*line == '"' && line[len-1] == '"') ||
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch (*line == '\'' && line[len-1] == '\''))) {
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch line[len-1] = '\0';
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch line = str_unescape(line+1);
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch }
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch errormsg = skip ? NULL :
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch callback(key, line, context);
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch } else if (strcmp(key, "}") != 0 || *line != '\0') {
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch /* b) + errors */
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch line[-1] = '\0';
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch if (*line == '{')
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch name = "";
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch else {
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch name = line;
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch while (!IS_WHITE(*line) && *line != '\0')
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch line++;
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch if (*line != '\0') {
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch *line++ = '\0';
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch while (IS_WHITE(*line))
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch line++;
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch }
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch }
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch if (*line != '{')
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch errormsg = "Expecting '='";
92e011227877493a1b6a5a38863aabde7e07bd76Timo Sirainen else {
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainen sections++;
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainen if (next_section != NULL &&
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch strcmp(next_section, name) == 0) {
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch section += strlen(next_section);
92e011227877493a1b6a5a38863aabde7e07bd76Timo Sirainen if (*section == '\0') {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch skip = 0;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch next_section = NULL;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch root_section = sections;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch } else {
92e011227877493a1b6a5a38863aabde7e07bd76Timo Sirainen i_assert(*section == '/');
92e011227877493a1b6a5a38863aabde7e07bd76Timo Sirainen section++;
92e011227877493a1b6a5a38863aabde7e07bd76Timo Sirainen next_section =
92e011227877493a1b6a5a38863aabde7e07bd76Timo Sirainen t_strcut(section, '/');
92e011227877493a1b6a5a38863aabde7e07bd76Timo Sirainen }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch if (skip > 0)
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch skip++;
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch else {
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch skip = sect_callback == NULL ? 1 :
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch !sect_callback(key, name,
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch context,
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch &errormsg);
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch if (errormsg != NULL &&
ebe0f5e387744621b73c4db79d5891ccbe0a1321Stephan Bosch last_section_line != 0) {
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch errormsg = t_strdup_printf(
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch SECTION_ERRORMSG,
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch errormsg,
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch last_section_line);
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch }
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch }
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch last_section_line = linenum;
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch }
1f1ba791ba565d4a31b031fee95617490fe96b11Stephan Bosch } else {
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch /* c) */
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch if (sections == 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch errormsg = "Unexpected '}'";
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch else {
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch if (skip > 0)
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch skip--;
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch else {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch sect_callback(NULL, NULL, context,
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch &errormsg);
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch if (root_section == sections &&
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch errormsg == NULL) {
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch /* we found the section,
ebe0f5e387744621b73c4db79d5891ccbe0a1321Stephan Bosch now quit */
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch break;
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch }
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch }
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch last_section_line = linenum;
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch sections--;
4aaec94d5ff8988591f47a51d6dde11862acce1bStephan Bosch }
4aaec94d5ff8988591f47a51d6dde11862acce1bStephan Bosch }
4aaec94d5ff8988591f47a51d6dde11862acce1bStephan Bosch
03435aae7b6634f84102e57d131e7dfd13f12b83Timo Sirainen if (errormsg != NULL) {
03435aae7b6634f84102e57d131e7dfd13f12b83Timo Sirainen i_error("Error in configuration file %s line %d: %s",
03435aae7b6634f84102e57d131e7dfd13f12b83Timo Sirainen path, linenum, errormsg);
ebe0f5e387744621b73c4db79d5891ccbe0a1321Stephan Bosch break;
4aaec94d5ff8988591f47a51d6dde11862acce1bStephan Bosch }
4aaec94d5ff8988591f47a51d6dde11862acce1bStephan Bosch str_truncate(full_line, 0);
4aaec94d5ff8988591f47a51d6dde11862acce1bStephan Bosch }
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch i_stream_destroy(&input);
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch t_pop();
03435aae7b6634f84102e57d131e7dfd13f12b83Timo Sirainen
03435aae7b6634f84102e57d131e7dfd13f12b83Timo Sirainen return errormsg == NULL;
03435aae7b6634f84102e57d131e7dfd13f12b83Timo Sirainen}
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch