quarantine.diff   [plain text]


--- src/buffer.c.orig	2004-12-21 07:09:24.000000000 -0800
+++ src/buffer.c	2008-03-03 19:49:46.000000000 -0800
@@ -438,6 +438,41 @@
   record_end = record_start + blocking_factor;
 }
 
+#if HAVE_QUARANTINE
+void
+init_qtn(const char *file_name)
+{
+	int fd;
+
+	if (strcmp(file_name, "-") == 0)
+		return;
+
+	if ((fd = open(file_name, O_RDONLY)) < 0)
+		return;
+
+	if ((archive_qtn_file = qtn_file_alloc()) != NULL) {
+		if (qtn_file_init_with_fd(archive_qtn_file, fd) != 0) {
+			qtn_file_free(archive_qtn_file);
+			archive_qtn_file = NULL;
+		}
+	}
+
+	close(fd);
+}
+
+void
+finish_qtn(void)
+{
+	if (archive_qtn_file != NULL) {
+		qtn_file_free(archive_qtn_file);
+		archive_qtn_file = NULL;
+	}
+}
+#else
+void init_qtn(const char *file_name) {}
+void finish_qtn(void) {}
+#endif
+
 /* Open an archive file.  The argument specifies whether we are
    reading or writing, or both.  */
 static void
@@ -571,6 +606,7 @@
   sys_detect_dev_null_output ();
   sys_save_archive_dev_ino ();
   SET_BINARY_MODE (archive);
+  init_qtn(archive_name_array[0]);
 
   switch (wanted_access)
     {
@@ -864,6 +900,8 @@
     free (real_s_name);
   free (record_buffer[0]);
   free (record_buffer[1]);
+
+  finish_qtn();
 }
 
 /* Called to initialize the global volume number.  */
--- src/common.h.orig	2004-12-21 06:31:58.000000000 -0800
+++ src/common.h	2008-03-03 18:42:03.000000000 -0800
@@ -20,6 +20,13 @@
 /* Declare the GNU tar archive format.  */
 #include "tar.h"
 
+#include <TargetConditionals.h>
+#define HAVE_QUARANTINE (!TARGET_OS_EMBEDDED)
+
+#if HAVE_QUARANTINE
+#include <quarantine.h>
+#endif
+
 /* The checksum field is filled with this while the checksum is computed.  */
 #define CHKBLANKS	"        "	/* 8 blanks, no null */
 
@@ -302,6 +309,9 @@
 
 /* File descriptor for archive file.  */
 GLOBAL int archive;
+#if HAVE_QUARANTINE
+GLOBAL qtn_file_t archive_qtn_file;
+#endif
 
 /* Nonzero when outputting to /dev/null.  */
 GLOBAL bool dev_null_output;
--- src/extract.c.orig	2004-12-21 01:55:12.000000000 -0800
+++ src/extract.c	2008-03-03 19:51:38.000000000 -0800
@@ -413,6 +413,51 @@
 	  quotearg_colon (dir)));
 }
 
+#if HAVE_QUARANTINE
+void
+apply_qtn(int fd)
+{
+	int stat_ok;
+	struct stat sb;
+	int qstatus;
+
+	if (archive_qtn_file != NULL) {
+		stat_ok = (fstat(fd, &sb) == 0);
+
+		if (stat_ok) fchmod(fd, sb.st_mode | S_IWUSR);
+		qstatus = qtn_file_apply_to_fd(archive_qtn_file, fd);
+		if (stat_ok) fchmod(fd, sb.st_mode);
+
+		if (qstatus) {
+			warnx("qtn_file_apply_to_fd: %s", qtn_error(qstatus));
+		}
+	}
+}
+
+void
+apply_qtn_to_path(char *path)
+{
+	int stat_ok;
+	struct stat sb;
+	int qstatus;
+
+	if (archive_qtn_file != NULL) {
+		stat_ok = (stat(path, &sb) == 0);
+
+		if (stat_ok) chmod(path, sb.st_mode | S_IWUSR);
+		qstatus = qtn_file_apply_to_path(archive_qtn_file, path);
+		if (stat_ok) chmod(path, sb.st_mode);
+
+		if (qstatus) {
+			warnx("qtn_file_apply_to_path: %s", qtn_error(qstatus));
+		}
+	}
+}
+#else
+void apply_qtn(int fd) {}
+void apply_qtn_to_path(char *path) {}
+#endif
+
 /* After a file/link/directory creation has failed, see if
    it's because some required directory was not present, and if so,
    create all required directories.  Return non-zero if a directory
@@ -452,6 +497,8 @@
 
       if (status == 0)
 	{
+	  apply_qtn_to_path(file_name);
+
 	  /* Create a struct delayed_set_stat even if
 	     invert_permissions is zero, because
 	     repair_delayed_set_stat may need to update the struct.  */
@@ -698,6 +745,7 @@
       || old_files_option == DEFAULT_OLD_FILES
       || old_files_option == OVERWRITE_OLD_FILES)
     {
+      apply_qtn_to_path(file_name);
       if (status == 0)
 	delay_set_stat (file_name, &current_stat_info,
 			((mode ^ current_stat_info.stat.st_mode)
@@ -807,6 +854,7 @@
   }
 #endif /* __APPLE__ */
 
+  apply_qtn(fd);
   mv_begin (&current_stat_info);
   if (current_stat_info.is_sparse)
     sparse_extract_file (fd, &current_stat_info, &size);
--- src/list.c.orig	2008-07-11 19:37:25.000000000 -0700
+++ src/list.c	2008-07-11 19:39:27.000000000 -0700
@@ -230,6 +230,9 @@
 	      rename(cle->tmp, cle->src);
 	    }
 
+	  /* 5781559: Make sure EAs don't destroy overriding quarantine information. */
+	  apply_qtn_to_path(cle->dst);
+
 	  free(cle->tmp);
 	  free(cle->dst);
 	  free(cle->src);