Blame librols/default.c

Packit 45fded
/* 
Packit 45fded
 * Copyright 2006 Eduard Bloch 
Packit 45fded
 *
Packit 45fded
 * Uses my config parser code and small wrappers to provide the old interface.
Packit 45fded
 *
Packit 45fded
 */
Packit 45fded
/*
Packit 45fded
 * This program is free software; you can redistribute it and/or modify
Packit 45fded
 * it under the terms of the GNU General Public License version 2
Packit 45fded
 * as published by the Free Software Foundation.
Packit 45fded
 *
Packit 45fded
 * This program is distributed in the hope that it will be useful,
Packit 45fded
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 45fded
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 45fded
 * GNU General Public License for more details.
Packit 45fded
 *
Packit 45fded
 * You should have received a copy of the GNU General Public License along with
Packit 45fded
 * this program; see the file COPYING.  If not, write to the Free Software
Packit 45fded
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Packit 45fded
 */
Packit 45fded
Packit 45fded
#include <mconfig.h>
Packit 45fded
#include <stdlib.h>
Packit 45fded
#include <stdio.h>
Packit 45fded
#include <ctype.h>
Packit 45fded
#include <string.h>
Packit 45fded
Packit 45fded
enum parstate {
Packit 45fded
	KEYBEGINSEARCH,
Packit 45fded
	KEYCOMPARE,
Packit 45fded
	EQSIGNSEARCH,
Packit 45fded
	VALBEGINSEARCH,
Packit 45fded
	LASTCHARSEARCH
Packit 45fded
};
Packit 45fded
Packit 45fded
#define GETVAL_BUF_LEN 512
Packit 45fded
#define isUspace(x) isspace( (int) (unsigned char) x)
Packit 45fded
Packit 45fded
static FILE *glob_cfg_ptr = NULL;
Packit 45fded
Packit 45fded
/*
Packit 45fded
 * Warning, uses static line buffer, not reentrant. NULL returned if the key isn't found.
Packit 45fded
 */
Packit 45fded
static char *get_value(FILE *srcfile, const char *key, int dorewind) {
Packit 45fded
	static char linebuf[GETVAL_BUF_LEN];
Packit 45fded
Packit 45fded
	if(!srcfile)
Packit 45fded
		return ((char *) NULL);
Packit 45fded
Packit 45fded
	if(dorewind)
Packit 45fded
		rewind(srcfile);
Packit 45fded
Packit 45fded
	if(!key)
Packit 45fded
		return NULL;
Packit 45fded
Packit 45fded
next_line:
Packit 45fded
	while(fgets(linebuf, sizeof(linebuf)-1, srcfile)) {
Packit 45fded
		int i;
Packit 45fded
		int keybeg=0;
Packit 45fded
		int s=KEYBEGINSEARCH;
Packit 45fded
		char *ret=NULL;
Packit 45fded
		int lastchar=0;
Packit 45fded
Packit 45fded
		/* simple state machine, char position moved by the states (or not),
Packit 45fded
		 * state change is done by the state (or not) */
Packit 45fded
		for( i=0 ; i
Packit 45fded
			/* printf("key: %s, %s, s: %d\n", key,  linebuf, s); */
Packit 45fded
			switch(s) {
Packit 45fded
				case(KEYBEGINSEARCH):
Packit 45fded
					{
Packit 45fded
						if(isUspace(linebuf[i]))
Packit 45fded
							i++;
Packit 45fded
						else if(linebuf[i] == '#' || linebuf[i]=='\0')
Packit 45fded
							goto next_line;
Packit 45fded
						else {
Packit 45fded
							s=KEYCOMPARE;
Packit 45fded
							keybeg=i;
Packit 45fded
						}
Packit 45fded
					}
Packit 45fded
					break;
Packit 45fded
				case(KEYCOMPARE): /* compare the key */
Packit 45fded
					{
Packit 45fded
						if(key[i-keybeg]=='\0') 
Packit 45fded
							/* end of key, next state decides what to do on this position */
Packit 45fded
							s=EQSIGNSEARCH;
Packit 45fded
						else {
Packit 45fded
							if(linebuf[i-keybeg]!=key[i-keybeg])
Packit 45fded
								goto next_line;
Packit 45fded
							else
Packit 45fded
								i++;
Packit 45fded
						}
Packit 45fded
					}
Packit 45fded
					break;
Packit 45fded
				case(EQSIGNSEARCH): /* skip whitespace, stop on =, break on anything else */
Packit 45fded
					{
Packit 45fded
						if(isUspace(linebuf[i]))
Packit 45fded
							i++;
Packit 45fded
						else if(linebuf[i]=='=') {
Packit 45fded
							s=VALBEGINSEARCH;
Packit 45fded
							i++;
Packit 45fded
						}
Packit 45fded
						else
Packit 45fded
							goto next_line;
Packit 45fded
					}
Packit 45fded
					break;
Packit 45fded
				case(VALBEGINSEARCH):
Packit 45fded
					{
Packit 45fded
						if(isUspace(linebuf[i]))
Packit 45fded
							i++;
Packit 45fded
						else {
Packit 45fded
							/* possible at EOF */
Packit 45fded
							if(linebuf[i] == '\0')
Packit 45fded
								return NULL;
Packit 45fded
Packit 45fded
							lastchar=i-1; /* lastchar can be a space, see below */
Packit 45fded
							ret= & linebuf[i];
Packit 45fded
							s=LASTCHARSEARCH;
Packit 45fded
						}
Packit 45fded
					}
Packit 45fded
					break;
Packit 45fded
				case(LASTCHARSEARCH):
Packit 45fded
					{
Packit 45fded
						if(linebuf[i]) {
Packit 45fded
							if(!isUspace(linebuf[i]))
Packit 45fded
								lastchar=i;
Packit 45fded
						}
Packit 45fded
						else { /* got string end, terminate after the last seen char */
Packit 45fded
							if(linebuf+lastchar < ret) /* no non-space found */
Packit 45fded
								return NULL;
Packit 45fded
							linebuf[lastchar+1]='\0';
Packit 45fded
							return ret;
Packit 45fded
						}
Packit 45fded
						i++;
Packit 45fded
					}
Packit 45fded
					break;
Packit 45fded
			}
Packit 45fded
		}
Packit 45fded
	}
Packit 45fded
	return NULL;
Packit 45fded
}
Packit 45fded
Packit 45fded
int cfg_open(const char *name)
Packit 45fded
{
Packit 45fded
	if(glob_cfg_ptr) {
Packit 45fded
		fclose(glob_cfg_ptr);
Packit 45fded
		glob_cfg_ptr=NULL;
Packit 45fded
	}
Packit 45fded
	if(!name) {
Packit 45fded
		glob_cfg_ptr=NULL;
Packit 45fded
		return 0;
Packit 45fded
	}
Packit 45fded
	glob_cfg_ptr = fopen(name, "r");
Packit 45fded
	return (glob_cfg_ptr ? 0 : -1);
Packit 45fded
}
Packit 45fded
Packit 45fded
int cfg_close()
Packit 45fded
{
Packit 45fded
	int r;
Packit 45fded
	if(!glob_cfg_ptr)
Packit 45fded
		return 0;
Packit 45fded
	r=fclose(glob_cfg_ptr);
Packit 45fded
	glob_cfg_ptr=NULL;
Packit 45fded
	return r;
Packit 45fded
}
Packit 45fded
Packit 45fded
void cfg_restart()
Packit 45fded
{
Packit 45fded
	get_value(glob_cfg_ptr, NULL, 1);
Packit 45fded
}
Packit 45fded
Packit 45fded
char *cfg_get(const char *key)
Packit 45fded
{
Packit 45fded
	return get_value(glob_cfg_ptr, key, 1);
Packit 45fded
}
Packit 45fded
Packit 45fded
char *cfg_get_next(const char *key)
Packit 45fded
{
Packit 45fded
	return get_value(glob_cfg_ptr, key, 0);
Packit 45fded
}