From: Ralph Ronnquist Date: Sun, 17 Jul 2022 01:32:50 +0000 (+1000) Subject: revise argument processing X-Git-Tag: 0.4~5 X-Git-Url: https://git.rrq.au/?a=commitdiff_plain;h=b33bccec9aef7758588edfb92a46bdd835c730f7;p=rrq%2Ffusefile.git revise argument processing --- diff --git a/fusefile.c b/fusefile.c index b9d3b2d..5a51066 100644 --- a/fusefile.c +++ b/fusefile.c @@ -61,49 +61,10 @@ static void print_source(struct Source *p) { } #endif -// Scan the source specification, and return the length of the -// inclusion. "filename/from,to" -// filename -// filename/from -// filename/-to -// filename/from-to -static size_t scan_source(char *in,struct Source *p) { - int e = strlen( in ); - int i = e-1; - int s = -1; - int m = -1; - // scan for last '/' and last '-' - for ( ; i >= 0; i-- ) { - if ( in[i] == '/' ) { - s = i; - break; - } - if ( in[i] == '-' ) { - m = i; - } - } -#if DEBUG - fprintf( stderr, "m=%d s=%d\n", m, s ); -#endif - // Copy the filename, and set from and to - p->filename = strndup( in, ( s < 0 )? e : s ); - struct stat buf; - if ( stat( p->filename, & buf ) ) { - perror( p->filename ); - return 1; - } - p->from = ( s < 0 )? 0 : atol( in+s+1 ); - if ( p->from < 0 ) { - p->from = 0; - } -#if DEBUG - fprintf( stderr, "p->from=%ld\n", p->from ); -#endif - p->to = ( m < 0 )? buf.st_size : atol( in+m+1 ); - if ( p->from > p->to || p->to > buf.st_size ) { - return 1; - } - return 0; +static char *range; +static unsigned int c; +static int RANGE(int SCAN,int N ) { + return ( SCAN == N ) && *(range+c) == 0; } static int setup_sources(char **argv,int i,int n) { @@ -115,22 +76,56 @@ static int setup_sources(char **argv,int i,int n) { int j = 0; sources.size = 0; for ( ; j < n; i++, j++ ) { + struct stat filestat; struct Source *p = sources.array + j; - if ( scan_source( argv[i], p ) ) { - // should free everything malloc-ed - return 1; - } - p->start = sources.size; - sources.size += p->to - p->from; + // Open the fragment file rw if possible, else ro + range = strrchr( argv[i], '/' ); // last '/' + p->filename = range? strndup( argv[i], range - argv[i] ) : argv[i]; p->fd = open( p->filename, O_RDWR ); + int rdonly = 0; if ( p->fd < 0 ) { - fprintf( stderr, "** %s opened read-only\n", p->filename ); + rdonly = 1; p->fd = open( p->filename, O_RDONLY ); } if ( p->fd < 0 ) { perror( p->filename ); - return 1; + return 1; // Error return + } + if ( stat( p->filename, &filestat ) ) { + perror( p->filename ); + return 1; } + if ( rdonly ) { + fprintf( stderr, "** %s opened read-only\n", p->filename ); + } + p->from = 0; + p->to = filestat.st_size; + // Process any range variation + if ( range && *(++range) ) { + unsigned int a,b; + if ( RANGE( sscanf( range, "%u-%u%n", &a, &b, &c ), 2 ) ) { + p->from = a; + p->to = b; + } else if ( RANGE( sscanf( range, "%u--%u%n", &a, &b, &c ), 2 ) ) { + p->from = a; + p->to -= b; + } else if ( RANGE( sscanf( range, "%u-%n", &a, &c ), 1 ) ) { + p->from = a; + } else if ( RANGE( sscanf( range, "%u%n", &a, &c ), 1 ) ) { + p->from = a; + } else if ( RANGE( sscanf( range, "-%u%n", &b, &c ), 1 ) ) { + p->to = b; + } else if ( RANGE( sscanf( range, "--%u%n", &b, &c ), 1 ) ) { + p->to -= b; + } else if ( RANGE( sscanf( range, "-%n", &c), 0 ) ) { + // Acceptable as "start-end" range + } else { + fprintf( stderr, "** BAD RANGE: %s\n", argv[i] ); + return 1; + } + } + p->start = sources.size; // the fusefile position of fragment + sources.size += p->to - p->from; #if DEBUG print_source( p ); #endif