cleanup the new getopt code a bit. sync remote's manpage.
This commit is contained in:
parent
415214f15b
commit
639896958f
199
daemon/getopts.c
199
daemon/getopts.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue