Fixed failing hunks.
[rsync/rsync-patches.git] / osx-create-time.diff
1 This patch handles the creation time on OS X by putting it into an
2 extended attribute.  This is a modified version of a patch that was
3 provided by Wesley W. Terpstra.
4
5 To 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
13 @@ -52,29 +52,106 @@ ssize_t sys_llistxattr(const char *path,
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;
25 +       struct timespec date;
26 +};
27 +
28 +static ssize_t getCreationTime(const char *path, char *buf, size_t size)
29 +{
30 +       struct attrlist attrList;
31 +       struct CreationTime attrBuf;
32 +
33 +       if (buf == NULL)
34 +               return CRTIME_XATTR_LEN;
35 +       if (size < CRTIME_XATTR_LEN)
36 +               return -1; /* Doesn't happen with rsync code... */
37 +
38 +       memset(&attrList, 0, sizeof attrList);
39 +       attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
40 +       attrList.commonattr = ATTR_CMN_CRTIME;
41 +       if (getattrlist(path, &attrList, &attrBuf, sizeof attrBuf, FSOPT_NOFOLLOW) < 0)
42 +               return -1;
43 +
44 +       SIVAL(buf, 0, attrBuf.date.tv_sec);
45 +#if SIZEOF_TIME_T > 4
46 +       SIVAL(buf, 4, attrBuf.date.tv_sec >> 32);
47 +#else
48 +       SIVAL(buf, 4, 0);
49 +#endif
50 +       SIVAL(buf, 8, attrBuf.date.tv_nsec);
51 +
52 +       return CRTIME_XATTR_LEN;
53 +}
54 +
55 +static int setCreationTime(const char *path, const char *buf, size_t size)
56 +{
57 +       struct attrlist attrList;
58 +       struct timespec date;
59 +
60 +       if (size != CRTIME_XATTR_LEN)
61 +               return -1;
62 +
63 +       date.tv_sec = IVAL(buf, 0);
64 +#if SIZEOF_TIME_T > 4
65 +       date.tv_sec += (time_t)IVAL(buf, 4) << 32;
66 +#endif
67 +       date.tv_nsec = IVAL(buf, 8);
68 +
69 +       memset(&attrList, 0, sizeof attrList);
70 +       attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
71 +       attrList.commonattr = ATTR_CMN_CRTIME;
72 +       return setattrlist(path, &attrList, &date, sizeof date, FSOPT_NOFOLLOW);
73 +}
74 +
75  ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
76  {
77 +       if (IS_CRTIME(name))
78 +               return getCreationTime(path, value, size);
79         return getxattr(path, name, value, size, 0, XATTR_NOFOLLOW);
80  }
81  
82  ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
83  {
84 +       /* XXX Figure out how to get creation date from an open filedes? */
85         return fgetxattr(filedes, name, value, size, 0, 0);
86  }
87  
88  int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
89  {
90 +       if (IS_CRTIME(name))
91 +               return setCreationTime(path, value, size);
92         return setxattr(path, name, value, size, 0, XATTR_NOFOLLOW);
93  }
94  
95  int sys_lremovexattr(const char *path, const char *name)
96  {
97 +       /* Every file on hfs+ has this; you can't remove it... */
98 +       if (IS_CRTIME(name))
99 +               return 0;
100         return removexattr(path, name, XATTR_NOFOLLOW);
101  }
102  
103  ssize_t sys_llistxattr(const char *path, char *list, size_t size)
104  {
105 -       return listxattr(path, list, size, XATTR_NOFOLLOW);
106 +       ssize_t ret = listxattr(path, list, size, XATTR_NOFOLLOW);
107 +       if (ret < 0)
108 +               return ret;
109 +       ret += sizeof CRTIME_XATTR;
110 +       if (list) {
111 +               if ((size_t)ret > size) {
112 +                       errno = ERANGE;
113 +                       return -1;
114 +               }
115 +               memcpy(list + ret - sizeof CRTIME_XATTR, CRTIME_XATTR, sizeof CRTIME_XATTR);
116 +       }
117 +       return ret;
118  }
119  
120  #elif HAVE_FREEBSD_XATTRS