diff options
Diffstat (limited to 'src/auth/db-dict-cache-key.c')
-rw-r--r-- | src/auth/db-dict-cache-key.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/auth/db-dict-cache-key.c b/src/auth/db-dict-cache-key.c new file mode 100644 index 0000000..a220d8d --- /dev/null +++ b/src/auth/db-dict-cache-key.c @@ -0,0 +1,64 @@ +/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */ + +#include "auth-common.h" +#include "array.h" +#include "str.h" +#include "var-expand.h" +#include "db-dict.h" + +const struct db_dict_key * +db_dict_set_key_find(const ARRAY_TYPE(db_dict_key) *keys, const char *name) +{ + const struct db_dict_key *key; + + array_foreach(keys, key) { + if (strcmp(key->name, name) == 0) + return key; + } + return NULL; +} + + +const char * +db_dict_parse_cache_key(const ARRAY_TYPE(db_dict_key) *keys, + const ARRAY_TYPE(db_dict_field) *fields, + const ARRAY_TYPE(db_dict_key_p) *objects) +{ + const struct db_dict_field *field; + const struct db_dict_key *key; + const char *p, *name; + unsigned int idx, size; + string_t *str = t_str_new(128); + + array_foreach(fields, field) { + for (p = field->value; *p != '\0'; ) { + if (*p != '%') { + p++; + continue; + } + + var_get_key_range(++p, &idx, &size); + if (size == 0) { + /* broken %variable ending too early */ + break; + } + p += idx; + if (size > 5 && memcmp(p, "dict:", 5) == 0) { + name = t_strcut(t_strndup(p+5, size-5), ':'); + key = db_dict_set_key_find(keys, name); + if (key != NULL) + str_printfa(str, "\t%s", key->key); + } else if (size == 1) { + str_printfa(str, "\t%%%c", p[0]); + } else { + str_append(str, "\t%{"); + str_append_data(str, p, size); + str_append_c(str, '}'); + } + p += size; + } + } + array_foreach_elem(objects, key) + str_printfa(str, "\t%s", key->key); + return str_c(str); +} |