]> arthur.barton.de Git - bup.git/blobdiff - lib/bup/metadata.py
metadata.py: be careful with the umask() when restoring symlinks.
[bup.git] / lib / bup / metadata.py
index 8b50a803f4eb56f6c025be985f2869f82af50597..6dae38b83bc08404b5952ce87e2d5c85c150ecb8 100644 (file)
@@ -259,7 +259,8 @@ class Metadata:
                 os.unlink(path)
 
         if stat.S_ISREG(self.mode):
-            os.mknod(path, 0600 | stat.S_IFREG)
+            fd = os.open(path, os.O_CREAT|os.O_WRONLY|os.O_EXCL, 0600)
+            os.close(fd)
         elif stat.S_ISDIR(self.mode):
             os.mkdir(path, 0700)
         elif stat.S_ISCHR(self.mode):
@@ -270,7 +271,14 @@ class Metadata:
             os.mknod(path, 0600 | stat.S_IFIFO)
         elif stat.S_ISLNK(self.mode):
             if self.symlink_target and create_symlinks:
-                os.symlink(self.symlink_target, path)
+                # 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 & 0777) ^ 0777)
+                try:
+                    os.symlink(self.symlink_target, path)
+                finally:
+                    os.umask(oldumask)
         # FIXME: S_ISDOOR, S_IFMPB, S_IFCMP, S_IFNWK, ... see stat(2).
         # Otherwise, do nothing.
 
@@ -535,7 +543,7 @@ class Metadata:
         self.posix1e_acl_default = None
 
     def write(self, port, include_path=True):
-        records = [(_rec_tag_path, self._encode_path())] if include_path else []
+        records = include_path and [(_rec_tag_path, self._encode_path())] or []
         records.extend([(_rec_tag_common, self._encode_common()),
                         (_rec_tag_symlink_target, self._encode_symlink_target()),
                         (_rec_tag_posix1e_acl, self._encode_posix1e_acl()),
@@ -603,7 +611,7 @@ class Metadata:
 def from_path(path, statinfo=None, archive_path=None, save_symlinks=True):
     result = Metadata()
     result.path = archive_path
-    st = statinfo if statinfo else lstat(path)
+    st = statinfo or lstat(path)
     result._add_common(path, st)
     if save_symlinks:
         result._add_symlink_target(path, st)