From: Wayne Davison Date: Sun, 14 Oct 2007 23:28:05 +0000 (+0000) Subject: My version of Wesley W. Terpstra's patch. X-Git-Url: https://mattmccutchen.net/rsync/rsync-patches.git/commitdiff_plain/55175a2c2ae78730167bed502a416fa37c645358 My version of Wesley W. Terpstra's patch. --- diff --git a/osx-create-time.diff b/osx-create-time.diff new file mode 100644 index 0000000..c490ef8 --- /dev/null +++ b/osx-create-time.diff @@ -0,0 +1,120 @@ +This patch handles the creation time on OS X by putting it into an +extended attribute. This is a modified version of a patch that was +provided by Wesley W. Terpstra. + +To use this patch, run these commands for a successful build: + + patch -p1 ++ ++#define CRTIME_XATTR "com.apple.crtime96" ++#define IS_CRTIME(name) (*(name) == *CRTIME_XATTR && strcmp(name, CRTIME_XATTR) == 0) ++#define CRTIME_XATTR_LEN (8+4) ++ ++struct CreationTime { ++ unsigned long length; ++ struct timespec date; ++}; ++ ++static ssize_t getCreationTime(const char *path, char *buf, size_t size) ++{ ++ struct attrlist attrList; ++ struct CreationTime attrBuf; ++ ++ if (buf == NULL) ++ return CRTIME_XATTR_LEN; ++ if (size < CRTIME_XATTR_LEN) ++ return -1; /* Doesn't happen with rsync code... */ ++ ++ memset(&attrList, 0, sizeof attrList); ++ attrList.bitmapcount = ATTR_BIT_MAP_COUNT; ++ attrList.commonattr = ATTR_CMN_CRTIME; ++ if (getattrlist(path, &attrList, &attrBuf, sizeof attrBuf, XATTR_NOFOLLOW) < 0) ++ return -1; ++ ++ SIVAL(buf, 0, attrBuf.date.tv_sec); ++#if SIZEOF_TIME_T > 4 ++ SIVAL(buf, 4, attrBuf.date.tv_sec >> 32); ++#else ++ SIVAL(buf, 4, 0); ++#endif ++ SIVAL(buf, 8, attrBuf.date.tv_nsec); ++ ++ return CRTIME_XATTR_LEN; ++} ++ ++static int setCreationTime(const char *path, const char *buf, size_t size) ++{ ++ struct attrlist attrList; ++ struct timespec date; ++ ++ if (size != CRTIME_XATTR_LEN) ++ return -1; ++ ++ date.tv_sec = IVAL(buf, 0); ++#if SIZEOF_TIME_T > 4 ++ date.tv_sec += (time_t)IVAL(buf, 4) << 32; ++#endif ++ date.tv_nsec = IVAL(buf, 8); ++ ++ memset(&attrList, 0, sizeof attrList); ++ attrList.bitmapcount = ATTR_BIT_MAP_COUNT; ++ attrList.commonattr = ATTR_CMN_CRTIME; ++ return setattrlist(path, &attrList, &date, sizeof date, XATTR_NOFOLLOW); ++} ++ + ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size) + { ++ if (IS_CRTIME(name)) ++ return getCreationTime(path, value, size); + return getxattr(path, name, value, size, 0, XATTR_NOFOLLOW); + } + + ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size) + { ++ /* XXX Figure out how to get creation date from an open filedes? */ + return fgetxattr(filedes, name, value, size, 0, 0); + } + + int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size) + { ++ if (IS_CRTIME(name)) ++ return setCreationTime(path, value, size); + return setxattr(path, name, value, size, 0, XATTR_NOFOLLOW); + } + + int sys_lremovexattr(const char *path, const char *name) + { ++ /* Every file on hfs+ has this; you can't remove it... */ ++ if (IS_CRTIME(name)) ++ return 0; + return removexattr(path, name, XATTR_NOFOLLOW); + } + + ssize_t sys_llistxattr(const char *path, char *list, size_t size) + { +- return listxattr(path, list, size, XATTR_NOFOLLOW); ++ ssize_t ret = listxattr(path, list, size, XATTR_NOFOLLOW); ++ if (ret < 0) ++ return ret; ++ ret += sizeof CRTIME_XATTR; ++ if (list) { ++ if ((size_t)ret > size) { ++ errno = ERANGE; ++ return -1; ++ } ++ memcpy(list + ret - sizeof CRTIME_XATTR, CRTIME_XATTR, sizeof CRTIME_XATTR); ++ } ++ return ret; + } + + #elif HAVE_FREEBSD_XATTRS