]> granicus.if.org Git - transmission/commitdiff
cleanup the new getopt code a bit. sync remote's manpage.
authorCharles Kerr <charles@transmissionbt.com>
Tue, 8 Jul 2008 03:19:01 +0000 (03:19 +0000)
committerCharles Kerr <charles@transmissionbt.com>
Tue, 8 Jul 2008 03:19:01 +0000 (03:19 +0000)
daemon/getopts.c
daemon/getopts.h
daemon/remote.c
daemon/transmission-remote.1

index 19e825a1ad2568147d0f35a328ced405d2dac307..6b16c3dbd735e62ef6627393fc0cd3eda8ccbd6f 100644 (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++)
-    {
-      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;
+}
index 43a25b47203801d56b41d52ee6226c5841fe134c..0b921ad6186755579cd2160f5799a9079614b584 100644 (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
 }
index 1588ca296cb817a9b10842b8f6ee21ea59104690..8267352170ef18685f655acfcb7aad30d846984c 100644 (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
index e2ce54cc470e0686920c757a4bfebb6d402c4859..b573eb33ff676dd0b3d3aea6736592211ab91d63 100644 (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 .
-.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