diff -urN rsync-2.6.3/Makefile.in rsync-2.6.3-dar/Makefile.in
--- rsync-2.6.3/Makefile.in	Thu Aug 12 14:59:03 2004
+++ rsync-2.6.3-dar/Makefile.in	Sun Oct 10 01:44:20 2004
@@ -35,7 +35,7 @@
 	main.o checksum.o match.o syscall.o log.o backup.o
 OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \
 	fileio.o batch.o clientname.o
-OBJS3=progress.o pipe.o
+OBJS3=progress.o pipe.o hfs.o
 DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
 popt_OBJS=popt/findme.o  popt/popt.o  popt/poptconfig.o \
 	popt/popthelp.o popt/poptparse.o
diff -urN rsync-2.6.3/flist.c rsync-2.6.3-dar/flist.c
--- rsync-2.6.3/flist.c	Tue Sep 21 05:24:02 2004
+++ rsync-2.6.3-dar/flist.c	Sun Oct 10 02:57:52 2004
@@ -960,6 +960,9 @@
 	struct file_struct *file;
 	char fbuf[MAXPATHLEN];
 
+	struct file_struct *file_ephemeral;	/* dar hfs */
+	extern char *hfs_mode;		/* dar hfs */
+
 	/* f is set to -1 when calculating deletion file list */
 	file = make_file(fname, flist,
 	    f == -1 && delete_excluded? SERVER_EXCLUDES : ALL_EXCLUDES);
@@ -988,8 +991,20 @@
 		clear_exclude_list(&local_exclude_list);
 		local_exclude_list = last_list;
 	}
-}
 
+	/* dar hfs */
+	if ( hfs_mode && file->basename[0] ) {
+		if ( S_ISREG(file->mode) ) {
+			if ( (file_ephemeral = hfs_rfmd(f,flist,file,fname)) ) {
+				file_ephemeral->length = file_ephemeral->meta->hdrlen
+					+ file_ephemeral->meta->rfsize;
+				flist_expand(flist);
+				flist->files[flist->count++] = file_ephemeral;
+				send_file_entry(file_ephemeral, f, base_flags);
+			}
+		}
+	}
+}
 
 static void send_directory(int f, struct file_list *flist, char *dir)
 {
diff -urN rsync-2.6.3/hfs.c rsync-2.6.3-dar/hfs.c
--- rsync-2.6.3/hfs.c	Wed Dec 31 19:00:00 1969
+++ rsync-2.6.3-dar/hfs.c	Sun Oct 10 04:10:16 2004
@@ -0,0 +1,482 @@
+/*
+   Copyright 2004 D Andrew Reynhout <reynhout@quesera.com>
+   Copyright assigned to rsync development group
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/** @file hfs.c
+ *
+ * HFS+ routines 
+ *
+ **/
+
+#include "rsync.h"
+
+/* applefile definitions used */
+#define AF_APPLESINGLE_MAGIC 0x00051600L
+#define AF_APPLEDOUBLE_MAGIC 0x00051607L
+#define AF_VERSION 0x00020000
+#define AF_FILLER 0
+#define AF_ENTRY_DATAFORK	1
+#define AF_ENTRY_RSRCFORK	2
+#define AF_ENTRY_REALNAME	3
+#define AF_ENTRY_COMMENT	4
+#define AF_ENTRY_DATES		8
+#define AF_ENTRY_FINDERINFO	9
+
+/* These are from RFC 1740: AppleSingle/AppleDouble */
+#define AF_INCLUDE_DATAFORK		(1<<1)
+#define AF_INCLUDE_RSRCFORK		(1<<2)
+#define AF_INCLUDE_REALNAME		(1<<3)
+#define AF_INCLUDE_COMMENT		(1<<4)
+#define AF_INCLUDE_DATES		(1<<8)
+#define AF_INCLUDE_FINDERINFO	(1<<9)
+
+#define UC (unsigned char *)
+
+/* applefile structures */
+typedef struct ap_header {
+	long magic;
+	long version;
+	char fill[16];
+	short entries;
+} ap_header;
+typedef struct ap_entry {
+	unsigned long id;
+	unsigned long offset;
+	unsigned long length;
+} ap_entry;
+
+extern int protocol_version;
+
+
+int do_open_ephemeral(struct file_struct *file, int flags, mode_t mode)
+	{
+	char path[MAXPATHLEN];
+
+	if ( file->meta->flags & META_HAS_HFS_RSRCFORK )
+		{
+		path[0]='\0';
+		if (file->basedir)
+			snprintf(path, MAXPATHLEN, "%s/", file->basedir);
+		if (strlcat(path, file->meta->basename_rf, MAXPATHLEN) >= MAXPATHLEN)
+			{
+			rprintf(FERROR, "do_open_ephemeral: path too long: %s\n", path);
+			return -1;
+			}
+		else
+			return open(path, flags | O_BINARY, mode);
+		}
+
+	return NULL;
+	}
+
+unsigned short get_af_flags()
+	{
+	extern char *hfs_mode;
+	unsigned short af_flags=0;
+
+	if (strcmp(hfs_mode,"appledouble") == 0)
+		{
+		af_flags |= AF_INCLUDE_RSRCFORK;
+		af_flags |= AF_INCLUDE_FINDERINFO;
+		}
+	if (strcmp(hfs_mode,"appledoublex") == 0)
+		{
+		af_flags |= AF_INCLUDE_RSRCFORK;	/* 2 */
+		af_flags |= AF_INCLUDE_REALNAME;	/* 3 */
+		af_flags |= AF_INCLUDE_COMMENT;		/* 4 */
+		af_flags |= AF_INCLUDE_DATES;		/* 8 */
+		af_flags |= AF_INCLUDE_FINDERINFO;	/* 9 */
+		}
+	return af_flags;
+	}
+
+struct map_struct *map_file_ephemeral(int fd, struct file_struct *file,
+			OFF_T map_size, size_t block_size)
+	{
+	struct map_struct *map;
+	STRUCT_STAT statbuf;
+	char	path[MAXPATHLEN];
+	OFF_T rsrcforklen=0;
+	unsigned short af_flags;
+
+	map = new(struct map_struct);
+	if (!map) out_of_memory("map_file_ephemeral");
+
+	if (block_size && (map_size % block_size))
+		map_size += block_size - (map_size % block_size);
+
+	memset(map, 0, sizeof map[0]);
+
+	af_flags=get_af_flags();
+
+	if ( file->meta->flags & META_HAS_HFS_RSRCFORK )
+		{
+		/* rprintf(FINFO, "has rsrcfork %s\n", path); */
+		path[0]='\0'; /* set for strlcat */
+		if (file->basedir)
+			snprintf(path, MAXPATHLEN, "%s/", file->basedir);
+		if (strlcat(path, file->meta->basename_rf, MAXPATHLEN) >= MAXPATHLEN)
+			{
+			rprintf(FERROR, "do_open_ephemeral: path too long: %s\n", path);
+			return NULL;
+			}
+		if (do_stat(path,&statbuf))
+			{
+			rprintf(FERROR, "do_open_ephemeral: nable to stat: %s\n", path);
+			return NULL;
+			}
+	    rsrcforklen=statbuf.st_size;
+		}
+	map->fd = fd;
+	map->p = applefile_hdr(file->meta,af_flags);
+	map->file_size = file->meta->hdrlen + rsrcforklen;
+	map->def_window_size = map_size;
+	map->p_size = file->meta->hdrlen;
+	map->p_fd_offset = file->meta->hdrlen;
+	map->p_offset = 0;
+	map->p_len = file->meta->hdrlen;
+	map->status = 0;
+
+	return map;
+	}
+
+int unmap_file_ephemeral(struct map_struct *map)
+	{
+	int	ret;
+
+	/* this was SIGBUS'ing before */
+	if (map->p) {
+		free(map->p);
+		map->p = NULL;
+	}
+
+	ret = map->status;
+	memset(map, 0, sizeof(*map));
+	free(map);
+
+	return ret;
+	}
+
+
+void long_to_str(long type, char *buf)
+	{
+	buf[0] = (type >> 24) & 0xFF; buf[1] = (type >> 16) & 0xFF;
+	buf[2] = (type >> 8) & 0xFF; buf[3] = type & 0xFF; buf[4] = 0;
+	}
+
+struct file_struct *hfs_rfmd(int f, struct file_list *flist,
+	struct file_struct *file, char *fname)
+	{
+	extern char *hfs_mode;
+	extern int delete_excluded;
+	struct file_struct *file_eph;
+	struct hfs_metadata_struct *md;
+	char buf[MAXPATHLEN];
+
+	if ( S_ISDIR(file->mode) )
+		{ return NULL; } /* can't handle dirs yet */
+
+	if ( (S_ISREG(file->mode)) )
+		{
+		file_eph = make_file(fname, flist,
+			f == -1 && delete_excluded? SERVER_EXCLUDES
+			: ALL_EXCLUDES);
+
+		md = get_hfs_metadata(fname);
+		if ( !md ) { return NULL; }
+
+		/* if md is non null */
+		file_eph->metaflags |= META_IS_EPHEMERAL;
+		if ( (strcmp(hfs_mode,"appledouble") == 0) ||
+				(strcmp(hfs_mode,"appledoublex") == 0) )
+			{
+			if (snprintf(buf, MAXPATHLEN, "._%s", file->basename) >=
+				MAXPATHLEN )
+				{
+				rprintf(FERROR,"hfs_rfmd: path too long: %s\n", buf);
+				free(file_eph);
+				free(md);
+				return NULL;
+				}
+			file_eph->basename = new_array(char, strlen(buf) + 1);
+			if ( !file_eph->basename ) { out_of_memory("hfs_metadata"); }
+			strcpy(file_eph->basename, buf);
+			file_eph->meta = md;
+
+			return file_eph;
+			}
+		free(file_eph);
+		free(md);
+		}
+		return NULL;
+	}
+
+struct hfs_metadata_struct *get_hfs_metadata(char *path)
+	{
+	FSRef	fileRef;
+	FSSpec	fileSpec;
+	FInfo	fileInfo;
+	FXInfo	fileXInfo;
+	/*
+	HFileInfo filePB;
+	DateTimeRec cur_time;
+	unsigned long cur_secs;
+	*/
+	ap_header *head;
+	ap_entry *entry;
+	struct hfs_dates_struct	*fileDates;
+	char	*fileComment;
+	struct	hfs_metadata_struct *md;
+	char	*fname_rf;
+	STRUCT_STAT statbuf;
+	char	*rfpath = "/..namedfork/rsrc";
+	#define CONVERT_TIME 1265437696L
+	int 	header_len=0;
+	int		num_entries=0;
+	unsigned short af_flags;
+	unsigned short f;
+
+	af_flags=get_af_flags();
+	f=af_flags;
+	while (f) { num_entries += f & 0x1u ; f >>= 1 ; }
+
+	/* struct alignment prevents this from being much simpler */
+	header_len = (
+		sizeof(head->magic) + sizeof(head->version) +
+		sizeof(head->fill) + sizeof(head->entries) +
+		num_entries * ( sizeof(entry->id) +
+			sizeof(entry->offset) + sizeof(entry->length)));
+
+	if ( af_flags & AF_INCLUDE_DATES )
+		{
+		header_len += sizeof(fileDates->create) + sizeof(fileDates->modify) +
+			sizeof(fileDates->backup) + sizeof(fileDates->access);
+		}
+	if ( af_flags & AF_INCLUDE_FINDERINFO )
+		{ header_len += sizeof(fileInfo) + sizeof(fileXInfo); }
+
+	md = new(struct hfs_metadata_struct);
+	if ( ! md ) { out_of_memory("get_hfs_metadata"); }
+
+	memset(md,0,sizeof(struct hfs_metadata_struct));
+
+	/** check for resource fork **/
+	fname_rf = new_array(char, strlen(path) + strlen(rfpath) + 1);
+	sprintf(fname_rf, "%s%s", path, rfpath);
+	if (do_stat(fname_rf,&statbuf))
+		{
+		rprintf(FERROR, "get_hfs_metadata: unable to stat: %s\n", path);
+		return NULL;
+		}
+	if ( (S_ISREG(statbuf.st_mode)) && (statbuf.st_size > 0) )
+		{
+		md->flags |= META_HAS_HFS_RSRCFORK;
+		md->basename_rf = fname_rf;
+		md->rfsize = statbuf.st_size;
+		}
+	else
+		{
+		md->rfsize=0;
+		free(fname_rf);
+		}
+
+	/** set up file **/
+	/* Get file ref to the file or folder pointed to by the path */
+	if (FSPathMakeRef((unsigned char *)path, &fileRef, NULL) == noErr)
+		{
+	    /* retrieve filespec from file ref */
+	    if (FSGetCatalogInfo(&fileRef, NULL, NULL, NULL,
+			&fileSpec, NULL) == noErr)
+			{
+			/* get the finder info */
+			FSpGetFInfo(&fileSpec, &fileInfo);
+			/* zero FXInfo cuz we don't know what else to do */
+			memset(&fileXInfo,0x00,sizeof(FXInfo));
+			}
+		}
+
+	/** get finder comment **/
+	/* http://developer.apple.com/documentation/Carbon/Reference/File_Manager/file_manager/function_group_40.html#//apple_ref/c/func/PBDTGetCommentSync */
+	fileComment=" sample comment ";
+	md->comment=fileComment;
+	if ( af_flags & AF_INCLUDE_COMMENT )
+		{ header_len += md->comment ? strlen(md->comment) : 0; }
+
+	/** get real (local) filename **/
+	if ( af_flags & AF_INCLUDE_REALNAME )
+		{ header_len += 0; }
+
+	/** get finder dates **/
+	fileDates = new(struct hfs_dates_struct);
+	if ( ! fileDates ) { out_of_memory("get_hfs_metadata"); }
+	/*
+	GetTime(&cur_time);
+	Date2Secs(&cur_time, &cur_secs);
+	dates.create = filePB->ioFlCrDat + CONVERT_TIME;
+	dates.modify = filePB->ioFlMdDat + CONVERT_TIME;
+	dates.backup = filePB->ioFlBkDat + CONVERT_TIME;
+	dates.access = cur_secs + CONVERT_TIME;
+	*/
+	fileDates->create=0;
+	fileDates->modify=0;
+	fileDates->backup=0;
+	fileDates->access=0;
+	md->dates=fileDates;
+	/* skip this for now */
+
+	if ( fileInfo.fdType || fileInfo.fdCreator
+			|| fileInfo.fdFlags
+		)
+		/* if (
+		|| fileComment[0] 
+		|| fileDATES
+		|| fileXInfo
+		) we don't really care
+		*/
+		{
+		md->flags |= META_HAS_HFS_METADATA;
+		md->fileInfo=fileInfo;
+		md->fileXInfo=fileXInfo;
+		}
+
+	if ( (md->flags & META_HAS_HFS_METADATA) ||
+		(md->flags & META_HAS_HFS_RSRCFORK) )
+		{
+		md->hdrlen = header_len;
+		return md;
+		}
+
+	free(md);
+	free(fileDates);
+	return NULL;
+	}
+
+void printhex(unsigned char *buf, int len)
+	{
+	int i=0;
+
+	rprintf(FINFO,":%d bytes:",len);
+	while ( i < len )
+		rprintf(FINFO,"%02x",buf[i++]);
+	rprintf(FINFO,":\n");
+	}
+
+void swrite(char *buf, char *buf2, unsigned int *off, unsigned int len)
+	{
+	unsigned int i=0;
+	while (i < len)
+		{ buf[(*off)++]=buf2[i++]; }
+	}
+
+char *applefile_hdr(struct hfs_metadata_struct *md, unsigned short af_flags)
+	{
+	char	*buf;
+	unsigned int	bc;
+	ap_header head;
+	ap_entry entry;
+	int	num_entries=0;
+	int i;
+	unsigned short f;
+
+	f=af_flags;
+	while (f) { num_entries += f & 0x1u ; f >>= 1 ; }
+
+	ap_entry entries[num_entries];
+
+	buf = new_array(char, MAXPATHLEN);
+
+	/* build header */
+	head.magic = AF_APPLEDOUBLE_MAGIC;
+	head.version = AF_VERSION;
+	memset(head.fill, AF_FILLER, sizeof (head.fill));
+	head.entries = num_entries;
+
+	i=0;
+	if ( af_flags & AF_INCLUDE_FINDERINFO )
+		{
+		entries[i].id = AF_ENTRY_FINDERINFO;
+		entries[i++].length = sizeof (FInfo) + sizeof (FXInfo);
+		}
+	if ( af_flags & AF_INCLUDE_DATES )
+		{
+		entries[i].id = AF_ENTRY_DATES;
+		entries[i++].length = sizeof (struct hfs_dates_struct);
+		}
+	if ( af_flags & AF_INCLUDE_REALNAME )
+		{
+		entries[i].id = AF_ENTRY_REALNAME;
+		entries[i++].length = 0;
+		}
+	if ( af_flags & AF_INCLUDE_COMMENT )
+		{
+		entries[i].id = AF_ENTRY_COMMENT;
+		entries[i++].length = (md->comment ? strlen(md->comment) : 0);
+		}
+	if ( af_flags & AF_INCLUDE_RSRCFORK )
+		{
+		entries[i].id = AF_ENTRY_RSRCFORK;
+		entries[i++].length = md->rfsize;
+		}
+
+	entries[0].offset = ( sizeof(head.magic) + sizeof(head.version) +
+			sizeof(head.fill) + sizeof(head.entries) +
+				num_entries * ( sizeof(entry.id) +
+				sizeof(entry.offset) + sizeof(entry.length) ) );
+	for (i = 1; i < num_entries; ++i)
+		{ entries[i].offset = entries[i-1].offset + entries[i-1].length; }
+
+	/* add elements individually.  probably could be shortened, but
+	** struct alignment issues preclude the ideal.  */
+	bc=0;
+	swrite(buf,UC &head.magic,&bc,sizeof(head.magic));
+	swrite(buf,UC &head.version,&bc,sizeof(head.version));
+	swrite(buf,UC &head.fill,&bc,sizeof(head.fill));
+	swrite(buf,UC &head.entries,&bc,sizeof(head.entries));
+	for (i = 0; i < num_entries; i++)
+		{
+		swrite(buf,UC &entries[i].id,&bc,sizeof(entries[i].id));
+		swrite(buf,UC &entries[i].offset,&bc,sizeof(entries[i].offset));
+		swrite(buf,UC &entries[i].length,&bc,sizeof(entries[i].length));
+		}
+	if ( af_flags & AF_INCLUDE_FINDERINFO )
+		{
+		swrite(buf,UC &md->fileInfo,&bc,sizeof(md->fileInfo));
+		swrite(buf,UC &md->fileXInfo,&bc,sizeof(md->fileXInfo));
+		}
+	if ( af_flags & AF_INCLUDE_DATES )
+		{
+		swrite(buf,UC &md->dates->create,&bc,sizeof(md->dates->create));
+		swrite(buf,UC &md->dates->modify,&bc,sizeof(md->dates->modify));
+		swrite(buf,UC &md->dates->backup,&bc,sizeof(md->dates->backup));
+		swrite(buf,UC &md->dates->access,&bc,sizeof(md->dates->access));
+		}
+	/*
+	if ( af_flags & AF_INCLUDE_REALNAME )
+		{
+		swrite(buf,md->comment,&bc,(md->comment ? strlen(md->comment) : 0));
+		}
+	*/
+	if ( af_flags & AF_INCLUDE_COMMENT )
+		{
+		swrite(buf,md->comment,&bc,(md->comment ? strlen(md->comment) : 0));
+		}
+
+	/* printhex(buf,bc); */
+	return buf;
+	}
+
diff -urN rsync-2.6.3/loadparm.c rsync-2.6.3-dar/loadparm.c
--- rsync-2.6.3/loadparm.c	Fri Jul 30 16:05:37 2004
+++ rsync-2.6.3-dar/loadparm.c	Sun Oct 10 01:44:20 2004
@@ -136,6 +136,7 @@
 	char *include;
 	char *include_from;
 	char *log_format;
+	char *hfs_mode;
 	char *refuse_options;
 	char *dont_compress;
 	int timeout;
@@ -178,6 +179,7 @@
 	NULL,    /* include */
 	NULL,    /* include from */
 	"%o %h [%a] %m (%u) %f %l",    /* log format */
+	NULL,    /* hfs mode */
 	NULL,    /* refuse options */
 	"*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz",    /* dont compress */
 	0,        /* timeout */
@@ -297,6 +299,7 @@
   {"transfer logging", P_BOOL,    P_LOCAL,  &sDefault.transfer_logging,NULL,0},
   {"ignore errors",    P_BOOL,    P_LOCAL,  &sDefault.ignore_errors,NULL,0},
   {"log format",       P_STRING,  P_LOCAL,  &sDefault.log_format,  NULL,   0},
+  {"HFS mode",         P_STRING,  P_LOCAL,  &sDefault.hfs_mode,    NULL,   0},
   {"refuse options",   P_STRING,  P_LOCAL,  &sDefault.refuse_options,NULL, 0},
   {"dont compress",    P_STRING,  P_LOCAL,  &sDefault.dont_compress,NULL,  0},
   {NULL,               P_BOOL,    P_NONE,   NULL,                  NULL,   0}
@@ -377,6 +380,7 @@
 FN_LOCAL_STRING(lp_include, include)
 FN_LOCAL_STRING(lp_include_from, include_from)
 FN_LOCAL_STRING(lp_log_format, log_format)
+FN_LOCAL_STRING(lp_hfs_mode, hfs_mode)
 FN_LOCAL_STRING(lp_refuse_options, refuse_options)
 FN_LOCAL_STRING(lp_dont_compress, dont_compress)
 FN_LOCAL_INTEGER(lp_timeout, timeout)
diff -urN rsync-2.6.3/options.c rsync-2.6.3-dar/options.c
--- rsync-2.6.3/options.c	Thu Sep 23 13:39:05 2004
+++ rsync-2.6.3-dar/options.c	Sun Oct 10 01:44:20 2004
@@ -123,6 +123,7 @@
 char *config_file = NULL;
 char *shell_cmd = NULL;
 char *log_format = NULL;
+char *hfs_mode = NULL;
 char *password_file = NULL;
 char *rsync_path = RSYNC_PATH;
 char *backup_dir = NULL;
@@ -299,6 +300,7 @@
   rprintf(F,"     --stats                 give some file transfer stats\n");
   rprintf(F,"     --progress              show progress during transfer\n");
   rprintf(F,"     --log-format=FORMAT     log file transfers using specified format\n");
+  rprintf(F,"     --hfs-mode=MODE         handle MacOS X HFS+ metadata in MODE\n");
   rprintf(F,"     --password-file=FILE    get password from FILE\n");
   rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth, KBytes per second\n");
   rprintf(F,"     --write-batch=FILE      write a batch to FILE\n");
@@ -320,6 +322,7 @@
       OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST,
       OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
       OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT,
+      OPT_HFS_MODE,
       OPT_REFUSED_BASE = 9000};
 
 static struct poptOption long_options[] = {
@@ -393,6 +396,7 @@
   {"config",           0,  POPT_ARG_STRING, &config_file, 0, 0, 0 },
   {"port",             0,  POPT_ARG_INT,    &rsync_port, 0, 0, 0 },
   {"log-format",       0,  POPT_ARG_STRING, &log_format, 0, 0, 0 },
+  {"hfs-mode",         0,  POPT_ARG_STRING, &hfs_mode, OPT_HFS_MODE, 0, 0 },
   {"bwlimit",          0,  POPT_ARG_INT,    &bwlimit, 0, 0, 0 },
   {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 0, 0 },
   {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
@@ -564,6 +568,26 @@
 					  ? XFLG_DEF_INCLUDE : 0));
 			break;
 
+ 		case OPT_HFS_MODE:
+ 			/* not necessary */
+ 			#ifndef __APPLE__
+ 				rprintf(FERROR,
+ 					"ERROR: hfs-mode not supported on this system.\n");
+ 				exit_cleanup(RERR_UNSUPPORTED);
+ 			#endif
+ 			if ( (strcmp(hfs_mode,"none") != 0) &&
+ 				(strcmp(hfs_mode,"appledouble") != 0) &&
+ 				(strcmp(hfs_mode,"appledoublex") != 0) ) {
+ 					snprintf(err_buf, sizeof err_buf,
+ 						"unsupported hfs-mode: \"%s\"\n",hfs_mode);
+ 					rprintf(FERROR, "ERROR: %s", err_buf);
+ 					exit_cleanup(RERR_UNSUPPORTED);
+ 				}
+ 			/* ephemeral files cannot be date-checked, but turning
+ 			** on ignore_times is not an ideal solution */
+ 			/* ignore_times++; */
+  			break;
+  
 		case 'h':
 			usage(FINFO);
 			exit_cleanup(0);
diff -urN rsync-2.6.3/rsync.h rsync-2.6.3-dar/rsync.h
--- rsync-2.6.3/rsync.h	Wed Sep 22 00:10:10 2004
+++ rsync-2.6.3-dar/rsync.h	Sun Oct 10 01:44:20 2004
@@ -55,6 +55,19 @@
 #define XMIT_SAME_DEV (1<<10)
 #define XMIT_RDEV_MINOR_IS_SMALL (1<<11)
 
+/* Placeholder for sending to an ephemeral-file-aware rsync */
+/* We only need one bit to tell the destination side that the
+** file being sent is a candidate for deconversion.  receiver
+** can autosense the file type and decide to deconvert or save
+** verbatim.  For HFS+, AppleSingle might be preferred to avoid
+** race conditions/parallelization issues! */
+#define XMIT_IS_EPHEMERAL (1<<15)
+
+/* metaflag bits */
+#define META_IS_EPHEMERAL (1<<0)
+#define META_HAS_HFS_METADATA (1<<1)
+#define META_HAS_HFS_RSRCFORK (1<<2)
+
 /* These flags are used in the live flist data. */
 
 #define FLAG_TOP_DIR (1<<0)
@@ -133,6 +146,11 @@
 	MSG_DATA=0	/* raw data on the multiplexed stream */
 };
 
+/* get carbon headers - dar hfs */
+#ifdef __APPLE__
+#include <Carbon/Carbon.h>
+#endif
+
 #include "errcode.h"
 
 #include "config.h"
@@ -421,6 +439,11 @@
 	char *basename;
 	char *dirname;
 	char *basedir;
+	/** these are used by hfs-mode **/
+	/* char *basename_src; */	/** dar hfs **/ /** OLD **/
+	uchar metaflags;	/** dar hfs **/
+	/* char *metadata; */		/** dar hfs **/ /** OLD **/
+	struct hfs_metadata_struct *meta;		/** dar hfs **/
 	union {
 		struct idev *idev;
 		struct hlink *links;
@@ -430,6 +453,21 @@
 	gid_t gid;
 	mode_t mode;
 	uchar flags;	/* this item MUST remain last */
+};
+
+struct hfs_metadata_struct {
+	int	hdrlen;
+	char *basename_rf;
+	OFF_T rfsize;
+	uchar flags;
+	FInfo fileInfo;
+	FXInfo fileXInfo;
+	struct hfs_dates_struct *dates;
+	char *comment;
+};
+
+struct hfs_dates_struct {
+	long create, modify, backup, access;
 };
 
 /*
diff -urN rsync-2.6.3/rsync.yo rsync-2.6.3-dar/rsync.yo
--- rsync-2.6.3/rsync.yo	Thu Sep 30 12:35:56 2004
+++ rsync-2.6.3-dar/rsync.yo	Sun Oct 10 01:44:20 2004
@@ -381,6 +381,7 @@
      --write-batch=FILE      write a batch to FILE 
      --read-batch=FILE       read a batch from FILE
      --checksum-seed=NUM     set block/file checksum seed
+     --hfs-mode=MODE         handle Mac OS X HFS+ metadata in MODE
  -4  --ipv4                  prefer IPv4
  -6  --ipv6                  prefer IPv6
  -h, --help                  show this help screen
@@ -1028,6 +1029,43 @@
 in the case where the user wants a more random checksum seed.
 Note that setting NUM to 0 causes rsync to use the default of time()
 for checksum seed.
+
+dit(bf(--hfs-mode=MODE)) Handle Mac OS X HFS+ files with resource
+forks and/or Finder metadata according to MODE.  This is currently
+a ONE-WAY, SEND-ONLY operation, and is only useful when backing up
+Mac OS X files to a non-HFS+ filesystem (e.g. a Linux fileserver).
+It is NOT necessary for the remote rsync to be patched.
+
+     MODE          Destination filename, file format, and notes
+     appledouble   ._<filename> AppleDouble standard RFC1740
+                   Metadata included Resource fork, Finder
+                   type/creator, Finder flags.
+                   This MODE sends files that are identical
+                   to those created by Apple's SplitForks tool,
+                   and therefore are compatible with Apple's
+                   reassembly tool, FixupResourceForks.
+                   
+     appledoublex  ._<filename> AppleDouble standard RFC1740
+                   Metadata included Resource fork, Finder
+                   type/creator, Finder flags, Finder comment,
+                   Finder create/modify/access/backup dates,
+                   Finder native filesystem filename.
+                   This MODE also sends standard RFC1470 files,
+                   but FixupResourceForks doesn't implement the
+                   additional metadata extraction, so this MODE
+                   should only be used if you have an alternate
+                   AppleDouble reconversion utility!
+                   
+No other MODEs are valid at this time.  See web page for updates.
+    http://www.quesera.com/reynhout/misc/rsync+hfsmode
+
+This command line will back up a home directory to fileserver:
+
+    rsync --archive --delete --verbose --hfs-mode=appledouble \
+        /Users/username fileserver:/backups/mac
+
+IMPORTANT: See the web page listed above for usage notes regarding
+entire filesystems, specifically including the /dev directory.
 
 enddit()
 
diff -urN rsync-2.6.3/sender.c rsync-2.6.3-dar/sender.c
--- rsync-2.6.3/sender.c	Mon Sep 20 00:17:42 2004
+++ rsync-2.6.3-dar/sender.c	Sun Oct 10 03:36:25 2004
@@ -185,7 +185,11 @@
 			return;
 		}
 
-		fd = do_open(fname, O_RDONLY, 0);
+		if ( file->metaflags & META_IS_EPHEMERAL )
+			{ fd = do_open_ephemeral(file, O_RDONLY, 0); }
+		else
+			{ fd = do_open(fname, O_RDONLY, 0); }
+
 		if (fd == -1) {
 			if (errno == ENOENT) {
 				enum logcode c = am_daemon
@@ -205,19 +209,30 @@
 		}
 
 		/* map the local file */
-		if (do_fstat(fd, &st) != 0) {
-			io_error |= IOERR_GENERAL;
-			rsyserr(FERROR, errno, "fstat failed");
-			free_sums(s);
-			close(fd);
-			return;
+		if ( !(file->metaflags & META_IS_EPHEMERAL) ) {
+			if ( do_fstat(fd, &st) != 0) {
+				io_error |= IOERR_GENERAL;
+				rsyserr(FERROR, errno, "fstat failed");
+				free_sums(s);
+				close(fd);
+				return;
+			}
+
+			if (st.st_size) {
+				OFF_T map_size = MAX(s->blength * 3, MAX_MAP_SIZE);
+				mbuf = map_file(fd, st.st_size, map_size, s->blength);
+			}
+			else
+				mbuf = NULL;
 		}
 
-		if (st.st_size) {
+		if ( (file->metaflags & META_IS_EPHEMERAL) ) {
+			/* rprintf(FINFO, "mapping EPHEMERAL %s\n", fname2); */
 			OFF_T map_size = MAX(s->blength * 3, MAX_MAP_SIZE);
-			mbuf = map_file(fd, st.st_size, map_size, s->blength);
-		} else
-			mbuf = NULL;
+			mbuf = map_file_ephemeral(fd, file, map_size, s->blength);
+			st.st_size = mbuf->file_size;
+			/* printhex(mbuf->p,mbuf->file_size); */
+		}
 
 		if (verbose > 2) {
 			rprintf(FINFO, "send_files mapped %s of size %.0f\n",
@@ -241,7 +256,11 @@
 		log_send(file, &initial_stats);
 
 		if (mbuf) {
-			j = unmap_file(mbuf);
+			if ( file->metaflags & META_IS_EPHEMERAL )
+				j = unmap_file_ephemeral(mbuf);  /** dar hfs **/
+			else
+				j = unmap_file(mbuf);
+
 			if (j) {
 				io_error |= IOERR_GENERAL;
 				rsyserr(FERROR, j,
@@ -249,7 +268,7 @@
 					full_fname(fname));
 			}
 		}
-		close(fd);
+		if ( fd != -1 ) { close(fd); }
 
 		free_sums(s);
 
