*
*/
#include <stdio.h>
-#include <stdlib.h>
+#include <stdlib.h> /* exit() */
#include <string.h>
#include "getopts.h"
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;
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" );
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; ++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;
+}
.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
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
.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