]> Dogcows Code - chaz/tar/blobdiff - src/create.c
Support for POSIX ACLs
[chaz/tar] / src / create.c
index 9839e1fdc81a2d0e5a4a08e978c96f3540fa6566..37a58089d6ffcfb6385e5d5c7384e1b9f9765f18 100644 (file)
@@ -1,7 +1,8 @@
 /* Create a tar archive.
 
    Copyright (C) 1985, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
-   2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+   2003, 2004, 2005, 2006, 2007, 2009, 2010, 2012
+   Free Software Foundation, Inc.
 
    Written by John Gilmore, on 1985-08-25.
 
@@ -785,9 +786,9 @@ start_header (struct tar_stat_info *st)
        . . . . . . . . .   9 = Omron UNIOS-B 4.3BSD 1.60Beta
 
             . = works
-            # = ``impossible file type''
+            # = "impossible file type"
 
-     The following mask for old archive removes the `#'s in column 4
+     The following mask for old archive removes the '#'s in column 4
      above, thus making GNU tar both a universal donor and a universal
      acceptor for Paul's test.  */
 
@@ -943,6 +944,28 @@ start_header (struct tar_stat_info *st)
       GNAME_TO_CHARS (st->gname, header->header.gname);
     }
 
+  if (archive_format == POSIX_FORMAT)
+    {
+      if (acls_option > 0)
+        {
+          if (st->acls_a_ptr)
+            xheader_store ("SCHILY.acl.access", st, NULL);
+          if (st->acls_d_ptr)
+            xheader_store ("SCHILY.acl.default", st, NULL);
+        }
+      if (xattrs_option > 0)
+        {
+          size_t scan_xattr = 0;
+          struct xattr_array *xattr_map = st->xattr_map;
+
+          while (scan_xattr < st->xattr_map_size)
+            {
+              xheader_store (xattr_map[scan_xattr].xkey, st, &scan_xattr);
+              ++scan_xattr;
+            }
+        }
+    }
+
   return header;
 }
 
@@ -1051,7 +1074,7 @@ dump_regular_file (int fd, struct tar_stat_info *st)
            memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
        }
 
-      count = (fd <= 0) ? bufsize : safe_read (fd, blk->buffer, bufsize);
+      count = (fd <= 0) ? bufsize : blocking_read (fd, blk->buffer, bufsize);
       if (count == SAFE_READ_ERROR)
        {
          read_diag_details (st->orig_file_name,
@@ -1718,6 +1741,9 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
       bool ok;
       struct stat final_stat;
 
+      xattrs_acls_get (parentfd, name, st, 0, !is_dir);
+      xattrs_xattrs_get (parentfd, name, st, fd);
+
       if (is_dir)
        {
          const char *tag_file_name;
@@ -1836,6 +1862,8 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
       if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
        write_long_link (st);
 
+      xattrs_xattrs_get (parentfd, name, st, 0);
+
       block_ordinal = current_block_ordinal ();
       st->stat.st_size = 0;    /* force 0 size on symlink */
       header = start_header (st);
@@ -1854,11 +1882,23 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
     }
 #endif
   else if (S_ISCHR (st->stat.st_mode))
-    type = CHRTYPE;
+    {
+      type = CHRTYPE;
+      xattrs_acls_get (parentfd, name, st, 0, true);
+      xattrs_xattrs_get (parentfd, name, st, 0);
+    }
   else if (S_ISBLK (st->stat.st_mode))
-    type = BLKTYPE;
+    {
+      type = BLKTYPE;
+      xattrs_acls_get (parentfd, name, st, 0, true);
+      xattrs_xattrs_get (parentfd, name, st, 0);
+    }
   else if (S_ISFIFO (st->stat.st_mode))
-    type = FIFOTYPE;
+    {
+      type = FIFOTYPE;
+      xattrs_acls_get (parentfd, name, st, 0, true);
+      xattrs_xattrs_get (parentfd, name, st, 0);
+    }
   else if (S_ISSOCK (st->stat.st_mode))
     {
       WARNOPT (WARN_FILE_IGNORED,
This page took 0.022947 seconds and 4 git commands to generate.