296 lines
5.8 KiB
C
296 lines
5.8 KiB
C
/*
|
|
Copyright (C) 2004, Wolfgang Hottgenroth
|
|
|
|
This file is part of smmapdfw.
|
|
|
|
smmapdfw is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
smmapdfw is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
|
License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with smmapdfw. If not, write to the Free Software Foundation, 59
|
|
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
|
|
|
|
#if HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#if STDC_HEADERS
|
|
#include <stdlib.h>
|
|
#endif
|
|
|
|
#if HAVE_SYSLOG_H
|
|
#include <syslog.h>
|
|
#endif
|
|
|
|
#include "cfg.h"
|
|
#include "htmalloc.h"
|
|
|
|
#include "sunos_comp.h"
|
|
|
|
#define LF 10
|
|
|
|
#define STATE_START 0
|
|
#define STATE_COMMENT 1
|
|
#define STATE_SECTION 2
|
|
#define STATE_NAME 3
|
|
#define STATE_EQUAL 4
|
|
#define STATE_VALUESTART 5
|
|
#define STATE_VALUE 6
|
|
|
|
#define BUFSIZE 1024
|
|
config_section_t *readcfg(char *cfgfile) {
|
|
FILE *f;
|
|
char buffer[BUFSIZE+1];
|
|
char c;
|
|
int state = STATE_START;
|
|
int i = 0;
|
|
char tmp;
|
|
|
|
config_section_t *cfg = NULL;
|
|
config_section_t *cs_head;
|
|
config_section_t *cs;
|
|
config_item_t *ci_head;
|
|
config_item_t *ci;
|
|
|
|
|
|
f = fopen(cfgfile, "r");
|
|
if (NULL == f) {
|
|
syslog(LOG_ERR, "readcfg: unable to open config file %s", cfgfile);
|
|
return NULL;
|
|
}
|
|
|
|
while (EOF != (c = fgetc(f))) {
|
|
/* printf("read: (%d) (%d) (%c)\n", state, c, c); */
|
|
|
|
switch (state) {
|
|
case STATE_START:
|
|
if ((';' == c) || ('#' == c)) {
|
|
state = STATE_COMMENT;
|
|
break;
|
|
} else if ('[' == c) {
|
|
state = STATE_SECTION;
|
|
i = 0;
|
|
break;
|
|
} else if (LF == c) {
|
|
break;
|
|
} else {
|
|
buffer[i++] = c;
|
|
state = STATE_NAME;
|
|
}
|
|
|
|
case STATE_COMMENT:
|
|
if (LF == c)
|
|
state = STATE_START;
|
|
break;
|
|
|
|
case STATE_SECTION:
|
|
if (']' == c) {
|
|
buffer[i] = '\0';
|
|
/* printf("section: (%s)\n", buffer); */
|
|
state = STATE_START;
|
|
i = 0;
|
|
|
|
cs = (config_section_t*) htmalloc(sizeof(config_section_t));
|
|
cs->next = NULL;
|
|
cs->name = (char*) htmalloc(strlen(buffer)+1);
|
|
strcpy(cs->name, buffer);
|
|
cs->item = NULL;
|
|
|
|
if (NULL == cfg) {
|
|
cfg = cs;
|
|
cs_head = cfg;
|
|
} else {
|
|
cs_head->next = cs;
|
|
cs_head = cs;
|
|
}
|
|
|
|
break;
|
|
} else if (LF == c) {
|
|
syslog(LOG_ERR, "readcfg: unexpected EOL in section");
|
|
freecfg(cfg);
|
|
fclose(f);
|
|
return NULL;
|
|
} else {
|
|
buffer[i++] = c;
|
|
break;
|
|
}
|
|
|
|
case STATE_NAME:
|
|
if (isblank(c)) {
|
|
buffer[i] = '\0';
|
|
/* printf("name: (%s)\n", buffer); */
|
|
state = STATE_EQUAL;
|
|
i = 0;
|
|
|
|
ci = (config_item_t*) htmalloc(sizeof(config_item_t));
|
|
ci->next = NULL;
|
|
ci->name = (char*) htmalloc(strlen(buffer)+1);
|
|
strcpy(ci->name, buffer);
|
|
ci->value = NULL;
|
|
|
|
if (NULL == cs->item) {
|
|
cs->item = ci;
|
|
ci_head = ci;
|
|
} else {
|
|
ci_head->next = ci;
|
|
ci_head = ci;
|
|
}
|
|
|
|
break;
|
|
} else if (LF == c) {
|
|
syslog(LOG_ERR, "readcfg: unexpected EOL in name");
|
|
freecfg(cfg);
|
|
fclose(f);
|
|
return NULL;
|
|
} else {
|
|
buffer[i++] = c;
|
|
break;
|
|
}
|
|
|
|
case STATE_EQUAL:
|
|
if ('=' == c) {
|
|
state = STATE_VALUESTART;
|
|
break;
|
|
} else if (isblank(c)) {
|
|
break;
|
|
} else {
|
|
syslog(LOG_ERR, "readcfg: unexpected character in equal");
|
|
freecfg(cfg);
|
|
fclose(f);
|
|
return NULL;
|
|
}
|
|
|
|
case STATE_VALUESTART:
|
|
if (isblank(c)) {
|
|
break;
|
|
} else if (LF == c) {
|
|
syslog(LOG_ERR, "readcfg: unexpected EOL in valuestart");
|
|
freecfg(cfg);
|
|
fclose(f);
|
|
return NULL;
|
|
} else {
|
|
buffer[i++] = c;
|
|
state = STATE_VALUE;
|
|
break;
|
|
}
|
|
|
|
case STATE_VALUE:
|
|
if (LF == c) {
|
|
buffer[i] = '\0';
|
|
/* printf("value: (%s)\n", buffer); */
|
|
state = STATE_START;
|
|
i = 0;
|
|
|
|
ci->value = (char*) htmalloc(strlen(buffer)+1);
|
|
strcpy(ci->value, buffer);
|
|
|
|
break;
|
|
} else {
|
|
buffer[i++] = c;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose(f);
|
|
if (STATE_START != state) {
|
|
syslog(LOG_ERR, "readcfg: unexpected EOF");
|
|
freecfg(cfg);
|
|
fclose(f);
|
|
return NULL;
|
|
}
|
|
|
|
return cfg;
|
|
}
|
|
|
|
|
|
void printcfg(config_section_t *cfg) {
|
|
config_section_t *cs;
|
|
config_item_t *ci;
|
|
|
|
for (cs = cfg; cs != NULL; cs = cs->next) {
|
|
printf("section: %s\n", cs->name);
|
|
for (ci = cs->item; ci != NULL; ci = ci->next) {
|
|
printf(" item: %s -> %s\n", ci->name, ci->value);
|
|
}
|
|
}
|
|
}
|
|
|
|
void freecfg(config_section_t *cfg) {
|
|
config_section_t *cs, *csf;
|
|
config_item_t *ci, *cif;
|
|
|
|
cs = cfg;
|
|
while (NULL != cs) {
|
|
ci = cs->item;
|
|
|
|
while (NULL != ci) {
|
|
cif = ci;
|
|
ci = ci->next;
|
|
|
|
free(cif->name);
|
|
free(cif->value);
|
|
free(cif);
|
|
}
|
|
|
|
csf = cs;
|
|
cs = cs->next;
|
|
|
|
free(csf->name);
|
|
free(csf);
|
|
}
|
|
}
|
|
|
|
config_item_t *findcfgsection(config_section_t *cfg, char *section) {
|
|
config_section_t *cs;
|
|
|
|
for (cs = cfg; cs != NULL; cs = cs->next)
|
|
if (0 == strcmp(section, cs->name))
|
|
return cs->item;
|
|
return NULL;
|
|
}
|
|
|
|
char *findcfg(config_section_t *cfg, char *section, char *name) {
|
|
config_item_t *ci;
|
|
|
|
for (ci = findcfgsection(cfg, section); ci != NULL; ci = ci->next)
|
|
if (0 == strcmp(name, ci->name))
|
|
return ci->value;
|
|
return NULL;
|
|
}
|
|
|
|
char *findcfgx(config_section_t *cfg, char *section, char *name, char *default_value) {
|
|
char *r = findcfg(cfg, section, name);
|
|
return (NULL != r) ? r : default_value;
|
|
}
|
|
|
|
|
|
|
|
#ifdef _TEST_MODE_
|
|
int main() {
|
|
config_section_t *cfg = readcfg("smmapd.ini");
|
|
printcfg(cfg);
|
|
printf("test1: %s\n", findcfg(cfg, "test_worker1", "obj"));
|
|
printf("test2: %s\n", findcfg(cfg, "global", "port"));
|
|
printf("test3: %s\n", findcfg(cfg, "nix", "obj"));
|
|
printf("test4: %s\n", findcfg(cfg, "global", "nix"));
|
|
printf("test5: %s\n", findcfgx(cfg, "global", "test", "test default"));
|
|
|
|
freecfg(cfg);
|
|
}
|
|
#endif /* _TEST_MODE_ */
|