def from_path(path, statinfo=None, archive_path=None, save_symlinks=True, hardlink_target=None, normalized=False, after_stat=None): # This function is also a test hook; see test-save-errors """Return the metadata associated with the path. When normalized is true, return the metadata appropriate for a typical save, which may or may not be all of it.""" result = Metadata() result.path = archive_path st = statinfo or xstat.lstat(path) if after_stat: after_stat(path) result._add_common(path, st) if save_symlinks: result._add_symlink_target(path, st) result._add_hardlink_target(hardlink_target) result._add_posix1e_acl(path, st) result._add_linux_attr(path, st) result._add_linux_xattr(path, st) if normalized: # Only store sizes for regular files and symlinks for now. if not (stat.S_ISREG(result.mode) or stat.S_ISLNK(result.mode)): result.size = None return result
def recursive_dirlist(paths, xdev, bup_dir=None, excluded_paths=None): startdir = OsFile('.') try: assert(type(paths) != type('')) for path in paths: try: pst = xstat.lstat(path) if stat.S_ISLNK(pst.st_mode): yield (path, pst) continue except OSError, e: add_error('recursive_dirlist: %s' % e) continue try: pfile = OsFile(path) except OSError, e: add_error(e) continue pst = pfile.stat() if xdev: xdev = pst.st_dev else: xdev = None if stat.S_ISDIR(pst.st_mode): pfile.fchdir() prepend = os.path.join(path, '') for i in _recursive_dirlist(prepend=prepend, xdev=xdev, bup_dir=bup_dir, excluded_paths=excluded_paths): yield i startdir.fchdir() else: prepend = path yield (prepend,pst)
def save_tree(output_file, paths, recurse=False, write_paths=True, save_symlinks=True, xdev=False): # Issue top-level rewrite warnings. for path in paths: safe_path = _clean_up_path_for_archive(path) if safe_path != path: log('archiving "%s" as "%s"\n' % (path, safe_path)) if not recurse: for p in paths: safe_path = _clean_up_path_for_archive(p) st = xstat.lstat(p) if stat.S_ISDIR(st.st_mode): safe_path += "/" m = from_path(p, statinfo=st, archive_path=safe_path, save_symlinks=save_symlinks) if verbose: print >> sys.stderr, m.path m.write(output_file, include_path=write_paths) else: start_dir = os.getcwd() try: for (p, st) in recursive_dirlist(paths, xdev=xdev): dirlist_dir = os.getcwd() os.chdir(start_dir) safe_path = _clean_up_path_for_archive(p) m = from_path(p, statinfo=st, archive_path=safe_path, save_symlinks=save_symlinks) if verbose: print >> sys.stderr, m.path m.write(output_file, include_path=write_paths) os.chdir(dirlist_dir) finally: os.chdir(start_dir)
def recursive_dirlist(paths, xdev, bup_dir=None, excluded_paths=None): startdir = OsFile('.') try: assert (type(paths) != type('')) for path in paths: try: pst = xstat.lstat(path) if stat.S_ISLNK(pst.st_mode): yield (path, pst) continue except OSError, e: add_error('recursive_dirlist: %s' % e) continue try: pfile = OsFile(path) except OSError, e: add_error(e) continue pst = pfile.stat() if xdev: xdev = pst.st_dev else: xdev = None if stat.S_ISDIR(pst.st_mode): pfile.fchdir() prepend = os.path.join(path, '') for i in _recursive_dirlist(prepend=prepend, xdev=xdev, bup_dir=bup_dir, excluded_paths=excluded_paths): yield i startdir.fchdir() else: prepend = path yield (prepend, pst)
def _create_via_common_rec(self, path, create_symlinks=True): # If the path already exists and is a dir, try rmdir. # If the path already exists and is anything else, try unlink. st = None try: st = lstat(path) except OSError, e: if e.errno != errno.ENOENT: raise
def _dirlist(): l = [] for n in os.listdir('.'): try: st = xstat.lstat(n) except OSError, e: add_error(Exception('%s: %s' % (realpath(n), str(e)))) continue if (st.st_mode & _IFMT) == stat.S_IFDIR: n += '/' l.append((n, st))
def from_path(path, statinfo=None, archive_path=None, save_symlinks=True): result = Metadata() result.path = archive_path st = statinfo or lstat(path) result._add_common(path, st) if save_symlinks: result._add_symlink_target(path, st) result._add_posix1e_acl(path, st) result._add_linux_attr(path, st) result._add_linux_xattr(path, st) return result
def _dirlist(): l = [] for n in os.listdir('.'): try: st = xstat.lstat(n) except OSError, e: add_error(Exception('%s: %s' % (realpath(n), str(e)))) continue if (st.st_mode & _IFMT) == stat.S_IFDIR: n += '/' l.append((n,st))
def _create_via_common_rec(self, path, create_symlinks=True): if not self.mode: raise ApplyError('no metadata - cannot create path ' + path) # If the path already exists and is a dir, try rmdir. # If the path already exists and is anything else, try unlink. st = None try: st = xstat.lstat(path) except OSError, e: if e.errno != errno.ENOENT: raise
def _create_via_common_rec(self, path, create_symlinks=True): if not self.mode: raise ApplyError("no metadata - cannot create path " + path) # If the path already exists and is a dir, try rmdir. # If the path already exists and is anything else, try unlink. st = None try: st = xstat.lstat(path) except OSError, e: if e.errno != errno.ENOENT: raise
def _dirlist(): l = [] for n in os.listdir('.'): try: st = xstat.lstat(n) except OSError as e: add_error(Exception('%s: %s' % (resolve_parent(n), str(e)))) continue if (st.st_mode & _IFMT) == stat.S_IFDIR: n += '/' l.append((n,st)) l.sort(reverse=True) return l
def _dirlist(): l = [] for n in os.listdir('.'): try: st = xstat.lstat(n) except OSError as e: add_error(Exception('%s: %s' % (resolve_parent(n), str(e)))) continue if (st.st_mode & _IFMT) == stat.S_IFDIR: n += '/' l.append((n, st)) l.sort(reverse=True) return l
def recursive_dirlist(paths, xdev, bup_dir=None, excluded_paths=None, exclude_rxs=None, xdev_exceptions=frozenset()): startdir = OsFile(b'.') try: assert not isinstance(paths, str_type) for path in paths: try: pst = xstat.lstat(path) if stat.S_ISLNK(pst.st_mode): yield (path, pst) continue except OSError as e: add_error('recursive_dirlist: %s' % e) continue try: pfile = OsFile(path) except OSError as e: add_error(e) continue pst = pfile.stat() if xdev: xdev = pst.st_dev else: xdev = None if stat.S_ISDIR(pst.st_mode): pfile.fchdir() prepend = os.path.join(path, b'') for i in _recursive_dirlist(prepend=prepend, xdev=xdev, bup_dir=bup_dir, excluded_paths=excluded_paths, exclude_rxs=exclude_rxs, xdev_exceptions=xdev_exceptions): yield i startdir.fchdir() else: prepend = path yield (prepend, pst) except: try: startdir.fchdir() except: pass raise
def recursive_dirlist(paths, xdev, bup_dir=None, excluded_paths=None, exclude_rxs=None, xdev_exceptions=frozenset()): with finalized_fd(b'.') as startdir: try: assert not isinstance(paths, str) for path in paths: try: pst = xstat.lstat(path) if stat.S_ISLNK(pst.st_mode): yield (path, pst) continue except OSError as e: add_error('recursive_dirlist: %s' % e) continue try: opened_pfile = finalized_fd(path) except OSError as e: add_error(e) continue with opened_pfile as pfile: pst = xstat.fstat(pfile) if xdev: xdev = pst.st_dev else: xdev = None if stat.S_ISDIR(pst.st_mode): os.fchdir(pfile) prepend = os.path.join(path, b'') for i in _recursive_dirlist(prepend=prepend, xdev=xdev, bup_dir=bup_dir, excluded_paths=excluded_paths, exclude_rxs=exclude_rxs, xdev_exceptions=xdev_exceptions): yield i os.fchdir(startdir) else: prepend = path yield (prepend,pst) except: try: os.fchdir(startdir) except: pass raise
def save_tree(output_file, paths, recurse=False, write_paths=True, save_symlinks=True, xdev=False): # Issue top-level rewrite warnings. for path in paths: safe_path = _clean_up_path_for_archive(path) if safe_path != path: log('archiving "%s" as "%s"\n' % (path_msg(path), path_msg(safe_path))) if not recurse: for p in paths: safe_path = _clean_up_path_for_archive(p) st = xstat.lstat(p) if stat.S_ISDIR(st.st_mode): safe_path += b'/' m = from_path(p, statinfo=st, archive_path=safe_path, save_symlinks=save_symlinks) if verbose: print(m.path, file=sys.stderr) m.write(output_file, include_path=write_paths) else: start_dir = os.getcwd() try: for (p, st) in recursive_dirlist(paths, xdev=xdev): dirlist_dir = os.getcwd() os.chdir(start_dir) safe_path = _clean_up_path_for_archive(p) m = from_path(p, statinfo=st, archive_path=safe_path, save_symlinks=save_symlinks) if verbose: print(m.path, file=sys.stderr) m.write(output_file, include_path=write_paths) os.chdir(dirlist_dir) finally: os.chdir(start_dir)
def _create_via_common_rec(self, path, create_symlinks=True): if not self.mode: raise ApplyError('no metadata - cannot create path ' + path) # If the path already exists and is a dir, try rmdir. # If the path already exists and is anything else, try unlink. st = None try: st = xstat.lstat(path) except OSError as e: if e.errno != errno.ENOENT: raise if st: if stat.S_ISDIR(st.st_mode): try: os.rmdir(path) except OSError as e: if e.errno in (errno.ENOTEMPTY, errno.EEXIST): msg = 'refusing to overwrite non-empty dir ' + path raise Exception(msg) raise else: os.unlink(path) if stat.S_ISREG(self.mode): assert(self._recognized_file_type()) fd = os.open(path, os.O_CREAT|os.O_WRONLY|os.O_EXCL, 0o600) os.close(fd) elif stat.S_ISDIR(self.mode): assert(self._recognized_file_type()) os.mkdir(path, 0o700) elif stat.S_ISCHR(self.mode): assert(self._recognized_file_type()) os.mknod(path, 0o600 | stat.S_IFCHR, self.rdev) elif stat.S_ISBLK(self.mode): assert(self._recognized_file_type()) os.mknod(path, 0o600 | stat.S_IFBLK, self.rdev) elif stat.S_ISFIFO(self.mode): assert(self._recognized_file_type()) os.mknod(path, 0o600 | stat.S_IFIFO) elif stat.S_ISSOCK(self.mode): try: os.mknod(path, 0o600 | stat.S_IFSOCK) except OSError as e: if e.errno in (errno.EINVAL, errno.EPERM): s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.bind(path) else: raise elif stat.S_ISLNK(self.mode): assert(self._recognized_file_type()) if self.symlink_target and create_symlinks: # on MacOS, symlink() permissions depend on umask, and there's # no way to chown a symlink after creating it, so we have to # be careful here! oldumask = os.umask((self.mode & 0o777) ^ 0o777) try: os.symlink(self.symlink_target, path) finally: os.umask(oldumask) # FIXME: S_ISDOOR, S_IFMPB, S_IFCMP, S_IFNWK, ... see stat(2). else: assert(not self._recognized_file_type()) add_error('not creating "%s" with unrecognized mode "0x%x"\n' % (path, self.mode))
def _create_via_common_rec(self, path, create_symlinks=True): if not self.mode: raise ApplyError('no metadata - cannot create path ' + path_msg(path)) # If the path already exists and is a dir, try rmdir. # If the path already exists and is anything else, try unlink. st = None try: st = xstat.lstat(path) except OSError as e: if e.errno != errno.ENOENT: raise if st: if stat.S_ISDIR(st.st_mode): try: os.rmdir(path) except OSError as e: if e.errno in (errno.ENOTEMPTY, errno.EEXIST): raise Exception('refusing to overwrite non-empty dir ' + path_msg(path)) raise else: os.unlink(path) if stat.S_ISREG(self.mode): assert(self._recognized_file_type()) fd = os.open(path, os.O_CREAT|os.O_WRONLY|os.O_EXCL, 0o600) os.close(fd) elif stat.S_ISDIR(self.mode): assert(self._recognized_file_type()) os.mkdir(path, 0o700) elif stat.S_ISCHR(self.mode): assert(self._recognized_file_type()) os.mknod(path, 0o600 | stat.S_IFCHR, self.rdev) elif stat.S_ISBLK(self.mode): assert(self._recognized_file_type()) os.mknod(path, 0o600 | stat.S_IFBLK, self.rdev) elif stat.S_ISFIFO(self.mode): assert(self._recognized_file_type()) os.mkfifo(path, 0o600 | stat.S_IFIFO) elif stat.S_ISSOCK(self.mode): try: os.mknod(path, 0o600 | stat.S_IFSOCK) except OSError as e: if e.errno in (errno.EINVAL, errno.EPERM): s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.bind(path) else: raise elif stat.S_ISLNK(self.mode): assert(self._recognized_file_type()) if self.symlink_target and create_symlinks: # on MacOS, symlink() permissions depend on umask, and there's # no way to chown a symlink after creating it, so we have to # be careful here! oldumask = os.umask((self.mode & 0o777) ^ 0o777) try: os.symlink(self.symlink_target, path) finally: os.umask(oldumask) # FIXME: S_ISDOOR, S_IFMPB, S_IFCMP, S_IFNWK, ... see stat(2). else: assert(not self._recognized_file_type()) add_error('not creating "%s" with unrecognized mode "0x%x"\n' % (path_msg(path), self.mode))