Index: Makefile.in ================================================================== --- Makefile.in +++ Makefile.in @@ -15,10 +15,11 @@ SHOBJEXT = @SHOBJEXT@ ARFLAGS = # @ARFLAGS@ AREXT = @AREXT@ PKGVERS = @PACKAGE_VERSION@ PKGVERSMAJOR = `echo $(PKGVERS) | cut -f 1 -d .` +EXEEXT = @EXEEXT@ prefix = @prefix@ mandir = @mandir@ sysconfdir = @sysconfdir@ datadir = @datadir@ Index: build/h-to-hin ================================================================== --- build/h-to-hin +++ build/h-to-hin @@ -1,9 +1,9 @@ #! /bin/sh if [ libconfig.h -nt libconfig.h.in ]; then echo 'Updating libconfig.h.in ...' - sed 's@^# @!@;s@^ *$@|__BLANK_LINE__|@' libconfig.h | tr '|' "\n" > libconfig.h.in + sed 's@^# @!@;s@^ *$@:__BLANK_LINE__:@' libconfig.h | tr ':' "\n" > libconfig.h.in else echo 'Updating libconfig.h ...' make libconfig.h fi ADDED build/test.conf Index: build/test.conf ================================================================== --- /dev/null +++ build/test.conf @@ -0,0 +1,14 @@ + + +
+ test Bob was here +
+ + + Free yes, no + + +# +# + +sally 3 Index: compat.h ================================================================== --- compat.h +++ compat.h @@ -86,10 +86,18 @@ #ifdef HAVE_OPENNET_H #include #endif #ifdef HAVE_LIBOPENNET #define lc_fopen(path, mode) fopen_net(path, mode) +#define lc_fgets(buf, size, stream) fgets_net(buf, size, stream) +#define lc_feof(stream) feof_net(stream) +#define lc_fclose(stream) fclose_net(stream) +#define LC_FILE NETFILE #else #define lc_fopen(path, mode) fopen(path, mode) +#define lc_fgets(buf, size, stream) fgets(buf, size, stream) +#define lc_feof(stream) feof(stream) +#define lc_fclose(stream) fclose(stream) +#define LC_FILE FILE #endif #endif Index: conf_apache.c ================================================================== --- conf_apache.c +++ conf_apache.c @@ -79,46 +79,57 @@ return(retval); } static int lc_process_conf_apache_file(const char *configfile, const char *pathprefix) { - FILE *configfp = NULL; + LC_FILE *configfp = NULL; + const char *local_lc_errfile; char linebuf[LC_LINEBUF_LEN] = {0}, *linebuf_ptr = NULL, *tmp_ptr = NULL; char *lastsection = NULL; char qualifbuf[LC_LINEBUF_LEN] = {0}; char *cmd = NULL, *value = NULL, *sep = NULL, *cmdend = NULL; char *fgetsret = NULL; int lcpvret = -1, lpcafret = -1; int invalid_section = 0, ignore_section = 0; + int local_lc_errline; int retval = 0; lc_err_t save_lc_errno = LC_ERR_NONE; if (pathprefix != NULL) { /* Copy the prefix, if specified. */ strncpy(qualifbuf, pathprefix, sizeof(qualifbuf) - 1); } + + local_lc_errfile = configfile; + local_lc_errline = 0; if (configfile == NULL) { + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_INVDATA; return(-1); } configfp = lc_fopen(configfile, "r"); if (configfp == NULL) { + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_CANTOPEN; return(-1); } while (1) { - fgetsret = fgets(linebuf, sizeof(linebuf) - 1, configfp); + fgetsret = lc_fgets(linebuf, sizeof(linebuf) - 1, configfp); if (fgetsret == NULL) { break; } - if (feof(configfp)) { + if (lc_feof(configfp)) { break; } + + local_lc_errline++; /* Remove trailing crap (but not spaces). */ linebuf_ptr = &linebuf[strlen(linebuf) - 1]; while (*linebuf_ptr < ' ' && linebuf_ptr >= linebuf) { *linebuf_ptr = '\0'; @@ -162,10 +173,12 @@ #ifdef DEBUG fprintf(stderr, "Section closing does not match last opened section.\n"); fprintf(stderr, "Last opened = \"%s\", Closing = \"%s\"\n", lastsection, cmd); #endif retval = -1; + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_BADFORMAT; /* For this error, we abort immediately. */ break; } @@ -230,10 +243,12 @@ if (lcpvret < 0) { #ifdef DEBUG fprintf(stderr, "Invalid section: \"%s\"\n", qualifbuf); #endif invalid_section = 1; + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_INVSECTION; retval = -1; } if (lcpvret == LC_CBRET_IGNORESECTION) { ignore_section = 1; @@ -286,10 +301,12 @@ cmd = linebuf_ptr; /* Handle special commands. */ if (strcasecmp(cmd, "include") == 0) { if (value == NULL) { + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_BADFORMAT; retval = -1; #ifdef DEBUG fprintf(stderr, "Invalid include command.\n"); #endif @@ -325,10 +342,12 @@ } else { #ifdef DEBUG fprintf(stderr, "Error processing command (command was valid, but an error occured, errno was set)\n"); #endif } + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; retval = -1; } else { lc_errno = save_lc_errno; } @@ -338,13 +357,13 @@ tmp_ptr = qualifbuf; } *tmp_ptr = '\0'; } - fclose(configfp); + lc_fclose(configfp); return(retval); } int lc_process_conf_apache(const char *appname, const char *configfile) { return(lc_process_conf_apache_file(configfile, NULL)); } Index: conf_section.c ================================================================== --- conf_section.c +++ conf_section.c @@ -10,41 +10,52 @@ #ifdef HAVE_STRING_H #include #endif int lc_process_conf_section(const char *appname, const char *configfile) { - FILE *configfp = NULL; + LC_FILE *configfp = NULL; + const char *local_lc_errfile; 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 local_lc_errline; int retval = 0; lc_err_t save_lc_errno = LC_ERR_NONE; + + local_lc_errfile = configfile; + local_lc_errline = 0; if (appname == NULL || configfile == NULL) { + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_INVDATA; return(-1); } configfp = lc_fopen(configfile, "r"); if (configfp == NULL) { + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_CANTOPEN; return(-1); } while (1) { - fgetsret = fgets(linebuf, sizeof(linebuf) - 1, configfp); + fgetsret = lc_fgets(linebuf, sizeof(linebuf) - 1, configfp); if (fgetsret == NULL) { break; } - if (feof(configfp)) { + if (lc_feof(configfp)) { break; } + + local_lc_errline++; /* Remove trailing crap (but not spaces). */ linebuf_ptr = &linebuf[strlen(linebuf) - 1]; while (*linebuf_ptr < ' ' && linebuf_ptr >= linebuf) { *linebuf_ptr = '\0'; @@ -73,10 +84,12 @@ if (lcpvret < 0) { #ifdef DEBUG fprintf(stderr, "Invalid section: \"%s\"\n", currsection); #endif invalid_section = 1; + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_INVSECTION; retval = -1; } else { invalid_section = 0; ignore_section = 0; @@ -161,10 +174,12 @@ } else { #ifdef DEBUG fprintf(stderr, "Error processing command (command was valid, but an error occured, errno was set)\n"); #endif } + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; retval = -1; } else { lc_errno = save_lc_errno; } } @@ -178,9 +193,9 @@ #endif } free(currsection); } - fclose(configfp); + lc_fclose(configfp); return(retval); } Index: conf_space.c ================================================================== --- conf_space.c +++ conf_space.c @@ -10,38 +10,49 @@ #ifdef HAVE_STRING_H #include #endif int lc_process_conf_space(const char *appname, const char *configfile) { - FILE *configfp = NULL; + LC_FILE *configfp = NULL; + const char *local_lc_errfile; char linebuf[LC_LINEBUF_LEN] = {0}, *linebuf_ptr = NULL; char *cmd = NULL, *value = NULL, *sep = NULL; char *fgetsret = NULL; + int local_lc_errline; int lcpvret = -1; int retval = 0; lc_err_t save_lc_errno = LC_ERR_NONE; + + local_lc_errfile = configfile; + local_lc_errline = 0; if (appname == NULL || configfile == NULL) { + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_INVDATA; return(-1); } configfp = lc_fopen(configfile, "r"); if (configfp == NULL) { + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_CANTOPEN; return(-1); } while (1) { - fgetsret = fgets(linebuf, sizeof(linebuf) - 1, configfp); + fgetsret = lc_fgets(linebuf, sizeof(linebuf) - 1, configfp); if (fgetsret == NULL) { break; } - if (feof(configfp)) { + if (lc_feof(configfp)) { break; } + + local_lc_errline++; linebuf_ptr = &linebuf[strlen(linebuf) - 1]; while (*linebuf_ptr < ' ' && linebuf_ptr >= linebuf) { *linebuf_ptr = '\0'; linebuf_ptr--; @@ -82,15 +93,17 @@ } else { #ifdef DEBUG fprintf(stderr, "Error processing command (command was valid, but an error occured, errno was set)\n"); #endif } + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; retval = -1; } else { lc_errno = save_lc_errno; } } - fclose(configfp); + lc_fclose(configfp); return(retval); } Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -1,7 +1,7 @@ AC_REVISION($Revision $) -AC_INIT(libconfig, 0.1.18) +AC_INIT(libconfig, 0.1.19) AC_CONFIG_HEADER(config.h) dnl Find out about the host OS DC_CHK_OS_INFO Index: libconfig.c ================================================================== --- libconfig.c +++ libconfig.c @@ -36,40 +36,44 @@ #include #endif struct lc_varhandler_st *varhandlers = NULL; lc_err_t lc_errno = LC_ERR_NONE; +const char *lc_errfile = NULL; int lc_optind = 0; +int lc_errline = 0; extern char **environ; -static int lc_process_var_string(void *data, const char *value) { +static int lc_process_var_string(void *data, const char *value, const char **endptr) { char **dataval; dataval = data; *dataval = strdup(value); + *endptr = NULL; + return(0); } -static int lc_process_var_cidr(void *data, const char *value) { +static int lc_process_var_cidr(void *data, const char *value, const char **endptr) { + return(-1); +} + +static int lc_process_var_hostname6(void *data, const char *value, const char **endptr) { return(-1); } -static int lc_process_var_hostname6(void *data, const char *value) { +static int lc_process_var_hostname4(void *data, const char *value, const char **endptr) { return(-1); } -static int lc_process_var_hostname4(void *data, const char *value) { +static int lc_process_var_ip6(void *data, const char *value, const char **endptr) { return(-1); } -static int lc_process_var_ip6(void *data, const char *value) { - return(-1); -} - -static int lc_process_var_ip4(void *data, const char *value) { +static int lc_process_var_ip4(void *data, const char *value, const char **endptr) { uint32_t *dataval, retval = 0; const char *dotptr = NULL; int tmpval = -1; // int dotcount @@ -96,90 +100,134 @@ dotptr++; } *dataval = retval; + *endptr = (char *) dotptr; + return(0); } -static int lc_process_var_longlong(void *data, const char *value) { +static int lc_process_var_longlong(void *data, const char *value, const char **endptr) { long long *dataval; dataval = data; - *dataval = strtoll(value, NULL, 10); + *dataval = strtoll(value, (char **) endptr, 10); return(0); } -static int lc_process_var_long(void *data, const char *value) { +static int lc_process_var_long(void *data, const char *value, const char **endptr) { long *dataval; dataval = data; - *dataval = strtoll(value, NULL, 10); + *dataval = strtoll(value, (char **) endptr, 10); return(0); } -static int lc_process_var_int(void *data, const char *value) { +static int lc_process_var_int(void *data, const char *value, const char **endptr) { int *dataval; dataval = data; - *dataval = strtoll(value, NULL, 10); + *dataval = strtoll(value, (char **) endptr, 10); return(0); } -static int lc_process_var_short(void *data, const char *value) { +static int lc_process_var_short(void *data, const char *value, const char **endptr) { short *dataval; dataval = data; - *dataval = strtoll(value, NULL, 10); + *dataval = strtoll(value, (char **) endptr, 10); return(0); } -static int lc_process_var_bool_byexistance(void *data, const char *value) { +static int lc_process_var_bool_byexistance(void *data, const char *value, const char **endptr) { int *dataval; dataval = data; *dataval = 1; + *endptr = NULL; + return(0); } -static int lc_process_var_bool(void *data, const char *value) { +static int lc_process_var_bool(void *data, const char *value, const char **endptr) { + char *trueval[] = {"enable", "true", "yes", "on", "y", "1"}; + char *falseval[] = {"disable", "false", "no", "off", "n", "0"}; + size_t chkvallen, vallen; int *dataval; + int i; dataval = data; *dataval = -1; - if (strcasecmp(value, "enable") == 0 || - strcasecmp(value, "true") == 0 || - strcasecmp(value, "yes") == 0 || - strcasecmp(value, "on") == 0 || - strcasecmp(value, "y") == 0 || - strcasecmp(value, "1") == 0) { - *dataval = 1; - return(0); - } else if (strcasecmp(value, "disable") == 0 || - strcasecmp(value, "false") == 0 || - strcasecmp(value, "off") == 0 || - strcasecmp(value, "no") == 0 || - strcasecmp(value, "n") == 0 || - strcasecmp(value, "0") == 0) { - *dataval = 0; - return(0); + vallen = strlen(value); + + for (i = 0; i < (sizeof(trueval) / sizeof(*trueval)); i++) { + chkvallen = strlen(trueval[i]); + + /* + * Skip if there's no way we could find a match here. + */ + if (chkvallen > vallen) { + continue; + } + + /* + * Skip if there is no partial match. + */ + if (strncasecmp(value, trueval[i], chkvallen) != 0) { + continue; + } + + if (value[chkvallen] == '\0' || value[chkvallen] == ',' || \ + value[chkvallen] == ' ') { + /* Declare a winner and set the next token. */ + *endptr = value + chkvallen; + *dataval = 1; + return(0); + } + } + + for (i = 0; i < (sizeof(falseval) / sizeof(*falseval)); i++) { + chkvallen = strlen(falseval[i]); + + /* + * Skip if there's no way we could find a match here. + */ + if (chkvallen > vallen) { + continue; + } + + /* + * Skip if there is no partial match. + */ + if (strncasecmp(value, falseval[i], chkvallen) != 0) { + continue; + } + + if (value[chkvallen] == '\0' || value[chkvallen] == ',' || \ + value[chkvallen] == ' ') { + /* Declare a winner and set the next token. */ + *endptr = value + chkvallen; + *dataval = 0; + return(0); + } } lc_errno = LC_ERR_BADFORMAT; return(-1); } -static long long lc_process_size(const char *value) { - long long retval = -1; +static unsigned long long lc_process_size(const char *value, const char **endptr) { + unsigned long long retval = 0; char *mult = NULL; retval = strtoll(value, &mult, 10); if (mult != NULL) { switch (tolower(mult[0])) { @@ -204,109 +252,117 @@ } return(retval); } -static int lc_process_var_sizelonglong(void *data, const char *value) { - long long *dataval; - - dataval = data; - *dataval = lc_process_size(value); - - return(0); -} - -static int lc_process_var_sizelong(void *data, const char *value) { - long *dataval; - - dataval = data; - *dataval = lc_process_size(value); - - return(0); -} - -static int lc_process_var_sizeint(void *data, const char *value) { - int *dataval; - - dataval = data; - *dataval = lc_process_size(value); - - return(0); -} - -static int lc_process_var_sizeshort(void *data, const char *value) { - short *dataval; - - dataval = data; - *dataval = lc_process_size(value); - - return(0); -} - -static int lc_process_var_sizesizet(void *data, const char *value) { - size_t *dataval; - - dataval = data; - *dataval = lc_process_size(value); +static int lc_process_var_sizelonglong(void *data, const char *value, const char **endptr) { + long long *dataval; + + dataval = data; + *dataval = lc_process_size(value, endptr); + + return(0); +} + +static int lc_process_var_sizelong(void *data, const char *value, const char **endptr) { + long *dataval; + + dataval = data; + *dataval = lc_process_size(value, endptr); + + return(0); +} + +static int lc_process_var_sizeint(void *data, const char *value, const char **endptr) { + int *dataval; + + dataval = data; + *dataval = lc_process_size(value, endptr); + + return(0); +} + +static int lc_process_var_sizeshort(void *data, const char *value, const char **endptr) { + short *dataval; + + dataval = data; + *dataval = lc_process_size(value, endptr); + + return(0); +} + +static int lc_process_var_sizesizet(void *data, const char *value, const char **endptr) { + size_t *dataval; + + dataval = data; + *dataval = lc_process_size(value, endptr); return(0); } static int lc_handle_type(lc_var_type_t type, const char *value, void *data) { + const char *next; + int is_list; + + is_list = type & LC_VAR_LIST; + + if (is_list == LC_VAR_LIST) { + } + switch (type) { case LC_VAR_STRING: - return(lc_process_var_string(data, value)); + return(lc_process_var_string(data, value, &next)); break; case LC_VAR_LONG_LONG: - return(lc_process_var_longlong(data, value)); + return(lc_process_var_longlong(data, value, &next)); break; case LC_VAR_LONG: - return(lc_process_var_long(data, value)); + return(lc_process_var_long(data, value, &next)); break; case LC_VAR_INT: - return(lc_process_var_int(data, value)); + return(lc_process_var_int(data, value, &next)); break; case LC_VAR_SHORT: - return(lc_process_var_short(data, value)); + return(lc_process_var_short(data, value, &next)); break; case LC_VAR_BOOL: - return(lc_process_var_bool(data, value)); + return(lc_process_var_bool(data, value, &next)); break; case LC_VAR_SIZE_LONG_LONG: - return(lc_process_var_sizelonglong(data, value)); + return(lc_process_var_sizelonglong(data, value, &next)); break; case LC_VAR_SIZE_LONG: - return(lc_process_var_sizelong(data, value)); + return(lc_process_var_sizelong(data, value, &next)); break; case LC_VAR_SIZE_INT: - return(lc_process_var_sizeint(data, value)); + return(lc_process_var_sizeint(data, value, &next)); break; case LC_VAR_SIZE_SHORT: - return(lc_process_var_sizeshort(data, value)); + return(lc_process_var_sizeshort(data, value, &next)); break; case LC_VAR_BOOL_BY_EXISTANCE: - return(lc_process_var_bool_byexistance(data, value)); + return(lc_process_var_bool_byexistance(data, value, &next)); break; case LC_VAR_SIZE_SIZE_T: - return(lc_process_var_sizesizet(data, value)); + return(lc_process_var_sizesizet(data, value, &next)); break; case LC_VAR_IP: case LC_VAR_IP4: - return(lc_process_var_ip4(data, value)); + return(lc_process_var_ip4(data, value, &next)); break; case LC_VAR_IP6: - return(lc_process_var_ip6(data, value)); + return(lc_process_var_ip6(data, value, &next)); break; case LC_VAR_HOSTNAME4: - return(lc_process_var_hostname4(data, value)); + return(lc_process_var_hostname4(data, value, &next)); break; case LC_VAR_HOSTNAME6: - return(lc_process_var_hostname6(data, value)); + return(lc_process_var_hostname6(data, value, &next)); break; case LC_VAR_CIDR: - return(lc_process_var_cidr(data, value)); + return(lc_process_var_cidr(data, value, &next)); break; case LC_VAR_TIME: case LC_VAR_DATE: case LC_VAR_FILENAME: case LC_VAR_DIRECTORY: @@ -367,20 +423,27 @@ char **currvar; char *sep = NULL, *value = NULL, *cmd = NULL; char *ucase_appname = NULL, *ucase_appname_itr = NULL; char *lastcomponent_handler = NULL; int varnamelen = 0; + char *local_lc_errfile; + int local_lc_errline; /* Make sure we have an environment to screw with, if not, no arguments were found to be in error */ if (environ == NULL || appname == NULL) { return(0); } + + local_lc_errfile = ""; + local_lc_errline = 0; /* Allocate and create our uppercase appname. */ ucase_appname = strdup(appname); if (ucase_appname == NULL) { + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_ENOMEM; return(-1); } for (ucase_appname_itr = ucase_appname; *ucase_appname_itr != '\0'; ucase_appname_itr++) { *ucase_appname_itr = toupper(*ucase_appname_itr); @@ -488,23 +551,32 @@ char *usedargv = NULL; int cmdargidx = 0; int newargvidx = 0; int retval = 0, chkretval = 0; int ch = 0; + char *local_lc_errfile; + int local_lc_errline; + + local_lc_errfile = ""; + local_lc_errline = 0; /* Allocate "argc + 1" (+1 for the NULL terminator) elements. */ newargv = malloc((argc + 1) * sizeof(*newargv)); if (newargv == NULL) { + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_ENOMEM; return(-1); } newargv[newargvidx++] = argv[0]; newargv[argc] = NULL; /* Allocate space to indicate which arguments have been used. */ usedargv = malloc(argc * sizeof(*usedargv)); if (usedargv == NULL) { + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_ENOMEM; free(newargv); return(-1); } for (cmdargidx = 0; cmdargidx < argc; cmdargidx++) { @@ -517,11 +589,11 @@ /* Make sure we have an argument here. */ if (cmdarg == NULL) { break; } - /* If the argument isn't an option, abort. */ + /* If the argument isn't an option, skip. */ if (cmdarg[0] != '-') { continue; } /* Setup a pointer in the new array for the actual argument. */ @@ -583,10 +655,12 @@ cmdoptarg = NULL; } else { cmdargidx++; if (cmdargidx >= argc) { fprintf(stderr, "Argument required.\n"); + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_BADFORMAT; free(usedargv); free(newargv); return(-1); } @@ -603,10 +677,12 @@ break; } if (handler == NULL) { fprintf(stderr, "Unknown option: --%s\n", cmdarg); + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_INVCMD; free(usedargv); free(newargv); return(-1); } @@ -631,10 +707,12 @@ cmdoptarg = NULL; } else { cmdargidx++; if (cmdargidx >= argc) { fprintf(stderr, "Argument required.\n"); + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_BADFORMAT; free(usedargv); free(newargv); return(-1); } @@ -643,18 +721,22 @@ usedargv[cmdargidx] = 1; } chkretval = lc_handle(handler, handler->var, NULL, cmdoptarg, LC_FLAGS_CMDLINE); if (chkretval < 0) { + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; retval = -1; } break; } if (handler == NULL) { fprintf(stderr, "Unknown option: -%c\n", ch); + lc_errfile = local_lc_errfile; + lc_errline = local_lc_errline; lc_errno = LC_ERR_INVCMD; free(usedargv); free(newargv); return(-1); } @@ -939,41 +1021,53 @@ return(retval); } char *lc_geterrstr(void) { - char *retval = NULL; - - switch (lc_errno) { - case LC_ERR_NONE: - retval = "Success"; - break; - case LC_ERR_INVCMD: - retval = "Invalid command"; - break; - case LC_ERR_INVSECTION: - retval = "Invalid section"; - break; - case LC_ERR_INVDATA: - retval = "Invalid application data (internal error)"; - break; - case LC_ERR_BADFORMAT: - retval = "Bad data specified or incorrect format."; - break; - case LC_ERR_CANTOPEN: - retval = "Can't open file."; - break; - case LC_ERR_CALLBACK: - retval = "Error return from application handler."; - break; - case LC_ERR_ENOMEM: - retval = "Insuffcient memory."; - break; - } - - lc_errno = LC_ERR_NONE; - - if (retval != NULL) { - return(retval); - } - return("Unknown error"); + static char retval[512]; + char *errmsg = NULL; + + switch (lc_errno) { + case LC_ERR_NONE: + errmsg = "Success"; + break; + case LC_ERR_INVCMD: + errmsg = "Invalid command or option"; + break; + case LC_ERR_INVSECTION: + errmsg = "Invalid section"; + break; + case LC_ERR_INVDATA: + errmsg = "Invalid application data (internal error)"; + break; + case LC_ERR_BADFORMAT: + errmsg = "Bad data specified or incorrect format."; + break; + case LC_ERR_CANTOPEN: + errmsg = "Can't open file."; + break; + case LC_ERR_CALLBACK: + errmsg = "Error return from application handler."; + break; + case LC_ERR_ENOMEM: + errmsg = "Insuffcient memory."; + break; + } + + /* + * This is not part of the switch statement so we will get warnings + * about unhandled enum values. + */ + if (errmsg == NULL) { + errmsg = "Unknown error"; + } + + if (lc_errfile == NULL) { + snprintf(retval, sizeof(retval), "%s:%i: %s", "", lc_errline, errmsg); + } else { + snprintf(retval, sizeof(retval), "%s:%i: %s", lc_errfile, lc_errline, errmsg); + } + + retval[sizeof(retval) - 1] = '\0'; + + return(retval); } Index: libconfig.h.in ================================================================== --- libconfig.h.in +++ libconfig.h.in @@ -1,11 +1,15 @@ !ifndef _RSK_LIBCONFIG_H !define _RSK_LIBCONFIG_H - !ifdef __cplusplus extern "C" { !endif + +__BLANK_LINE__ + +!define LC_VAR_LIST 0x80 + __BLANK_LINE__ typedef enum { LC_CONF_SECTION, LC_CONF_APACHE, @@ -37,16 +41,16 @@ LC_VAR_SECTION, LC_VAR_SECTIONSTART, LC_VAR_SECTIONEND, LC_VAR_BOOL_BY_EXISTANCE, LC_VAR_SIZE_SIZE_T, - LC_VAR_CIDR, - LC_VAR_IP, - LC_VAR_IP4, - LC_VAR_IP6, - LC_VAR_HOSTNAME4, - LC_VAR_HOSTNAME6, + LC_VAR_CIDR, + LC_VAR_IP, + LC_VAR_IP4, + LC_VAR_IP6, + LC_VAR_HOSTNAME4, + LC_VAR_HOSTNAME6, } lc_var_type_t; __BLANK_LINE__ typedef enum { @@ -89,10 +93,10 @@ __BLANK_LINE__ extern int lc_optind; __BLANK_LINE__ + !ifdef __cplusplus } !endif - !endif Index: libconfig_private.h ================================================================== --- libconfig_private.h +++ libconfig_private.h @@ -2,10 +2,12 @@ #define _RSK_LIBCONFIG_PRIVATE_H #include "libconfig.h" extern lc_err_t lc_errno; +extern int lc_errline; +extern const char *lc_errfile; int lc_process_var(const char *var, const char *varargs, const char *value, lc_flags_t flags); struct lc_varhandler_st; Index: test-lc.c ================================================================== --- test-lc.c +++ test-lc.c @@ -34,11 +34,11 @@ size_t xval = -1; int onoff = -1; int lcpret = -1; int i = 0; int onoff2 = 0; - uint32_t ipaddr; + uint32_t ipaddr = 0; lc_register_var("Section", LC_VAR_SECTION, NULL, 0); lc_register_var("Somesection", LC_VAR_SECTION, NULL, 0); lc_register_var("Section.Test", LC_VAR_STRING, &joeval, 'j'); lc_register_var("bob", LC_VAR_SIZE_SIZE_T, &xval, 's'); @@ -46,17 +46,23 @@ lc_register_var("long", LC_VAR_BOOL_BY_EXISTANCE, &onoff2, 'l'); lc_register_var("ipaddr", LC_VAR_IP, &ipaddr, 'i'); lc_register_callback("sally", 0, LC_VAR_STRING, sally_cmd, NULL); lc_register_callback("HELP", 'h', LC_VAR_NONE, help_cmd, NULL); lc_register_callback("*.ifmodule", 0, LC_VAR_NONE, cmd_ifmodule, NULL); - lcpret = lc_process_file("testapp", "http://10.8.0.2/test.conf", LC_CONF_APACHE); + lcpret = lc_process_file("testapp", "build/test.conf", LC_CONF_APACHE); + if (lcpret < 0) { + fprintf(stderr, "Error processing config file: %s\n", lc_geterrstr()); + return(EXIT_FAILURE); + } + lcpret = lc_process(argc, argv, "testapp", LC_CONF_APACHE, "test.cfg"); - lc_cleanup(); if (lcpret < 0) { fprintf(stderr, "Error processing config file: %s\n", lc_geterrstr()); return(EXIT_FAILURE); } + + lc_cleanup(); if (joeval != NULL) { fprintf(stderr, "joeval = \"%s\"\n", joeval); } else { fprintf(stderr, "joeval = \"(null)\"\n");