187 строки
4.3 KiB
C
187 строки
4.3 KiB
C
![]() |
#include "compat.h"
|
||
|
#include "libconfig.h"
|
||
|
#include "libconfig_private.h"
|
||
|
#include "conf_section.h"
|
||
|
|
||
|
#ifdef HAVE_STDIO_H
|
||
|
#include <stdio.h>
|
||
|
#endif
|
||
|
|
||
|
#ifdef HAVE_STRING_H
|
||
|
#include <string.h>
|
||
|
#endif
|
||
|
|
||
|
int lc_process_conf_section(const char *appname, const char *configfile) {
|
||
|
FILE *configfp = NULL;
|
||
|
char linebuf[LC_LINEBUF_LEN] = {0}, *linebuf_ptr = NULL;
|
||
|
char qualifbuf[LC_LINEBUF_LEN] = {0};
|
||
|
char *cmd = NULL, *value = NULL, *sep = NULL, *cmdend = NULL;
|
||
|
char *currsection = NULL;
|
||
|
char *fgetsret = NULL;
|
||
|
int lcpvret = -1;
|
||
|
int invalid_section = 1, ignore_section = 0;
|
||
|
int retval = 0;
|
||
|
lc_err_t save_lc_errno = LC_ERR_NONE;
|
||
|
|
||
|
if (appname == NULL || configfile == NULL) {
|
||
|
lc_errno = LC_ERR_INVDATA;
|
||
|
return(-1);
|
||
|
}
|
||
|
|
||
|
configfp = lc_fopen(configfile, "r");
|
||
|
|
||
|
if (configfp == NULL) {
|
||
|
lc_errno = LC_ERR_CANTOPEN;
|
||
|
return(-1);
|
||
|
}
|
||
|
|
||
|
while (1) {
|
||
|
fgetsret = fgets(linebuf, sizeof(linebuf) - 1, configfp);
|
||
|
if (fgetsret == NULL) {
|
||
|
break;
|
||
|
}
|
||
|
if (feof(configfp)) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Remove trailing crap (but not spaces). */
|
||
|
linebuf_ptr = &linebuf[strlen(linebuf) - 1];
|
||
|
while (*linebuf_ptr < ' ' && linebuf_ptr >= linebuf) {
|
||
|
*linebuf_ptr = '\0';
|
||
|
linebuf_ptr--;
|
||
|
}
|
||
|
|
||
|
/* Handle section header. */
|
||
|
if (linebuf[0] == '[' && linebuf[strlen(linebuf) - 1] == ']') {
|
||
|
linebuf[strlen(linebuf) - 1] = '\0';
|
||
|
linebuf_ptr = &linebuf[1];
|
||
|
|
||
|
/* If a section was open, close it. */
|
||
|
if (currsection != NULL) {
|
||
|
lcpvret = lc_process_var(currsection, NULL, NULL, LC_FLAGS_SECTIONEND);
|
||
|
if (lcpvret < 0) {
|
||
|
#ifdef DEBUG
|
||
|
fprintf(stderr, "Invalid section terminating: \"%s\"\n", currsection);
|
||
|
#endif
|
||
|
}
|
||
|
free(currsection);
|
||
|
}
|
||
|
|
||
|
/* Open new section. */
|
||
|
currsection = strdup(linebuf_ptr);
|
||
|
lcpvret = lc_process_var(currsection, NULL, NULL, LC_FLAGS_SECTIONSTART);
|
||
|
if (lcpvret < 0) {
|
||
|
#ifdef DEBUG
|
||
|
fprintf(stderr, "Invalid section: \"%s\"\n", currsection);
|
||
|
#endif
|
||
|
invalid_section = 1;
|
||
|
lc_errno = LC_ERR_INVSECTION;
|
||
|
retval = -1;
|
||
|
} else {
|
||
|
invalid_section = 0;
|
||
|
ignore_section = 0;
|
||
|
}
|
||
|
|
||
|
if (lcpvret == LC_CBRET_IGNORESECTION) {
|
||
|
ignore_section = 1;
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* Remove leading spaces. */
|
||
|
linebuf_ptr = &linebuf[0];
|
||
|
while (*linebuf_ptr == ' ') {
|
||
|
linebuf_ptr++;
|
||
|
}
|
||
|
|
||
|
/* Drop comments and blank lines. */
|
||
|
if (*linebuf_ptr == ';' || *linebuf_ptr == '\0') {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* Don't handle things for a section that doesn't exist. */
|
||
|
if (invalid_section == 1) {
|
||
|
#ifdef DEBUG
|
||
|
fprintf(stderr, "Ignoring line (because invalid section): %s\n", linebuf);
|
||
|
#endif
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* Don't process commands if this section is specifically ignored. */
|
||
|
if (ignore_section == 1) {
|
||
|
#ifdef DEBUG
|
||
|
fprintf(stderr, "Ignoring line (because ignored section): %s\n", linebuf);
|
||
|
#endif
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* Find the command and the data in the line. */
|
||
|
cmdend = sep = strpbrk(linebuf_ptr, "=");
|
||
|
if (sep == NULL) {
|
||
|
#ifdef DEBUG
|
||
|
fprintf(stderr, "Invalid line: \"%s\"\n", linebuf);
|
||
|
#endif
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* Delete space at the end of the command. */
|
||
|
cmdend--; /* It currently derefs to the seperator.. */
|
||
|
while (*cmdend <= ' ') {
|
||
|
*cmdend = '\0';
|
||
|
cmdend--;
|
||
|
}
|
||
|
|
||
|
cmd = linebuf_ptr;
|
||
|
|
||
|
/* Delete the seperator char and any leading space. */
|
||
|
*sep = '\0';
|
||
|
sep++;
|
||
|
while (*sep == ' ' || *sep == '\t') {
|
||
|
sep++;
|
||
|
}
|
||
|
value = sep;
|
||
|
|
||
|
/* Create the fully qualified variable name. */
|
||
|
if (currsection == NULL) {
|
||
|
strncpy(qualifbuf, cmd, sizeof(qualifbuf) - 1);
|
||
|
} else {
|
||
|
snprintf(qualifbuf, sizeof(qualifbuf) - 1, "%s.%s", currsection, cmd);
|
||
|
}
|
||
|
|
||
|
/* Call the parent and tell them we have data. */
|
||
|
save_lc_errno = lc_errno;
|
||
|
lc_errno = LC_ERR_NONE;
|
||
|
lcpvret = lc_process_var(qualifbuf, NULL, value, LC_FLAGS_VAR);
|
||
|
if (lcpvret < 0) {
|
||
|
if (lc_errno == LC_ERR_NONE) {
|
||
|
#ifdef DEBUG
|
||
|
fprintf(stderr, "Invalid command: \"%s\"\n", cmd);
|
||
|
#endif
|
||
|
lc_errno = LC_ERR_INVCMD;
|
||
|
} else {
|
||
|
#ifdef DEBUG
|
||
|
fprintf(stderr, "Error processing command (command was valid, but an error occured, errno was set)\n");
|
||
|
#endif
|
||
|
}
|
||
|
retval = -1;
|
||
|
} else {
|
||
|
lc_errno = save_lc_errno;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Close any open section, and clean-up. */
|
||
|
if (currsection != NULL) {
|
||
|
lcpvret = lc_process_var(currsection, NULL, NULL, LC_FLAGS_SECTIONEND);
|
||
|
if (lcpvret < 0) {
|
||
|
#ifdef DEBUG
|
||
|
fprintf(stderr, "Invalid section terminating: \"%s\"\n", currsection);
|
||
|
#endif
|
||
|
}
|
||
|
free(currsection);
|
||
|
}
|
||
|
|
||
|
fclose(configfp);
|
||
|
|
||
|
return(retval);
|
||
|
}
|