settings.c revision 7761b23ef311d4a27ed78ad864287b290d4066f2
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2002-2007 Dovecot authors, see the included COPYING file */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#define SECTION_ERRORMSG "%s (section changed at line %d)"
7384b4e78eaab44693c985192276e31322155e32Stephan Boschsettings_section_callback_t *null_settings_section_callback = NULL;
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic const char *get_bool(const char *value, bool *result)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return t_strconcat("Invalid boolean: ", value, NULL);
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic const char *get_uint(const char *value, unsigned int *result)
930a2323047a5f0cdcc79a090488b72205c913f3Stephan Bosch return t_strconcat("Invalid number: ", value, NULL);
7384b4e78eaab44693c985192276e31322155e32Stephan Boschparse_setting_from_defs(pool_t pool, struct setting_def *defs, void *base,
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch void *ptr = STRUCT_MEMBER_P(base, def->offset);
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch /* use %i so we can handle eg. 0600
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch as octal value with umasks */
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch return t_strconcat("Unknown setting: ", key, NULL);
7b572cf527dc0d9d9c7344041e50aef16f419571Stephan Bosch#define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
7384b4e78eaab44693c985192276e31322155e32Stephan Boschbool settings_read(const char *path, const char *section,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch settings_section_callback_t *sect_callback, void *context)
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch int fd, linenum, last_section_line = 0, skip, sections, root_section;
8192e6fcab193e174a3258457e967a6fcc60b05eStephan Bosch i_error("Can't open configuration file %s: %m", path);
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch linenum = 0; sections = 0; root_section = 0; errormsg = NULL;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* EOF. Also handle the last line even if it doesn't
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch contain LF. */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const unsigned char *data;
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch line = t_strdup_noconst(t_strndup(data, size));
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch /* @UNSAFE: line is modified */
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch /* skip whitespace */
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch /* ignore comments or empty lines */
a321ac56cfe330e3b28a4690f285419d36c3c6f4Timo Sirainen /* strip away comments. pretty kludgy way really.. */
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch if (*p == '\0')
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch } else if (*p == '#') {
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch /* remove whitespace from end of line */
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch /* continues in next line */
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch /* a) key = value
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch b) section_type [section_name] {
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch while (!IS_WHITE(*line) && *line != '\0' && *line != '=')
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch } else if (strcmp(key, "}") != 0 || *line != '\0') {
8d5b57113f8f90003fd54a426fc70a8bdd5db099Stephan Bosch /* b) + errors */
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch /* we found the section,
03435aae7b6634f84102e57d131e7dfd13f12b83Timo Sirainen i_error("Error in configuration file %s line %d: %s",