settings-parser.c revision 822ae9061773d9ac1246c35d3c47cc0f49cee3ab
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
d186a2391d98a3efa3fe1078879ef2798e169c29Timo Sirainen#define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* Points to array inside parent->set_struct.
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen SET_DEFLIST : array of set_structs
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen SET_STRLIST : array of const_strings */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* Pointer to structure containing the values */
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen /* Pointer to structure containing non-zero values for settings that
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen have been changed. */
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen /* SET_DEFLIST: array of change_structs */
0f97c2b6ec76e7f600e983cb952cf265a6189114Timo Sirainen unsigned int linenum;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainenstatic const struct setting_parser_info strlist_info = {
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainensetting_parser_copy_defaults(struct setting_parser_context *ctx,
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainensettings_parser_init(pool_t set_pool, const struct setting_parser_info *root,
2848ed04730e9f2ed91829d41312ebc3132b5613Timo Sirainen return settings_parser_init_list(set_pool, &root, 1, flags);
cf05592015b99607095f970bf914f5d069bf0666Timo Sirainencopy_unique_defaults(struct setting_parser_context *ctx,
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen STRUCT_MEMBER_P(link->set_struct, def->offset);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen unsigned int i, count;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen carr = STRUCT_MEMBER_P(link->change_struct, def->offset);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen for (i = 0; i < count; i++) {
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen new_set = p_malloc(ctx->set_pool, info.struct_size);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen new_changes = p_malloc(ctx->set_pool, info.struct_size);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen keyp = CONST_PTR_OFFSET(children[i], info.type_offset);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen new_link = p_new(ctx->set_pool, struct setting_link, 1);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen t_strconcat(def->key, SETTINGS_SEPARATOR_S, NULL) :
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen t_strconcat(link->full_key, SETTINGS_SEPARATOR_S,
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen full_key = p_strconcat(ctx->set_pool, prefix, key, NULL);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen hash_table_insert(ctx->links, full_key, new_link);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen setting_parser_copy_defaults(ctx, &info, new_link);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainensetting_parser_copy_defaults(struct setting_parser_context *ctx,
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen const char *p, **strp;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen memcpy(link->set_struct, info->defaults, info->struct_size);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen for (def = info->defines; def->key != NULL; def++) {
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen /* fix enums by dropping everything after the
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen strp = STRUCT_MEMBER_P(link->set_struct, def->offset);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen *strp = p_strdup_until(ctx->set_pool, *strp, p);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen /* insert the unexpanded-character */
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen strp = STRUCT_MEMBER_P(link->set_struct, def->offset);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen unsigned int count, enum settings_parser_flags flags)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen unsigned int i;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen parser_pool = pool_alloconly_create("settings parser", 16384);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx = p_new(parser_pool, struct setting_parser_context, 1);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->links = hash_table_create(default_pool, ctx->parser_pool, 0,
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->roots = p_new(ctx->parser_pool, struct setting_link, count);
for (i = 0; i < count; i++) {
return ctx;
void **sets;
return sets;
static const struct setting_define *
return list;
return NULL;
unsigned int *result_r)
int num;
const char **error_r)
switch (i_toupper(*p)) {
const char **error_r)
switch (i_toupper(*p)) {
if (p == NULL) {
const char *const *list;
char *full_key;
const char *error;
def--;
case SET_BOOL:
case SET_UINT:
case SET_TIME:
case SET_SIZE:
case SET_STR:
case SET_STR_VARS:
case SET_ENUM:
*(const char **)ptr2) < 0)
case SET_DEFLIST:
case SET_DEFLIST_UNIQUE:
case SET_STRLIST: {
case SET_ALIAS:
i_unreached();
const char *end;
return TRUE;
return FALSE;
return FALSE;
return TRUE;
const char *key)
int ret;
T_BEGIN {
} T_END;
return ret;
const struct setting_parser_info *
char *dest, *p;
return value;
if (*p == SETTING_STREAM_LF_CHAR[0])
return dest;
bool ignore_unknown_keys =
const char *line;
int ret;
T_BEGIN {
} T_END;
int ret;
if (ret == 0) {
switch (ret) {
i_unreached();
if (fd < 0) {
return ret;
extern char **environ;
char *const *sorted_envs;
unsigned int i, count;
int ret = 0;
} T_END;
return ret;
const char *service)
if (pid == 0) {
static const char *argv[] = {
NULL,
} else if (status != 0) {
return ret;
void *const *children;
unsigned int i, count;
return FALSE;
for (i = 0; i < count; i++) {
return FALSE;
return TRUE;
const char **error_r)
return FALSE;
return TRUE;
bool is_expanded)
const char **val;
unsigned int i, count;
case SET_BOOL:
case SET_UINT:
case SET_TIME:
case SET_SIZE:
case SET_STR:
case SET_ENUM:
case SET_STRLIST:
case SET_ALIAS:
case SET_STR_VARS: {
case SET_DEFLIST:
case SET_DEFLIST_UNIQUE: {
for (i = 0; i < count; i++) {
T_BEGIN {
} T_END;
const void *value;
void *const *children;
unsigned int i, count;
case SET_BOOL:
case SET_UINT:
case SET_TIME:
case SET_SIZE:
case SET_STR:
case SET_ENUM:
case SET_STRLIST:
case SET_ALIAS:
case SET_STR_VARS: {
long_var_key)) {
return TRUE;
case SET_DEFLIST:
case SET_DEFLIST_UNIQUE: {
for (i = 0; i < count; i++) {
return TRUE;
return FALSE;
void **ptr;
switch (type) {
case SET_BOOL: {
case SET_UINT:
case SET_TIME: {
case SET_SIZE: {
case SET_STR_VARS:
case SET_STR:
case SET_ENUM: {
case SET_DEFLIST:
case SET_DEFLIST_UNIQUE:
return FALSE;
case SET_STRLIST: {
unsigned int i, count;
for (i = 0; i < count; i++) {
case SET_ALIAS:
return TRUE;
const void *src;
unsigned int i, count;
return NULL;
void *child_set;
for (i = 0; i < count; i++) {
dest_set);
return dest_set;
const void *src;
unsigned int i, count;
return NULL;
case SET_BOOL:
case SET_UINT:
case SET_TIME:
case SET_SIZE:
case SET_STR_VARS:
case SET_STR:
case SET_ENUM:
case SET_STRLIST:
case SET_DEFLIST:
case SET_DEFLIST_UNIQUE: {
void *child_set;
for (i = 0; i < count; i++) {
children[i],
pool);
case SET_ALIAS:
return dest_set;
void *parent_defaults;
} T_END;
return NULL;
return NULL;
static struct setting_link *
return new_link;
for (i = 0; i < count; i++) {
return new_link;
struct setting_parser_context *
new_link);
return new_ctx;
unsigned int i, count;
return NULL;
for (i = 0; i < count; i++) {
return dest_set;
unsigned int i, count;
for (i = 0; i < count; i++) {
for (i = 0; i < count; i++) {
unsigned int type_offset;
for (i = 0; i < src_count; i++) {
for (j = 0; j < dest_count; j++) {
if (j < dest_count) {
src_cchildren[i],
pool);
} else if (*((const char *)csrc) == 0) {
} else if (*((const char *)cdest) != 0) {
conflict_key_r) < 0)
conflict_key_r) < 0)
#define CHAR_NEED_ESCAPE(c) \
return name;
switch (name[i]) {
case SETTINGS_SEPARATOR: