X-Git-Url: https://arthur.barton.de/gitweb/?p=bup.git;a=blobdiff_plain;f=lib%2Fbup%2Fcmd%2Fftp.py;h=86392301016a798b4c4238ba92c1f78db9d2e173;hp=eb14fc0689e01d5d55ecdaf3100580b31c1b9054;hb=7cc2d57520cf33cae948b2eba9a240b976f1eb43;hpb=d2419265cf0504d98e7661b828d34b72f1cb9eeb diff --git a/lib/bup/cmd/ftp.py b/lib/bup/cmd/ftp.py index eb14fc0..8639230 100755 --- a/lib/bup/cmd/ftp.py +++ b/lib/bup/cmd/ftp.py @@ -1,18 +1,3 @@ -#!/bin/sh -"""": # -*-python-*- -# https://sourceware.org/bugzilla/show_bug.cgi?id=26034 -export "BUP_ARGV_0"="$0" -arg_i=1 -for arg in "$@"; do - export "BUP_ARGV_${arg_i}"="$arg" - shift - arg_i=$((arg_i + 1)) -done -# Here to end of preamble replaced during install -bup_python="$(dirname "$0")/../../../config/bin/python" || exit $? -exec "$bup_python" "$0" -""" -# end of bup preamble # For now, this completely relies on the assumption that the current # encoding (LC_CTYPE, etc.) is ASCII compatible, and that it returns @@ -20,33 +5,29 @@ exec "$bup_python" "$0" # (e.g. ISO-8859-1). from __future__ import absolute_import, print_function +import os, fnmatch, stat, sys, traceback -# Intentionally replace the dirname "$0" that python prepends -import os, sys -sys.path[0] = os.path.dirname(os.path.realpath(__file__)) + '/..' - -import fnmatch, stat - -from bup import _helpers, compat, options, git, shquote, ls, vfs -from bup.compat import argv_bytes, fsdecode -from bup.helpers import chunkyreader, handle_ctrl_c, log +from bup import _helpers, options, git, shquote, ls, vfs +from bup.compat import argv_bytes +from bup.helpers import chunkyreader, log from bup.io import byte_stream, path_msg from bup.repo import LocalRepo -handle_ctrl_c() +repo = None class OptionError(Exception): pass -def do_ls(repo, args, out): +def do_ls(repo, pwd, args, out): + pwd_str = b'/'.join(name for name, item in pwd) or b'/' try: - opt = ls.opts_from_cmdline(args, onabort=OptionError) + opt = ls.opts_from_cmdline(args, onabort=OptionError, pwd=pwd_str) except OptionError as e: log('error: %s' % e) - return - return ls.within_repo(repo, opt, out) + return None + return ls.within_repo(repo, opt, out, pwd_str) def write_to_file(inf, outf): @@ -54,28 +35,6 @@ def write_to_file(inf, outf): outf.write(blob) -def inputiter(): - if os.isatty(stdin.fileno()): - while 1: - if hasattr(_helpers, 'readline'): - try: - yield _helpers.readline(b'bup> ') - except EOFError: - print() # Clear the line for the terminal's next prompt - break - else: - out.write(b'bup> ') - out.flush() - read_line = stdin.readline() - if not read_line: - print('') - break - yield read_line - else: - for line in stdin: - yield line - - def _completer_get_subs(repo, line): (qtype, lastword) = shquote.unfinished_word(line) dir, name = os.path.split(lastword) @@ -96,7 +55,6 @@ def attempt_completion(text, start, end): global _attempt_start, _attempt_end _attempt_start = start _attempt_end = end - return None _last_line = None _last_res = None @@ -126,135 +84,157 @@ def enter_completion(text, iteration): return text + ret except Exception as e: log('\n') - try: - import traceback - traceback.print_tb(sys.exc_traceback) - except Exception as e2: - log('Error printing traceback: %s\n' % e2) + _, _, tb = sys.exc_info() + traceback.print_tb(tb) log('\nError in completion: %s\n' % e) + return None optspec = """ bup ftp [commands...] """ -o = options.Options(optspec) -opt, flags, extra = o.parse(compat.argv[1:]) -git.check_repo_or_die() +def main(argv): + o = options.Options(optspec) + opt, flags, extra = o.parse_bytes(argv[1:]) -sys.stdout.flush() -out = byte_stream(sys.stdout) -stdin = byte_stream(sys.stdin) -repo = LocalRepo() -pwd = vfs.resolve(repo, b'/') -rv = 0 + git.check_repo_or_die() + global repo + sys.stdout.flush() + out = byte_stream(sys.stdout) + stdin = byte_stream(sys.stdin) + repo = LocalRepo() + pwd = vfs.resolve(repo, b'/') + rv = 0 + + def inputiter(f): + if os.isatty(f.fileno()): + while 1: + prompt = b'bup %s> ' % (b'/'.join(name for name, item in pwd) or b'/', ) + if hasattr(_helpers, 'readline'): + try: + yield _helpers.readline(prompt) + except EOFError: + print() # Clear the line for the terminal's next prompt + break + else: + out.write(prompt) + out.flush() + read_line = f.readline() + if not read_line: + print('') + break + yield read_line + else: + for line in f: + yield line -if extra: - lines = (argv_bytes(arg) for arg in extra) -else: - if hasattr(_helpers, 'readline'): - _helpers.set_completer_word_break_characters(b' \t\n\r/') - _helpers.set_attempted_completion_function(attempt_completion) - _helpers.set_completion_entry_function(enter_completion) - if sys.platform.startswith('darwin'): - # MacOS uses a slightly incompatible clone of libreadline - _helpers.parse_and_bind(b'bind ^I rl_complete') - _helpers.parse_and_bind(b'tab: complete') - lines = inputiter() -for line in lines: - if not line.strip(): - continue - words = [word for (wordstart,word) in shquote.quotesplit(line)] - cmd = words[0].lower() - #log('execute: %r %r\n' % (cmd, parm)) - try: - if cmd == b'ls': - # FIXME: respect pwd (perhaps via ls accepting resolve path/parent) - do_ls(repo, words[1:], out) - out.flush() - elif cmd == b'cd': - np = pwd - for parm in words[1:]: - res = vfs.resolve(repo, parm, parent=np) - _, leaf_item = res[-1] - if not leaf_item: - raise Exception('%s does not exist' - % path_msg(b'/'.join(name for name, item - in res))) - if not stat.S_ISDIR(vfs.item_mode(leaf_item)): - raise Exception('%s is not a directory' % path_msg(parm)) - np = res - pwd = np - elif cmd == b'pwd': - if len(pwd) == 1: - out.write(b'/') - out.write(b'/'.join(name for name, item in pwd) + b'\n') - out.flush() - elif cmd == b'cat': - for parm in words[1:]: - res = vfs.resolve(repo, parm, parent=pwd) + if extra: + lines = (argv_bytes(arg) for arg in extra) + else: + if hasattr(_helpers, 'readline'): + _helpers.set_completer_word_break_characters(b' \t\n\r/') + _helpers.set_attempted_completion_function(attempt_completion) + _helpers.set_completion_entry_function(enter_completion) + if sys.platform.startswith('darwin'): + # MacOS uses a slightly incompatible clone of libreadline + _helpers.parse_and_bind(b'bind ^I rl_complete') + _helpers.parse_and_bind(b'tab: complete') + lines = inputiter(stdin) + + for line in lines: + if not line.strip(): + continue + words = [word for (wordstart,word) in shquote.quotesplit(line)] + cmd = words[0].lower() + #log('execute: %r %r\n' % (cmd, parm)) + try: + if cmd == b'ls': + do_ls(repo, pwd, words[1:], out) + out.flush() + elif cmd == b'cd': + np = pwd + for parm in words[1:]: + res = vfs.resolve(repo, parm, parent=np) + _, leaf_item = res[-1] + if not leaf_item: + raise Exception('%s does not exist' + % path_msg(b'/'.join(name for name, item + in res))) + if not stat.S_ISDIR(vfs.item_mode(leaf_item)): + raise Exception('%s is not a directory' % path_msg(parm)) + np = res + pwd = np + elif cmd == b'pwd': + if len(pwd) == 1: + out.write(b'/') + out.write(b'/'.join(name for name, item in pwd) + b'\n') + out.flush() + elif cmd == b'cat': + for parm in words[1:]: + res = vfs.resolve(repo, parm, parent=pwd) + _, leaf_item = res[-1] + if not leaf_item: + raise Exception('%s does not exist' % + path_msg(b'/'.join(name for name, item + in res))) + with vfs.fopen(repo, leaf_item) as srcfile: + write_to_file(srcfile, out) + out.flush() + elif cmd == b'get': + if len(words) not in [2,3]: + rv = 1 + raise Exception('Usage: get [localname]') + rname = words[1] + (dir,base) = os.path.split(rname) + lname = len(words) > 2 and words[2] or base + res = vfs.resolve(repo, rname, parent=pwd) _, leaf_item = res[-1] if not leaf_item: raise Exception('%s does not exist' % - path_msg(b'/'.join(name for name, item - in res))) + path_msg(b'/'.join(name for name, item in res))) with vfs.fopen(repo, leaf_item) as srcfile: - write_to_file(srcfile, out) - out.flush() - elif cmd == b'get': - if len(words) not in [2,3]: + with open(lname, 'wb') as destfile: + log('Saving %s\n' % path_msg(lname)) + write_to_file(srcfile, destfile) + elif cmd == b'mget': + for parm in words[1:]: + dir, base = os.path.split(parm) + + res = vfs.resolve(repo, dir, parent=pwd) + _, dir_item = res[-1] + if not dir_item: + raise Exception('%s does not exist' % path_msg(dir)) + for name, item in vfs.contents(repo, dir_item): + if name == b'.': + continue + if fnmatch.fnmatch(name, base): + if stat.S_ISLNK(vfs.item_mode(item)): + deref = vfs.resolve(repo, name, parent=res) + deref_name, deref_item = deref[-1] + if not deref_item: + raise Exception('%s does not exist' % + path_msg('/'.join(name for name, item + in deref))) + item = deref_item + with vfs.fopen(repo, item) as srcfile: + with open(name, 'wb') as destfile: + log('Saving %s\n' % path_msg(name)) + write_to_file(srcfile, destfile) + elif cmd in (b'help', b'?'): + out.write(b'Commands: ls cd pwd cat get mget help quit\n') + out.flush() + elif cmd in (b'quit', b'exit', b'bye'): + break + else: rv = 1 - raise Exception('Usage: get [localname]') - rname = words[1] - (dir,base) = os.path.split(rname) - lname = len(words) > 2 and words[2] or base - res = vfs.resolve(repo, rname, parent=pwd) - _, leaf_item = res[-1] - if not leaf_item: - raise Exception('%s does not exist' % - path_msg(b'/'.join(name for name, item in res))) - with vfs.fopen(repo, leaf_item) as srcfile: - with open(lname, 'wb') as destfile: - log('Saving %s\n' % path_msg(lname)) - write_to_file(srcfile, destfile) - elif cmd == b'mget': - for parm in words[1:]: - dir, base = os.path.split(parm) - - res = vfs.resolve(repo, dir, parent=pwd) - _, dir_item = res[-1] - if not dir_item: - raise Exception('%s does not exist' % path_msg(dir)) - for name, item in vfs.contents(repo, dir_item): - if name == b'.': - continue - if fnmatch.fnmatch(name, base): - if stat.S_ISLNK(vfs.item_mode(item)): - deref = vfs.resolve(repo, name, parent=res) - deref_name, deref_item = deref[-1] - if not deref_item: - raise Exception('%s does not exist' % - path_msg('/'.join(name for name, item - in deref))) - item = deref_item - with vfs.fopen(repo, item) as srcfile: - with open(name, 'wb') as destfile: - log('Saving %s\n' % path_msg(name)) - write_to_file(srcfile, destfile) - elif cmd == b'help' or cmd == b'?': - out.write(b'Commands: ls cd pwd cat get mget help quit\n') - out.flush() - elif cmd in (b'quit', b'exit', b'bye'): - break - else: + raise Exception('no such command %r' % cmd) + except Exception as e: rv = 1 - raise Exception('no such command %r' % cmd) - except Exception as e: - rv = 1 - log('error: %s\n' % e) - raise + log('error: %s\n' % e) + raise -sys.exit(rv) + sys.exit(rv)