1--- src/create.c.orig 2007-06-01 03:17:10.000000000 -0700 2+++ src/create.c 2008-08-18 19:10:08.000000000 -0700 3@@ -26,6 +26,15 @@ 4 #include "common.h" 5 #include <hash.h> 6 7+#ifdef __APPLE__ 8+#include <copyfile.h> 9+#include <libgen.h> 10+#include <paths.h> 11+ 12+int copyfile_on = 0; 13+char *copyfile_fname = NULL; 14+#endif 15+ 16 struct link 17 { 18 dev_t dev; 19@@ -1485,9 +1494,18 @@ 20 if (interactive_option && !confirm ("add", p)) 21 return; 22 23+ if (copyfile_on) 24+ { 25+ assign_string (&st->orig_file_name, copyfile_fname); 26+ assign_string (&st->file_name, 27+ safer_name_suffix (copyfile_fname, false, absolute_names_option)); 28+ } 29+ else 30+ { 31 assign_string (&st->orig_file_name, p); 32 assign_string (&st->file_name, 33 safer_name_suffix (p, false, absolute_names_option)); 34+ } 35 36 transform_name (&st->file_name); 37 38@@ -1777,6 +1795,40 @@ 39 dump_file (const char *p, int top_level, dev_t parent_device) 40 { 41 struct tar_stat_info st; 42+ 43+#ifdef __APPLE__ 44+ if (!getenv(COPYFILE_DISABLE_VAR) && !strncmp(basename(p), "._", 2)) { 45+ return; 46+ } 47+ 48+ if (!getenv(COPYFILE_DISABLE_VAR) && strncmp(basename(p), "._", 2)) 49+ { 50+ char *tmpdir = getenv("TMPDIR"), *md_p; 51+ asprintf(&md_p, "%s/tar.md.XXXXXXXX", tmpdir ? tmpdir : _PATH_TMP); 52+ asprintf(©file_fname, "%s/._%s", dirname(p), basename(p)); 53+ 54+ if (copyfile(p, NULL, 0, COPYFILE_CHECK | COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR)) 55+ { 56+ copyfile_on = 1; 57+ tar_stat_init (&st); 58+ 59+ if(mktemp(md_p)) 60+ { 61+ if (copyfile(p, md_p, 0, COPYFILE_PACK | COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR) == 0) 62+ dump_file0 (&st, md_p, top_level, parent_device); 63+ else 64+ WARN((0, 0, "copyfile pack (%s) failed: %s", p, strerror(errno))); 65+ } 66+ 67+ tar_stat_destroy (&st); 68+ unlink(md_p); 69+ free(copyfile_fname); 70+ copyfile_on = 0; 71+ } 72+ free(md_p); 73+ } 74+#endif 75+ 76 tar_stat_init (&st); 77 dump_file0 (&st, p, top_level, parent_device); 78 if (listed_incremental_option) 79--- src/extract.c.orig 2007-06-08 01:14:42.000000000 -0700 80+++ src/extract.c 2008-08-18 19:10:08.000000000 -0700 81@@ -27,6 +27,19 @@ 82 83 #include "common.h" 84 85+#ifdef __APPLE__ 86+#include <libgen.h> 87+#include <sys/queue.h> 88+#include <copyfile.h> 89+struct copyfile_list_entry_t { 90+ char *src; 91+ char *dst; 92+ char *tmp; 93+ LIST_ENTRY(copyfile_list_entry_t) link; 94+} *cle; 95+extern LIST_HEAD(copyfile_list_t, copyfile_list_entry_t) copyfile_list; 96+#endif 97+ 98 static bool we_are_root; /* true if our effective uid == 0 */ 99 static mode_t newdir_umask; /* umask when creating new directories */ 100 static mode_t current_umask; /* current umask (which is set to 0 if -p) */ 101@@ -1200,6 +1213,9 @@ 102 { 103 char typeflag; 104 tar_extractor_t fun; 105+#ifdef __APPLE__ 106+ struct copyfile_list_entry_t *cle = NULL; 107+#endif 108 109 set_next_block_after (current_header); 110 decode_header (current_header, ¤t_stat_info, ¤t_format, 1); 111@@ -1240,7 +1256,31 @@ 112 113 if (prepare_to_extract (current_stat_info.file_name, typeflag, &fun)) 114 { 115- if (fun && (*fun) (current_stat_info.file_name, typeflag) 116+#ifdef __APPLE__ 117+ if (strncmp(basename(current_stat_info.file_name), "._", 2) == 0) { 118+ if ((cle = calloc(1, sizeof(struct copyfile_list_entry_t))) == NULL) 119+ goto err; 120+ if ((cle->src = strdup(current_stat_info.file_name)) == NULL) 121+ goto err; 122+ if (asprintf(&cle->tmp, "%s.XXX", current_stat_info.file_name) == -1) 123+ goto err; 124+ if (mktemp(cle->tmp) == NULL) 125+ goto err; 126+ if (asprintf(&cle->dst, "%s/%s", dirname(current_stat_info.file_name), basename(current_stat_info.file_name) + 2) != -1) 127+ LIST_INSERT_HEAD(©file_list, cle, link); 128+ else { 129+err: 130+ if (cle->src) free(cle->src); 131+ if (cle->dst) free(cle->dst); 132+ if (cle->tmp) free(cle->tmp); 133+ if (cle) { 134+ free(cle); 135+ cle = NULL; 136+ } 137+ } 138+ } 139+#endif 140+ if (fun && (*fun) (cle ? cle->tmp : current_stat_info.file_name, typeflag) 141 && backup_option) 142 undo_last_backup (); 143 } 144--- src/list.c.orig 2007-06-08 01:14:42.000000000 -0700 145+++ src/list.c 2008-08-18 19:10:08.000000000 -0700 146@@ -23,6 +23,19 @@ 147 #include <inttostr.h> 148 #include <quotearg.h> 149 150+#ifdef __APPLE__ 151+#include <copyfile.h> 152+#include <sys/param.h> 153+#include <sys/queue.h> 154+struct copyfile_list_entry_t { 155+ char *src; 156+ char *dst; 157+ char *tmp; 158+ LIST_ENTRY(copyfile_list_entry_t) link; 159+} *cle; 160+LIST_HEAD(copyfile_list_t, copyfile_list_entry_t) copyfile_list; 161+#endif 162+ 163 #include "common.h" 164 165 #define max(a, b) ((a) < (b) ? (b) : (a)) 166@@ -68,6 +81,12 @@ 167 enum read_header prev_status; 168 struct timespec mtime; 169 170+#ifdef __APPLE__ 171+ int disable_copyfile = (getenv(COPYFILE_DISABLE_VAR) != NULL); 172+ struct copyfile_list_entry_t *cle; 173+ LIST_INIT(©file_list); 174+#endif 175+ 176 base64_init (); 177 name_gather (); 178 179@@ -195,6 +214,28 @@ 180 } 181 while (!all_names_found (¤t_stat_info)); 182 183+#ifdef __APPLE__ 184+ LIST_FOREACH(cle, ©file_list, link) 185+ { 186+ if(!disable_copyfile && copyfile(cle->tmp, cle->dst, 0, COPYFILE_UNPACK | COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR) == 0) 187+ { 188+ unlink(cle->tmp); 189+ } 190+ else 191+ { 192+ if (!disable_copyfile) 193+ { 194+ WARN((0, 0, "copyfile unpack (%s) failed: %s", cle->dst, strerror(errno))); 195+ } 196+ rename(cle->tmp, cle->src); 197+ } 198+ 199+ free(cle->tmp); 200+ free(cle->dst); 201+ free(cle->src); 202+ } 203+#endif 204+ 205 close_archive (); 206 names_notfound (); /* print names not found */ 207 } 208--- lib/version-etc.c.orig 2008-08-18 19:17:17.000000000 -0700 209+++ lib/version-etc.c 2008-08-18 19:19:10.000000000 -0700 210@@ -74,6 +74,8 @@ 211 "), 212 stream); 213 214+ fputs (_("Modified to support extended attributes.\n"), stream); 215+ 216 switch (n_authors) 217 { 218 case 0: 219