3 bup_python="$(dirname "$0")/bup-python" || exit $?
4 exec "$bup_python" "$0" ${1+"$@"}
8 import sys, os, stat, fnmatch
10 from bup import options, git, shquote, vfs, ls
11 from bup.helpers import chunkyreader, handle_ctrl_c, log
17 class OptionError(Exception):
21 # Check out lib/bup/ls.py for the opt spec
24 ls.do_ls(cmd_args, pwd, onabort=OptionError)
25 except OptionError as e:
29 def write_to_file(inf, outf):
30 for blob in chunkyreader(inf):
35 if os.isatty(sys.stdin.fileno()):
38 yield raw_input('bup> ')
40 print '' # Clear the line for the terminal's next prompt
43 for line in sys.stdin:
47 def _completer_get_subs(line):
48 (qtype, lastword) = shquote.unfinished_word(line)
49 (dir,name) = os.path.split(lastword)
50 #log('\ncompleter: %r %r %r\n' % (qtype, lastword, text))
53 subs = list(filter(lambda x: x.name.startswith(name),
55 except vfs.NoSuchFile as e:
57 return (dir, name, qtype, lastword, subs)
60 def find_readline_lib():
61 """Return the name (and possibly the full path) of the readline library
62 linked to the given readline module.
65 f = open(readline.__file__, "rb")
71 m = re.search('\0([^\0]*libreadline[^\0]*)\0', data)
77 def init_readline_vars():
78 """Work around trailing space automatically inserted by readline.
79 See http://bugs.python.org/issue5833"""
83 # python before 2.5 didn't have the ctypes module; but those
84 # old systems probably also didn't have this readline bug, so
87 lib_name = find_readline_lib()
88 if lib_name is not None:
89 lib = ctypes.cdll.LoadLibrary(lib_name)
90 global rl_completion_suppress_append
91 rl_completion_suppress_append = ctypes.c_int.in_dll(lib,
92 "rl_completion_suppress_append")
95 rl_completion_suppress_append = None
98 def completer(text, state):
101 global rl_completion_suppress_append
102 if rl_completion_suppress_append is not None:
103 rl_completion_suppress_append.value = 1
105 line = readline.get_line_buffer()[:readline.get_endidx()]
106 if _last_line != line:
107 _last_res = _completer_get_subs(line)
109 (dir, name, qtype, lastword, subs) = _last_res
110 if state < len(subs):
112 sn1 = sn.try_resolve() # find the type of any symlink target
113 fullname = os.path.join(dir, sn.name)
114 if stat.S_ISDIR(sn1.mode):
115 ret = shquote.what_to_add(qtype, lastword, fullname+'/',
118 ret = shquote.what_to_add(qtype, lastword, fullname,
119 terminate=True) + ' '
121 except Exception as e:
125 traceback.print_tb(sys.exc_traceback)
126 except Exception as e2:
127 log('Error printing traceback: %s\n' % e2)
128 log('\nError in completion: %s\n' % e)
132 bup ftp [commands...]
134 o = options.Options(optspec)
135 (opt, flags, extra) = o.parse(sys.argv[1:])
137 git.check_repo_or_die()
139 top = vfs.RefList(None)
149 log('* readline module not available: line editing disabled.\n')
153 readline.set_completer_delims(' \t\n\r/')
154 readline.set_completer(completer)
155 if sys.platform.startswith('darwin'):
156 # MacOS uses a slighly incompatible clone of libreadline
157 readline.parse_and_bind('bind ^I rl_complete')
158 readline.parse_and_bind('tab: complete')
165 words = [word for (wordstart,word) in shquote.quotesplit(line)]
166 cmd = words[0].lower()
167 #log('execute: %r %r\n' % (cmd, parm))
173 for parm in words[1:]:
174 np = np.resolve(parm)
175 if not stat.S_ISDIR(np.mode):
176 raise vfs.NotDir('%s is not a directory' % parm)
181 for parm in words[1:]:
182 write_to_file(pwd.resolve(parm).open(), sys.stdout)
184 if len(words) not in [2,3]:
186 raise Exception('Usage: get <filename> [localname]')
188 (dir,base) = os.path.split(rname)
189 lname = len(words)>2 and words[2] or base
190 inf = pwd.resolve(rname).open()
191 log('Saving %r\n' % lname)
192 write_to_file(inf, open(lname, 'wb'))
194 for parm in words[1:]:
195 (dir,base) = os.path.split(parm)
196 for n in pwd.resolve(dir).subs():
197 if fnmatch.fnmatch(n.name, base):
199 log('Saving %r\n' % n.name)
201 outf = open(n.name, 'wb')
202 write_to_file(inf, outf)
204 except Exception as e:
206 log(' error: %s\n' % e)
207 elif cmd == 'help' or cmd == '?':
208 log('Commands: ls cd pwd cat get mget help quit\n')
209 elif cmd == 'quit' or cmd == 'exit' or cmd == 'bye':
213 raise Exception('no such command %r' % cmd)
214 except Exception as e:
216 log('error: %s\n' % e)