cleanup the new getopt code a bit. sync remote's manpage.

This commit is contained in:
Charles Kerr 2008-07-08 03:19:01 +00:00
parent 415214f15b
commit 639896958f
4 changed files with 190 additions and 180 deletions

View File

@ -37,7 +37,7 @@
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h> /* exit() */
#include <string.h>
#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++)
size_t len;
const struct options * o;
for( o=opts; o->number; ++o )
{
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)
{
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; ++i )
if( !strcmp(argv[i], "-h") || !strcmp(argv[i], "--help" ) )
showUsageAndExit( argv[0], usage, opts );
/* out of options */
if( option_index >= 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;
}

View File

@ -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
}

View File

@ -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

View File

@ -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 .
Show details of the current torrent(s)
.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.
List all torrents
.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 m Fl -portmap
Enable portmapping via NAT-PMP or UPnP
.It Fl M Fl -no-portmap
Disable portmapping
.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 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 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 U Fl -upload-unlimited
Remove the upload limit.
.It Fl r Fl -remove
Remove the current torrent(s). This does not delete the downloaded data.
.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 -start
Start the current torrent(s)
.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