more libstrongswan-like error handling in optionsfrom
This commit is contained in:
@@ -21,35 +21,47 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
|
#include <debug.h>
|
||||||
#include <utils/lexparser.h>
|
#include <utils/lexparser.h>
|
||||||
|
|
||||||
#include "optionsfrom.h"
|
#include "optionsfrom.h"
|
||||||
|
|
||||||
#define MAX_USES 100 /* loop-detection limit */
|
#define MAX_USES 20 /* loop-detection limit */
|
||||||
#define SOME_ARGS 10 /* first guess at how many arguments we'll need */
|
#define SOME_ARGS 10 /* first guess at how many arguments we'll need */
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* parse the options from a file
|
* Defined in header.
|
||||||
* does not alter the existing arguments, but does relocate and alter
|
|
||||||
* the argv pointer vector.
|
|
||||||
*/
|
*/
|
||||||
static err_t parse_options_file(const char *filename, int *argcp, char **argvp[], int optind)
|
bool optionsfrom(const char *filename, int *argcp, char **argvp[], int optind)
|
||||||
{
|
{
|
||||||
|
static int nuses = 0;
|
||||||
char **newargv;
|
char **newargv;
|
||||||
int newargc;
|
int newargc;
|
||||||
int next; /* place for next argument */
|
int next; /* place for next argument */
|
||||||
int room; /* how many more new arguments we can hold */
|
int room; /* how many more new arguments we can hold */
|
||||||
size_t bytes;
|
size_t bytes;
|
||||||
chunk_t chunk, src, line, token;
|
chunk_t chunk, src, line, token;
|
||||||
err_t ugh = NULL;
|
bool good = TRUE;
|
||||||
|
int linepos = 0;
|
||||||
FILE *fd = fopen(filename, "r");
|
FILE *fd;
|
||||||
|
|
||||||
|
/* avoid endless loops with recursive --optionsfrom arguments */
|
||||||
|
nuses++;
|
||||||
|
if (nuses >= MAX_USES)
|
||||||
|
{
|
||||||
|
DBG1("optionsfrom called %d times - looping?", (*argvp)[0], nuses);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = fopen(filename, "r");
|
||||||
if (fd == NULL)
|
if (fd == NULL)
|
||||||
{
|
{
|
||||||
return "unable to open file";
|
DBG1("optionsfrom: unable to open file '%s': %s",
|
||||||
|
filename, strerror(errno));
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* determine the file size */
|
/* determine the file size */
|
||||||
@@ -74,8 +86,9 @@ static err_t parse_options_file(const char *filename, int *argcp, char **argvp[]
|
|||||||
/* we keep the chunk pointer so that we can still free it */
|
/* we keep the chunk pointer so that we can still free it */
|
||||||
src = chunk;
|
src = chunk;
|
||||||
|
|
||||||
while (fetchline(&src, &line) && ugh == NULL)
|
while (fetchline(&src, &line) && good)
|
||||||
{
|
{
|
||||||
|
linepos++;
|
||||||
while (eat_whitespace(&line))
|
while (eat_whitespace(&line))
|
||||||
{
|
{
|
||||||
if (*line.ptr == '"'|| *line.ptr == '\'')
|
if (*line.ptr == '"'|| *line.ptr == '\'')
|
||||||
@@ -86,7 +99,9 @@ static err_t parse_options_file(const char *filename, int *argcp, char **argvp[]
|
|||||||
line.len--;
|
line.len--;
|
||||||
if (!extract_token(&token, delimiter, &line))
|
if (!extract_token(&token, delimiter, &line))
|
||||||
{
|
{
|
||||||
ugh = "missing terminating delimiter";
|
DBG1("optionsfrom: missing terminator at %s:%d",
|
||||||
|
filename, linepos);
|
||||||
|
good = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,49 +133,16 @@ static err_t parse_options_file(const char *filename, int *argcp, char **argvp[]
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ugh) /* error of some kind */
|
if (!good) /* error of some kind */
|
||||||
{
|
{
|
||||||
free(chunk.ptr);
|
free(chunk.ptr);
|
||||||
free(newargv);
|
free(newargv);
|
||||||
return ugh;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(newargv + next, *argvp + optind, (*argcp + 1 - optind) * sizeof(char *));
|
memcpy(newargv + next, *argvp + optind, (*argcp + 1 - optind) * sizeof(char *));
|
||||||
*argcp += next - optind;
|
*argcp += next - optind;
|
||||||
*argvp = newargv;
|
*argvp = newargv;
|
||||||
return NULL;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Defined in header.
|
|
||||||
*/
|
|
||||||
err_t optionsfrom(const char *filename, int *argcp, char **argvp[], int optind, FILE *errfile)
|
|
||||||
{
|
|
||||||
static int nuses = 0;
|
|
||||||
err_t ugh = NULL;
|
|
||||||
|
|
||||||
/* avoid endless loops with recursive --optionsfrom arguments */
|
|
||||||
if (errfile != NULL)
|
|
||||||
{
|
|
||||||
nuses++;
|
|
||||||
if (nuses >= MAX_USES)
|
|
||||||
{
|
|
||||||
fprintf(errfile, "%s: optionsfrom called %d times - looping?\n",
|
|
||||||
(*argvp)[0], nuses);
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nuses = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ugh = parse_options_file(filename, argcp, argvp, optind);
|
|
||||||
|
|
||||||
if (ugh != NULL && errfile != NULL)
|
|
||||||
{
|
|
||||||
fprintf(errfile, "%s: optionsfrom failed: %s\n", (*argvp)[0], ugh);
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
return ugh;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -30,9 +30,8 @@
|
|||||||
* @param argcp pointer to argc
|
* @param argcp pointer to argc
|
||||||
* @param argvp pointer to argv[]
|
* @param argvp pointer to argv[]
|
||||||
* @param optind current optind, number of next argument
|
* @param optind current optind, number of next argument
|
||||||
* @param errfile where to report errors (NULL means return)
|
* @return TRUE if optionsfrom parsing successful
|
||||||
* @return NULL if successful, error string otherwise
|
|
||||||
*/
|
*/
|
||||||
err_t optionsfrom(const char *filename, int *argcp, char **argvp[], int optind, FILE *errfile);
|
bool optionsfrom(const char *filename, int *argcp, char **argvp[], int optind);
|
||||||
|
|
||||||
#endif /*OPTIONSFROM_H_*/
|
#endif /*OPTIONSFROM_H_*/
|
||||||
|
|||||||
+4
-2
@@ -291,8 +291,10 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
snprintf(path, BUF_LEN, "%s/%s", OPENAC_PATH, optarg);
|
snprintf(path, BUF_LEN, "%s/%s", OPENAC_PATH, optarg);
|
||||||
}
|
}
|
||||||
optionsfrom(path, &argc, &argv, optind, stderr);
|
if (!optionsfrom(path, &argc, &argv, optind))
|
||||||
/* does not return on error */
|
{
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user