settings.c revision 317f390961bd996932acf3d4bfbbf16c3d21e755
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
317f390961bd996932acf3d4bfbbf16c3d21e755Timo Sirainen#define SECTION_ERRORMSG "%s (section changed at line %d)"
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainensettings_section_callback_t *null_settings_section_callback = NULL;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenstatic const char *get_bool(const char *value, bool *result)
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainen return t_strconcat("Invalid boolean: ", value, NULL);
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainenstatic const char *get_uint(const char *value, unsigned int *result)
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainen return t_strconcat("Invalid number: ", value, NULL);
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainenparse_setting_from_defs(pool_t pool, struct setting_def *defs, void *base,
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainen void *ptr = STRUCT_MEMBER_P(base, def->offset);
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainen /* use %i so we can handle eg. 0600
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainen as octal value with umasks */
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainen return t_strconcat("Unknown setting: ", key, NULL);
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainen#define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool settings_read(const char *path, const char *section,
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen settings_section_callback_t *sect_callback, void *context)
317f390961bd996932acf3d4bfbbf16c3d21e755Timo Sirainen int fd, linenum, last_section_line = 0, skip, sections, root_section;
0cb57ee35d4cab9c03434d7abf312c081ed554d4Timo Sirainen i_error("Can't open configuration file %s: %m", path);
0cb57ee35d4cab9c03434d7abf312c081ed554d4Timo Sirainen linenum = 0; sections = 0; root_section = 0; errormsg = NULL;
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainen input = i_stream_create_file(fd, default_pool, 2048, TRUE);
6bfd8baac71b2c4ab7191834da36e843ae0dbd14Timo Sirainen /* EOF. Also handle the last line even if it doesn't
6bfd8baac71b2c4ab7191834da36e843ae0dbd14Timo Sirainen contain LF. */
6bfd8baac71b2c4ab7191834da36e843ae0dbd14Timo Sirainen const unsigned char *data;
6bfd8baac71b2c4ab7191834da36e843ae0dbd14Timo Sirainen line = t_strdup_noconst(t_strndup(data, size));
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainen /* @UNSAFE: line is modified */
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainen /* skip whitespace */
9e49712b9cddbf47568ea4f3676e59b151489356Timo Sirainen /* ignore comments or empty lines */
6cc8fac7fd9b47e179629a61acef0e8758763803Timo Sirainen /* strip away comments. pretty kludgy way really.. */
6cc8fac7fd9b47e179629a61acef0e8758763803Timo Sirainen if (*p == '\0')
6cc8fac7fd9b47e179629a61acef0e8758763803Timo Sirainen } else if (*p == '#') {
3f8a5d2a09e90961d1d86dea294be162ccdb64a8Timo Sirainen /* remove whitespace from end of line */
3f8a5d2a09e90961d1d86dea294be162ccdb64a8Timo Sirainen /* a) key = value
d81433c272dc189ff50ecde109cd0040f21fa8b0Timo Sirainen b) section_type [section_name] {
337e0bdea4c5b1a9e3ac3e915b31a6413f46220cTimo Sirainen while (!IS_WHITE(*line) && *line != '\0' && *line != '=')
d81433c272dc189ff50ecde109cd0040f21fa8b0Timo Sirainen } else if (strcmp(key, "}") != 0 || *line != '\0') {
d81433c272dc189ff50ecde109cd0040f21fa8b0Timo Sirainen /* b) + errors */
d81433c272dc189ff50ecde109cd0040f21fa8b0Timo Sirainen /* we found the section,
0cb57ee35d4cab9c03434d7abf312c081ed554d4Timo Sirainen i_error("Error in configuration file %s line %d: %s",