diff --git a/docs/internals/frontends.rst b/docs/internals/frontends.rst index b34f9ed7b..b4c2d0550 100644 --- a/docs/internals/frontends.rst +++ b/docs/internals/frontends.rst @@ -587,6 +587,8 @@ Errors There is already something at {}. Repository.StorageQuotaExceeded rc: 20 traceback: no The storage quota ({}) has been exceeded ({}). Try deleting some archives. + Repository.PathPermissionDenied rc: 21 traceback: no + Permission denied to {}. MandatoryFeatureUnsupported rc: 25 traceback: no Unsupported repository feature(s) {}. A newer version of borg is required to access this repository. diff --git a/src/borg/remote.py b/src/borg/remote.py index a7a2bad4d..52ed46d88 100644 --- a/src/borg/remote.py +++ b/src/borg/remote.py @@ -772,6 +772,8 @@ This problem will go away as soon as the server has been upgraded to 1.0.7+. raise PathNotAllowed('(unknown)') else: raise PathNotAllowed(args[0].decode()) + elif error == 'PathPermissionDenied': + raise Repository.PathPermissionDenied(args[0].decode()) elif error == 'ParentPathDoesNotExist': raise Repository.ParentPathDoesNotExist(args[0].decode()) elif error == 'ObjectNotFound': diff --git a/src/borg/repository.py b/src/borg/repository.py index ab6a9afb2..5a97617e7 100644 --- a/src/borg/repository.py +++ b/src/borg/repository.py @@ -168,6 +168,10 @@ class Repository: """The storage quota ({}) has been exceeded ({}). Try deleting some archives.""" exit_mcode = 20 + class PathPermissionDenied(Error): + """Permission denied to {}.""" + exit_mcode = 21 + def __init__(self, path, create=False, exclusive=False, lock_wait=None, lock=True, append_only=False, storage_quota=None, check_segment_magic=True, make_parent_dirs=False): @@ -261,13 +265,23 @@ class Repository: st = os.stat(path) except FileNotFoundError: pass # nothing there! + except PermissionError: + raise self.PathPermissionDenied(path) from None else: # there is something already there! if self.is_repository(path): raise self.AlreadyExists(path) - if not stat.S_ISDIR(st.st_mode) or os.listdir(path): + if not stat.S_ISDIR(st.st_mode): raise self.PathAlreadyExists(path) - # an empty directory is acceptable for us. + try: + files = os.listdir(path) + except PermissionError: + raise self.PathPermissionDenied(path) from None + else: + if files: # a dir, but not empty + raise self.PathAlreadyExists(path) + else: # an empty directory is acceptable for us. + pass while True: # Check all parent directories for Borg's repository README