diff options
Diffstat (limited to 'util')
-rw-r--r-- | util/argparse.c | 225 | ||||
-rw-r--r-- | util/fileutil.c | 35 | ||||
-rw-r--r-- | util/iobuf.c | 71 | ||||
-rw-r--r-- | util/memory.c | 16 |
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; +} + |