def _recursive_dirlist(prepend, xdev, bup_dir=None, excluded_paths=None, exclude_rxs=None): for (name, pst) in _dirlist(): path = prepend + name if excluded_paths: if os.path.normpath(path) in excluded_paths: debug1('Skipping %r: excluded.\n' % path) continue if exclude_rxs and should_rx_exclude_path(path, exclude_rxs): continue if name.endswith('/'): if bup_dir != None: if os.path.normpath(path) == bup_dir: debug1('Skipping BUP_DIR.\n') continue if xdev != None and pst.st_dev != xdev: debug1('Skipping contents of %r: different filesystem.\n' % path) else: try: OsFile(name).fchdir() except OSError as e: add_error('%s: %s' % (prepend, e)) else: for i in _recursive_dirlist(prepend=prepend + name, xdev=xdev, bup_dir=bup_dir, excluded_paths=excluded_paths, exclude_rxs=exclude_rxs): yield i os.chdir('..') yield (path, pst)
def _recursive_dirlist(prepend, xdev, bup_dir=None, excluded_paths=None, exclude_rxs=None): for (name,pst) in _dirlist(): path = prepend + name if excluded_paths: if os.path.normpath(path) in excluded_paths: debug1('Skipping %r: excluded.\n' % path) continue if exclude_rxs and should_rx_exclude_path(path, exclude_rxs): continue if name.endswith('/'): if bup_dir != None: if os.path.normpath(path) == bup_dir: debug1('Skipping BUP_DIR.\n') continue if xdev != None and pst.st_dev != xdev: debug1('Skipping contents of %r: different filesystem.\n' % path) else: try: OsFile(name).fchdir() except OSError as e: add_error('%s: %s' % (prepend, e)) else: for i in _recursive_dirlist(prepend=prepend+name, xdev=xdev, bup_dir=bup_dir, excluded_paths=excluded_paths, exclude_rxs=exclude_rxs): yield i os.chdir('..') yield (path, pst)
def do_node(top, n, sparse, owner_map, meta = None): # Create n.fullname(), relative to the current directory, and # restore all of its metadata, when available. The meta argument # will be None for dirs, or when there is no .bupm (i.e. no # metadata). global total_restored, opt meta_stream = None write_content = sparse and write_file_content_sparsely or write_file_content try: fullname = n.fullname(stop_at=top) # Match behavior of index --exclude-rx with respect to paths. exclude_candidate = '/' + fullname if(stat.S_ISDIR(n.mode)): exclude_candidate += '/' if should_rx_exclude_path(exclude_candidate, exclude_rxs): return # If this is a directory, its metadata is the first entry in # any .bupm file inside the directory. Get it. if(stat.S_ISDIR(n.mode)): mfile = n.metadata_file() # VFS file -- cannot close(). if mfile: meta_stream = mfile.open() meta = metadata.Metadata.read(meta_stream) print_info(n, fullname) created_hardlink = False if meta and meta.hardlink_target: created_hardlink = hardlink_if_possible(fullname, n, meta) if not created_hardlink: create_path(n, fullname, meta) if meta: if stat.S_ISREG(meta.mode): write_content(fullname, n) elif stat.S_ISREG(n.mode): write_content(fullname, n) total_restored += 1 plog('Restoring: %d\r' % total_restored) for sub in n: m = None # Don't get metadata if this is a dir -- handled in sub do_node(). if meta_stream and not stat.S_ISDIR(sub.mode): m = metadata.Metadata.read(meta_stream) do_node(top, sub, sparse, owner_map, meta = m) if meta and not created_hardlink: apply_metadata(meta, fullname, opt.numeric_ids, owner_map) finally: if meta_stream: meta_stream.close() n.release()
def _recursive_dirlist(prepend, xdev, bup_dir=None, excluded_paths=None, exclude_rxs=None, xdev_exceptions=frozenset()): for (name,pst) in _dirlist(): path = prepend + name if excluded_paths: if os.path.normpath(path) in excluded_paths: debug1('Skipping %r: excluded.\n' % path_msg(path)) continue if exclude_rxs and should_rx_exclude_path(path, exclude_rxs): continue if name.endswith(b'/'): if bup_dir != None: if os.path.normpath(path) == bup_dir: debug1('Skipping BUP_DIR.\n') continue if xdev != None and pst.st_dev != xdev \ and path not in xdev_exceptions: debug1('Skipping contents of %r: different filesystem.\n' % path_msg(path)) else: try: with finalized_fd(name) as fd: os.fchdir(fd) except OSError as e: add_error('%s: %s' % (prepend, e)) else: for i in _recursive_dirlist(prepend=prepend+name, xdev=xdev, bup_dir=bup_dir, excluded_paths=excluded_paths, exclude_rxs=exclude_rxs, xdev_exceptions=xdev_exceptions): yield i os.chdir(b'..') yield (path, pst)
def restore(repo, parent_path, name, item, top, sparse, numeric_ids, owner_map, exclude_rxs, verbosity, hardlinks): global total_restored mode = vfs.item_mode(item) treeish = S_ISDIR(mode) fullname = parent_path + b'/' + name # Match behavior of index --exclude-rx with respect to paths. if should_rx_exclude_path(fullname + (b'/' if treeish else b''), exclude_rxs): return if not treeish: # Do this now so we'll have meta.symlink_target for verbose output item = vfs.augment_item_meta(repo, item, include_size=True) meta = item.meta assert (meta.mode == mode) if stat.S_ISDIR(mode): if verbosity >= 1: out.write(b'%s/\n' % fullname) elif stat.S_ISLNK(mode): assert (meta.symlink_target) if verbosity >= 2: out.write(b'%s@ -> %s\n' % (fullname, meta.symlink_target)) else: if verbosity >= 2: out.write(fullname + b'\n') orig_cwd = os.getcwd() try: if treeish: # Assumes contents() returns '.' with the full metadata first sub_items = vfs.contents(repo, item, want_meta=True) dot, item = next(sub_items, None) assert (dot == b'.') item = vfs.augment_item_meta(repo, item, include_size=True) meta = item.meta meta.create_path(name) os.chdir(name) total_restored += 1 if verbosity >= 0: qprogress('Restoring: %d\r' % total_restored) for sub_name, sub_item in sub_items: restore(repo, fullname, sub_name, sub_item, top, sparse, numeric_ids, owner_map, exclude_rxs, verbosity, hardlinks) os.chdir(b'..') apply_metadata(meta, name, numeric_ids, owner_map) else: created_hardlink = False if meta.hardlink_target: created_hardlink = hardlink_if_possible( fullname, item, top, hardlinks) if not created_hardlink: meta.create_path(name) if stat.S_ISREG(meta.mode): if sparse: write_file_content_sparsely(repo, name, item) else: write_file_content(repo, name, item) total_restored += 1 if verbosity >= 0: qprogress('Restoring: %d\r' % total_restored) if not created_hardlink: apply_metadata(meta, name, numeric_ids, owner_map) finally: os.chdir(orig_cwd)
def restore(repo, parent_path, name, item, top, sparse, numeric_ids, owner_map, exclude_rxs, verbosity, hardlinks): global total_restored mode = vfs.item_mode(item) treeish = S_ISDIR(mode) fullname = parent_path + '/' + name # Match behavior of index --exclude-rx with respect to paths. if should_rx_exclude_path(fullname + ('/' if treeish else ''), exclude_rxs): return if not treeish: # Do this now so we'll have meta.symlink_target for verbose output item = vfs.augment_item_meta(repo, item, include_size=True) meta = item.meta assert(meta.mode == mode) if stat.S_ISDIR(mode): if verbosity >= 1: print('%s/' % fullname) elif stat.S_ISLNK(mode): assert(meta.symlink_target) if verbosity >= 2: print('%s@ -> %s' % (fullname, meta.symlink_target)) else: if verbosity >= 2: print(fullname) orig_cwd = os.getcwd() try: if treeish: # Assumes contents() returns '.' with the full metadata first sub_items = vfs.contents(repo, item, want_meta=True) dot, item = next(sub_items, None) assert(dot == '.') item = vfs.augment_item_meta(repo, item, include_size=True) meta = item.meta meta.create_path(name) os.chdir(name) total_restored += 1 if verbosity >= 0: qprogress('Restoring: %d\r' % total_restored) for sub_name, sub_item in sub_items: restore(repo, fullname, sub_name, sub_item, top, sparse, numeric_ids, owner_map, exclude_rxs, verbosity, hardlinks) os.chdir('..') apply_metadata(meta, name, numeric_ids, owner_map) else: created_hardlink = False if meta.hardlink_target: created_hardlink = hardlink_if_possible(fullname, item, top, hardlinks) if not created_hardlink: meta.create_path(name) if stat.S_ISREG(meta.mode): if sparse: write_file_content_sparsely(repo, name, item) else: write_file_content(repo, name, item) total_restored += 1 if verbosity >= 0: qprogress('Restoring: %d\r' % total_restored) if not created_hardlink: apply_metadata(meta, name, numeric_ids, owner_map) finally: os.chdir(orig_cwd)