def _get_file(self, repo, path, resolved): """Process a request on a file. Return value is either a file object, or None (indicating an error). In either case, the headers are sent. """ try: file_item = resolved[-1][1] file_item = vfs.augment_item_meta(repo, file_item, include_size=True) # we defer the set_header() calls until after we start writing # so we can still generate a 500 failure if something fails ... if self.request.method != 'HEAD': set_header = False with vfs.fopen(self.repo, file_item) as f: it = chunkyreader(f) for blob in chunkyreader(f): if not set_header: self._set_header(path, file_item) set_header = True self.write(blob) else: self._set_header(path, file_item) except Exception as e: self.set_status(500) self.write("<h1>Server Error</h1>\n") self.write("%s: %s\n" % (e.__class__.__name__, str(e))) raise gen.Return()
def read_act(act_pos): with vfs.fopen(repo, item) as actual: actual.seek(act_pos) wvpasseq(act_pos, actual.tell()) act_buf = actual.read(read_size) act_pos += len(act_buf) wvpasseq(act_pos, actual.tell()) return act_pos, act_buf
def read(self, path, size, offset): if self.verbose > 0: log('--read(%r)\n' % path) res = vfs.lresolve(self.repo, path) name, item = res[-1] if not item: return -errno.ENOENT with vfs.fopen(repo, item) as f: f.seek(offset) return f.read(size)
def read(self, path, size, offset): if self.verbose > 0: log('--read(%r)\n' % path) res = vfs.resolve(self.repo, path, follow=False) name, item = res[-1] if not item: return -errno.ENOENT with vfs.fopen(repo, item) as f: f.seek(offset) return f.read(size)
def write_file_content_sparsely(repo, dest_path, vfs_file): with vfs.fopen(repo, vfs_file) as inf: outfd = os.open(dest_path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600) try: trailing_zeros = 0; for b in chunkyreader(inf): trailing_zeros = write_sparsely(outfd, b, 512, trailing_zeros) pos = os.lseek(outfd, trailing_zeros, os.SEEK_END) os.ftruncate(outfd, pos) finally: os.close(outfd)
def read(self, path, size, offset): path = argv_bytes(path) if self.verbose > 0: log('--read(%r)\n' % path) res = vfs.resolve(self.repo, path, follow=False) name, item = res[-1] if not item: return -errno.ENOENT with vfs.fopen(self.repo, item) as f: f.seek(offset) return f.read(size)
def main(argv): o = options.Options(optspec) opt, flags, extra = o.parse_bytes(argv[1:]) git.check_repo_or_die() if not extra: o.fatal('must specify a target') if len(extra) > 1: o.fatal('only one target file allowed') if opt.bupm and opt.meta: o.fatal('--meta and --bupm are incompatible') target = argv_bytes(extra[0]) if not re.match(br'/*[^/]+/[^/]+', target): o.fatal("path %r doesn't include a branch and revision" % target) with LocalRepo() as repo: resolved = vfs.resolve(repo, target, follow=False) leaf_name, leaf_item = resolved[-1] if not leaf_item: log('error: cannot access %r in %r\n' % (b'/'.join(name for name, item in resolved), target)) sys.exit(1) mode = vfs.item_mode(leaf_item) sys.stdout.flush() out = byte_stream(sys.stdout) if opt.bupm: if not stat.S_ISDIR(mode): o.fatal('%r is not a directory' % target) _, bupm_oid = vfs.tree_data_and_bupm(repo, leaf_item.oid) if bupm_oid: with vfs.tree_data_reader(repo, bupm_oid) as meta_stream: out.write(meta_stream.read()) elif opt.meta: augmented = vfs.augment_item_meta(repo, leaf_item, include_size=True) out.write(augmented.meta.encode()) else: if stat.S_ISREG(mode): with vfs.fopen(repo, leaf_item) as f: for b in chunkyreader(f): out.write(b) else: o.fatal('%r is not a plain file' % target) if saved_errors: log('warning: %d errors encountered\n' % len(saved_errors)) sys.exit(1)
def validate_vfs_streaming_read(repo, item, expected_path, read_sizes): for read_size in read_sizes: with open(expected_path, 'rb') as expected: with vfs.fopen(repo, item) as actual: ex_buf = expected.read(read_size) act_buf = actual.read(read_size) while ex_buf and act_buf: wvpassge(read_size, len(ex_buf)) wvpassge(read_size, len(act_buf)) wvpasseq(len(ex_buf), len(act_buf)) wvpass(ex_buf == act_buf) ex_buf = expected.read(read_size) act_buf = actual.read(read_size) wvpasseq('', ex_buf) wvpasseq('', act_buf)
def _get_file(self, repo, path, resolved): """Process a request on a file. Return value is either a file object, or None (indicating an error). In either case, the headers are sent. """ file_item = resolved[-1][1] file_item = vfs.augment_item_meta(repo, file_item, include_size=True) meta = file_item.meta ctype = self._guess_type(path) self.set_header("Last-Modified", http_date_from_utc_ns(meta.mtime)) self.set_header("Content-Type", ctype) self.set_header("Content-Length", str(meta.size)) assert len(file_item.oid) == 20 self.set_header("Etag", file_item.oid.encode('hex')) if self.request.method != 'HEAD': with vfs.fopen(self.repo, file_item) as f: it = chunkyreader(f) for blob in chunkyreader(f): self.write(blob) raise gen.Return()
def _get_file(self, repo, path, resolved): """Process a request on a file. Return value is either a file object, or None (indicating an error). In either case, the headers are sent. """ file_item = resolved[-1][1] file_item = vfs.augment_item_meta(repo, file_item, include_size=True) meta = file_item.meta ctype = self._guess_type(path) self.set_header("Last-Modified", http_date_from_utc_ns(meta.mtime)) self.set_header("Content-Type", ctype) self.set_header("Content-Length", str(meta.size)) assert len(file_item.oid) == 20 self.set_header("Etag", hexlify(file_item.oid)) if self.request.method != 'HEAD': with vfs.fopen(self.repo, file_item) as f: it = chunkyreader(f) for blob in chunkyreader(f): self.write(blob) raise gen.Return()
def write_file_content(repo, dest_path, vfs_file): with vfs.fopen(repo, vfs_file) as inf: with open(dest_path, 'wb') as outf: for b in chunkyreader(inf): outf.write(b)
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 <filename> [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)))
resolved = vfs.resolve(repo, target, follow=False) leaf_name, leaf_item = resolved[-1] if not leaf_item: log('error: cannot access %r in %r\n' % ('/'.join(name for name, item in resolved), path)) sys.exit(1) mode = vfs.item_mode(leaf_item) if opt.bupm: if not stat.S_ISDIR(mode): o.fatal('%r is not a directory' % target) _, bupm_oid = vfs.tree_data_and_bupm(repo, leaf_item.oid) if bupm_oid: with vfs.tree_data_reader(repo, bupm_oid) as meta_stream: sys.stdout.write(meta_stream.read()) elif opt.meta: augmented = vfs.augment_item_meta(repo, leaf_item, include_size=True) sys.stdout.write(augmented.meta.encode()) else: if stat.S_ISREG(mode): with vfs.fopen(repo, leaf_item) as f: for b in chunkyreader(f): sys.stdout.write(b) else: o.fatal('%r is not a plain file' % target) if saved_errors: log('warning: %d errors encountered\n' % len(saved_errors)) sys.exit(1)
def present_interface(stdin, out, extra, repo): pwd = vfs.resolve(repo, b'/') 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, pwd, out) 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 CommandError('path does not exist: ' + rpath_msg(res)) if not stat.S_ISDIR(vfs.item_mode(leaf_item)): raise CommandError('path 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 CommandError('path does not exist: ' + rpath_msg(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]: raise CommandError('Usage: get <filename> [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 CommandError('path does not exist: ' + rpath_msg(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 CommandError('path 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 CommandError( 'path does not exist: ' + rpath_msg(res)) 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: raise CommandError('no such command: ' + cmd.encode(errors='backslashreplace')) except CommandError as ex: out.write(b'error: %s\n' % str(ex).encode(errors='backslashreplace')) out.flush()
def main(argv): o = options.Options(optspec) opt, flags, extra = o.parse_bytes(argv[1:]) global repo repo = from_opts(opt, reverse=False) sys.stdout.flush() out = byte_stream(sys.stdout) stdin = byte_stream(sys.stdin) 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(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 CommandError(b'"%s" does not exist' % b'/'.join(name for name, item in res)) if not stat.S_ISDIR(vfs.item_mode(leaf_item)): raise CommandError(b'"%s" is not a directory' % 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 CommandError(b'"%s" does not exist' % 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 CommandError(b'Usage: get <filename> [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 CommandError(b'"%s" does not exist' % 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 CommandError(b'"%s" does not exist' % 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 CommandError(b'"%s" does not exist' % b'/'.join(name for name, item in res)) 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: rv = 1 raise CommandError(b'no such command "%s"' % cmd) except CommandError as e: rv = 1 out.write(b'error: %s\n' % e.args[0]) out.flush() except Exception as e: rv = 1 out.write(b'error: %s\n' % str(e).encode()) out.flush() sys.exit(rv)
if not stat.S_ISDIR(vfs.item_mode(leaf_item)): raise Exception('%r is not a directory' % parm) np = res pwd = np elif cmd == 'pwd': if len(pwd) == 1: sys.stdout.write('/') print('/'.join(name for name, item in pwd)) elif cmd == 'cat': for parm in words[1:]: res = vfs.resolve(repo, parm, parent=pwd) _, leaf_item = res[-1] if not leaf_item: raise Exception('%r does not exist' % '/'.join(name for name, item in res)) with vfs.fopen(repo, leaf_item) as srcfile: write_to_file(srcfile, sys.stdout) elif cmd == 'get': if len(words) not in [2,3]: rv = 1 raise Exception('Usage: get <filename> [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('%r does not exist' % '/'.join(name for name, item in res)) with vfs.fopen(repo, leaf_item) as srcfile: with open(lname, 'wb') as destfile:
resolved = vfs.lresolve(repo, target) leaf_name, leaf_item = resolved[-1] if not leaf_item: log('error: cannot access %r in %r\n' % ('/'.join(name for name, item in resolved), path)) sys.exit(1) mode = vfs.item_mode(leaf_item) if opt.bupm: if not stat.S_ISDIR(mode): o.fatal('%r is not a directory' % target) _, bupm_oid = vfs.tree_data_and_bupm(repo, leaf_item.oid) if bupm_oid: with vfs.tree_data_reader(repo, bupm_oid) as meta_stream: sys.stdout.write(meta_stream.read()) elif opt.meta: augmented = vfs.augment_item_meta(repo, leaf_item, include_size=True) sys.stdout.write(augmented.meta.encode()) else: if stat.S_ISREG(mode): with vfs.fopen(repo, leaf_item) as f: for b in chunkyreader(f): sys.stdout.write(b) else: o.fatal('%r is not a plain file' % target) if saved_errors: log('warning: %d errors encountered\n' % len(saved_errors)) sys.exit(1)