settings-parser.c revision 8d3278a82b964217d95c340ec6f82037cdc59d19
/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "hash.h"
#include "network.h"
#include "istream.h"
#include "str.h"
#include "strescape.h"
#include "var-expand.h"
#include "settings-parser.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
struct setting_link {
struct setting_link *parent;
const struct setting_parser_info *info;
void *set_struct;
};
struct setting_parser_context {
enum settings_parser_flags flags;
bool str_vars_are_expanded;
struct setting_link *roots;
unsigned int root_count;
struct hash_table *links;
unsigned int linenum;
const char *error;
const struct setting_parser_info *prev_info;
};
static const struct setting_parser_info strlist_info = {
};
struct setting_parser_context *
enum settings_parser_flags flags)
{
}
static void
{
const struct setting_define *def;
const char *p, **strp;
return;
case SET_ENUM: {
/* fix enums by dropping everything after the
first ':' */
if (p != NULL)
break;
}
case SET_STR_VARS: {
/* insert the unexpanded-character */
}
break;
}
default:
break;
}
}
}
struct setting_parser_context *
const struct setting_parser_info *const *roots,
{
struct setting_parser_context *ctx;
unsigned int i;
for (i = 0; i < count; i++) {
}
return ctx;
}
{
}
{
}
{
unsigned int i;
void **sets;
for (i = 0; i < ctx->root_count; i++)
return sets;
}
{
}
static const struct setting_define *
{
const struct setting_define *list;
return list;
}
return NULL;
}
static int
{
else {
return -1;
}
return 0;
}
static int
unsigned int *result_r)
{
int num;
/* use %i so we can handle eg. 0600 as octal value with umasks */
return -1;
}
return 0;
}
char **result_r, const char *allowed_values)
{
const char *p;
while (allowed_values != NULL) {
if (p == NULL) {
break;
"Invalid value: ",
return -1;
}
break;
allowed_values = p + 1;
}
return 0;
}
static int
const struct setting_parser_info *info,
{
struct setting_link *link;
const char *const *list;
char *full_key;
if (!array_is_created(result))
if (**list == '\0')
continue;
" already exists", NULL);
return -1;
}
}
return 0;
}
static int
const struct setting_define *def,
{
link->set_struct =
link->set_struct);
}
}
case SET_INTERNAL:
i_unreached();
case SET_BOOL:
case SET_UINT:
case SET_STR:
return 0;
case SET_STR_VARS:
return 0;
case SET_ENUM:
/* get the available values from default string */
case SET_DEFLIST:
case SET_STRLIST: {
}
}
i_unreached();
return -1;
}
static bool
const struct setting_define **def_r,
struct setting_link **link_r)
{
const struct setting_define *def;
struct setting_link *link;
const char *end;
unsigned int i;
/* try to find from roots */
for (i = 0; i < ctx->root_count; i++) {
return TRUE;
}
}
/* try to find from links */
return FALSE;
return FALSE;
return TRUE;
} else {
}
}
{
const struct setting_define *def;
struct setting_link *link;
return 1;
}
return -1;
return 1;
} else {
return 0;
}
}
const char *key)
{
const struct setting_define *def;
struct setting_link *link;
}
{
int ret;
return -1;
}
return -1;
}
T_BEGIN {
} T_END;
return ret;
}
const struct setting_parser_info *
{
}
{
const char *line;
int ret = 1;
if (*line == '\0') {
/* empty line finishes it */
ret = 0;
break;
}
line++;
continue;
len--;
/* line continues */
} else {
/* full line */
}
if (ret == 0 &&
ret = -1;
if (ret < 0) {
"Line %u: %s",
ret = -1;
break;
}
str_truncate(full_line, 0);
}
}
return ret;
}
{
const unsigned char *data;
int ret;
}
return -1;
if (ret == 0) {
/* empty line read */
return 0;
}
}
switch (ret) {
case -1:
if (input->stream_errno != 0) {
"read() failed: %m");
} else {
}
break;
case -2:
"Line %u: line too long",
break;
case 0:
/* blocks */
return 1;
default:
i_unreached();
}
return -1;
}
{
if (fd < 0) {
"open(%s) failed: %m", path);
return -1;
}
return ret;
}
{
extern char **environ;
unsigned int i;
int ret = 0;
"Invalid setting %s: %s",
ret = -1;
}
} T_END;
}
return ret;
}
const char *bin_path, const char *config_path,
const char *service)
{
i_error("pipe() failed: %m");
return -1;
}
i_error("fork() failed: %m");
return -1;
}
if (pid == 0) {
/* child */
static const char *argv[] = {
NULL,
"-c", NULL,
"-s", NULL,
};
i_fatal("dup2() failed: %m");
return -1;
}
i_error("waitpid() failed: %m");
ret = -1;
} else if (status != 0) {
ret = -1;
}
return ret;
}
static bool
{
const struct setting_define *def;
void *const *children;
unsigned int i, count;
return FALSE;
}
continue;
if (!array_is_created(val))
continue;
for (i = 0; i < count; i++) {
return FALSE;
}
}
return TRUE;
}
const char **error_r)
{
unsigned int i;
for (i = 0; i < ctx->root_count; i++) {
error_r))
return FALSE;
}
return TRUE;
}
bool is_expanded)
{
}
static void
{
const struct setting_define *def;
unsigned int i, count;
case SET_STR_VARS: {
break;
if (**val == SETTING_STRVAR_UNEXPANDED[0]) {
str_truncate(str, 0);
} else {
*val += 1;
}
break;
}
case SET_DEFLIST: {
if (!array_is_created(val))
break;
for (i = 0; i < count; i++) {
}
break;
}
default:
break;
}
}
}
{
const struct setting_define *def;
struct setting_link *link;
const char **val;
continue;
**val == SETTING_STRVAR_EXPANDED[0]);
}
}
}
const struct var_expand_table *table)
{
T_BEGIN {
} T_END;
}
char var_key, const char *long_var_key,
{
const struct setting_define *def;
const void *value;
void *const *children;
unsigned int i, count;
case SET_STR_VARS: {
break;
if (**val == SETTING_STRVAR_UNEXPANDED[0]) {
long_var_key)) {
return TRUE;
}
} else {
}
break;
}
case SET_DEFLIST: {
if (!array_is_created(val))
break;
for (i = 0; i < count; i++) {
return TRUE;
}
break;
}
default:
break;
}
}
return FALSE;
}
{
const struct setting_define *def;
const void *src;
unsigned int i, count;
case SET_INTERNAL:
case SET_BOOL:
case SET_UINT:
break;
case SET_STR_VARS:
case SET_STR:
case SET_ENUM: {
break;
}
case SET_DEFLIST: {
void *child_set;
if (!array_is_created(src_arr))
break;
for (i = 0; i < count; i++) {
}
break;
}
case SET_STRLIST: {
if (!array_is_created(src_arr))
break;
for (i = 0; i < count; i += 2)
break;
}
}
}
return dest_set;
}
{
}
static void
{
/* @UNSAFE */
struct setting_parser_info *parent;
struct dynamic_settings_parser new_parser;
const struct setting_define *cur_defines;
void *parent_defaults;
unsigned int i, j;
/* add existing defines */
/* add new dynamic defines */
new_define = cur_defines[j];
}
}
/* update defaults */
}
/* update dynamic parsers list */
}
}
new_parser = parsers[i];
}
sizeof(*parent->dynamic_parsers) *
}
const struct dynamic_settings_parser *parsers)
{
} T_END;
}
{
unsigned int i;
return NULL;
return CONST_PTR_OFFSET(base_set,
}
}
return NULL;
}