[dovecot-cvs] dovecot/src/lib-settings .cvsignore,NONE,1.1 Makefile.am,NONE,1.1 settings.c,NONE,1.1 settings.h,NONE,1.1

cras at procontrol.fi cras at procontrol.fi
Thu Jan 30 21:01:43 EET 2003


Update of /home/cvs/dovecot/src/lib-settings
In directory danu:/tmp/cvs-serv5678/src/lib-settings

Added Files:
	.cvsignore Makefile.am settings.c settings.h 
Log Message:
Moved settings parsing to lib-settings.



--- NEW FILE: .cvsignore ---
*.la
*.lo
*.o
.deps
.libs
Makefile
Makefile.in
so_locations

--- NEW FILE: Makefile.am ---
noinst_LIBRARIES = libsettings.a

INCLUDES = \
	-I$(top_srcdir)/src/lib

libsettings_a_SOURCES = \
	settings.c

noinst_HEADERS = \
	settings.h

--- NEW FILE: settings.c ---
/* Copyright (C) 2002 Timo Sirainen */

#include "lib.h"
#include "istream.h"
#include "settings.h"

#include <stdio.h>
#include <fcntl.h>

static const char *get_bool(const char *value, int *result)
{
	if (strcasecmp(value, "yes") == 0)
		*result = TRUE;
	else if (strcasecmp(value, "no") == 0)
		*result = FALSE;
	else
		return t_strconcat("Invalid boolean: ", value, NULL);

	return NULL;
}

static const char *get_uint(const char *value, unsigned int *result)
{
	int num;

	if (!sscanf(value, "%i", &num) || num < 0)
		return t_strconcat("Invalid number: ", value, NULL);
	*result = num;
	return NULL;
}

const char *
parse_setting_from_defs(pool_t pool, struct setting_def *defs, void *base,
			const char *key, const char *value)
{
	struct setting_def *def;

	for (def = defs; def->name != NULL; def++) {
		if (strcmp(def->name, key) == 0) {
			void *ptr = STRUCT_MEMBER_P(base, def->offset);

			switch (def->type) {
			case SET_STR:
				*((char **) ptr) =
					p_strdup_empty(pool, value);
				return NULL;
			case SET_INT:
				/* use %i so we can handle eg. 0600
				   as octal value with umasks */
				return get_uint(value, (unsigned int *) ptr);
			case SET_BOOL:
				return get_bool(value, (int *) ptr);
			}
		}
	}

	return t_strconcat("Unknown setting: ", key, NULL);
}

#define IS_WHITE(c) ((c) == ' ' || (c) == '\t')

void settings_read(const char *path,
		   const char *(*callback)(const char *key, const char *value))
{
	struct istream *input;
	const char *errormsg;
	char *line, *key, *p;
	int fd, linenum;

	fd = open(path, O_RDONLY);
	if (fd < 0)
		i_fatal("Can't open configuration file %s: %m", path);

	linenum = 0;
	input = i_stream_create_file(fd, default_pool, 2048, TRUE);
	for (;;) {
		line = i_stream_next_line(input);
		if (line == NULL) {
			if (i_stream_read(input) <= 0)
				break;
                        continue;
		}
		linenum++;

		/* @UNSAFE: line is modified */

		/* skip whitespace */
		while (IS_WHITE(*line))
			line++;

		/* ignore comments or empty lines */
		if (*line == '#' || *line == '\0')
			continue;

		/* all lines must be in format "key = value" */
		key = line;
		while (!IS_WHITE(*line) && *line != '\0')
			line++;
		if (IS_WHITE(*line)) {
			*line++ = '\0';
			while (IS_WHITE(*line)) line++;
		}

		if (*line != '=') {
			errormsg = "Missing value";
		} else {
			/* skip whitespace after '=' */
			*line++ = '\0';
			while (IS_WHITE(*line)) line++;

			/* skip trailing whitespace */
			p = line + strlen(line);
			while (p > line && IS_WHITE(p[-1]))
				p--;
			*p = '\0';

			errormsg = callback(key, line);
		}

		if (errormsg != NULL) {
			i_fatal("Error in configuration file %s line %d: %s",
				path, linenum, errormsg);
		}
	};

	i_stream_unref(input);
}

--- NEW FILE: settings.h ---
#ifndef __SETTINGS_H
#define __SETTINGS_H

enum setting_type {
	SET_STR,
	SET_INT,
	SET_BOOL
};

struct setting_def {
	enum setting_type type;
	const char *name;
	size_t offset;
};

const char *
parse_setting_from_defs(pool_t pool, struct setting_def *defs, void *base,
			const char *key, const char *value);

void settings_read(const char *path,
		   const char *(*callback)(const char *key, const char *value));

#endif




More information about the dovecot-cvs mailing list