[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[minion-cvs] Improve usage and error messages



Update of /home/minion/cvsroot/src/minion/lib/mixminion
In directory moria.mit.edu:/tmp/cvs-serv14596/lib/mixminion

Modified Files:
	ClientMain.py Main.py 
Log Message:
Improve usage and error messages

Index: ClientMain.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ClientMain.py,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- ClientMain.py	5 Jan 2003 13:19:53 -0000	1.27
+++ ClientMain.py	6 Jan 2003 03:29:45 -0000	1.28
@@ -113,7 +113,10 @@
         # Start downloading the directory.
         url = MIXMINION_DIRECTORY_URL
         LOG.info("Downloading directory from %s", url)
-        infile = urllib.FancyURLopener().open(url)
+        try:
+            infile = urllib.FancyURLopener().open(url)
+        except IOError, e:
+            raise MixError("Couldn't connect to directory server: %s"%e)
         # Open a temporary output file.
         if url.endswith(".gz"):
             fname = os.path.join(self.dir, "dir_new.gz")
@@ -344,6 +347,8 @@
         lines = []
         nicknames = self.byNickname.keys()
         nicknames.sort()
+        if not nicknames:
+            return [ "No servers known" ]
         longestnamelen = max(map(len, nicknames))
         fmtlen = min(longestnamelen, 20)
         format = "%"+str(fmtlen)+"s:"
@@ -929,25 +934,68 @@
         sys.exit(1)
     return None #suppress pychecker warning
 
+
+_SEND_USAGE = """\
+Usage: %(cmd)s [options] <-t address>|<--to=address>
+Options:
+  -h, --help                 Print this usage message and exit.
+  -v, --verbose              Display extra debugging messages.
+  -D <yes|no>, --download-directory=<yes|no>
+                             Force the client to download/not to download a
+                               fresh directory.
+  -f <file>, --config=<file> Use a configuration file other than ~.mixminionrc
+                               (You can also use MIXMINIONRC=FILE)
+  -H <n>, --hops=<n>         Force the path to use <n> hops.
+  -i <file>, --input=<file>  Read the message to send from <file>.
+                               (Defaults to standard input.)
+  -P <path>, --path=<path>   Specify an explicit message path.
+  -t address, --to=address   Specify the recipient's address.
+  --swap-at=<n>              Spcecify an explicit swap point.
+
+EXAMPLES:
+  Send a message contained in a file <data> to user@domain.
+      %(cmd)s -t user@domain -i data
+  As above, but force 6 hops.
+      %(cmd)s -t user@domain -i data -H 6
+  As above, but use the server nicknamed Foo for the first hop and the server
+  whose descriptor is stored in bar/baz for the last hop.
+      %(cmd)s -t user@domain -i data -H 6 -P 'Foo,*,bar/baz'
+  As above, but switch legs of the path after the second hop.
+      %(cmd)s -t user@domain -i data -H 6 -P 'Foo,*,bar/baz' --swap-at=2
+  Specify an explicit path
+      %(cmd)s -t user@domain -i data -P 'Foo,Bar,Baz,Quux,Fee,Fie,Foe'
+  Specify an explicit path with a swap point
+      %(cmd)s -t user@domain -i data -P 'Foo,Bar,Baz,Quux:Fee,Fie,Foe'
+  Force a fresh directory download
+      %(cmd)s -D yes
+  Send a message without dowloading a new directory, even if the current
+  directory is out of date.
+      %(cmd)s -D no -t user@domain -i data
+""".strip()
+
 def usageAndExit(cmd, error=None):
-    #XXXX002 correct this.
     if error:
         print >>sys.stderr, "ERROR: %s"%error
-    print >>sys.stderr, """\
-Usage: %s [-h] [-v] [-f configfile] [-i inputfile]
-          [--path1=server1,server2,...]
-          [--path2=server1,server2,...] [-t <address>]"""%cmd
-    sys.exit(1)
+    print >>sys.stderr, _SEND_USAGE % { 'cmd' : cmd }
+    if error:
+        sys.exit(1)
+    else:
+        sys.exit(0)
 
 # NOTE: This isn't anything LIKE the final client interface.  Many or all
 #       options will change between now and 1.0.0
 def runClient(cmd, args):
-    # DOCDOC
+    if cmd.endswith(" client"):
+        print >>sys.stderr, \
+              "The 'client' command is deprecated.  Use 'send' instead."
+    
     options, args = getopt.getopt(args, "hvf:i:t:H:P:D:",
                                   ["help", "verbose", "config=", "input=",
                                    "to=", "hops=", "swap-at=", "path",
                                    "download-directory=",
                                   ])
+    if not options:
+        usageAndExit(cmd)
     configFile = '~/.mixminionrc'
     inFile = "-"
     verbose = 0
@@ -991,9 +1039,7 @@
                 usageAndExit(cmd, "Unrecognized value for %s"%opt)
 
     if args:
-        usageAndExit(cmd,"Unexpected options")
-    if address is None:
-        usageAndExit(cmd,"No recipient specified")
+        usageAndExit(cmd,"Unexpected arguments")
 
     config = readConfigFile(configFile)
     LOG.configure(config)
@@ -1011,6 +1057,10 @@
     if download != 0:
         keystore.updateDirectory(forceDownload=download)
 
+    if address is None:
+        print >>sys.stderr, "No recipients specified; exiting."
+        sys.exit(0)
+
     try:
         path1, path2 = parsePath(keystore, config, path, address, nHops, nSwap)
         LOG.info("Chose path: [%s][%s]",
@@ -1033,12 +1083,19 @@
 
     print >>sys.stderr, "Message sent"
 
+_IMPORT_SERVER_USAGE = """\
+Usage: %s [options] <filename> ...
+Options:
+   -h, --help:             Print this usage message and exit.
+   -f FILE, --config=FILE  Use a configuration file other than ~/.mixminionrc
+""".strip()
+
 def importServer(cmd, args):
     options, args = getopt.getopt(args, "hf:", ['help', 'config='])
     configFile = None
     for o,v in options:
         if o in ('-h', '--help'):
-            print "Usage %s [--help] [--config=configFile] <filename> ..."
+            print _IMPORT_SERVER_USAGE % cmd
             sys.exit(1)
         elif o in ('-f', '--config'):
             configFile = v
@@ -1056,12 +1113,20 @@
 
     print "Done."
 
+_LIST_SERVERS_USAGE = """\
+Usage: %s [options]
+Options:
+  -h, --help:                Print this usage message and exit.
+  -f <file>, --config=<file> Use a configuration file other than ~/.mixminionrc
+                             (You can also use MIXMINIONRC=FILE)
+""".strip()
+
 def listServers(cmd, args):
     options, args = getopt.getopt(args, "hf:", ['help', 'config='])
     configFile = None
     for o,v in options:
         if o in ('-h', '--help'):
-            print "Usage %s [--help] [--config=configFile]"
+            print _LIST_SERVERS_USAGE % cmd
             sys.exit(1)
         elif o in ('-f', '--config'):
             configFile = v

Index: Main.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Main.py,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- Main.py	5 Jan 2003 13:19:53 -0000	1.20
+++ Main.py	6 Jan 2003 03:29:46 -0000	1.21
@@ -88,7 +88,7 @@
             foundEntry = 1; break
 
     if not foundEntry:
-        sys.stderr.write("Adding %s to PYTHONPATH\n" % parentdir)
+        #sys.stderr.write("Adding %s to PYTHONPATH\n" % parentdir)
         sys.path[0:0] = [ parentdir ]
 
     # Finally, we make sure it all works.
@@ -101,9 +101,9 @@
         sys.stderr.write("Unable to find correct path for mixminion.\n")
         sys.exit(1)
 
-# Global map from command name to 2-tuples of (module_name, function_name).
-# The function 'main' below uses this map to pick which module to import,
-# and which function to invoke.
+#   Global map from command name to 2-tuples of (module_name, function_name).
+#   The function 'main' below uses this map to pick which module to import,
+#   and which function to invoke.
 #
 #  'Main.py <cmd> arg1 arg2 arg3' will result in a call to <function_name>
 #   in <module_name>.  The function should take two arguments: a string to
@@ -112,9 +112,10 @@
 #   By convention, all commands must print a usage message and exit when
 #   invoked with a single argument, "--help"
 _COMMANDS = {
-    "version" :        ( 'mixminion.Main',       'printVersion'),
+    "version" :        ( 'mixminion.Main',       'printVersion' ),
     "unittests" :      ( 'mixminion.test',       'testAll' ),
     "benchmarks" :     ( 'mixminion.benchmark',  'timeAll' ),
+    "send" :           ( 'mixminion.ClientMain', 'runClient' ),
     "client" :         ( 'mixminion.ClientMain', 'runClient' ),
     "import-server" :  ( 'mixminion.ClientMain', 'importServer' ),
     "list-servers" :   ( 'mixminion.ClientMain', 'listServers' ),
@@ -124,13 +125,29 @@
     "dir":             ( 'mixminion.directory.DirMain', 'main'),
 }
 
+_USAGE = (
+  "Usage: %s <command> [arguments]\n"+
+  "where <command> is one of:\n"+
+  "                              (For Everyone)\n"+
+  "       version        [Print the version of Mixminion and exit]\n"+
+  "       send           [Send an anonymous message]\n"+
+  "       import-server  [Tell the client about a new server]\n"+
+  "       list-servers   [Print a list of currently known servers]\n"+
+  "                               (For Servers)\n"+
+  "       server         [Begin running a Mixminon server]\n"+
+  "       server-keygen  [Generate keys for a Mixminion server]\n"+
+  "       setver-DELKEYS [Remove generated keys for a Mixminion server]\n"+
+  "                             (For Developers)\n"+
+  "       dir            [Administration for server directories]\n"+
+  "       unittests      [Run the mixminion unit tests]\n"+
+  "       benchmarks     [Time underlying cryptographic operations]\n"
+)
+
 def printVersion(cmd,args):
     import mixminion
     print "Mixminion version %s" % mixminion.__version__
     print ("Copyright 2002-2003 Nick Mathewson.  "+
            "See LICENSE for licensing information.")
-    print "Run '%s help' for more information." % cmd
-    sys.exit(0)
 
 def main(args):
     "Use <args> to fix path, pick a command and pass it arguments."
@@ -142,13 +159,8 @@
 
     # Check whether we have a recognized command.
     if len(args) == 1 or not _COMMANDS.has_key(args[1]):
-        # FFFF we could do better in generating a usage message here.
-        cmds = _COMMANDS.keys()
-        cmds.sort()
-        sys.stderr.write("Usage: %s <command> [arguments]\n" %args[0])
-        sys.stderr.write("Where <command> is one of:\n")
-        for c in cmds:
-            sys.stderr.write("     %s\n"%c)
+        printVersion(args[0],args[1:])
+        print _USAGE % args[0]
         sys.exit(1)
 
     # Read the module and function.