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(&copyfile_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, &current_stat_info, &current_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(&copyfile_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(&copyfile_list);
174+#endif
175+
176   base64_init ();
177   name_gather ();
178 
179@@ -195,6 +214,28 @@
180     }
181   while (!all_names_found (&current_stat_info));
182 
183+#ifdef __APPLE__
184+      LIST_FOREACH(cle, &copyfile_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