1--- src/buffer.c.orig 2004-12-21 07:09:24.000000000 -0800 2+++ src/buffer.c 2008-03-03 19:49:46.000000000 -0800 3@@ -438,6 +438,41 @@ 4 record_end = record_start + blocking_factor; 5 } 6 7+#if HAVE_QUARANTINE 8+void 9+init_qtn(const char *file_name) 10+{ 11+ int fd; 12+ 13+ if (strcmp(file_name, "-") == 0) 14+ return; 15+ 16+ if ((fd = open(file_name, O_RDONLY)) < 0) 17+ return; 18+ 19+ if ((archive_qtn_file = qtn_file_alloc()) != NULL) { 20+ if (qtn_file_init_with_fd(archive_qtn_file, fd) != 0) { 21+ qtn_file_free(archive_qtn_file); 22+ archive_qtn_file = NULL; 23+ } 24+ } 25+ 26+ close(fd); 27+} 28+ 29+void 30+finish_qtn(void) 31+{ 32+ if (archive_qtn_file != NULL) { 33+ qtn_file_free(archive_qtn_file); 34+ archive_qtn_file = NULL; 35+ } 36+} 37+#else 38+void init_qtn(const char *file_name) {} 39+void finish_qtn(void) {} 40+#endif 41+ 42 /* Open an archive file. The argument specifies whether we are 43 reading or writing, or both. */ 44 static void 45@@ -571,6 +606,7 @@ 46 sys_detect_dev_null_output (); 47 sys_save_archive_dev_ino (); 48 SET_BINARY_MODE (archive); 49+ init_qtn(archive_name_array[0]); 50 51 switch (wanted_access) 52 { 53@@ -864,6 +900,8 @@ 54 free (real_s_name); 55 free (record_buffer[0]); 56 free (record_buffer[1]); 57+ 58+ finish_qtn(); 59 } 60 61 /* Called to initialize the global volume number. */ 62--- src/common.h.orig 2007-06-08 01:14:42.000000000 -0700 63+++ src/common.h 2014-02-04 16:28:35.000000000 -0800 64@@ -20,6 +20,17 @@ 65 /* Declare the GNU tar archive format. */ 66 #include "tar.h" 67 68+#include <TargetConditionals.h> 69+#if defined(__has_include) && __has_include(<quarantine.h>) 70+#define HAVE_QUARANTINE 1 71+#else 72+#define HAVE_QUARANTINE 0 73+#endif 74+ 75+#if HAVE_QUARANTINE 76+#include <quarantine.h> 77+#endif 78+ 79 /* The checksum field is filled with this while the checksum is computed. */ 80 #define CHKBLANKS " " /* 8 blanks, no null */ 81 82@@ -302,6 +313,9 @@ 83 84 /* File descriptor for archive file. */ 85 GLOBAL int archive; 86+#if HAVE_QUARANTINE 87+GLOBAL qtn_file_t archive_qtn_file; 88+#endif 89 90 /* Nonzero when outputting to /dev/null. */ 91 GLOBAL bool dev_null_output; 92--- src/extract.c.orig 2004-12-21 01:55:12.000000000 -0800 93+++ src/extract.c 2008-03-03 19:51:38.000000000 -0800 94@@ -413,6 +413,51 @@ 95 quotearg_colon (dir))); 96 } 97 98+#if HAVE_QUARANTINE 99+void 100+apply_qtn(int fd) 101+{ 102+ int stat_ok; 103+ struct stat sb; 104+ int qstatus; 105+ 106+ if (archive_qtn_file != NULL) { 107+ stat_ok = (fstat(fd, &sb) == 0); 108+ 109+ if (stat_ok) fchmod(fd, sb.st_mode | S_IWUSR); 110+ qstatus = qtn_file_apply_to_fd(archive_qtn_file, fd); 111+ if (stat_ok) fchmod(fd, sb.st_mode); 112+ 113+ if (qstatus) { 114+ warnx("qtn_file_apply_to_fd: %s", qtn_error(qstatus)); 115+ } 116+ } 117+} 118+ 119+void 120+apply_qtn_to_path(char *path) 121+{ 122+ int stat_ok; 123+ struct stat sb; 124+ int qstatus; 125+ 126+ if (archive_qtn_file != NULL) { 127+ stat_ok = (stat(path, &sb) == 0); 128+ 129+ if (stat_ok) chmod(path, sb.st_mode | S_IWUSR); 130+ qstatus = qtn_file_apply_to_path(archive_qtn_file, path); 131+ if (stat_ok) chmod(path, sb.st_mode); 132+ 133+ if (qstatus) { 134+ warnx("qtn_file_apply_to_path: %s", qtn_error(qstatus)); 135+ } 136+ } 137+} 138+#else 139+void apply_qtn(int fd) {} 140+void apply_qtn_to_path(char *path) {} 141+#endif 142+ 143 /* After a file/link/directory creation has failed, see if 144 it's because some required directory was not present, and if so, 145 create all required directories. Return non-zero if a directory 146@@ -452,6 +497,8 @@ 147 148 if (status == 0) 149 { 150+ apply_qtn_to_path(file_name); 151+ 152 /* Create a struct delayed_set_stat even if 153 invert_permissions is zero, because 154 repair_delayed_set_stat may need to update the struct. */ 155@@ -698,6 +745,7 @@ 156 || old_files_option == DEFAULT_OLD_FILES 157 || old_files_option == OVERWRITE_OLD_FILES) 158 { 159+ apply_qtn_to_path(file_name); 160 if (status == 0) 161 delay_set_stat (file_name, ¤t_stat_info, 162 ((mode ^ current_stat_info.stat.st_mode) 163@@ -807,6 +854,7 @@ 164 } 165 #endif /* __APPLE__ */ 166 167+ apply_qtn(fd); 168 mv_begin (¤t_stat_info); 169 if (current_stat_info.is_sparse) 170 sparse_extract_file (fd, ¤t_stat_info, &size); 171--- src/list.c.orig 2008-07-11 19:37:25.000000000 -0700 172+++ src/list.c 2008-07-11 19:39:27.000000000 -0700 173@@ -230,6 +230,9 @@ 174 rename(cle->tmp, cle->src); 175 } 176 177+ /* 5781559: Make sure EAs don't destroy overriding quarantine information. */ 178+ apply_qtn_to_path(cle->dst); 179+ 180 free(cle->tmp); 181 free(cle->dst); 182 free(cle->src); 183