Beispiel #1
0
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
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
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)
Beispiel #5
0
 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
Beispiel #6
0
 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
Beispiel #7
0
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))
Beispiel #8
0
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
Beispiel #9
0
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))
Beispiel #10
0
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
Beispiel #11
0
    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
Beispiel #12
0
    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
Beispiel #13
0
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
Beispiel #14
0
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
Beispiel #15
0
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
Beispiel #16
0
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
Beispiel #17
0
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)
Beispiel #18
0
    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))
Beispiel #19
0
    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))