aboutsummaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/argparse.c225
-rw-r--r--util/fileutil.c35
-rw-r--r--util/iobuf.c71
-rw-r--r--util/memory.c16
4 files changed, 271 insertions, 76 deletions
diff --git a/util/argparse.c b/util/argparse.c
index 2f733eb4b..10cfd5c1d 100644
--- a/util/argparse.c
+++ b/util/argparse.c
@@ -23,6 +23,7 @@
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
+#include <ctype.h>
#include <string.h>
#include "util.h"
@@ -124,20 +125,13 @@
*/
-static void set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s);
+static int set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s);
static void show_help(ARGPARSE_OPTS *opts, unsigned flags);
static void show_version(void);
-
-int
-arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
+static void
+initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno )
{
- int index;
- int argc;
- char **argv;
- char *s, *s2;
- int i;
-
if( !(arg->flags & (1<<15)) ) { /* initialize this instance */
arg->internal.index = 0;
arg->internal.last = NULL;
@@ -148,20 +142,199 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
if( *arg->argc < 0 )
log_bug("Invalid argument for ArgParse\n");
}
- argc = *arg->argc;
- argv = *arg->argv;
- index = arg->internal.index;
if( arg->err ) { /* last option was erroneous */
- if( arg->r_opt == -3 )
- s = "Missing argument for option \"%.50s\"\n";
- else
- s = "Invalid option \"%.50s\"\n";
- log_error(s, arg->internal.last? arg->internal.last:"[??]" );
+ const char *s;
+
+ if( filename ) {
+ if( arg->r_opt == -6 )
+ s = "%s:%u: argument not expected\n";
+ else if( arg->r_opt == -5 )
+ s = "%s:%u: read error\n";
+ else if( arg->r_opt == -4 )
+ s = "%s:%u: keyword too long\n";
+ else if( arg->r_opt == -3 )
+ s = "%s:%u: missing argument\n";
+ else
+ s = "%s:%u: invalid option\n";
+ log_error(s, filename, *lineno );
+ }
+ else {
+ if( arg->r_opt == -3 )
+ s = "Missing argument for option \"%.50s\"\n";
+ else
+ s = "Invalid option \"%.50s\"\n";
+ log_error(s, arg->internal.last? arg->internal.last:"[??]" );
+ }
if( arg->err != 1 )
exit(2);
arg->err = 0;
}
+}
+
+
+
+/****************
+ * Get options from a file.
+ * Lines starting with '#' are comment lines.
+ * Syntax is simply a keyword and the argument.
+ * Valid keywords are all keywords from the long_opt list without
+ * the leading dashes. The special keywords help, warranty and version
+ * are not valid here.
+ * Caller must free returned strings.
+ * If called with FP set to NULL command line args are parse instead.
+ */
+int
+optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
+ ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
+{
+ char *s, *s2;
+ int state, i, c;
+ int index=0;
+ char keyword[100];
+ char *buffer = NULL;
+ size_t buflen = 0;
+
+ if( !fp ) /* same as arg_parse() in this case */
+ return arg_parse( arg, opts );
+
+ initialize( arg, filename, lineno );
+
+ /* find the next keyword */
+ state = i = 0;
+ for(;;) {
+ c=getc(fp);
+ if( c == '\n' || c== EOF ) {
+ if( c != EOF )
+ ++*lineno;
+ if( state == -1 )
+ break;
+ else if( state == 2 ) {
+ keyword[i] = 0;
+ for(i=0; opts[i].short_opt; i++ )
+ if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) )
+ break;
+ index = i;
+ arg->r_opt = opts[index].short_opt;
+ if( !opts[index].short_opt )
+ arg->r_opt = -2; /* unknown option */
+ else if( (opts[index].flags & 8) ) /* no optional argument */
+ arg->r_type = 0; /* okay */
+ else /* no required argument */
+ arg->r_opt = -3; /* error */
+ break;
+ }
+ else if( state == 3 ) { /* no argument found */
+ if( !(opts[index].flags & 7) ) /* does not take an argument */
+ arg->r_type = 0; /* okay */
+ else if( (opts[index].flags & 8) ) /* no optional argument */
+ arg->r_type = 0; /* okay */
+ else /* no required argument */
+ arg->r_opt = -3; /* error */
+ break;
+ }
+ else if( state == 4 ) { /* have an argument */
+ if( !(opts[index].flags & 7) ) /* does not take an argument */
+ arg->r_opt = -6; /* error */
+ else {
+ if( !buffer ) {
+ keyword[i] = 0;
+ buffer = m_strdup(keyword);
+ }
+ else
+ buffer[i] = 0;
+
+ if( !set_opt_arg(arg, opts[index].flags, buffer) )
+ m_free(buffer);
+ }
+ break;
+ }
+ else if( c == EOF ) {
+ if( ferror(fp) )
+ arg->r_opt = -5; /* read error */
+ else
+ arg->r_opt = 0; /* eof */
+ break;
+ }
+ state = 0;
+ i = 0;
+ }
+ else if( state == -1 )
+ ; /* skip */
+ else if( !state && isspace(c) )
+ ; /* skip leading white space */
+ else if( !state && c == '#' )
+ state = 1; /* start of a comment */
+ else if( state == 1 )
+ ; /* skip comments */
+ else if( state == 2 && isspace(c) ) {
+ keyword[i] = 0;
+ for(i=0; opts[i].short_opt; i++ )
+ if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) )
+ break;
+ index = i;
+ arg->r_opt = opts[index].short_opt;
+ if( !opts[index].short_opt ) {
+ arg->r_opt = -2; /* unknown option */
+ state = -1; /* skip rest of line and leave */
+ }
+ else
+ state = 3;
+ }
+ else if( state == 3 ) { /* skip leading spaces of the argument */
+ if( !isspace(c) ) {
+ i = 0;
+ keyword[i] = c;
+ state = 4;
+ }
+ }
+ else if( state == 4 ) { /* collect the argument */
+ if( buffer ) {
+ if( i < buflen-1 )
+ buffer[i++] = c;
+ else {
+ buflen += 50;
+ buffer = m_realloc(buffer, buflen);
+ buffer[i++] = c;
+ }
+ }
+ else if( i < DIM(keyword)-1 )
+ keyword[i++] = c;
+ else {
+ buflen = DIM(keyword)+50;
+ buffer = m_alloc(buflen);
+ memcpy(buffer, keyword, i);
+ buffer[i++] = c;
+ }
+ }
+ else if( i >= DIM(keyword)-1 ) {
+ arg->r_opt = -4; /* keyword to long */
+ state = -1; /* skip rest of line and leave */
+ }
+ else {
+ keyword[i++] = c;
+ state = 2;
+ }
+ }
+
+ return arg->r_opt;
+}
+
+
+
+int
+arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
+{
+ int index;
+ int argc;
+ char **argv;
+ char *s, *s2;
+ int i;
+
+ initialize( arg, NULL, NULL );
+ argc = *arg->argc;
+ argv = *arg->argv;
+ index = arg->internal.index;
if( !index && argc && !(arg->flags & (1<<4)) ) { /* skip the first entry */
argc--; argv++; index++;
@@ -322,7 +495,7 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
-static void
+static int
set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s)
{
int base = (flags & 16)? 0 : 10;
@@ -330,17 +503,17 @@ set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s)
switch( arg->r_type = (flags & 7) ) {
case 1: /* takes int argument */
arg->r.ret_int = (int)strtol(s,NULL,base);
- break;
- default:
- case 2: /* takes string argument */
- arg->r.ret_str = s;
- break;
+ return 0;
case 3: /* takes long argument */
arg->r.ret_long= strtol(s,NULL,base);
- break;
+ return 0;
case 4: /* takes ulong argument */
arg->r.ret_ulong= strtoul(s,NULL,base);
- break;
+ return 0;
+ case 2: /* takes string argument */
+ default:
+ arg->r.ret_str = s;
+ return 1;
}
}
diff --git a/util/fileutil.c b/util/fileutil.c
index e2ea9b20e..28bd866c5 100644
--- a/util/fileutil.c
+++ b/util/fileutil.c
@@ -21,6 +21,7 @@
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
@@ -29,3 +30,37 @@
#include "ttyio.h"
+/****************
+ * Construct a filename form the NULL terminated list of parts.
+ * Tilde expansion is done here.
+ */
+char *
+make_filename( const char *first_part, ... )
+{
+ va_list arg_ptr ;
+ size_t n;
+ const char *s;
+ char *name, *home, *p;
+
+ va_start( arg_ptr, first_part ) ;
+ n = strlen(first_part)+1;
+ while( (s=va_arg(arg_ptr, const char *)) )
+ n += strlen(s) + 1;
+ va_end(arg_ptr);
+
+ home = NULL;
+ if( *first_part == '~' && first_part[1] == '/'
+ && (home = getenv("HOME")) && *home )
+ n += strlen(home);
+
+ name = m_alloc(n);
+ p = home ? stpcpy(stpcpy(name,home), first_part+1)
+ : stpcpy(name, first_part);
+ va_start( arg_ptr, first_part ) ;
+ while( (s=va_arg(arg_ptr, const char *)) )
+ p = stpcpy(stpcpy(p,"/"), s);
+ va_end(arg_ptr);
+
+ return name;
+}
+
diff --git a/util/iobuf.c b/util/iobuf.c
index 61e1c5909..da8fea479 100644
--- a/util/iobuf.c
+++ b/util/iobuf.c
@@ -271,7 +271,6 @@ iobuf_close( IOBUF a )
if( a->filter && (rc = a->filter(a->filter_ov, IOBUFCTRL_FREE,
a->chain, NULL, &dummy_len)) )
log_error("IOBUFCTRL_FREE failed on close: %s\n", g10_errstr(rc) );
- m_free(a->recorder.buf);
m_free(a->d.buf);
m_free(a);
}
@@ -406,9 +405,8 @@ iobuf_push_filter( IOBUF a,
a->d.start = 0;
}
/* disable nlimit for the new stream */
+ a->ntotal = b->ntotal + b->nbytes;
a->nlimit = a->nbytes = 0;
- /* disable recorder for the original stream */
- b->recorder.buf = NULL;
/* make a link from the new stream to the original stream */
a->chain = b;
a->opaque = b->opaque;
@@ -601,14 +599,6 @@ iobuf_readbyte(IOBUF a)
return -1; /* EOF */
a->nbytes++;
-
- if( a->recorder.buf ) {
- if( a->recorder.len >= a->recorder.size ) {
- a->recorder.size += 500;
- a->recorder.buf = m_realloc( a->recorder.buf, a->recorder.size );
- }
- ((byte*)a->recorder.buf)[a->recorder.len++] = c;
- }
return c;
}
@@ -678,47 +668,12 @@ void
iobuf_set_limit( IOBUF a, unsigned long nlimit )
{
a->nlimit = nlimit;
+ a->ntotal += a->nbytes;
a->nbytes = 0;
}
-void
-iobuf_start_recorder( IOBUF a )
-{
- m_free(a->recorder.buf);
- a->recorder.size = 500;
- a->recorder.buf = m_alloc(a->recorder.size);
- a->recorder.len = 0;
-}
-
-void
-iobuf_push_recorder( IOBUF a, int c )
-{
- if( a->recorder.buf ) {
- if( a->recorder.len >= a->recorder.size ) {
- a->recorder.size += 500;
- a->recorder.buf = m_realloc( a->recorder.buf, a->recorder.size );
- }
- ((byte*)a->recorder.buf)[a->recorder.len++] = c;
- }
-}
-
-
-char *
-iobuf_stop_recorder( IOBUF a, size_t *n )
-{
- char *p;
- if( !a->recorder.buf )
- log_bug("iobuf_recorder not started\n");
- p = a->recorder.buf;
- if( n )
- *n = a->recorder.len;
- a->recorder.buf = NULL;
- return p;
-}
-
-
/****************
* Return the length of an open file
*/
@@ -742,6 +697,28 @@ iobuf_get_filelength( IOBUF a )
}
/****************
+ * Tell the file position, where the next read will take place
+ */
+ulong
+iobuf_tell( IOBUF a )
+{
+ return a->ntotal + a->nbytes;
+}
+
+
+int
+iobuf_seek( IOBUF a, ulong newpos )
+{
+
+ return -1;
+}
+
+
+
+
+
+
+/****************
* Retrieve the filename
*/
const char *
diff --git a/util/memory.c b/util/memory.c
index 9ba9a8e82..1a60b4931 100644
--- a/util/memory.c
+++ b/util/memory.c
@@ -54,6 +54,7 @@ const void membug( const char *fmt, ... );
#undef m_realloc
#undef m_free
#undef m_check
+ #undef m_strdup
#define FNAME(a) m_debug_ ##a
#define FNAMEPRT , const char *info
#define FNAMEARG , info
@@ -370,7 +371,7 @@ FNAME(alloc_secure_clear)( size_t n FNAMEPRT)
/****************
- * realloc and clear the new space
+ * realloc and clear the old space
*/
void *
FNAME(realloc)( void *a, size_t n FNAMEPRT )
@@ -461,13 +462,13 @@ m_is_secure( const void *p )
* Make a copy of the memory block at a
*/
void *
-FNAME(copy)( void *a FNAMEPRT )
+FNAME(copy)( const void *a FNAMEPRT )
{
void *b;
size_t n;
if( !a )
- return a;
+ return NULL;
n = m_size(a);
if( m_is_secure(a) )
@@ -479,3 +480,12 @@ FNAME(copy)( void *a FNAMEPRT )
}
+char *
+FNAME(strdup)( const char *a FNAMEPRT )
+{
+ size_t n = strlen(a);
+ char *p = FNAME(alloc)(n+1 FNAMEARG);
+ strcpy(p, a);
+ return p;
+}
+