]> arthur.barton.de Git - bup.git/blobdiff - cmd/ftp-cmd.py
cmd/ftp: don't die if we can't import the ctypes module.
[bup.git] / cmd / ftp-cmd.py
index c6f26af7700eb1eab8be62317416cb09fbcc8913..f103a61f3867e344b6c3330d8cf09366202004f6 100755 (executable)
@@ -3,11 +3,7 @@ import sys, os, re, stat, fnmatch
 from bup import options, git, shquote, vfs
 from bup.helpers import *
 
-try:
-    import readline
-except ImportError:
-    log('* readline module not available: line editing disabled.\n')
-    readline = None
+handle_ctrl_c()
 
 
 def node_name(text, n):
@@ -19,20 +15,42 @@ def node_name(text, n):
         return '%s' % text
 
 
-def do_ls(path, n):
-    l = []
-    if stat.S_ISDIR(n.mode):
-        for sub in n:
-            l.append(node_name(sub.name, sub))
-    else:
-        l.append(node_name(path, n))
-    print columnate(l, '')
-    
+class OptionError(Exception):
+    pass
+
+
+ls_optspec = """
+ls [-a] [path...]
+--
+a,all   include hidden files in the listing
+"""
+ls_opt = options.Options('ls', ls_optspec, onabort=OptionError)
+
+def do_ls(cmd_args):
+    try:
+        (opt, flags, extra) = ls_opt.parse(cmd_args)
+    except OptionError, e:
+        return
+
+    L = []
+
+    for path in (extra or ['.']):
+        n = pwd.try_resolve(path)
+
+        if stat.S_ISDIR(n.mode):
+            for sub in n:
+                name = sub.name
+                if opt.all or not len(name)>1 or not name.startswith('.'):
+                    L.append(node_name(name, sub))
+        else:
+            L.append(node_name(path, n))
+        print columnate(L, '')
+
 
 def write_to_file(inf, outf):
     for blob in chunkyreader(inf):
         outf.write(blob)
-    
+
 
 def inputiter():
     if os.isatty(sys.stdin.fileno()):
@@ -50,9 +68,12 @@ def _completer_get_subs(line):
     (qtype, lastword) = shquote.unfinished_word(line)
     (dir,name) = os.path.split(lastword)
     #log('\ncompleter: %r %r %r\n' % (qtype, lastword, text))
-    n = pwd.resolve(dir)
-    subs = list(filter(lambda x: x.name.startswith(name),
-                       n.subs()))
+    try:
+        n = pwd.resolve(dir)
+        subs = list(filter(lambda x: x.name.startswith(name),
+                           n.subs()))
+    except vfs.NoSuchFile, e:
+        subs = []
     return (dir, name, qtype, lastword, subs)
 
 
@@ -76,7 +97,13 @@ def find_readline_lib():
 def init_readline_vars():
     """Work around trailing space automatically inserted by readline.
     See http://bugs.python.org/issue5833"""
-    import ctypes
+    try:
+        import ctypes
+    except ImportError:
+        # python before 2.5 didn't have the ctypes module; but those
+        # old systems probably also didn't have this readline bug, so
+        # just ignore it.
+        return
     lib_name = find_readline_lib()
     if lib_name is not None:
         lib = ctypes.cdll.LoadLibrary(lib_name)
@@ -102,7 +129,7 @@ def completer(text, state):
         (dir, name, qtype, lastword, subs) = _last_res
         if state < len(subs):
             sn = subs[state]
-            sn1 = sn.resolve('')  # deref symlinks
+            sn1 = sn.try_resolve()  # find the type of any symlink target
             fullname = os.path.join(dir, sn.name)
             if stat.S_ISDIR(sn1.mode):
                 ret = shquote.what_to_add(qtype, lastword, fullname+'/',
@@ -112,11 +139,17 @@ def completer(text, state):
                                           terminate=True) + ' '
             return text + ret
     except Exception, e:
-        log('\nerror in completion: %s\n' % e)
+        log('\n')
+        try:
+            import traceback
+            traceback.print_tb(sys.exc_traceback)
+        except Exception, e2:
+            log('Error printing traceback: %s\n' % e2)
+        log('\nError in completion: %s\n' % e)
 
 
 optspec = """
-bup ftp
+bup ftp [commands...]
 """
 o = options.Options('bup ftp', optspec)
 (opt, flags, extra) = o.parse(sys.argv[1:])
@@ -130,6 +163,12 @@ rv = 0
 if extra:
     lines = extra
 else:
+    try:
+        import readline
+    except ImportError:
+        log('* readline module not available: line editing disabled.\n')
+        readline = None
+
     if readline:
         readline.set_completer_delims(' \t\n\r/')
         readline.set_completer(completer)
@@ -145,11 +184,14 @@ for line in lines:
     #log('execute: %r %r\n' % (cmd, parm))
     try:
         if cmd == 'ls':
-            for parm in (words[1:] or ['.']):
-                do_ls(parm, pwd.resolve(parm))
+            do_ls(words[1:])
         elif cmd == 'cd':
+            np = pwd
             for parm in words[1:]:
-                pwd = pwd.resolve(parm)
+                np = np.resolve(parm)
+                if not stat.S_ISDIR(np.mode):
+                    raise vfs.NotDir('%s is not a directory' % parm)
+            pwd = np
         elif cmd == 'pwd':
             print pwd.fullname()
         elif cmd == 'cat':