From 639896958f530648fc3d9a58eb0710cc8176dad6 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 8 Jul 2008 03:19:01 +0000 Subject: [PATCH] cleanup the new getopt code a bit. sync remote's manpage. --- daemon/getopts.c | 199 ++++++++++++++++++----------------- daemon/getopts.h | 11 +- daemon/remote.c | 7 +- daemon/transmission-remote.1 | 153 +++++++++++++-------------- 4 files changed, 190 insertions(+), 180 deletions(-) diff --git a/daemon/getopts.c b/daemon/getopts.c index 19e825a1a..6b16c3dbd 100644 --- a/daemon/getopts.c +++ b/daemon/getopts.c @@ -37,7 +37,7 @@ * */ #include -#include +#include /* exit() */ #include #include "getopts.h" @@ -65,11 +65,10 @@ getopts_usage_line( const struct options * opt, int nameWidth, int shortWidth, i printf( " -%*s, --%-*s %-*s %s\n", shortWidth, shortName, nameWidth, name, argWidth, arg, opt->description ); } -/* int getopts_usage() - * - * Returns: 1 - Successful - */ -int getopts_usage(const char *progName, const char *usage, struct options opts[]) +void +getopts_usage( const char * progName, + const char * description, + const struct options opts[] ) { int count; int nameWidth = 0; @@ -91,9 +90,9 @@ int getopts_usage(const char *progName, const char *usage, struct options opts[] argWidth = MAX( argWidth, (int)strlen( arg ) ); } - if( !usage ) - usage = "Usage: %s [options]"; - printf( usage, progName ); + if( !description ) + description = "Usage: %s [options]"; + printf( description, progName ); printf( "\n\n" ); printf( "Usage:\n" ); @@ -106,103 +105,115 @@ int getopts_usage(const char *progName, const char *usage, struct options opts[] for( count=0; opts[count].description; ++count ) getopts_usage_line( &opts[count], nameWidth, shortWidth, argWidth ); - - return 1; } -/* int getopts() - * - * Returns: -1 - Couldn't allocate memory. Please handle me. - * 0 - No arguements to parse - * # - The number in the struct for the matched arg. - * -*/ -int -getopts( const char * usage, - int argc, - char ** argv, - struct options * opts, - char ** args ) +static const struct options * +findOption( const struct options * opts, + const char * str, + const char ** nested ) { - int argCounter, sizeOfArgs; - if (argc == 1 || option_index == argc) - return 0; - -/* Search for '-h' or '--help' first. Then we can just exit */ - for (argCounter = 1; argCounter < argc; argCounter++) - { - if (!strcmp(argv[argCounter], "-h") || !strcmp(argv[argCounter], "--help")) - { -useage: -fprintf( stderr, "dkdkdkdkdkd\n" ); - getopts_usage(argv[0], usage, opts); - exit(0); - } - } -/* End of -h --help section */ - - *args = NULL; - if (option_index <= argc) + size_t len; + const struct options * o; + + for( o=opts; o->number; ++o ) { - for (argCounter = 0; opts[argCounter].number!=0; argCounter++) - { - if ((opts[argCounter].name && !strcmp(opts[argCounter].name, (argv[option_index]+2))) || - (opts[argCounter].shortName && !strcmp(opts[argCounter].shortName, (argv[option_index]+1)))) - { - if (opts[argCounter].args) - { - option_index++; - if (option_index >= argc) - goto useage; -/* This grossness that follows is to support having a '-' in the argument. */ - if (*argv[option_index] == '-') - { - int optionSeeker; - for (optionSeeker = 0; opts[optionSeeker].description; optionSeeker++) - { - if ((opts[optionSeeker].name && - !strcmp(opts[optionSeeker].name, (argv[option_index]+2))) || - (opts[optionSeeker].shortName && - !strcmp(opts[optionSeeker].shortName, (argv[option_index]+1)))) - { - goto useage; - } - } -/* End of gross hack for supporting '-' in arguments. */ - } - sizeOfArgs = strlen(argv[option_index]); -#ifdef __cplusplus - if ((*args = (char *)calloc(1, sizeOfArgs+1)) == NULL) -#else - if ((*args = calloc(1, sizeOfArgs+1)) == NULL) -#endif - return -1; - strncpy(*args, argv[option_index], sizeOfArgs); - } - option_index++; - return opts[argCounter].number; + if( o->name && (str[0]=='-') && (str[1]=='-') ) { + if( !strcmp( o->name, str+2 ) ) { + if( nested ) *nested = NULL; + return o; + } + len = strlen( o->name ); + if( !memcmp( o->name, str+2, len ) && str[len+2]=='=' ) { + if( nested ) *nested = str+len+3; + return o; } } -/** The Option doesn't exist. We should warn them. */ - //if (*argv[option_index] == '-') - { - sizeOfArgs = strlen(argv[option_index]); -#ifdef __cplusplus - if ((*args = (char *)calloc(1, sizeOfArgs+1)) == NULL) -#else - if ((*args = calloc(1, sizeOfArgs+1)) == NULL) -#endif - return -1; - strncpy(*args, argv[option_index], sizeOfArgs); - option_index++; - return -2; + + if( o->shortName && (str[0]=='-') ) { + if( !strcmp( o->shortName, str+1 ) ) { + if( nested ) *nested = NULL; + return o; + } + len = strlen( o->shortName ); + if( !memcmp( o->shortName, str+1, len ) && str[len+1]=='=' ) { + if( nested ) *nested = str+len+2; + return o; + } } } - return 0; + + return NULL; } +static void +showUsageAndExit( const char * appName, + const char * description, + const struct options * opts ) +{ + getopts_usage( appName, description, opts ); + exit( 0 ); +} + + +/* + * Returns: 0 - No arguments to parse + * # - The number in the struct for the matched arg. + * -2 - Unrecognized option + */ +int +getopts( const char * usage, + int argc, + const char ** argv, + const struct options * opts, + const char ** setme_optarg ) +{ + int i; + const char * nest = NULL; + const struct options * o = NULL; + + *setme_optarg = NULL; + if( argc==1 || argc==option_index ) + return 0; + + /* handle the builtin 'help' option */ + for( i=1; i= argc ) + return 0; + + o = findOption( opts, argv[option_index], &nest ); + if( !o ) { + /* let the user know we got an unknown option... */ + *setme_optarg = argv[option_index++]; + return -2; + } + if( !o->args ) { + /* no argument needed for this option, so we're done */ + if( nest ) + showUsageAndExit( argv[0], usage, opts ); + *setme_optarg = NULL; + option_index++; + return o->number; + } + /* option needed an argument, and it was nested in this string */ + if( nest ) { + *setme_optarg = nest; + option_index++; + return o->number; + } + /* throw an error if the option needed an argument but didn't get one */ + if( ++option_index >= argc ) + showUsageAndExit( argv[0], usage, opts ); + if( findOption( opts, argv[option_index], NULL )) + showUsageAndExit( argv[0], usage, opts ); + *setme_optarg = argv[option_index++]; + return o->number; +} diff --git a/daemon/getopts.h b/daemon/getopts.h index 43a25b472..0b921ad61 100644 --- a/daemon/getopts.h +++ b/daemon/getopts.h @@ -49,8 +49,15 @@ struct options char *argName; /* Argument name, for the `help' option */ }; -int getopts(const char * summary, int argc, char **argv, struct options opts[], char **args); -int getopts_usage(const char *progName, const char * summary, struct options opts[]); +int getopts( const char * summary, + int argc, + const char ** argv, + const struct options * opts, + const char ** setme_optarg ); + +void getopts_usage( const char * appName, + const char * description, + const struct options * opts ); #ifdef __cplusplus } diff --git a/daemon/remote.c b/daemon/remote.c index 1588ca296..826735217 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -76,7 +76,6 @@ static struct options opts[] = static void showUsage( void ) { -fprintf( stderr, "asdfasdfasdfasdfasdfasdf\n"); getopts_usage( MY_NAME, getUsage(), opts ); exit( 0 ); } @@ -133,11 +132,11 @@ addIdArg( tr_benc * args, const char * id ) } static void -readargs( int argc, char ** argv ) +readargs( int argc, const char ** argv ) { int c; int addingTorrents = 0; - char * optarg; + const char * optarg; char id[4096]; *id = '\0'; @@ -705,7 +704,7 @@ main( int argc, char ** argv ) if( host == NULL ) host = tr_strdup( DEFAULT_HOST ); - readargs( argc, argv ); + readargs( argc, (const char**)argv ); if( reqCount ) processRequests( host, port, (const char**)reqs, reqCount ); else diff --git a/daemon/transmission-remote.1 b/daemon/transmission-remote.1 index e2ce54cc4..b573eb33f 100644 --- a/daemon/transmission-remote.1 +++ b/daemon/transmission-remote.1 @@ -9,40 +9,29 @@ and .Xr transmission 1 .Sh SYNOPSIS .Bk -words -.Nm transmission-remote -.Fl h .Nm .Op Ar host:port | host | port -.Op Fl a Ar torrent-file -.Op Fl d Ar download-rate +.Op Fl a Ar torrent-files +.Op Fl d Ar number .Op Fl D -.Op Fl e Ar encryption-mode -.Oo -.Fl f Ar id | Ar hash -.Oc -.Oo -.Fl i Ar id | Ar hash -.Oc +.Op Fl e Ar mode +.Op Fl f +.Op Fl g +.Op Fl h +.Op Fl i .Op Fl l .Op Fl m .Op Fl M +.Op Fl n Ar user:pass .Op Fl p Ar port -.Op Fl t Ar user:pass -.Oo -.Fl r Ar all | Ar id | Ar hash -.Oc -.Oo -.Fl s Ar all | Ar id | Ar hash -.Oc -.Oo -.Fl S Ar all | Ar id | Ar hash -.Oc -.Op Fl u Ar upload-rate +.Op Fl r +.Op Fl s +.Op Fl S +.Op Fl t Ar all | Ar id | Ar hash +.Op Fl u Ar number .Op Fl U -.Oo -.Fl v Ar all | Ar id | Ar hash -.Oc -.Op Fl w Ar directory +.Op Fl v +.Op Fl w Ar download-dir .Op Fl x .Op Fl X .Ek @@ -61,82 +50,79 @@ Other sessions can be controlled by specifying a different host and/or port. The options are as follows: .Bl -tag -width Ds .It Fl a Fl -add Ar torrent-file -Add the torrent metainfo file -.Ar torrent-file . -.It Fl d Fl -download-limit Ar download-rate -Set maximum download rate to -.Ar download-rate -in kilobytes per second. -.It Fl D Fl -download-unlimited +Add metainfo +.Ar torrent-file(s) . + +.It Fl d Fl -downlimit Ar limit +Limit the download speed to +.Ar limit +kilobytes per second. + +.It Fl D Fl -no-downlimit Remove the download limit. + .It Fl e Fl -encryption Ar required Require all peer connections to be encrypted. .It Fl e Fl -encryption Ar preferred Prefer encrypted peer connections. .It Fl e Fl -encryption Ar tolerated Prefer unencrypted peer connections. -.It Fl f Fl -files Ar id | torrent-hash -Get file information for the torrent matching the specified -.Ar id -or -.Ar hash . + +.It Fl f Fl -files +Get a file list for the current torrent(s) + .It Fl h Fl -help Print command-line option descriptions. -.It Fl i Fl -info Ar id | torrent-hash -Print detailed information for the torrent matching the specified -.Ar id -or -.Ar hash . -.It Fl l Fl -list -List all torrents, their Id numbers, and current status. -.It Fl m Fl -port-mapping -Enable automatic port mapping via NAT-PMP or UPnP IGD. -.It Fl M Fl -no-port-mapping -Disable automatic port mapping. -.It Fl p Fl -port Ar port -Attempt to bind to -.Ar port -for use as a listening port to accept incoming peer connections. -.It Fl r Fl -remove Ar all | id | torrent-hash -Remove all torrents, or the torrent matching the specified -.Ar id -or -.Ar hash . -This does not delete the downloaded data. +.It Fl i Fl -info Ar id | torrent-hash +Show details of the current torrent(s) -.It Fl s Fl -start Ar all | id | torrent-hash -Start all torrents downloading or seeding, or the torrent matching the specified -.Ar id -or -.Ar hash . +.It Fl l Fl -list +List all torrents -.It Fl S Fl -stop Ar all | id | torrent-hash -Stop all torrents from downloading or seeding, or the torrent matching the specified -.Ar id -or -.Ar hash . +.It Fl m Fl -portmap +Enable portmapping via NAT-PMP or UPnP +.It Fl M Fl -no-portmap +Disable portmapping -.It Fl t Fl -auth Ar user:pass +.It Fl n Fl -auth Ar user:pass .Ar Username and .Ar password for authentication -.It Fl u Fl -upload-limit Ar upload-rate -Set maximum upload rate to -.Ar upload-rate -in kilobytes per second. +.It Fl p Fl -port Ar port +Set the +.Ar port +for use when listening for incoming peer connections + +.It Fl r Fl -remove +Remove the current torrent(s). This does not delete the downloaded data. -.It Fl U Fl -upload-unlimited -Remove the upload limit. +.It Fl s Fl -start +Start the current torrent(s) -.It Fl v Fl -verify Ar all | id | torrent-hash -Queue all the torrents for verification, or the torrent matching the specified +.It Fl S Fl -stop +Stop the current torrent(s) from downloading or seeding + +.It Fl t Fl -torrent Ar all | id | torrent-hash +Set the current torrent(s) for use by subsequent options. +.Ar all +will apply following requests to all torrents, while specific torrents can be chosen by .Ar id or .Ar hash . +.It Fl u Fl -uplimit Ar limit +Limit the upload speed to +.Ar limit +kilobytes per second. +.It Fl U Fl -no-uplimit +Remove the upload limit. + +.It Fl v Fl -verify +Verify the current torrent(s) + .It Fl w Fl -download-dir Ar directory Use .Ar directory @@ -155,15 +141,22 @@ Show all torrents, their ID numbers, and their status: .Pp Pause torrent #12: .Pp -.Dl transmission-remote -S 12 +.Dl transmission-remote -t 12 -S +.Dl transmission-remote --torrent=12 --stop +.Pp +Start all torrents: +.Pp +.Dl transmission-remote -t all -s +.Dl transmission-remote --torrent=all --start .Pp Set download and upload limits to 100 KiB/sec and 20 KiB/sec: .Pp .Dl transmission-remote -d 100 -u 20 +.Dl transmission-remote -d=100 -u=20 .Pp Add two torrents: .Pp -.Dl transmission-remote -a foo.torrent -a bar.torrent +.Dl transmission-remote -a one.torrent two.torrent .Sh AUTHORS .An -nosplit -- 2.40.0