Fixed 2 failing hunks.
[rsync/rsync-patches.git] / osx-create-time.diff
CommitLineData
55175a2c
WD
1This patch handles the creation time on OS X by putting it into an
2extended attribute. This is a modified version of a patch that was
3provided by Wesley W. Terpstra.
4
5To use this patch, run these commands for a successful build:
6
7 patch -p1 <patches/osx-create-time.diff
8 ./configure (optional if already run)
9 make
10
11--- old/lib/sysxattrs.c
12+++ new/lib/sysxattrs.c
42d12f3d 13@@ -52,29 +52,118 @@ ssize_t sys_llistxattr(const char *path,
55175a2c
WD
14
15 #elif HAVE_OSX_XATTRS
16
17+#include <sys/attr.h>
18+
19+#define CRTIME_XATTR "com.apple.crtime96"
20+#define IS_CRTIME(name) (*(name) == *CRTIME_XATTR && strcmp(name, CRTIME_XATTR) == 0)
21+#define CRTIME_XATTR_LEN (8+4)
22+
23+struct CreationTime {
24+ unsigned long length;
42d12f3d 25+ struct timespec crtime;
55175a2c
WD
26+};
27+
42d12f3d 28+static struct timespec *getCreationTime(const char *path)
55175a2c 29+{
42d12f3d 30+ static struct CreationTime attrBuf;
55175a2c 31+ struct attrlist attrList;
42d12f3d
WD
32+
33+ memset(&attrList, 0, sizeof attrList);
34+ attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
35+ attrList.commonattr = ATTR_CMN_CRTIME;
36+ if (getattrlist(path, &attrList, &attrBuf, sizeof attrBuf, FSOPT_NOFOLLOW) < 0)
37+ return NULL;
38+ return &attrBuf.crtime;
39+}
40+
41+static ssize_t get_crtime_xattr(const char *path, char *buf, size_t size)
42+{
43+ struct timespec *crtime_p;
55175a2c
WD
44+
45+ if (buf == NULL)
46+ return CRTIME_XATTR_LEN;
47+ if (size < CRTIME_XATTR_LEN)
48+ return -1; /* Doesn't happen with rsync code... */
49+
42d12f3d 50+ if ((crtime_p = getCreationTime(path)) == NULL)
55175a2c
WD
51+ return -1;
52+
42d12f3d 53+ SIVAL(buf, 0, crtime_p->tv_sec);
55175a2c 54+#if SIZEOF_TIME_T > 4
42d12f3d 55+ SIVAL(buf, 4, crtime_p->tv_sec >> 32);
55175a2c
WD
56+#else
57+ SIVAL(buf, 4, 0);
58+#endif
42d12f3d 59+ SIVAL(buf, 8, crtime_p->tv_nsec);
55175a2c
WD
60+
61+ return CRTIME_XATTR_LEN;
62+}
63+
42d12f3d 64+static int set_crtime_xattr(const char *path, const char *buf, size_t size)
55175a2c
WD
65+{
66+ struct attrlist attrList;
42d12f3d 67+ struct timespec crtime;
55175a2c
WD
68+
69+ if (size != CRTIME_XATTR_LEN)
70+ return -1;
71+
42d12f3d 72+ crtime.tv_sec = IVAL(buf, 0);
55175a2c 73+#if SIZEOF_TIME_T > 4
42d12f3d 74+ crtime.tv_sec += (time_t)IVAL(buf, 4) << 32;
55175a2c 75+#endif
42d12f3d 76+ crtime.tv_nsec = IVAL(buf, 8);
55175a2c
WD
77+
78+ memset(&attrList, 0, sizeof attrList);
79+ attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
80+ attrList.commonattr = ATTR_CMN_CRTIME;
42d12f3d 81+ return setattrlist(path, &attrList, &crtime, sizeof crtime, FSOPT_NOFOLLOW);
55175a2c
WD
82+}
83+
84 ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
85 {
86+ if (IS_CRTIME(name))
42d12f3d 87+ return get_crtime_xattr(path, value, size);
55175a2c
WD
88 return getxattr(path, name, value, size, 0, XATTR_NOFOLLOW);
89 }
90
91 ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
92 {
42d12f3d 93+ /* XXX Figure out how to get creation time from an open filedes? */
55175a2c
WD
94 return fgetxattr(filedes, name, value, size, 0, 0);
95 }
96
97 int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
98 {
99+ if (IS_CRTIME(name))
42d12f3d 100+ return set_crtime_xattr(path, value, size);
55175a2c
WD
101 return setxattr(path, name, value, size, 0, XATTR_NOFOLLOW);
102 }
103
104 int sys_lremovexattr(const char *path, const char *name)
105 {
106+ /* Every file on hfs+ has this; you can't remove it... */
107+ if (IS_CRTIME(name))
108+ return 0;
109 return removexattr(path, name, XATTR_NOFOLLOW);
110 }
111
112 ssize_t sys_llistxattr(const char *path, char *list, size_t size)
113 {
114- return listxattr(path, list, size, XATTR_NOFOLLOW);
115+ ssize_t ret = listxattr(path, list, size, XATTR_NOFOLLOW);
116+ if (ret < 0)
117+ return ret;
42d12f3d
WD
118+ if (getCreationTime(path) != NULL) {
119+ ret += sizeof CRTIME_XATTR;
120+ if (list) {
121+ if ((size_t)ret > size) {
122+ errno = ERANGE;
123+ return -1;
124+ }
125+ memcpy(list + ret - sizeof CRTIME_XATTR,
126+ CRTIME_XATTR, sizeof CRTIME_XATTR);
55175a2c 127+ }
55175a2c
WD
128+ }
129+ return ret;
130 }
131
132 #elif HAVE_FREEBSD_XATTRS