[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Fwd: Subversion AppleDouble patch updated to 1.5.0

From: Karl Fogel <kfogel_at_red-bean.com>
Date: Fri, 08 Aug 2008 17:44:09 -0400

Steve Sisak <sgs_at_codewell.com> writes:
> With all the talk, of 1.6 features, it seems an opportune time to
> reopen an old discussion that I'd been holding off until 1.5 shipped.
>
> I'd still like to switch my repositories over from cvs to svn but am
> unable to do so until svn can round trip a Mac OS file without
> destroying it by deleting the resource fork, finder attributes, etc.
>
> Matt Slott at Ambrosia software has been maintaining a patch and
> resubmitting it every release. (See below)
>
> We had talked about reviewing it and getting it rolled into the trunk
> when 1.5 shipped, so I guess it's time for another poke. :-)

I think the current idea is that this problem will simply go away when
the "next generation" working copy library is done (see
https://svn.collab.net/repos/svn/trunk/notes/wc-ng-design). I don't
have a timetable for that, so I realize this is small comfort.

On http://www.ambrosiasw.com/~fprefect/subversion-appledouble.html, the
language is a little, well, tiresome:

   "This patch enables Subversion to manage HFS metadata and resource
    forks on MacOS X. It seems like a no-brainer to most Mac folks, but
    so far the Subversion community has been dismissive. With this
    patch, Subversion will automatically import, add, update, and
    checkout any metadata associated with the file into the property
    file:appledouble."

Dismissive? I don't recall specific threads, but not wanting to apply a
patch for technical reasons, and explaining those reasons clearly, is
not the same as being dismissive. It's kind of the opposite, really.
And I'll bet that's what happened here; it's hard to imagine any of the
maintainers being dismissive of such a patch, although there are plenty
of reasons why they might not want to apply it.

I took a look at the patch. There are a few stylistic nits ("if (1)"
comes to mind :-) ), but they're no big deal. Basically, the patch
seems pretty straightforward and like it does what it says it does. I'm
not a Mac developer myself, and do not feel competent to give a final
evaluation of the patch. (I also am not sure if/when the wc-ng work is
going to happen, though we're all on board with it in principle.)

A log message would help :-).

Because the patch is a bit hard to extract from the site, I'll insert it
at the bottom of this mail, for others to review.

> For reference, the patch works by storing Mac OS specific data in an
> property in the repository (which can be ignored by other platforms),
> and reconstituting it on checkout.
>
> Note that Leopard supports extended attributes on all files (yes,
> metadata is back in fovor), so we might consider saving all extended
> attributes as well on Leopard.
>
> See "xattr --help" for documentation (there is not currently a man page)
>
> For instance, Leopard stores FinderInfo (file type, creator, creation
> date, etc.) in the com.apple.FinderInfo extended attribute -- for
> example:
>
> MBP:~ sgs$ ls -l logs.zip
> -rw-r--r--@ 1 sgs 3000 175152 Feb 28 23:43 logs.zip
> MBP:~ sgs$ xattr logs.zip
> com.apple.FinderInfo
> MBP:~ sgs$ xattr -p com.apple.FinderInfo logs.zip
> pZIP?IC?
>
> Note that there is some overlap between the Leopard xattr's and Apple
> Double and that xattrs can be added at any time by Apple or 3rd party
> developers, so it may make sense to do things the "new" way and break
> up the AppleDouble property by defining xattr's for the the
> AppleDouble entryIDs defined in RFC 1740 where Apple hasn't done so
> already and store them as separate properties.
>
> (For instance, Leopard's com.apple.FinderInfo corresponds exactly to
> Entry ID 9 in AppleDouble)
>
> I assume this technique would apply equally to other platforms' unique
> extended attributes, where the client would interpret attributes
> appropriate to that platform and ignore the rest.
>
> While it might be a slightly better implementation by breaking the
> AppleDouble blob up into multiple properties, Matt's implementation
> seems forward compatible by simply breaking up the big property on a
> check-in.

And here's the patch (there doesn't appear to be any log message):

diff -ruN subversion-1.5.0/subversion/include/applefile.h subversion-appledouble-1.5.0/subversion/include/applefile.h
--- subversion-1.5.0/subversion/include/applefile.h 1969-12-31 19:00:00.000000000 -0500
+++ subversion-appledouble-1.5.0/subversion/include/applefile.h 2008-06-19 15:25:57.000000000 -0400
@@ -0,0 +1,348 @@
+/* applefile.h - Data structures used by AppleSingle/AppleDouble
+* file format
+*
+* Written by Lee Jones, 22-Oct-1993
+*
+* For definitive information, see "AppleSingle/AppleDouble
+* Formats for Foreign Files Developer's Note"; Apple Computer
+* Inc.; (c) 1990.
+*
+* Other details were added from:
+* Inside Macintosh [old version], volumes II to VI,
+* Apple include files supplied with Think C 5.0.1,
+* Microsoft MS-DOS Programmer's Reference, version 5, and
+* Microsoft C 6.00a's dos.h include file.
+*
+* I don't have ProDOS or AFP Server documentation so related
+* entries may be a bit skimpy.
+*
+* Edit history:
+*
+* when who why
+* --------- --- ------------------------------------------
+* 22-Oct-93 LMJ Pull together from Inside Macintosh,
+* Developer's Note, etc
+* 26-Oct-93 LMJ Finish writing first version and list
+* references
+* 06-Feb-94 EEF Very minor cleanup
+*/
+
+/* Following items define machine specific size (for porting). */
+
+typedef char xchar8; /* 8-bit field */
+typedef char schar8; /* signed 8-bit field */
+typedef unsigned char uchar8; /* unsigned 8-bit field */
+typedef short xint16; /* 16-bit field */
+typedef unsigned short uint16; /* unsigned 16-bit field */
+typedef long xint32; /* 32-bit field */
+typedef long sint32; /* signed 32-bit field */
+typedef unsigned long uint32; /* unsigned 32-bit field */
+
+/* REMINDER: the Motorola 680x0 is a big-endian architecture! */
+
+typedef uint32 OSType; /* 32 bit field */
+
+/* In the QuickDraw coordinate plane, each coordinate is
+* -32767..32767. Each point is at the intersection of a
+* horizontal grid line and a vertical grid line. Horizontal
+* coordinates increase from left to right. Vertical
+* coordinates increase from top to bottom. This is the way
+* both a TV screen and page of English text are scanned:
+* from top left to bottom right.
+*/
+
+struct Point /* spot in QuickDraw 2-D grid */
+{
+ xint16 v; /* vertical coordinate */
+ xint16 h; /* horizontal coordinate */
+}; /* Point */
+
+typedef struct Point Point;
+
+/* See older Inside Macintosh, Volume II page 84 or Volume IV
+* page 104.
+*/
+
+struct FInfo /* Finder information */
+{
+ OSType fdType; /* File type, 4 ASCII chars */
+ OSType fdCreator; /* File's creator, 4 ASCII chars */
+ uint16 fdFlags; /* Finder flag bits */
+ Point fdLocation; /* file's location in folder */
+ xint16 fdFldr; /* file 's folder (aka window) */
+}; /* FInfo */
+
+typedef struct FInfo FInfo;
+
+/*
+* Masks for finder flag bits (field fdFlags in struct
+* FInfo).
+*/
+
+#define F_fOnDesk 0x0001 /* file is on desktop (HFS only) */
+#define F_maskColor 0x000E /* color coding (3 bits) */
+/* 0x0010 /* reserved (System 7) */
+#define F_fSwitchLaunch 0x0020 /* reserved (System 7) */
+#define F_fShared 0x0040 /* appl available to multiple users */
+#define F_fNoINITs 0x0080 /* file contains no INIT resources */
+#define F_fBeenInited 0x0100 /* Finder has loaded bundle res. */
+/* 0x0200 /* reserved (System 7) */
+#define F_fCustomIcom 0x0400 /* file contains custom icon */
+#define F_fStationary 0x0800 /* file is a stationary pad */
+#define F_fNameLocked 0x1000 /* file can't be renamed by Finder */
+#define F_fHasBundle 0x2000 /* file has a bundle */
+#define F_fInvisible 0x4000 /* file's icon is invisible */
+#define F_fAlias 0x8000 /* file is an alias file (System 7) */
+
+/* See older Inside Macintosh, Volume IV, page 105.
+*/
+
+struct FXInfo /* Extended finder information */
+
+{
+ xint16 fdIconID; /* icon ID number */
+ xint16 fdUnused[3]; /* spare */
+ schar8 fdScript; /* scrip flag and code */
+ schar8 fdXFlags; /* reserved */
+ xint16 fdComment; /* comment ID number */
+ xint32 fdPutAway; /* home directory ID */
+}; /* FXInfo */
+
+typedef struct FXInfo FXInfo;
+
+/* Pieces used by AppleSingle & AppleDouble (defined later). */
+
+struct ASHeader /* header portion of AppleSingle */
+{
+ /* AppleSingle = 0x00051600; AppleDouble = 0x00051607 */
+ uint32 magicNum; /* internal file type tag */
+ uint32 versionNum; /* format version: 2 = 0x00020000 */
+ uchar8 filler[16]; /* filler, currently all bits 0 */
+ uint16 numEntries; /* number of entries which follow */
+}; /* ASHeader */
+
+typedef struct ASHeader ASHeader;
+
+struct ASEntry /* one AppleSingle entry descriptor */
+{
+ uint32 entryID; /* entry type: see list, 0 invalid */
+ uint32 entryOffset; /* offset, in octets, from beginning */
+ /* of file to this entry's data */
+ uint32 entryLength; /* length of data in octets */
+}; /* ASEntry */
+
+typedef struct ASEntry ASEntry;
+
+/* Apple reserves the range of entry IDs from 1 to 0x7FFFFFFF.
+* Entry ID 0 is invalid. The rest of the range is available
+* for applications to define their own entry types. "Apple does
+* not arbitrate the use of the rest of the range."
+*/
+
+#define AS_DATA 1 /* data fork */
+#define AS_RESOURCE 2 /* resource fork */
+#define AS_REALNAME 3 /* File's name on home file system */
+#define AS_COMMENT 4 /* standard Mac comment */
+#define AS_ICONBW 5 /* Mac black & white icon */
+#define AS_ICONCOLOR 6 /* Mac color icon */
+ /* 7 /* not used */
+#define AS_FILEDATES 8 /* file dates; create, modify, etc */
+#define AS_FINDERINFO 9 /* Mac Finder info & extended info */
+#define AS_MACINFO 10 /* Mac file info, attributes, etc */
+#define AS_PRODOSINFO 11 /* Pro-DOS file info, attrib., etc */
+#define AS_MSDOSINFO 12 /* MS-DOS file info, attributes, etc */
+#define AS_AFPNAME 13 /* Short name on AFP server */
+#define AS_AFPINFO 14 /* AFP file info, attrib., etc */
+
+#define AS_AFPDIRID 15 /* AFP directory ID */
+
+/* matrix of entry types and their usage:
+*
+* Macintosh Pro-DOS MS-DOS AFP server
+* --------- ------- ------ ----------
+* 1 AS_DATA xxx xxx xxx xxx
+* 2 AS_RESOURCE xxx xxx
+* 3 AS_REALNAME xxx xxx xxx xxx
+*
+* 4 AS_COMMENT xxx
+* 5 AS_ICONBW xxx
+* 6 AS_ICONCOLOR xxx
+*
+* 8 AS_FILEDATES xxx xxx xxx xxx
+* 9 AS_FINDERINFO xxx
+* 10 AS_MACINFO xxx
+*
+* 11 AS_PRODOSINFO xxx
+* 12 AS_MSDOSINFO xxx
+*
+* 13 AS_AFPNAME xxx
+* 14 AS_AFPINFO xxx
+* 15 AS_AFPDIRID xxx
+*/
+
+/* entry ID 1, data fork of file - arbitrary length octet string */
+
+/* entry ID 2, resource fork - arbitrary length opaque octet string;
+* as created and managed by Mac O.S. resoure manager
+*/
+
+/* entry ID 3, file's name as created on home file system - arbitrary
+* length octet string; usually short, printable ASCII
+*/
+
+/* entry ID 4, standard Macintosh comment - arbitrary length octet
+* string; printable ASCII, claimed 200 chars or less
+*/
+
+/* This is probably a simple duplicate of the 128 octet bitmap
+* stored as the 'ICON' resource or the icon element from an 'ICN#'
+* resource.
+*/
+
+struct ASIconBW /* entry ID 5, standard Mac black and white icon */
+{
+ uint32 bitrow[32]; /* 32 rows of 32 1-bit pixels */
+}; /* ASIconBW */
+
+typedef struct ASIconBW ASIconBW;
+
+/* entry ID 6, "standard" Macintosh color icon - several competing
+* color icons are defined. Given the copyright dates
+* of the Inside Macintosh volumes, the 'cicn' resource predominated
+* when the AppleSingle Developer's Note was written (most probable
+* candidate). See Inside Macintosh, Volume V, pages 64 & 80-81 for
+* a description of 'cicn' resources.
+*
+* With System 7, Apple introduced icon families. They consist of:
+* large (32x32) B&W icon, 1-bit/pixel, type 'ICN#',
+* small (16x16) B&W icon, 1-bit/pixel, type 'ics#',
+* large (32x32) color icon, 4-bits/pixel, type 'icl4',
+* small (16x16) color icon, 4-bits/pixel, type 'ics4',
+* large (32x32) color icon, 8-bits/pixel, type 'icl8', and
+* small (16x16) color icon, 8-bits/pixel, type 'ics8'.
+* If entry ID 6 is one of these, take your pick. See Inside
+* Macintosh, Volume VI, pages 2-18 to 2-22 and 9-9 to 9-13, for
+* descriptions.
+*/
+
+/* entry ID 7, not used */
+
+/* Times are stored as a "signed number of seconds before of after
+* 12:00 a.m. (midnight), January 1, 2000 Greenwich Mean Time (GMT).
+* Applications must convert to their native date and time
+* conventions." Any unknown entries are set to 0x80000000
+* (earliest reasonable time).
+*/
+
+struct ASFileDates /* entry ID 8, file dates info */
+{
+ sint32 create; /* file creation date/time */
+ sint32 modify; /* last modification date/time */
+ sint32 backup; /* last backup date/time */
+ sint32 access; /* last access date/time */
+}; /* ASFileDates */
+
+typedef struct ASFileDates ASFileDates;
+
+/* See older Inside Macintosh, Volume II, page 115 for
+* PBGetFileInfo(), and Volume IV, page 155, for PBGetCatInfo().
+*/
+
+/* entry ID 9, Macintosh Finder info & extended info */
+struct ASFinderInfo
+{
+ FInfo ioFlFndrInfo; /* PBGetFileInfo() or PBGetCatInfo() */
+ FXInfo ioFlXFndrInfo; /* PBGetCatInfo() (HFS only) */
+}; /* ASFinderInfo */
+
+typedef struct ASFinderInfo ASFinderInfo;
+
+struct ASMacInfo /* entry ID 10, Macintosh file information */
+{
+ uchar8 filler[3]; /* filler, currently all bits 0 */
+ uchar8 ioFlAttrib; /* PBGetFileInfo() or PBGetCatInfo() */
+}; /* ASMacInfo */
+
+typedef struct ASMacInfo ASMacInfo;
+
+#define AS_PROTECTED 0x0002 /* protected bit */
+#define AS_LOCKED 0x0001 /* locked bit */
+
+/* NOTE: ProDOS-16 and GS/OS use entire fields. ProDOS-8 uses low
+* order half of each item (low byte in access & filetype, low word
+* in auxtype); remainder of each field should be zero filled.
+*/
+
+struct ASProdosInfo /* entry ID 11, ProDOS file information */
+{
+ uint16 access; /* access word */
+ uint16 filetype; /* file type of original file */
+ uint32 auxtype; /* auxiliary type of the orig file */
+}; /* ASProDosInfo */
+
+typedef struct ASProdosInfo ASProdosInfo;
+
+/* MS-DOS file attributes occupy 1 octet; since the Developer Note
+* is unspecific, I've placed them in the low order portion of the
+* field (based on example of other ASMacInfo & ASProdosInfo).
+*/
+
+struct ASMsdosInfo /* entry ID 12, MS-DOS file information */
+{
+ uchar8 filler; /* filler, currently all bits 0 */
+ uchar8 attr; /* _dos_getfileattr(), MS-DOS */
+ /* interrupt 21h function 4300h */
+}; /* ASMsdosInfo */
+
+typedef struct ASMsdosInfo ASMsdosInfo;
+
+#define AS_DOS_NORMAL 0x00 /* normal file (all bits clear) */
+#define AS_DOS_READONLY 0x01 /* file is read-only */
+#define AS_DOS_HIDDEN 0x02 /* hidden file (not shown by DIR) */
+#define AS_DOS_SYSTEM 0x04 /* system file (not shown by DIR) */
+#define AS_DOS_VOLID 0x08 /* volume label (only in root dir) */
+#define AS_DOS_SUBDIR 0x10 /* file is a subdirectory */
+#define AS_DOS_ARCHIVE 0x20 /* new or modified (needs backup) */
+
+/* entry ID 13, short file name on AFP server - arbitrary length
+* octet string; usualy printable ASCII starting with
+* '!' (0x21)
+*/
+
+struct ASAfpInfo /* entry ID 12, AFP server file information */
+{
+ uchar8 filler[3]; /* filler, currently all bits 0 */
+ uchar8 attr; /* file attributes */
+}; /* ASAfpInfo */
+
+typedef struct ASAfpInfo ASAfpInfo;
+
+#define AS_AFP_Invisible 0x01 /* file is invisible */
+#define AS_AFP_MultiUser 0x02 /* simultaneous access allowed */
+#define AS_AFP_System 0x04 /* system file */
+#define AS_AFP_BackupNeeded 0x40 /* new or modified (needs backup) */
+
+struct ASAfpDirId /* entry ID 15, AFP server directory ID */
+{
+ uint32 dirid; /* file's directory ID on AFP server */
+}; /* ASAfpDirId */
+
+typedef struct ASAfpDirId ASAfpDirId;
+
+/*
+* The format of an AppleSingle/AppleDouble header
+*/
+struct AppleSingle /* format of disk file */
+{
+ ASHeader header; /* AppleSingle header part */
+ ASEntry entry[1]; /* array of entry descriptors */
+/* uchar8 filedata[]; /* followed by rest of file */
+}; /* AppleSingle */
+
+typedef struct AppleSingle AppleSingle;
+
+/*
+* FINAL REMINDER: the Motorola 680x0 is a big-endian architecture!
+*/
+
+/* End of applefile.h */
diff -ruN subversion-1.5.0/subversion/include/svn_io.h subversion-appledouble-1.5.0/subversion/include/svn_io.h
--- subversion-1.5.0/subversion/include/svn_io.h 2008-06-11 01:26:41.000000000 -0400
+++ subversion-appledouble-1.5.0/subversion/include/svn_io.h 2008-06-19 18:10:55.000000000 -0400
@@ -394,6 +394,25 @@
                                        apr_pool_t *pool);
 
 
+#if DARWIN
+/** Manage HFS metadata by storing it as an AppleDouble encoded property.
+ *
+ * @a path is the utf8-encoded path to the file. If @a appledouble
+ * is non-empty, then apply the indicated metadata. If empty, remove
+ * any HFS metadata and the resource fork from the file.
+ */
+svn_error_t *svn_io_set_appledouble_data(const char *path,
+ const svn_string_t *appledouble,
+ svn_boolean_t ignore_enoent,
+ apr_pool_t *pool);
+
+/** Enocde the HFS metadata into an binary property.
+ */
+svn_error_t *svn_io_get_appledouble_data(svn_string_t **appledouble,
+ const char *path,
+ apr_pool_t *pool);
+#endif /* DARWIN */
+
 /** Read a line from @a file into @a buf, but not exceeding @a *limit bytes.
  * Does not include newline, instead '\\0' is put there.
  * Length (as in strlen) is returned in @a *limit.
diff -ruN subversion-1.5.0/subversion/include/svn_props.h subversion-appledouble-1.5.0/subversion/include/svn_props.h
--- subversion-1.5.0/subversion/include/svn_props.h 2008-05-21 17:24:24.000000000 -0400
+++ subversion-appledouble-1.5.0/subversion/include/svn_props.h 2008-06-19 18:11:57.000000000 -0400
@@ -254,6 +254,11 @@
  */
 #define SVN_PROP_EXECUTABLE_VALUE SVN_PROP_BOOLEAN_TRUE
 
+#if DARWIN
+/** Contains any HFS metadata in AppleDouble format. */
+#define SVN_PROP_APPLEDOUBLE "file:appledouble"
+#endif /* DARWIN */
+
 /** Set to TRUE ('*') if we want a file to be set to read-only when
  * not locked. FALSE is indicated by deleting the property. */
 #define SVN_PROP_NEEDS_LOCK SVN_PROP_PREFIX "needs-lock"
diff -ruN subversion-1.5.0/subversion/include/svn_version.h subversion-appledouble-1.5.0/subversion/include/svn_version.h
--- subversion-1.5.0/subversion/include/svn_version.h 2008-06-17 23:33:48.000000000 -0400
+++ subversion-appledouble-1.5.0/subversion/include/svn_version.h 2008-06-19 21:02:57.000000000 -0400
@@ -131,6 +131,11 @@
 /** Complete version string */
 #define SVN_VERSION SVN_VER_NUM SVN_VER_TAG
 
+#if DARWIN
+/** Append our patch information to the display */
+#undef SVN_VERSION
+#define SVN_VERSION SVN_VER_NUM SVN_VER_TAG " (svn-appledouble patch 2008-06-19)"
+#endif /* DARWIN */
 
 
 /* Version queries and compatibility checks */
diff -ruN subversion-1.5.0/subversion/libsvn_client/add.c subversion-appledouble-1.5.0/subversion/libsvn_client/add.c
--- subversion-1.5.0/subversion/libsvn_client/add.c 2008-05-21 17:24:24.000000000 -0400
+++ subversion-appledouble-1.5.0/subversion/libsvn_client/add.c 2008-06-19 16:36:12.000000000 -0400
@@ -202,6 +202,18 @@
     }
 #endif
 
+#if DARWIN
+ /* load any appledouble data for the indicated file */
+ if (1)
+ {
+ svn_string_t *appledouble = FALSE;
+ SVN_ERR (svn_io_get_appledouble_data (&appledouble, path, pool));
+ if (appledouble)
+ apr_hash_set (autoprops.properties, SVN_PROP_APPLEDOUBLE,
+ strlen (SVN_PROP_APPLEDOUBLE), appledouble);
+ }
+#endif /* DARWIN */
+
   *mimetype = autoprops.mimetype;
   return SVN_NO_ERROR;
 }
diff -ruN subversion-1.5.0/subversion/libsvn_client/export.c subversion-appledouble-1.5.0/subversion/libsvn_client/export.c
--- subversion-1.5.0/subversion/libsvn_client/export.c 2008-04-07 05:22:45.000000000 -0400
+++ subversion-appledouble-1.5.0/subversion/libsvn_client/export.c 2008-06-19 16:58:58.000000000 -0400
@@ -104,6 +104,9 @@
   apr_hash_t *props;
   const char *base;
   svn_string_t *eol_style, *keywords, *executable, *externals, *special;
+#if DARWIN
+ svn_string_t *appledouble;
+#endif /* DARWIN */
   const char *eol = NULL;
   svn_boolean_t local_mod = FALSE;
   apr_time_t tm;
@@ -149,6 +152,10 @@
                           APR_HASH_KEY_STRING);
   executable = apr_hash_get(props, SVN_PROP_EXECUTABLE,
                             APR_HASH_KEY_STRING);
+#if DARWIN
+ appledouble = apr_hash_get(props, SVN_PROP_APPLEDOUBLE,
+ APR_HASH_KEY_STRING);
+#endif /* DARWIN */
   externals = apr_hash_get(props, SVN_PROP_EXTERNALS,
                            APR_HASH_KEY_STRING);
   special = apr_hash_get(props, SVN_PROP_SPECIAL,
@@ -202,6 +209,11 @@
     SVN_ERR(svn_io_set_file_executable(to, TRUE,
                                        FALSE, pool));
 
+#if DARWIN
+ if (appledouble)
+ SVN_ERR(svn_io_set_appledouble_data(to, appledouble, FALSE, pool));
+#endif /* DARWIN */
+
   if (! special)
     SVN_ERR(svn_io_set_file_affected_time(tm, to, pool));
 
@@ -469,6 +481,9 @@
   const svn_string_t *eol_style_val;
   const svn_string_t *keywords_val;
   const svn_string_t *executable_val;
+#if DARWIN
+ const svn_string_t *appledouble_val;
+#endif /* DARWIN */
   svn_boolean_t special;
 
   /* Any keyword vals to be substituted */
@@ -665,6 +680,11 @@
   else if (strcmp(name, SVN_PROP_EXECUTABLE) == 0)
     fb->executable_val = svn_string_dup(value, fb->pool);
 
+#if DARWIN
+ else if (strcmp(name, SVN_PROP_APPLEDOUBLE) == 0)
+ fb->appledouble_val = svn_string_dup(value, fb->pool);
+#endif /* DARWIN */
+
   /* Try to fill out the baton's keywords-structure too. */
   else if (strcmp(name, SVN_PROP_ENTRY_COMMITTED_REV) == 0)
     fb->revision = apr_pstrdup(fb->pool, value->data);
@@ -762,6 +782,12 @@
   if (fb->executable_val)
     SVN_ERR(svn_io_set_file_executable(fb->path, TRUE, FALSE, pool));
 
+#if DARWIN
+ if (fb->appledouble_val)
+ SVN_ERR (svn_io_set_appledouble_data(fb->path, fb->appledouble_val,
+ FALSE, pool));
+#endif /* DARWIN */
+
   if (fb->date && (! fb->special))
     SVN_ERR(svn_io_set_file_affected_time(fb->date, fb->path, pool));
 
diff -ruN subversion-1.5.0/subversion/libsvn_subr/io.c subversion-appledouble-1.5.0/subversion/libsvn_subr/io.c
--- subversion-1.5.0/subversion/libsvn_subr/io.c 2008-05-03 09:30:01.000000000 -0400
+++ subversion-appledouble-1.5.0/subversion/libsvn_subr/io.c 2008-06-19 16:59:42.000000000 -0400
@@ -1476,6 +1476,269 @@
   return SVN_NO_ERROR;
 }
 
+#if DARWIN
+
+#include <sys/attr.h>
+#include <sys/paths.h>
+#include <sys/stat.h>
+#include "applefile.h" /* RFC 1740 */
+
+#define APPLEDOUBLE_MAGIC_NUMBER 0x00051607
+#define APPLEDOUBLE_VERSION_NUMBER 0x00020000
+#define APPLEDOUBLE_HEADER_BYTES 26 /* Without padding */
+
+typedef struct resource_fork_attr
+{
+ unsigned long attr_length;
+ off_t fork_length;
+} resource_fork_attr;
+
+typedef struct finder_info_attr
+{
+ unsigned long attr_length;
+ ASFinderInfo finder_info;
+} finder_info_attr;
+
+svn_error_t *
+svn_io_set_appledouble_data (const char *path,
+ const svn_string_t *appledouble,
+ svn_boolean_t ignore_enoent,
+ apr_pool_t *pool)
+{
+ apr_status_t status;
+ unsigned char *data = NULL;
+ size_t length, offset;
+ size_t bytes_written;
+ struct ASHeader header;
+ struct ASEntry entry;
+ finder_info_attr fi_attr;
+ int finder_info_valid = 0;
+ unsigned char *resource_data = NULL;
+ size_t resource_length = 0;
+ struct attrlist attrs;
+ const char *path_apr;
+ int i, result;
+
+ if ((appledouble != NULL) && (appledouble->len != 0))
+ {
+ data = (unsigned char *) appledouble->data;
+ length = appledouble->len;
+ offset = 0;
+
+ if (length < APPLEDOUBLE_HEADER_BYTES)
+ return svn_error_create (SVN_ERR_INCOMPLETE_DATA, NULL,
+ _("Incomplete AppleDouble encoding"));
+
+ memcpy(&header, data + offset, APPLEDOUBLE_HEADER_BYTES);
+ offset += APPLEDOUBLE_HEADER_BYTES;
+ header.magicNum = ntohl(header.magicNum);
+ header.versionNum = ntohl(header.versionNum);
+ header.numEntries = ntohs(header.numEntries);
+
+ if (header.magicNum != APPLEDOUBLE_MAGIC_NUMBER)
+ return svn_error_create (SVN_ERR_MALFORMED_FILE, NULL,
+ _("Malformed AppleDouble encoding"));
+
+ for(i = 0; i< header.numEntries; i++)
+ {
+ if (offset + sizeof(entry) > length)
+ return svn_error_create (SVN_ERR_INCOMPLETE_DATA, NULL,
+ _("Incomplete AppleDouble encoding"));
+ memcpy(&entry, data + offset, sizeof(entry));
+ offset += sizeof(entry);
+ entry.entryID = ntohl(entry.entryID);
+ entry.entryOffset = ntohl(entry.entryOffset);
+ entry.entryLength = ntohl(entry.entryLength);
+
+ if (entry.entryID == 0)
+ return svn_error_create (SVN_ERR_MALFORMED_FILE, NULL,
+ _("Malformed AppleDouble encoding"));
+ if (entry.entryLength)
+ {
+ if (entry.entryOffset > length)
+ return svn_error_create (SVN_ERR_INCOMPLETE_DATA, NULL,
+ _("Incomplete AppleDouble encoding"));
+ if (entry.entryOffset + entry.entryLength > length)
+ return svn_error_create (SVN_ERR_INCOMPLETE_DATA, NULL,
+ _("Incomplete AppleDouble encoding"));
+ if (entry.entryOffset < APPLEDOUBLE_HEADER_BYTES +
+ header.numEntries * sizeof(ASEntry))
+ return svn_error_create (SVN_ERR_MALFORMED_FILE, NULL,
+ _("Malformed AppleDouble encoding"));
+ }
+
+ switch(entry.entryID)
+ {
+ case AS_RESOURCE:
+ resource_data = data + entry.entryOffset;
+ resource_length = entry.entryLength;
+ break;
+ case AS_FINDERINFO:
+ if (entry.entryLength != sizeof(fi_attr.finder_info))
+ return svn_error_create (SVN_ERR_MALFORMED_FILE, NULL,
+ _("Malformed AppleDouble encoding"));
+ memcpy(&fi_attr.finder_info, data + entry.entryOffset,
+ sizeof(fi_attr.finder_info));
+ fi_attr.finder_info.ioFlXFndrInfo.fdIconID = htons(0);
+ fi_attr.finder_info.ioFlXFndrInfo.fdComment = htons(0);
+ fi_attr.finder_info.ioFlXFndrInfo.fdPutAway = htonl(0);
+ finder_info_valid = 1;
+ break;
+ default:
+ /* ignore */
+ break;
+ }
+ }
+
+ if (resource_length)
+ {
+ const char *resource_path;
+ apr_file_t *file;
+ apr_size_t bytes_written;
+ svn_error_t *err;
+
+ resource_path = svn_path_join_many(pool, path, "..namedfork", "rsrc", NULL);
+ if (resource_path == NULL)
+ return svn_error_wrap_apr
+ (apr_get_os_error (), _("Can't create resource path"));
+
+ SVN_ERR (svn_io_file_open (&file, resource_path, APR_READ | APR_WRITE,
+ APR_OS_DEFAULT, pool));
+ bytes_written = resource_length;
+ err = svn_io_file_write (file, resource_data,
+ &bytes_written, pool);
+ SVN_ERR (svn_io_file_flush_to_disk (file, pool));
+ SVN_ERR (svn_io_file_close (file, pool));
+ if (err && !APR_STATUS_IS_EOF(err->apr_err))
+ return err;
+ }
+
+ /* The FinderInfo struct is populated directly from the HFS volume, so the
+ fields are already in network byte order. See the getattrlist manpage. */
+
+ if (finder_info_valid)
+ {
+ SVN_ERR(svn_path_cstring_from_utf8(&path_apr, path, pool));
+
+ memset(&attrs, 0, sizeof(attrs));
+ attrs.bitmapcount = ATTR_BIT_MAP_COUNT;
+ attrs.commonattr = ATTR_CMN_FNDRINFO;
+ fi_attr.attr_length = sizeof(fi_attr.finder_info);
+ result = setattrlist(path_apr, &attrs, &fi_attr.finder_info,
+ sizeof(fi_attr.finder_info), 0);
+ if (result < 0)
+ return svn_error_wrap_apr
+ (apr_get_os_error (), _("Can't set file attributes"));
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+
+svn_error_t *
+svn_io_get_appledouble_data(svn_string_t **appledouble,
+ const char *path,
+ apr_pool_t *pool)
+{
+ int result = 0;
+ const char *path_apr;
+ unsigned char *data = NULL;
+ size_t total_header;
+ struct ASHeader header;
+ struct ASEntry entries[2];
+ struct attrlist attrs;
+ finder_info_attr fi_attr;
+ resource_fork_attr rf_attr;
+
+ *appledouble = NULL;
+
+ SVN_ERR(svn_path_cstring_from_utf8(&path_apr, path, pool));
+
+ memset(&attrs, 0, sizeof(attrs));
+ memset(&fi_attr, 0, sizeof(fi_attr));
+ attrs.bitmapcount = ATTR_BIT_MAP_COUNT;
+ attrs.commonattr = ATTR_CMN_FNDRINFO;
+ fi_attr.attr_length = sizeof(fi_attr.finder_info);
+ result = getattrlist(path_apr, &attrs, &fi_attr, sizeof(fi_attr), 0);
+ if (result < 0)
+ return svn_error_wrap_apr
+ (apr_get_os_error (), _("Can't get file attributes"));
+
+ memset(&attrs, 0, sizeof(attrs));
+ attrs.bitmapcount = ATTR_BIT_MAP_COUNT;
+ attrs.fileattr = ATTR_FILE_RSRCLENGTH;
+ result = getattrlist(path_apr, &attrs, &rf_attr, sizeof(rf_attr), 0);
+ if (result < 0)
+ return svn_error_wrap_apr
+ (apr_get_os_error (), _("Can't get file attributes"));
+
+ if (!rf_attr.fork_length &&
+ !fi_attr.finder_info.ioFlFndrInfo.fdType &&
+ !fi_attr.finder_info.ioFlFndrInfo.fdCreator &&
+ !fi_attr.finder_info.ioFlFndrInfo.fdFlags)
+ return SVN_NO_ERROR;
+
+ total_header = APPLEDOUBLE_HEADER_BYTES +
+ sizeof(entries) + sizeof(fi_attr.finder_info);
+ data = (unsigned char *) apr_palloc(pool,
+ total_header + rf_attr.fork_length);
+
+ memset(&header, 0, APPLEDOUBLE_HEADER_BYTES);
+ header.magicNum = htonl(APPLEDOUBLE_MAGIC_NUMBER);
+ header.versionNum = htonl(APPLEDOUBLE_VERSION_NUMBER);
+ header.numEntries = htons(2);
+
+ entries[0].entryID = htonl(AS_FINDERINFO);
+ entries[0].entryOffset = htonl(APPLEDOUBLE_HEADER_BYTES + sizeof(entries));
+ entries[0].entryLength = htonl(sizeof(ASFinderInfo));
+ entries[1].entryID = htonl(AS_RESOURCE);
+ entries[1].entryOffset = htonl(total_header);
+ entries[1].entryLength = htonl(rf_attr.fork_length);
+
+ memcpy(data + 0, &header, APPLEDOUBLE_HEADER_BYTES);
+ memcpy(data + APPLEDOUBLE_HEADER_BYTES, entries, sizeof(entries));
+
+
+ /* The FinderInfo struct is populated directly from the HFS volume, so the
+ fields are already in network byte order. See the getattrlist manpage. */
+
+ memcpy(data + APPLEDOUBLE_HEADER_BYTES + sizeof(entries),
+ &fi_attr.finder_info, sizeof(fi_attr.finder_info));
+
+ if (rf_attr.fork_length)
+ {
+ const char *resource_path;
+ apr_file_t *file;
+ apr_size_t bytes_read;
+ svn_error_t *err;
+
+ resource_path = svn_path_join_many(pool, path, "..namedfork", "rsrc", NULL);
+ if (resource_path == NULL)
+ return svn_error_wrap_apr
+ (apr_get_os_error (), _("Can't create resource path"));
+
+ SVN_ERR (svn_io_file_open (&file, resource_path, APR_READ,
+ APR_OS_DEFAULT, pool));
+ bytes_read = rf_attr.fork_length;
+ err = svn_io_file_read (file, data + total_header, &bytes_read, pool);
+ SVN_ERR (svn_io_file_close (file, pool));
+ if (err && !APR_STATUS_IS_EOF(err->apr_err))
+ return err;
+ if (bytes_read != rf_attr.fork_length)
+ return svn_error_create (SVN_ERR_INCOMPLETE_DATA, NULL,
+ _("Incomplete AppleDouble encoding"));
+ }
+
+ *appledouble = svn_string_ncreate (data, total_header +
+ rf_attr.fork_length, pool);
+
+ return SVN_NO_ERROR;
+}
+
+#endif /* DARWIN */
+
 
 /*** File locking. ***/
 /* Clear all outstanding locks on ARG, an open apr_file_t *. */
diff -ruN subversion-1.5.0/subversion/libsvn_wc/adm_crawler.c subversion-appledouble-1.5.0/subversion/libsvn_wc/adm_crawler.c
--- subversion-1.5.0/subversion/libsvn_wc/adm_crawler.c 2007-10-14 17:11:29.000000000 -0400
+++ subversion-appledouble-1.5.0/subversion/libsvn_wc/adm_crawler.c 2008-06-19 18:28:26.000000000 -0400
@@ -86,6 +86,10 @@
   /* If necessary, tweak the new working file's executable bit. */
   SVN_ERR(svn_wc__maybe_set_executable(NULL, file_path, adm_access, pool));
 
+#if DARWIN
+ SVN_ERR(svn_wc__maybe_set_appledouble(NULL, file_path, adm_access, pool));
+#endif /* DARWIN */
+
   /* Remove any text conflict */
   SVN_ERR(svn_wc_resolved_conflict3(file_path, adm_access, TRUE, FALSE,
                                     svn_depth_empty,
diff -ruN subversion-1.5.0/subversion/libsvn_wc/log.c subversion-appledouble-1.5.0/subversion/libsvn_wc/log.c
--- subversion-1.5.0/subversion/libsvn_wc/log.c 2007-12-10 23:13:52.000000000 -0500
+++ subversion-appledouble-1.5.0/subversion/libsvn_wc/log.c 2008-06-19 17:38:24.000000000 -0400
@@ -107,6 +107,11 @@
    executable property is set. */
 #define SVN_WC__LOG_MAYBE_EXECUTABLE "maybe-executable"
 
+#if DARWIN
+/* Apply the cached AppleDouble data to file SVN_WC__LOG_ATTR_NAME . */
+#define SVN_WC__LOG_MAYBE_APPLEDOUBLE "maybe-appledouble"
+#endif /* DARWIN */
+
 /* Set SVN_WC__LOG_ATTR_NAME to have timestamp SVN_WC__LOG_ATTR_TIMESTAMP. */
 #define SVN_WC__LOG_SET_TIMESTAMP "set-timestamp"
 
@@ -326,6 +331,11 @@
         SVN_ERR(svn_wc__maybe_set_executable(NULL, full_dest_path,
                                              adm_access, pool));
 
+#if DARWIN
+ SVN_ERR(svn_wc__maybe_set_appledouble(NULL, full_dest_path,
+ adm_access, pool));
+#endif /* DARWIN */
+
         return SVN_NO_ERROR;
       }
     case svn_wc__xfer_cp_and_detranslate:
@@ -386,6 +396,9 @@
 install_committed_file(svn_boolean_t *overwrote_working,
                        svn_wc_adm_access_t *adm_access,
                        const char *name,
+#if DARWIN
+ svn_boolean_t remove_appledouble,
+#endif /* DARWIN */
                        svn_boolean_t remove_executable,
                        svn_boolean_t remove_read_only,
                        apr_pool_t *pool)
@@ -491,6 +504,28 @@
         *overwrote_working = TRUE;
     }
 
+#if DARWIN
+ if (remove_appledouble)
+ {
+ /* Update the appledouble data for the indicated file */
+ if (same)
+ SVN_ERR(svn_io_set_appledouble_data(filepath,
+ NULL, /* delete */
+ FALSE, pool));
+ *overwrote_working = TRUE; /* entry needs wc-file's timestamp */
+ }
+ else
+ {
+ /* Set the working file's appledouble data if props dictate. */
+ SVN_ERR(svn_wc__maybe_set_appledouble(&did_set, filepath,
+ adm_access, pool));
+ if (did_set)
+ /* okay, so we didn't -overwrite- the working file, but we changed
+ its timestamp, which is the point of returning this flag. :-) */
+ *overwrote_working = TRUE;
+ }
+#endif /* DARWIN */
+
   /* Install the new text base if one is waiting. */
   if (kind == svn_node_file) /* tmp_text_base exists */
     SVN_ERR(svn_wc__sync_text_base(filepath, pool));
@@ -664,6 +699,22 @@
   return SVN_NO_ERROR;
 }
 
+#if DARWIN
+static svn_error_t *
+log_do_file_maybe_appledouble(struct log_runner *loggy,
+ const char *name)
+{
+ const char *full_path
+ = svn_path_join(svn_wc_adm_access_path(loggy->adm_access), name,
+ loggy->pool);
+
+ SVN_ERR(svn_wc__maybe_set_appledouble(NULL, full_path, loggy->adm_access,
+ loggy->pool));
+
+ return SVN_NO_ERROR;
+}
+#endif /* DARWIN */
+
 /* Maybe make file NAME in log's CWD readonly */
 static svn_error_t *
 log_do_file_maybe_readonly(struct log_runner *loggy,
@@ -1063,6 +1114,9 @@
   int is_this_dir = (strcmp(name, SVN_WC_ENTRY_THIS_DIR) == 0);
   const char *rev = svn_xml_get_attr_value(SVN_WC__LOG_ATTR_REVISION, atts);
   svn_boolean_t wc_root, overwrote_working = FALSE, remove_executable = FALSE;
+#if DARWIN
+ svn_boolean_t remove_appledouble = FALSE;
+#endif /* DARWIN */
   svn_boolean_t set_read_write = FALSE;
   const char *full_path;
   const char *pdir, *base_name;
@@ -1251,6 +1305,11 @@
               if ((! strcmp(propchange->name, SVN_PROP_EXECUTABLE))
                   && (propchange->value == NULL))
                 remove_executable = TRUE;
+#if DARWIN
+ else if ((! strcmp(propchange->name, SVN_PROP_APPLEDOUBLE))
+ && (propchange->value == NULL))
+ remove_appledouble = TRUE;
+#endif /* DARWIN */
               else if ((! strcmp(propchange->name, SVN_PROP_NEEDS_LOCK))
                        && (propchange->value == NULL))
                 set_read_write = TRUE;
@@ -1275,6 +1334,9 @@
 
       if ((err = install_committed_file
            (&overwrote_working, loggy->adm_access, name,
+#if DARWIN
+ remove_appledouble,
+#endif /* DARWIN */
             remove_executable, set_read_write, pool)))
         return svn_error_createf
           (pick_error_code(loggy), err,
@@ -1574,6 +1636,11 @@
   else if (strcmp(eltname, SVN_WC__LOG_MAYBE_EXECUTABLE) == 0) {
     err = log_do_file_maybe_executable(loggy, name);
   }
+#if DARWIN
+ else if (strcmp(eltname, SVN_WC__LOG_MAYBE_APPLEDOUBLE) == 0) {
+ err = log_do_file_maybe_appledouble(loggy, name);
+ }
+#endif /* DARWIN */
   else if (strcmp(eltname, SVN_WC__LOG_SET_TIMESTAMP) == 0) {
     err = log_do_file_timestamp(loggy, name, atts);
   }
@@ -2297,6 +2364,26 @@
   return SVN_NO_ERROR;
 }
 
+#if DARWIN
+svn_error_t *
+svn_wc__loggy_maybe_set_appledouble(svn_stringbuf_t **log_accum,
+ svn_wc_adm_access_t *adm_access,
+ const char *path,
+ apr_pool_t *pool)
+{
+ svn_xml_make_open_tag(log_accum,
+ pool,
+ svn_xml_self_closing,
+ SVN_WC__LOG_MAYBE_APPLEDOUBLE,
+ SVN_WC__LOG_ATTR_NAME,
+ loggy_path(path, adm_access),
+ NULL);
+
+ return SVN_NO_ERROR;
+}
+#endif /* DARWIN */
+
+
 svn_error_t *
 svn_wc__loggy_maybe_set_readonly(svn_stringbuf_t **log_accum,
                                  svn_wc_adm_access_t *adm_access,
diff -ruN subversion-1.5.0/subversion/libsvn_wc/log.h subversion-appledouble-1.5.0/subversion/libsvn_wc/log.h
--- subversion-1.5.0/subversion/libsvn_wc/log.h 2007-11-06 19:26:32.000000000 -0500
+++ subversion-appledouble-1.5.0/subversion/libsvn_wc/log.h 2008-06-19 17:38:51.000000000 -0400
@@ -199,6 +199,18 @@
                                    const char *path,
                                    apr_pool_t *pool);
 
+#if DARWIN
+/* Extend **LOG_ACCUM with log instructions to set the appledouble
+ properties for the file.
+*/
+
+svn_error_t *
+svn_wc__loggy_maybe_set_appledouble(svn_stringbuf_t **log_accum,
+ svn_wc_adm_access_t *adm_access,
+ const char *path,
+ apr_pool_t *pool);
+#endif /* DARWIN */
+
 /* Extend **LOG_ACCUM with log instructions to set permissions of PATH
    to 'readonly' if it has the 'needs-lock' property set and there is
    no lock for the file in the working copy.
diff -ruN subversion-1.5.0/subversion/libsvn_wc/merge.c subversion-appledouble-1.5.0/subversion/libsvn_wc/merge.c
--- subversion-1.5.0/subversion/libsvn_wc/merge.c 2008-05-23 10:57:21.000000000 -0400
+++ subversion-appledouble-1.5.0/subversion/libsvn_wc/merge.c 2008-06-19 19:33:23.000000000 -0400
@@ -821,6 +821,12 @@
                                                  adm_access, merge_target,
                                                  pool));
 
+#if DARWIN
+ SVN_ERR(svn_wc__loggy_maybe_set_appledouble(log_accum,
+ adm_access, merge_target,
+ pool));
+#endif /* DARWIN */
+
       SVN_ERR(svn_wc__loggy_maybe_set_readonly(log_accum,
                                                 adm_access, merge_target,
                                                 pool));
diff -ruN subversion-1.5.0/subversion/libsvn_wc/props.c subversion-appledouble-1.5.0/subversion/libsvn_wc/props.c
--- subversion-1.5.0/subversion/libsvn_wc/props.c 2008-02-20 23:40:00.000000000 -0500
+++ subversion-appledouble-1.5.0/subversion/libsvn_wc/props.c 2008-06-19 17:49:41.000000000 -0400
@@ -2323,6 +2323,9 @@
                                   SVN_PROP_EXTERNALS,
                                   NULL };
   const char *dir_prohibit[] = { SVN_PROP_EXECUTABLE,
+#if DARWIN
+ SVN_PROP_APPLEDOUBLE,
+#endif /* DARWIN */
                                  SVN_PROP_KEYWORDS,
                                  SVN_PROP_EOL_STYLE,
                                  SVN_PROP_MIME_TYPE,
@@ -2511,6 +2514,15 @@
         SVN_ERR(svn_io_set_file_executable(path, TRUE, TRUE, pool));
     }
 
+#if DARWIN
+ if (entry->kind == svn_node_file && strcmp(name, SVN_PROP_APPLEDOUBLE) == 0)
+ {
+ /* If the svn:appledouble property exists, apply the HFS metadata.
+ If the svn:appledouble property was deleted, clear the metadata. */
+ SVN_ERR (svn_io_set_appledouble_data (path, value, TRUE, pool));
+ }
+#endif /* DARWIN */
+
   if (entry->kind == svn_node_file && strcmp(name, SVN_PROP_NEEDS_LOCK) == 0)
     {
       /* If the svn:needs-lock property was set to NULL, set the file
@@ -3430,6 +3442,9 @@
       const svn_prop_t *property = &APR_ARRAY_IDX(properties, i, svn_prop_t);
 
       if (strcmp(property->name, SVN_PROP_EXECUTABLE) == 0
+#if DARWIN
+ || strcmp(property->name, SVN_PROP_APPLEDOUBLE) == 0
+#endif /* DARWIN */
           || strcmp(property->name, SVN_PROP_KEYWORDS) == 0
           || strcmp(property->name, SVN_PROP_EOL_STYLE) == 0
           || strcmp(property->name, SVN_PROP_SPECIAL) == 0
diff -ruN subversion-1.5.0/subversion/libsvn_wc/translate.c subversion-appledouble-1.5.0/subversion/libsvn_wc/translate.c
--- subversion-1.5.0/subversion/libsvn_wc/translate.c 2007-12-27 15:42:46.000000000 -0500
+++ subversion-appledouble-1.5.0/subversion/libsvn_wc/translate.c 2008-06-19 18:12:40.000000000 -0400
@@ -322,6 +322,31 @@
 }
 
 
+#if DARWIN
+svn_error_t *
+svn_wc__maybe_set_appledouble (svn_boolean_t *did_set,
+ const char *path,
+ svn_wc_adm_access_t *adm_access,
+ apr_pool_t *pool)
+{
+ const svn_string_t *propval;
+ SVN_ERR (svn_wc_prop_get (&propval, SVN_PROP_APPLEDOUBLE, path, adm_access,
+ pool));
+
+ if (propval != NULL)
+ {
+ SVN_ERR (svn_io_set_appledouble_data (path, propval, FALSE, pool));
+ if (did_set)
+ *did_set = TRUE;
+ }
+ else if (did_set)
+ *did_set = FALSE;
+
+ return SVN_NO_ERROR;
+}
+#endif /* DARWIN */
+
+
 svn_error_t *
 svn_wc__maybe_set_read_only(svn_boolean_t *did_set,
                             const char *path,
diff -ruN subversion-1.5.0/subversion/libsvn_wc/translate.h subversion-appledouble-1.5.0/subversion/libsvn_wc/translate.h
--- subversion-1.5.0/subversion/libsvn_wc/translate.h 2006-02-15 16:30:49.000000000 -0500
+++ subversion-appledouble-1.5.0/subversion/libsvn_wc/translate.h 2008-06-19 18:13:47.000000000 -0400
@@ -103,6 +103,18 @@
                              svn_wc_adm_access_t *adm_access,
                              apr_pool_t *pool);
 
+#if DARWIN
+/* If the SVN_PROP_APPLEDOUBLE property is present at all, apply
+ the HFS metadata. If DID_SET is non-null, then set *DID_SET to
+ TRUE if did apply HFS metadata, or to FALSE if not. ADM_ACCESS
+ is an access baton set that contains PATH. */
+svn_error_t *
+svn_wc__maybe_set_appledouble (svn_boolean_t *did_set,
+ const char *path,
+ svn_wc_adm_access_t *adm_access,
+ apr_pool_t *pool);
+#endif /* DARWIN */
+
 /* If the SVN_PROP_NEEDS_LOCK property is present and there is no
    lock token for the file in the working copy, set PATH to
    read-only. If DID_SET is non-null, then set *DID_SET to TRUE if

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-08-08 23:44:37 CEST

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.