View Issue Details

IDProjectCategoryView StatusLast Update
0000348RsyncFeature Requestpublic2020-08-24 12:44
ReporterSteven Levine Assigned ToSteven Levine  
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Product Version3.0.4 
Fixed in Version3.0.6 
Summary0000348: rsync --perms does not preserve OS/2 permissions
DescriptionFor a number of reasons rsync does not support OS/2 native permissions. It would be better if it did so this ticket will track the progress of patches to implement this.
TagsNo tags attached.
Attached Files
rsync-3.0.5-20090427-shl.diff (60,134 bytes)   
Only in .: 0_285_secrets
Only in .: 0_copy_from_root
Only in .: 0_preserve_perms
Only in .: Makefile
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/Makefile.in ./Makefile.in
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/Makefile.in	2008-11-15 15:32:02.000000000 -0800
+++ ./Makefile.in	2009-02-06 11:19:06.000000000 -0800
@@ -189,9 +189,10 @@
 	yodl2man -o rsyncd.conf.5 $(srcdir)/rsyncd.conf.yo
 	-$(srcdir)/tweak_manpage rsyncd.conf.5
 
+# 06 Feb 09 SHL clean maps
 clean: cleantests
 	rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) \
-		rounding rounding.h *.old
+		rounding rounding.h *.old rsync.map rounding.map
 
 cleantests:
 	rm -rf ./testtmp*
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/access.c ./access.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/access.c	2008-03-01 12:01:40.000000000 -0800
+++ ./access.c	2009-02-06 10:47:20.000000000 -0800
@@ -100,7 +100,9 @@
 	hints.ai_flags = AI_NUMERICHOST;
 #endif
 
-	if (getaddrinfo(addr, NULL, &hints, &resa) != 0) {
+	// if (getaddrinfo(addr, NULL, &hints, &resa) != 0) {
+	if ((gai = getaddrinfo(addr, NULL, &hints, &resa)) != 0) {			// 27 Jul 08 SHL debug
+		// rprintf(FLOG, "* match_address: gai %d %s:%u\n", gai, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		if (p)
 			*p = '/';
 		return 0;
@@ -110,8 +112,8 @@
 	if (p)
 		*p++ = '/';
 	if (gai != 0) {
-		rprintf(FLOG, "error matching address %s: %s\n",
-			tok, gai_strerror(gai));
+		rprintf(FLOG, "* error matching address %s: %s (%d)\n",
+			tok, gai_strerror(gai), gai);
 		freeaddrinfo(resa);
 		return 0;
 	}
@@ -222,7 +224,11 @@
 	if (host)
 		strlower(host);
 
+	// rprintf(FLOG, "* access_match: %s (%s) %s:%u\n", host, addr, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+
 	for (tok = strtok(list2, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
+
+		// rprintf(FLOG, "* access_match: tok %s %s:%u\n", tok, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		if (match_hostname(host, tok) || match_address(addr, tok)) {
 			free(list2);
 			return 1;
Only in .: access.o
Only in .: acls.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/authenticate.c ./authenticate.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/authenticate.c	2008-03-01 12:01:40.000000000 -0800
+++ ./authenticate.c	2009-02-06 10:47:20.000000000 -0800
@@ -173,13 +173,16 @@
 	if (do_stat(filename, &st) == -1) {
 		rsyserr(FWARNING, errno, "stat(%s)", filename);
 		ok = 0;
-	} else if ((st.st_mode & 06) != 0) {
+	}
+#ifndef __OS2__	 /* 12 Jun 08 SHL ignore unsupported mode checks */
+	else if ((st.st_mode & 06) != 0) {
 		rprintf(FWARNING, "password file must not be other-accessible\n");
 		ok = 0;
 	} else if (MY_UID() == 0 && st.st_uid != 0) {
 		rprintf(FWARNING, "password file must be owned by root when running as root\n");
 		ok = 0;
 	}
+#endif /* __OS2__ */
 	if (!ok) {
 		close(fd);
 		rprintf(FWARNING, "continuing without password file\n");
Only in .: authenticate.o
Only in .: backup.o
Only in .: batch.o
Only in .: cfg_shl
Only in .: changes.os2
Only in .: checksum.o
Only in .: chmod.o
Only in .: cleanup.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/clientname.c ./clientname.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/clientname.c	2008-10-11 11:13:42.000000000 -0700
+++ ./clientname.c	2009-02-06 10:47:20.000000000 -0800
@@ -95,8 +95,10 @@
 	struct sockaddr_storage ss;
 	socklen_t ss_len;
 
-	if (initialised)
+	if (initialised) {
+		// rprintf(FLOG, "* client_name: %s %s:%u\n", name_buf, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		return name_buf;
+	}
 
 	strlcpy(name_buf, default_name, sizeof name_buf);
 	initialised = 1;
@@ -148,6 +150,8 @@
 			port_buf, sizeof port_buf) == 0)
 		check_name(fd, &ss, name_buf, sizeof name_buf);
 
+	// rprintf(FLOG, "* client_name: %s %s:%u\n", name_buf, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+
 	return name_buf;
 }
 
@@ -216,14 +220,17 @@
 	int name_err;
 
 	/* reverse lookup */
+	// rprintf(FLOG, "* lookup_name: %s:%u\n", __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 	name_err = getnameinfo((struct sockaddr *) ss, ss_len,
 			       name_buf, name_buf_size,
 			       port_buf, port_buf_size,
 			       NI_NAMEREQD | NI_NUMERICSERV);
 	if (name_err != 0) {
 		strlcpy(name_buf, default_name, name_buf_size);
-		rprintf(FLOG, "name lookup failed for %s: %s\n",
-			client_addr(fd), gai_strerror(name_err));
+		// rprintf(FLOG, "name lookup failed for %s: %s\n",
+		//	client_addr(fd), gai_strerror(name_err));
+		rprintf(FLOG, "* lookup_name: failed for %s: %s (%d)\n",	// 27 Jul 08 SHL debug
+			client_addr(fd), gai_strerror(name_err), name_err);	// 28 Jul 08 SHL debug
 		return name_err;
 	}
 
Only in .: clientname.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/clientserver.c ./clientserver.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/clientserver.c	2008-11-09 18:55:14.000000000 -0800
+++ ./clientserver.c	2009-02-06 17:09:26.000000000 -0800
@@ -428,6 +428,7 @@
 	iconv_opt = NULL;
 #endif
 
+	rprintf(FLOG, "* rsync_module: %s %s %s:%u\n", addr, host, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 	if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
 		rprintf(FLOG, "rsync denied on module %s from %s (%s)\n",
 			name, host, addr);
@@ -481,6 +482,7 @@
 
 	am_root = (MY_UID() == 0);
 
+#ifndef __OS2__
 	if (am_root) {
 		p = lp_uid(i);
 		if (!name_to_uid(p, &uid)) {
@@ -503,6 +505,7 @@
 		}
 	}
 
+#endif
 	/* TODO: If we're not root, but the configuration requests
 	 * that we change to some uid other than the current one, then
 	 * log a warning. */
@@ -511,6 +514,7 @@
 	 * supplementary groups. */
 
 	module_dir = lp_path(i);
+	rprintf(FLOG, "* module_dir %s %s(%u)\n", module_dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 	if (use_chroot) {
 		if ((p = strstr(module_dir, "/./")) != NULL) {
 			*p = '\0'; /* Temporary... */
@@ -533,6 +537,7 @@
 		if (!(module_chdir = normalize_path(module_dir, False, &module_dirlen)))
 			return path_failure(f_out, module_dir, False);
 		full_module_path = module_dir = module_chdir;
+		rprintf(FLOG, "* full_module_path %s %s(%u)\n", full_module_path, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 	}
 
 	if (module_dirlen == 1) {
@@ -679,8 +684,11 @@
 		module_chdir = module_dir;
 	}
 
-	if (!change_dir(module_chdir, CD_NORMAL))
+	if (!change_dir(module_chdir, CD_NORMAL)) {
+		rsyserr(FERROR, errno, "chdir %s failed\n", module_chdir);	// 15 Dec 08 SHL debug
+		rprintf(FLOG, "* module_chdir %s %s(%u)\n", module_chdir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 		return path_failure(f_out, module_chdir, True);
+	}
 	if (module_dirlen || !use_chroot)
 		sanitize_paths = 1;
 
@@ -963,6 +971,8 @@
 #endif
 	SIGACTION(SIGCHLD, remember_children);
 
+	// rprintf(FLOG, "* start_daemon: %s %s %s:%u\n", addr, host, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+
 	return rsync_module(f_in, f_out, i, addr, host);
 }
 
@@ -991,6 +1001,7 @@
 	close(fd);
 }
 
+#ifndef __OS2__
 /* Become a daemon, discarding the controlling terminal. */
 static void become_daemon(void)
 {
@@ -1024,6 +1035,7 @@
 		open("/dev/null", O_RDWR);
 	}
 }
+#endif // __OS2__
 
 int daemon_main(void)
 {
@@ -1046,10 +1058,14 @@
 		exit_cleanup(RERR_SYNTAX);
 	}
 
+#ifndef __OS2__
 	if (no_detach)
 		create_pid_file();
 	else
 		become_daemon();
+#else
+	create_pid_file();
+#endif
 
 	if (rsync_port == 0 && (rsync_port = lp_rsync_port()) == 0)
 		rsync_port = RSYNC_PORT;
Only in .: clientserver.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/compat.c ./compat.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/compat.c	2008-08-02 07:04:54.000000000 -0700
+++ ./compat.c	2009-03-06 10:03:56.000000000 -0800
@@ -198,11 +198,12 @@
 			exit_cleanup(RERR_PROTOCOL);
 		}
 		if (preserve_xattrs && !local_server) {
-			rprintf(FERROR,
-			    "--xattrs requires protocol 30 or higher"
+		  	preserve_xattrs = 0;	// 06 Feb 09 SHL force off for old servers
+			rprintf(FWARNING,
+			    "--xattrs requires protocol 30 or higher - option disabled"
 			    " (negotiated %d).\n",
 			    protocol_version);
-			exit_cleanup(RERR_PROTOCOL);
+			// exit_cleanup(RERR_PROTOCOL);	// 06 Feb 09 SHL
 		}
 	}
 
@@ -291,6 +292,7 @@
 	if (need_unsorted_flist && (!am_sender || inc_recurse))
 		unsort_ndx = ++file_extra_cnt;
 
+	// 16 Feb 09 SHL fixme slash?
 	if (partial_dir && *partial_dir != '/' && (!am_server || local_server)) {
 		int flags = MATCHFLG_NO_PREFIXES | MATCHFLG_DIRECTORY;
 		if (!am_sender || protocol_version >= 30)
Only in .: compat.o
Only in .: config.cache
Only in .: config.h
Only in .: config.log
Only in .: config.status
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/configure.sh ./configure.sh
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/configure.sh	2008-12-28 18:03:34.000000000 -0800
+++ ./configure.sh	2009-03-01 18:33:16.000000000 -0800
@@ -1274,12 +1274,12 @@
   --enable-profile        turn on CPU profiling
   --enable-maintainer-mode
                           turn on extra debug features
+  --enable-xattr-support  enable extended attributes
   --disable-largefile     omit support for large files
   --disable-ipv6          don't even try to use IPv6
   --disable-locale        disable locale features
   --disable-iconv         disable rsync's --iconv option
   --disable-acl-support   disable ACL support
-  --disable-xattr-support disable extended attributes
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -16624,6 +16624,15 @@
 _ACEOF
 
 	;;
+    *os2*)
+	{ echo "$as_me:$LINENO: result: Using OS/2 extattrs" >&5
+echo "${ECHO_T}Using OS/2 extattrs" >&6; }
+	cat >>confdefs.h <<\_ACEOF
+#define SUPPORT_XATTRS 1
+_ACEOF
+
+	;;
+
     *)
 	if test x"$enable_xattr_support" = x"yes"; then
 	    { { echo "$as_me:$LINENO: error: Failed to find extended attribute support" >&5
Only in .: connection.o
Only in .: ctags.tag
Only in .: diff_shl.cmd
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/exclude.c ./exclude.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/exclude.c	2008-07-31 07:57:54.000000000 -0700
+++ ./exclude.c	2009-02-16 23:00:44.000000000 -0800
@@ -298,7 +298,7 @@
 	unsigned int fn_len;
 
 	if (!parent_dirscan && *merge_file != '/') {
-		/* Return the name unchanged it doesn't have any slashes. */
+		/* Return the name unchanged if it doesn't have any slashes. */
 		if (len_ptr) {
 			const char *p = merge_file + *len_ptr;
 			while (--p > merge_file && *p != '/') {}
@@ -310,6 +310,7 @@
 			return (char *)merge_file;
 	}
 
+	// 16 Feb 09 SHL fixme slash
 	fn = *merge_file == '/' ? buf : tmpbuf;
 	if (sanitize_paths) {
 		const char *r = prefix_skip ? "/" : NULL;
@@ -351,6 +352,7 @@
 void set_filter_dir(const char *dir, unsigned int dirlen)
 {
 	unsigned int len;
+	// 16 Feb 09 SHL fixme slash?
 	if (*dir != '/') {
 		memcpy(dirbuf, curr_dir, curr_dir_len);
 		dirbuf[curr_dir_len] = '/';
@@ -548,6 +550,7 @@
 	int ret_match = ex->match_flags & MATCHFLG_NEGATE ? 0 : 1;
 	char *p, *pattern = ex->pattern;
 	const char *strings[16]; /* more than enough */
+	// 16 Feb 09 SHL fixme slash?
 	const char *name = fname + (*fname == '/');
 
 	if (!*name)
Only in .: exclude.o
Only in .: fileio.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/flist.c ./flist.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/flist.c	2008-12-28 17:51:36.000000000 -0800
+++ ./flist.c	2009-03-06 18:54:52.000000000 -0800
@@ -348,8 +348,17 @@
 {
 	if (dirlen < 0) {
 		char *cpy = strdup(dir);
+#ifndef __OS2__ // 06 Mar 09 SHL use is_abs_path...
 		if (*cpy != '/')
 			change_dir(orig_dir, CD_SKIP_CHDIR);
+#else
+		if (!is_abs_path(cpy)) {
+			if (drive_spec_width(cpy))
+				rprintf(FERROR, "relative directory with drive letter not supported %s %s(%u)\n", cpy, __FILE__, __LINE__);	// 06 Feb 09 SHL
+			if (!change_dir(orig_dir, CD_SKIP_CHDIR))
+				rprintf(FLOG, "* [%s] orig_dir %s %s(%u)\n", who_am_i(), orig_dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+	        }
+#endif
 		if (path_is_daemon_excluded(cpy, 0))
 			goto chdir_error;
 		dir = cpy;
@@ -363,8 +372,17 @@
 				dirlen = strlen(dir);
 		} else if (pathname == dir)
 			return 1;
+#ifndef __OS2__ // 06 Mar 09 SHL use is_abs_path...
 		if (dir && *dir != '/')
 			change_dir(orig_dir, CD_SKIP_CHDIR);
+#else
+		if (dir && !is_abs_path(dir)) {
+			if (drive_spec_width(dir))
+				rprintf(FERROR, "relative directory with drive letter not supported %s %s(%u)\n", dir, __FILE__, __LINE__);	// 06 Feb 09 SHL
+			if (!change_dir(orig_dir, CD_SKIP_CHDIR))
+				rprintf(FERROR, "* [%s] orig_dir %s %s(%u)\n", who_am_i(), orig_dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
+		}
+#endif
 	}
 
 	pathname = dir;
@@ -377,8 +395,11 @@
 	  chdir_error:
 		io_error |= IOERR_GENERAL;
 		rsyserr(FERROR_XFER, errno, "change_dir %s failed", full_fname(dir));
-		if (dir != orig_dir)
-			change_dir(orig_dir, CD_NORMAL);
+		rprintf(FERROR_XFER, "* [%s] dir %s %s(%u)\n", who_am_i(), dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
+		if (dir != orig_dir) {
+			if (!change_dir(orig_dir, CD_NORMAL))
+				rprintf(FLOG, "* [%s] orig_dir %s %s(%u)\n", who_am_i(), orig_dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
+		}
 		pathname = NULL;
 		pathname_len = 0;
 		return 0;
@@ -1318,6 +1339,8 @@
 {
 	struct file_struct *file;
 
+	// rprintf(FINFO, "* [%s] send_file_name fname %s %s(%u)\n", who_am_i(), fname, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
+
 	file = make_file(fname, flist, stp, flags, filter_level);
 	if (!file)
 		return NULL;
@@ -1922,6 +1945,7 @@
 	int len, dirlen;
 	STRUCT_STAT st;
 	char *p, *dir;
+	static char* the_root = "/";
 	struct file_list *flist;
 	struct timeval start_tv, end_tv;
 	int64 start_write;
@@ -1965,6 +1989,7 @@
 		if (argv[0] && !change_dir(argv[0], CD_NORMAL)) {
 			rsyserr(FERROR_XFER, errno, "change_dir %s failed",
 				full_fname(argv[0]));
+			rprintf(FERROR_XFER, "* [%s] argv[0] %s %s(%u)\n", who_am_i(), argv[0], __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 			exit_cleanup(RERR_FILESELECT);
 		}
 		use_ff_fd = 1;
@@ -1984,17 +2009,31 @@
 			if (argc-- == 0)
 				break;
 			strlcpy(fbuf, *argv++, MAXPATHLEN);
+			// rprintf(FINFO, "* [%s] send_file_list fbuf %s %s(%u)\n", who_am_i(), fbuf, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 			if (sanitize_paths)
 				sanitize_path(fbuf, fbuf, "", 0, SP_KEEP_DOT_DIRS);
+#ifdef __OS2__
+			else {
+				// 06 Mar 09 SHL normalize slashes
+				for (p = fbuf; *p; p++) {
+					if (*p == '\\')
+						*p = '/';
+				}
 		}
+#endif
+		}
+
+		// rprintf(FINFO, "* [%s] send_file_list fbuf %s %s(%u)\n", who_am_i(), fbuf, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 
 		len = strlen(fbuf);
 		if (relative_paths) {
 			/* We clean up fbuf below. */
 			name_type = NORMAL_NAME;
 		} else if (!len || fbuf[len - 1] == '/') {
-			if (len == 2 && fbuf[0] == '.') {
-				/* Turn "./" into just "." rather than "./." */
+			// Empty path or trailing /
+			// 06 Mar 09 SHL
+			if (len == 2 + drive_spec_width(fbuf) && fbuf[drive_spec_width(fbuf)] == '.') {
+				/* Turn trailing "./" into just "." rather than "./." */
 				fbuf[--len] = '\0';
 			} else {
 				if (len + 1 >= MAXPATHLEN)
@@ -2005,6 +2044,7 @@
 			name_type = DOTDIR_NAME;
 		} else if (len > 1 && fbuf[len-1] == '.' && fbuf[len-2] == '.'
 		    && (len == 2 || fbuf[len-3] == '/')) {
+			// Got ..  or trailing /..
 			if (len + 2 >= MAXPATHLEN)
 				overflow_exit("send_file_list");
 			fbuf[len++] = '/';
@@ -2023,18 +2063,39 @@
 			if (p) {
 				*p = '\0';
 				if (p == fbuf)
-					dir = "/";
+					dir = the_root;
+#ifdef __OS2__
+				// 06 Mar 09 SHL Preserve drive letter
+				else if (p == fbuf + (dirlen = drive_spec_width(fbuf))) {
+					if (!(dir = malloc(dirlen + 2)))
+						out_of_memory("send_file_list");
+					memcpy(dir, fbuf, dirlen);
+					dir[dirlen] = '/';
+					dir[dirlen + 1] = 0;
+				}
+#endif
 				else
 					dir = fbuf;
-				len -= p - fbuf + 1;
-				fn = p + 1;
+				fn = p + 1;		// Point at filename part
+				len -= fn - fbuf;	//  fn length
+				// rprintf(FINFO, "* [%s] send_file_list fn %s len %d %s(%u)\n", who_am_i(), fn, len, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
 			} else
 				fn = fbuf;
 		} else {
 			if ((p = strstr(fbuf, "/./")) != NULL) {
 				*p = '\0';
 				if (p == fbuf)
-					dir = "/";
+					dir = the_root;
+#ifdef __OS2__
+				// 06 Mar 09 SHL Preserve drive letter
+				else if (p == fbuf + (dirlen = drive_spec_width(fbuf))) {
+					if (!(dir = malloc(dirlen + 2)))
+						out_of_memory("send_file_list");
+					memcpy(dir, fbuf, dirlen);
+					dir[dirlen] = '/';
+					dir[dirlen + 1] = 0;
+				}
+#endif
 				else {
 					dir = fbuf;
 					clean_fname(dir, 0);
@@ -2056,6 +2117,8 @@
 			}
 			len = clean_fname(fn, CFN_KEEP_TRAILING_SLASH
 					    | CFN_DROP_TRAILING_DOT_DIR);
+			rprintf(FINFO, "* [%s] send_file_list fn %s len %d %s(%u)\n", who_am_i(), fn, len, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
+			// 06 Mar 09 SHL fixme?
 			if (len == 1) {
 				if (fn[0] == '/') {
 					fn = "/.";
@@ -2088,6 +2151,8 @@
 			name_type = DOTDIR_NAME;
 		}
 
+		// rprintf(FINFO, "* [%s] send_file_list dir %s fn %s len %d %s(%u)\n", who_am_i(), dir ? dir : "(null)", fn, len, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
+
 		dirlen = dir ? strlen(dir) : 0;
 		if (dirlen != lastdir_len || memcmp(lastdir, dir, dirlen) != 0) {
 			if (!change_pathname(NULL, dir, -dirlen))
@@ -2097,9 +2162,16 @@
 		} else if (!change_pathname(NULL, lastdir, lastdir_len))
 			continue;
 
+		// 06 Mar 09 SHL
+		if (dir && dir != the_root && dir != fbuf)
+			free(dir);	// We allocated it
+
 		if (fn != fbuf)
 			memmove(fbuf, fn, len + 1);
 
+		// rprintf(FINFO, "* [%s] send_file_list fn %s %s(%u)\n", who_am_i(), fn, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
+		// rprintf(FINFO, "* [%s] send_file_list fbuf %s len %d %s(%u)\n", who_am_i(), fbuf, len, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
+
 		if (link_stat(fbuf, &st, copy_dirlinks || name_type != NORMAL_NAME) != 0
 		 || (name_type != DOTDIR_NAME && is_daemon_excluded(fbuf, S_ISDIR(st.st_mode)))
 		 || (relative_paths && path_is_daemon_excluded(fbuf, 1))) {
@@ -2120,12 +2192,14 @@
 		}
 
 		if (inc_recurse && relative_paths && *fbuf) {
+			// 06 Mar 09 SHL fixme
 			if ((p = strchr(fbuf+1, '/')) != NULL) {
 				if (p - fbuf == 1 && *fbuf == '.') {
 					if ((fn = strchr(p+1, '/')) != NULL)
 						p = fn;
 				} else
 					fn = p;
+			        // rprintf(FINFO, "* [%s] send_file_list %s %s(%u)\n", who_am_i(), fbuf, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
 				send_implied_dirs(f, flist, fbuf, fbuf, p, flags, name_type);
 				if (fn == p)
 					continue;
@@ -2133,6 +2207,7 @@
 		} else if (implied_dirs && (p=strrchr(fbuf,'/')) && p != fbuf) {
 			/* Send the implied directories at the start of the
 			 * source spec, so we get their permissions right. */
+			// rprintf(FINFO, "* [%s] send_file_list %s %s(%u)\n", who_am_i(), fbuf, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
 			send_implied_dirs(f, flist, fbuf, fbuf, p, flags, 0);
 		}
 
@@ -2141,6 +2216,7 @@
 
 		if (recurse || (xfer_dirs && name_type != NORMAL_NAME)) {
 			struct file_struct *file;
+			// rprintf(FINFO, "* [%s] send_file_list fbuf %s %s(%u)\n", who_am_i(), fbuf, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
 			file = send_file_name(f, flist, fbuf, &st,
 					      FLAG_TOP_DIR | FLAG_CONTENT_DIR | flags,
 					      NO_FILTERS);
@@ -2156,9 +2232,11 @@
 				}
 			} else
 				send_if_directory(f, flist, file, fbuf, len, flags);
-		} else
+		} else {
+			// rprintf(FINFO, "* [%s] send_file_list %s %s(%u)\n", who_am_i(), fbuf, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
 			send_file_name(f, flist, fbuf, &st, flags, NO_FILTERS);
 	}
+	}
 
 	gettimeofday(&end_tv, NULL);
 	stats.flist_buildtime = (int64)(end_tv.tv_sec - start_tv.tv_sec) * 1000
Only in .: flist.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/generator.c ./generator.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/generator.c	2008-11-10 07:46:40.000000000 -0800
+++ ./generator.c	2009-02-16 23:24:28.000000000 -0800
@@ -272,6 +272,7 @@
 	}
 
 	p = fname + dlen;
+	// 16 Feb 09 SHL fixme slash?
 	if (dlen != 1 || *fname != '/')
 		*p++ = '/';
 	remainder = MAXPATHLEN - (p - fname);
Only in .: generator.o
Only in .: hashtable.o
Only in .: hlink.o
Only in .: init_shl
Only in .: init_shl.cmd
Only in .: io.o
Only in ./lib: compat.o
Only in ./lib: ctags.tag
Only in ./lib: dummy
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/lib/getaddrinfo.c ./lib/getaddrinfo.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/lib/getaddrinfo.c	2008-10-25 08:39:40.000000000 -0700
+++ ./lib/getaddrinfo.c	2009-02-06 10:47:20.000000000 -0800
@@ -404,12 +404,16 @@
 	int ret = -1;
 	char *p = NULL;
 
+	// rprintf(FLOG, "* gethostnameinfo: NI_NUMERICHOST %u %s:%u\n", flags & NI_NUMERICHOST, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 	if (!(flags & NI_NUMERICHOST)) {
+		// rprintf(FLOG, "* gethostnameinfo: %s:%u\n", __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		struct hostent *hp = gethostbyaddr(
 				(void *)&((struct sockaddr_in *)sa)->sin_addr,
 				sizeof (struct in_addr),
 				sa->sa_family);
+		// rprintf(FLOG, "* gethostnameinfo: hp %p %s:%u\n", hp, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		ret = check_hostent_err(hp);
+		// rprintf(FLOG, "* ret %d %s:%u\n", ret, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		if (ret == 0) {
 			/* Name looked up successfully. */
 			ret = snprintf(node, nodelen, "%s", hp->h_name);
@@ -425,6 +429,7 @@
 			return 0;
 		}
 
+		// rprintf(FLOG, "* %s:%u\n", __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		if (flags & NI_NAMEREQD) {
 			/* If we require a name and didn't get one,
 			 * automatically fail. */
@@ -432,6 +437,7 @@
 		}
 		/* Otherwise just fall into the numeric host code... */
 	}
+	// rprintf(FLOG, "* %s:%u\n", __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 	p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr);
 	ret = snprintf(node, nodelen, "%s", p);
 	if (ret < 0 || (size_t)ret >= nodelen) {
Only in ./lib: getaddrinfo.o
Only in ./lib: md5.o
Only in ./lib: mdfour.o
Only in ./lib: permstring.o
Only in ./lib: pool_alloc.o
Only in ./lib: snprintf.o
Only in ./lib: sysacls.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/lib/sysxattrs.c ./lib/sysxattrs.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/lib/sysxattrs.c	2008-03-01 12:01:40.000000000 -0800
+++ ./lib/sysxattrs.c	2009-03-07 09:27:18.000000000 -0800
@@ -126,6 +126,373 @@
 	return len;
 }
 
+#elif defined(__OS2__)
+
+#define INCL_LONGLONG
+#define INCL_DOS
+#define INCL_DOSPROCESS
+#define INCL_DOSPROFILE
+#define INCL_DOSMISC
+#define INCL_DOSMODULEMGR
+#define INCL_DOSERRORS
+
+#include <os2.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <types.h>
+ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
+{
+	return unigetxattr(path, 0, name, value, size);
+}
+
+ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
+{
+	return unigetxattr(0, filedes, name, value, size);
+}
+
+int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
+{
+	return unisetxattr (path, 0, name, value, size, 0);
+}
+
+int sys_lremovexattr(const char *path, const char *name)
+{
+	return uniremovexattr (path, 0, name);
+}
+
+ssize_t sys_llistxattr(const char *path, char *list, size_t size)
+{
+	return unilistxattr(path, 0, list, size);
+}
+
+ssize_t unigetxattr (const char *path, int file, const char *name, void *value, size_t size)
+{
+	int rc, namelen;
+	EAOP2       eaop2 = {0,0,0};
+	PGEA2LIST   pgea2list = NULL;
+	PFEA2LIST   pfea2list = NULL;
+	char * p;
+
+	if ((!path && !file) || !name)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	namelen = strlen(name);
+	if (namelen > 0xFF)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	pgea2list = (PGEA2LIST)calloc(sizeof(GEA2LIST) + namelen + 1, 1);
+	pgea2list->list[0].oNextEntryOffset = 0;
+	pgea2list->list[0].cbName = namelen;
+	strcpy(pgea2list->list[0].szName, name);
+	pgea2list->cbList = sizeof(GEA2LIST) + namelen;
+
+	// max ea is 64kb
+	pfea2list = (PFEA2LIST)calloc(sizeof(FEA2LIST) + 0x10000, 1);
+	pfea2list->cbList = sizeof(FEA2LIST) + 0x10000;
+
+	eaop2.fpGEA2List = pgea2list;
+	eaop2.fpFEA2List = pfea2list;
+	eaop2.oError = 0;
+	do
+	{
+		if (path)
+		{
+			char npath[CCHMAXPATH + 1] = {0};
+			strncpy(npath, path, CCHMAXPATH);
+			for (p = npath; *p; p++)
+			{
+				if (*p == '/') *p = '\\';	// 29 Jul 08 SHL fixme to be gone? - OS/2 does not care?
+			}
+			rc = DosQueryPathInfo(npath, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2));
+			if (rc)
+				rprintf(FERROR, "* unigetxattr: DosQueryPathInfo(%s, FIL_QUERYEASFROMLIST) returned %u %s:%u\n", npath, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+			else if (verbose > 2)
+				rprintf(FINFO, "%s has %lu EA bytes\n", path, eaop2.fpFEA2List->cbList);	// 28 Jul 08 SHL
+		}
+		else
+		{
+			rc = DosQueryFileInfo( file, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2));
+			if (rc)
+				rprintf(FERROR, "* unigetxattr: DosQueryFileInfo(%u, FIL_QUERYEASFROMLIST) returned %u %s:%u\n", file, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+			else if (verbose > 2)
+				rprintf(FINFO, "Handle %d has %lu EA bytes\n", file, eaop2.fpFEA2List->cbList);	// 28 Jul 08 SHL
+		}
+		if (rc)
+		{
+			break;
+		}
+		if (strnicmp(pfea2list->list[0].szName, name, namelen) || pfea2list->list[0].cbValue == 0)
+		{
+			errno = ENOATTR;
+			rc = -1;
+			break;
+		}
+		rc = pfea2list->list[0].cbValue;
+		if (value)
+		{
+			if ((size_t)rc > size)
+			{
+				errno = ERANGE;
+				rc = -1;
+			}
+			else
+			{
+				p = pfea2list->list[0].szName + pfea2list->list[0].cbName + 1;
+				memcpy(value, p, rc);
+			}
+		}
+	} while (0);
+	if (pgea2list)
+	{
+		free(pgea2list);
+	}
+	if (pgea2list)
+	{
+		free(pfea2list);
+	}
+
+	return rc;
+}
+
+ssize_t unilistxattr (const char *path, int file, char *list, size_t size)
+{
+	ssize_t gotsize = 0;
+	unsigned long ulCount = -1;
+	int rc;
+	char * buf, *p = list;
+	PFEA2 pfea;
+	FILESTATUS4 stat;
+	char npath[CCHMAXPATH + 1] = {0};
+	memset(&stat, 0, sizeof(stat));
+	if (!path && !file)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	if (path)
+	{
+		char * p;
+		strncpy(npath, path, CCHMAXPATH);
+		for (p = npath; *p; p++)
+		{
+			if (*p == '/') *p = '\\';
+		}
+		rc = DosQueryPathInfo(npath, FIL_QUERYEASIZE, &stat, sizeof(stat));
+		if (rc)
+			rprintf(FERROR, "* unilistxattr: DosQueryPathInfo(%s, FIL_QUERYEASIZE) returned %u %s:%u\n", npath, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		else if (verbose > 2)
+			rprintf(FINFO, "%s has %lu EA bytes\n", path, stat.cbList);	// 28 Jul 08 SHL
+	}
+	else
+	{
+		rc = DosQueryFileInfo( file, FIL_QUERYEASIZE, &stat, sizeof(stat));
+		if (rc)
+			rprintf(FERROR, "* unilistxattr: DosQueryFilInfo(%u, FIL_QUERYEASIZE) returned %u %s:%u\n", file, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		else if (verbose > 2)
+			rprintf(FINFO, "Handle %d has %lu EA bytes\n", file, stat.cbList);	// 28 Jul 08 SHL
+	}
+	if (rc)
+	{
+		return -1;
+	}
+	if (stat.cbList <= 4)
+	{
+		// NO ea
+		return 0;
+	}
+	//YD DosEnumAttribute doesn't like high-mem buffers, get a low one.
+	buf = (char *)_tmalloc(stat.cbList * 2);
+	rc = DosEnumAttribute(path ? 1 : 0, path ? (PVOID)path : (PVOID)&file, 1, (PVOID)buf, stat.cbList * 2, &ulCount, 1);
+	if (rc)
+	{
+		rprintf(FERROR, "* unilistxattr: DosEnumAttribute returned %u %s:%u\n", rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		_tfree(buf);
+		return -1;
+	}
+	else if (verbose > 2) {
+		if (path)
+			rprintf(FINFO, "%s has %lu EA items\n", path, ulCount);	// 28 Jul 08 SHL
+		else
+			rprintf(FINFO, "Handle %d has %lu EA items\n", file, ulCount);	// 28 Jul 08 SHL
+	}
+	if (ulCount > 0)
+	for (pfea = (PFEA2)buf;;pfea = (PFEA2)((char *)pfea + pfea->oNextEntryOffset))
+	{
+		if (pfea->cbName > 0)
+		{
+			gotsize += pfea->cbName + 1;
+			// Avoid overflow
+			if (p && (size_t)gotsize <= size)
+			{
+				pfea->szName[pfea->cbName] = 0;
+				strcpy(p, pfea->szName);
+				p += strlen(p) + 1;
+			}
+		}
+		if (!pfea->oNextEntryOffset)
+		{
+			break;
+		}
+	}
+	_tfree(buf);
+	if ((size_t)gotsize > size)
+	{
+		errno = ERANGE;
+		return list ? -1 : gotsize;
+	}
+	if (verbose > 2)
+		rprintf(FINFO, "Returning %ld EA list bytes\n", (unsigned long)gotsize);	// 28 Jul 08 SHL
+	return gotsize;
+}
+
+int uniremovexattr (const char *path, int file, const char *name)
+{
+	int rc, namelen;
+	EAOP2 eaop2 = {0,0,0};
+	PFEA2LIST pfea2list = NULL;
+	char buf[300] = {0};
+
+	if ((!path && !file) || !name)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	namelen = strlen(name);
+	if (namelen > 0xFF)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	pfea2list = (PFEA2LIST)buf;
+	pfea2list->list[0].cbName = namelen;
+	pfea2list->list[0].cbValue = 0;
+	pfea2list->list[0].fEA = 0;
+	strcpy(pfea2list->list[0].szName, name);
+	pfea2list->cbList = sizeof(FEA2LIST) + namelen;
+	eaop2.fpFEA2List = pfea2list;
+
+	if (path)
+	{
+		char npath[CCHMAXPATH + 1];
+		char * p;
+		strncpy(npath, path, CCHMAXPATH);
+		for (p = npath; *p; p++)
+		{
+			if (*p == '/') *p = '\\';
+		}
+		rc = DosSetPathInfo(npath, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), DSPI_WRTTHRU);
+		if (rc)
+			rprintf(FERROR, "* uniremovexattr: DosSetPathInfo(%s, FIL_QUERYEASIZE) returned %u %s:%u\n", npath, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		else if (verbose > 1)
+			rprintf(FINFO, "Deleted EA %s from %s\n", name, path);	// 28 Jul 08 SHL
+	}
+	else
+	{
+		rc = DosSetFileInfo( file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2));
+		if (rc)
+			rprintf(FERROR, "* uniremovexattr: DosFileInfo(%u, FIL_QUERYEASIZE) returned %u %s:%u\n", file, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		else if (verbose > 1)
+			rprintf(FINFO, "Deleted EA %s from handle %d \n", name, file);	// 28 Jul 08 SHL
+	}
+	if (rc)
+	{
+		return -1;
+	}
+	return 0;
+}
+
+#ifndef XATTR_CREATE
+#define XATTR_CREATE  1
+#endif
+#ifndef XATTR_REPLACE
+#define XATTR_REPLACE 2
+#endif
+
+int unisetxattr (const char *path, int file, const char *name, const void *value, size_t size, int flags)
+{
+	int rc, namelen, totalsize;
+	EAOP2       eaop2 = {0,0,0};
+	PFEA2LIST   pfea2list = NULL;
+	char * p;
+
+	if ((!path && !file) || !name || (!value && size))
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	namelen = strlen(name);
+	if (namelen > 0xFF)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (flags & (XATTR_CREATE | XATTR_REPLACE))
+	{
+		ssize_t esize = unigetxattr(path, file, name, 0, 0);
+		if (flags & XATTR_CREATE && esize > 0)
+		{
+			errno = EEXIST;
+			return -1;
+		}
+		if (flags & XATTR_REPLACE && esize < 0)
+		{
+			errno = ENOATTR;
+			return -1;
+		}
+	}
+
+	totalsize = sizeof(FEA2LIST) + size + namelen + 1;
+
+	pfea2list = (PFEA2LIST)calloc(totalsize, 1);
+	pfea2list->cbList = totalsize;
+	pfea2list->list[0].oNextEntryOffset = 0;
+	pfea2list->list[0].cbName = namelen;
+	pfea2list->list[0].cbValue = size;
+	strcpy(pfea2list->list[0].szName, name);
+	if (value)
+	{
+		memcpy(pfea2list->list[0].szName + namelen + 1, value, size);
+	}
+	eaop2.fpFEA2List = pfea2list;
+
+	if (path)
+	{
+		char npath[CCHMAXPATH + 1] = {0};
+		strncpy(npath, path, CCHMAXPATH);
+		for (p = npath; *p; p++)
+		{
+			if (*p == '/') *p = '\\';
+		}
+		rc = DosSetPathInfo(npath, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), DSPI_WRTTHRU);
+		if (rc)
+			rprintf(FERROR, "* unisetxattr: DosSetPathInfo(%s, FIL_QUERYEASIZE) returned %u %s:%u\n", npath, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		else if (verbose > 1)
+			rprintf(FINFO, "Set EA %s for %s\n", name, path);	// 28 Jul 08 SHL
+	}
+	else
+	{
+		rc = DosSetFileInfo( file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2));
+		if (rc)
+			rprintf(FERROR, "* unisetxattr: DosSetFileInfo(%u, FIL_QUERYEASIZE) returned %u %s:%u\n", file, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		else if (verbose > 1)
+			rprintf(FINFO, "Set EA %s for handle %d\n", name, file);	// 28 Jul 08 SHL
+	}
+	free(pfea2list);
+	if (rc)
+	{
+		return -1;
+	}
+	return 0;
+}
+
 #else
 
 #error You need to create xattr compatibility functions.
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/lib/sysxattrs.h ./lib/sysxattrs.h
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/lib/sysxattrs.h	2007-04-07 10:22:24.000000000 -0700
+++ ./lib/sysxattrs.h	2009-02-06 10:47:20.000000000 -0800
@@ -19,6 +19,13 @@
 int sys_lremovexattr(const char *path, const char *name);
 ssize_t sys_llistxattr(const char *path, char *list, size_t size);
 
+#ifdef __OS2__
+ssize_t unigetxattr (const char *path, int file, const char *name, void *value, size_t size);
+ssize_t unilistxattr (const char *path, int file, char *list, size_t size);
+int uniremovexattr (const char *path, int file, const char *name);
+int unisetxattr (const char *path, int file, const char *name, const void *value, size_t size, int flags);
+#endif
+
 #else
 
 /* No xattrs available */
Only in ./lib: sysxattrs.o
Only in ./lib: wildmatch.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/loadparm.c ./loadparm.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/loadparm.c	2008-02-15 22:19:42.000000000 -0800
+++ ./loadparm.c	2009-03-06 20:21:28.000000000 -0800
@@ -630,6 +630,9 @@
                          service *pserviceSource)
 {
   int i;
+#ifdef __OS2__
+  char *p;
+#endif
 
   for (i=0;parm_table[i].label;i++)
     if (parm_table[i].ptr && parm_table[i].class == P_LOCAL) {
@@ -656,10 +659,26 @@
 	    *(char *)dest_ptr = *(char *)src_ptr;
 	    break;
 
+#ifndef __OS2__
 	  case P_PATH:
 	  case P_STRING:
 	    string_set(dest_ptr,*(char **)src_ptr);
 	    break;
+#else
+	  case P_PATH:
+	    string_set(dest_ptr,*(char **)src_ptr);
+	    // 06 Mar 09 SHL Force unix slashes
+	    if ((p = *(char **)dest_ptr)) {
+	        for (; *p; p++) {
+	          if (*p == '\\') *p = '/';
+	        }
+	    }
+	    break;
+
+	  case P_STRING:
+	    string_set(dest_ptr,*(char **)src_ptr);
+	    break;
+#endif
 
 	  default:
 	    break;
@@ -728,7 +747,12 @@
        string_set(parm_ptr,parmvalue);
        if ((cp = *(char**)parm_ptr) != NULL) {
 	   int len = strlen(cp);
+#ifndef __OS2__
 	   while (len > 1 && cp[len-1] == '/') len--;
+#else
+	   int drive_letter_adj = *(cp + 1) == ':' && isalpha(*cp) ? 2 : 0;
+	   while (len > 1 + drive_letter_adj && cp[len-1] == '/') len--;
+#endif
 	   cp[len] = '\0';
        }
        break;
Only in .: loadparm.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/log.c ./log.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/log.c	2008-09-26 21:19:50.000000000 -0700
+++ ./log.c	2009-04-27 19:50:54.000000000 -0700
@@ -371,6 +371,7 @@
 	va_list ap;
 	char buf[BIGPATHBUFLEN];
 	size_t len;
+	int e = errno;			// 27 Apr 09 SHL preserve errno
 
 	va_start(ap, format);
 	len = vsnprintf(buf, sizeof buf, format, ap);
@@ -403,6 +404,7 @@
 	}
 
 	rwrite(code, buf, len, 0);
+	errno = e;
 }
 
 /* This is like rprintf, but it also tries to print some
Only in .: log.o
Only in .: m_shl
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/main.c ./main.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/main.c	2008-10-11 11:14:42.000000000 -0700
+++ ./main.c	2009-02-16 23:13:48.000000000 -0800
@@ -529,8 +529,9 @@
 		/* If the destination is a dir, enter it and use mode 1. */
 		if (S_ISDIR(st.st_mode)) {
 			if (!change_dir(dest_path, CD_NORMAL)) {
-				rsyserr(FERROR, errno, "change_dir#1 %s failed",
+				rsyserr(FERROR, errno, "change_dir %s failed",
 					full_fname(dest_path));
+				rprintf(FLOG, "* dest_path %s %s(%u)\n", dest_path, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 				exit_cleanup(RERR_FILESELECT);
 			}
 			return NULL;
@@ -589,8 +590,9 @@
 		}
 
 		if (!change_dir(dest_path, dry_run > 1 ? CD_SKIP_CHDIR : CD_NORMAL)) {
-			rsyserr(FERROR, errno, "change_dir#2 %s failed",
+			rsyserr(FERROR, errno, "change_dir %s failed",
 				full_fname(dest_path));
+			rprintf(FLOG, "* dest_path %s %s(%u)\n", dest_path, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 			exit_cleanup(RERR_FILESELECT);
 		}
 
@@ -609,8 +611,9 @@
 
 	*cp = '\0';
 	if (!change_dir(dest_path, CD_NORMAL)) {
-		rsyserr(FERROR, errno, "change_dir#3 %s failed",
+		rsyserr(FERROR, errno, "change_dir %s failed",
 			full_fname(dest_path));
+		rprintf(FLOG, "* dest_path %s %s(%u)\n", dest_path, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 		exit_cleanup(RERR_FILESELECT);
 	}
 	*cp = '/';
@@ -702,8 +705,9 @@
 
 	if (!relative_paths) {
 		if (!change_dir(dir, CD_NORMAL)) {
-			rsyserr(FERROR, errno, "change_dir#3 %s failed",
+			rsyserr(FERROR, errno, "change_dir %s failed",
 				full_fname(dir));
+			rprintf(FLOG, "* dir %s %s(%u)\n", dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 			exit_cleanup(RERR_FILESELECT);
 		}
 	}
@@ -874,6 +878,7 @@
 		if (!am_daemon && !change_dir(dir, CD_NORMAL)) {
 			rsyserr(FERROR, errno, "change_dir#4 %s failed",
 				full_fname(dir));
+			rprintf(FLOG, "* dir %s %s(%u)\n", dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 			exit_cleanup(RERR_FILESELECT);
 		}
 	}
@@ -922,12 +927,14 @@
 		struct filter_list_struct *elp = &daemon_filter_list;
 
 		for (dir_p = basis_dir; *dir_p; dir_p++) {
+			// 16 Feb 09 SHL fixme slash?
 			char *dir = *dir_p;
 			if (*dir == '/')
 				dir += module_dirlen;
 			if (check_filter(elp, FLOG, dir, 1) < 0)
 				goto options_rejected;
 		}
+		// 16 Feb 09 SHL fixme slash?
 		if (partial_dir && *partial_dir == '/'
 		 && check_filter(elp, FLOG, partial_dir + module_dirlen, 1) < 0) {
 		    options_rejected:
@@ -1441,6 +1448,7 @@
 	 * (implemented by forking "pwd" and reading its output) doesn't
 	 * work when there are other child processes.  Also, on all systems
 	 * that implement getcwd that way "pwd" can't be found after chroot. */
+	// rprintf(FLOG, "* %s %s(%u)\n", "(null)", __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 	change_dir(NULL, CD_NORMAL);
 
 	init_flist();
Only in .: main.o
Only in .: match.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/options.c ./options.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/options.c	2008-11-09 18:55:14.000000000 -0800
+++ ./options.c	2009-03-06 11:54:36.000000000 -0800
@@ -51,7 +51,12 @@
 int preserve_links = 0;
 int preserve_hard_links = 0;
 int preserve_acls = 0;
+#ifndef __OS2__
 int preserve_xattrs = 0;
+#else
+/* OS/2 uses Extended attributes extensively - make preserving them the default */
+int preserve_xattrs = 1;
+#endif
 int preserve_perms = 0;
 int preserve_executability = 0;
 int preserve_devices = 0;
@@ -1034,6 +1039,7 @@
 		case OPT_EXCLUDE_FROM:
 		case OPT_INCLUDE_FROM:
 			arg = poptGetOptArg(pc);
+			// printf("PS - pc = %s\n",arg);	// 16 Feb 09 SHL fixme debug ps?
 			if (sanitize_paths)
 				arg = sanitize_path(NULL, arg, NULL, 0, SP_DEFAULT);
 			if (daemon_filter_list.head) {
@@ -1043,6 +1049,7 @@
 					out_of_memory("parse_arguments");
 				if (!*cp)
 					goto options_rejected;
+				// 16 Feb 09 SHL fixme slash?
 				dir = cp + (*cp == '/' ? module_dirlen : 0);
 				clean_fname(dir, CFN_COLLAPSE_DOT_DOT_DIRS);
 				rej = check_filter(&daemon_filter_list, FLOG, dir, 0) < 0;
@@ -2138,7 +2145,10 @@
 
 	*host_ptr = new_array(char, hostlen + 1);
 	strlcpy(*host_ptr, s, hostlen + 1);
-
+#ifdef __OS2__
+	if (p[0] == ':' && (p[1] == '\\' || p[1] == '/'))
+                return NULL;		// Assume drive letter
+#endif
 	if (p[1] == ':') {
 		if (port_ptr && !*port_ptr)
 			*port_ptr = RSYNC_PORT;
Only in .: options.o
Only in .: params.o
Only in .: patch_shl.cmd
Only in .: patch_shl.out
Only in .: pipe.o
Only in ./popt: ctags.tag
Only in ./popt: dummy
Only in ./popt: findme.o
Only in ./popt: popt.o
Only in ./popt: poptconfig.o
Only in ./popt: popthelp.o
Only in ./popt: poptparse.o
Only in .: progress.o
Only in .: readme.os2
Only in .: receiver.o
Only in .: rounding.exe
Only in .: rounding.h
Only in .: rounding.map
Only in .: rsync-3.0.5-20090206-shl.diff
Only in .: rsync-3.0.5-20090306-before-shl.diff
Only in .: rsync-3.0.5-20090306-shl.diff
Only in .: rsync-3.0.5-20090306-shl_diff.zip
Only in .: rsync-3.0.5-20090410-shl.diff
Only in .: rsync-3.0.5-20090427-shl.diff
Only in .: rsync-3.0.5pre2-20090206-shl.diff
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/rsync.c ./rsync.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/rsync.c	2008-10-11 10:16:46.000000000 -0700
+++ ./rsync.c	2009-04-27 10:57:28.000000000 -0700
@@ -386,6 +386,8 @@
 	mode_t new_mode = file->mode;
 	int inherit;
 
+	rprintf(FINFO, "* set_file_attrs fname %s mode %o file %p sxp %p %s(%u)\n", fname, file->mode, file, sxp, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+
 	if (!sxp) {
 		if (dry_run)
 			return 1;
@@ -498,6 +500,7 @@
 
 #ifdef HAVE_CHMOD
 	if (!BITS_EQUAL(sxp->st.st_mode, new_mode, CHMOD_BITS)) {
+		rprintf(FINFO, "* set_file_attrs fname %s new_mode %o %s(%u)\n", fname, new_mode, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
 		int ret = am_root < 0 ? 0 : do_chmod(fname, new_mode);
 		if (ret < 0) {
 			rsyserr(FERROR_XFER, errno,
@@ -555,6 +558,7 @@
 		    int overwriting_basis)
 {
 	int ret;
+	// 16 Feb 09 SHL fixme slash?
 	const char *temp_copy_name = partialptr && *partialptr != '/' ? partialptr : NULL;
 
 	if (inplace) {
Only in .: rsync.exe
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/rsync.h ./rsync.h
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/rsync.h	2008-09-26 21:21:52.000000000 -0700
+++ ./rsync.h	2009-03-06 13:14:38.000000000 -0800
@@ -1144,3 +1144,19 @@
 #ifdef MAINTAINER_MODE
 const char *get_panic_action(void);
 #endif
+
+// 05 Mar 09 SHL
+#ifndef __OS2__
+#define drive_spec_width(p) 0
+#define is_path_sep(p) (*(p) == '/')
+#define is_path_sep2(p) (*(p) == '/')
+#define is_abs_path(p) (*(p) == '/')
+#define is_abs_path2(p) (*(p) == '/')
+#else
+#define drive_spec_width(p) ((isalpha(*(p)) && *((p) + 1) == ':') ? 2 : 0)
+#define is_path_sep(p) (*(p) == '/')	// Unix only
+#define is_path_sep2(p) (*(p) == '/' || *(p) == '\\')	// Unix or OS/2
+#define is_abs_path(p) (*((p) + drive_spec_width(p)) == '/')	// Unix only
+// Unix or OS/2
+#define is_abs_path2(p) ((*((p) + drive_spec_width(p)) == '/') || (*((p) + drive_spec_width(p)) == '\\'))
+#endif
Only in .: rsync.map
Only in .: rsync.o
Only in .: rsync_exe-20090306.zip
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/sender.c ./sender.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/sender.c	2008-08-14 07:32:18.000000000 -0700
+++ ./sender.c	2009-03-06 14:07:08.000000000 -0800
@@ -363,7 +363,7 @@
 		make_backups = -make_backups;
 
 	if (verbose > 2)
-		rprintf(FINFO, "send files finished\n");
+		rprintf(FINFO, "send_files finished\n");	// 06 Mar 09 SHL
 
 	match_report();
 
Only in .: sender.o
Only in .: shconfig
Only in .: socket.o
Only in ./support: ctags.tag
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/syscall.c ./syscall.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/syscall.c	2008-03-21 07:26:24.000000000 -0700
+++ ./syscall.c	2009-04-27 18:56:38.000000000 -0700
@@ -28,6 +28,18 @@
 #ifdef HAVE_SYS_ATTR_H
 #include <sys/attr.h>
 #endif
+// 06 Mar 09 SHL libc io.h name conflict with rsync io.h - need to cheat to define setmode
+#if defined HAVE_SETMODE && O_BINARY && __OS2__
+// From gcc io.h
+int setmode (int, int);
+// From gcc os2emx.h
+#endif
+#if defined __OS2__
+// 27 Apr 09 SHL Need definitions for FILE_...
+#define INCL_DOS
+// #include <os2.h>
+#include <os2emx.h>
+#endif
 
 extern int dry_run;
 extern int am_root;
@@ -152,6 +164,9 @@
 	int code;
 	if (dry_run) return 0;
 	RETURN_ERROR_IF_RO_OR_LO;
+
+	rprintf(FINFO, "* do_chmod path %s mode %o %s(%u)\n", path, mode, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+
 	if (S_ISLNK(mode)) {
 #ifdef HAVE_LCHMOD
 		code = lchmod(path, mode & CHMOD_BITS);
@@ -167,7 +182,51 @@
 		code = 1;
 #endif
 	} else
+#ifndef __OS2__
 		code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */
+#else
+	{
+		ULONG attributes = 0;
+		code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */
+		if (!code) {
+			// 27 Apr 09 SHL map mode to os/2 permissions
+			// Adjust attributes for system and hidden files
+			// Maybe libc will do this someday
+			// chmod handles readonly already
+			if (~mode & S_IRUSR) {
+				switch (mode & (S_IRGRP | S_IROTH)) {
+				case S_IRGRP:
+					attributes = FILE_SYSTEM | FILE_HIDDEN;
+					break;
+				case S_IRGRP | S_IROTH:
+					attributes = FILE_SYSTEM;
+					break;
+				default:
+					attributes = FILE_HIDDEN;
+				}
+			}
+			if (attributes) {
+				FILESTATUS3 fs3;
+				APIRET apiret = DosQueryPathInfo((PCSZ)path,
+								 FIL_STANDARD,
+								 &fs3,
+								 sizeof(fs3));
+				if (apiret)
+					rprintf(FERROR, "DosQueryPathInfo(%s) failed with error %lu %s(%u)\n", path, apiret, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+				else {
+					fs3.attrFile |= attributes;
+					rprintf(FINFO, "* do_chmod path %s attrFile %lx %s(%u)\n", path, fs3.attrFile, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+					apiret = DosSetPathInfo((PCSZ)path,
+								 FIL_STANDARD,
+								 &fs3, sizeof(fs3),
+								 0);
+					if (apiret)
+						rprintf(FERROR, "DosSetPathInfo(%s) failed with error %lu %s(%u)\n", path, apiret, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+				}
+			}
+		}
+	}
+#endif
 	if (code != 0 && (preserve_perms || preserve_executability))
 		return code;
 	return 0;
@@ -238,12 +297,41 @@
 #endif
 }
 
+#ifdef __OS2__
+
+static void map_os2_attributes(STRUCT_STAT *st)
+{
+	// If readonly, writable by none
+	if (st->st_attr & FILE_READONLY)
+		st->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+	// If hidden, readable by none
+	if (st->st_attr & FILE_HIDDEN)
+		st->st_mode &= ~(S_IRUSR | S_IRGRP | S_IROTH);
+	// If system, not readable by owner, readable by group - hack cough
+	// If system, hidden not readable by owner, not readable by others
+	if (st->st_attr & FILE_SYSTEM) {
+		st->st_mode &= ~S_IRUSR;
+		st->st_mode |= S_IRGRP;
+	}
+}
+
+#endif
+
 int do_stat(const char *fname, STRUCT_STAT *st)
 {
 #ifdef USE_STAT64_FUNCS
 	return stat64(fname, st);
 #else
+#ifndef __OS2__
 	return stat(fname, st);
+#else
+	int code;
+	code = stat(fname, st);
+	if (!code)
+		map_os2_attributes(st);
+	rprintf(FINFO, "* do_stat fname %s st->st_mode %o st->st_attr %o code %d %s(%u)\n", fname, st->st_mode, st->st_attr, code, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+	return code;
+#endif
 #endif
 }
 
@@ -253,7 +341,16 @@
 # ifdef USE_STAT64_FUNCS
 	return lstat64(fname, st);
 # else
+#ifndef __OS2__
 	return lstat(fname, st);
+#else
+	// 27 Apr 09 SHL map OS/2 permissions
+	int code = lstat(fname, st);
+	if (!code)
+		map_os2_attributes(st);
+	rprintf(FINFO, "* do_lstat fname %s st->st_mode %o st->st_attr %o code %d %s(%u)\n", fname, st->st_mode, st->st_attr, code, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+	return code;
+#endif
 # endif
 #else
 	return do_stat(fname, st);
@@ -265,7 +362,16 @@
 #ifdef USE_STAT64_FUNCS
 	return fstat64(fd, st);
 #else
+#ifndef __OS2__
 	return fstat(fd, st);
+#else
+	int code;
+	code = fstat(fd, st);
+	if (!code)
+		map_os2_attributes(st);
+	rprintf(FINFO, "* do_fstat fd %d st->st_mode %o st->st_attr %o code %d %s(%u)\n", fd, st->st_mode, st->st_attr, code, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+	return code;
+#endif
 #endif
 }
 
Only in .: syscall.o
Only in .: token.o
Only in .: uidlist.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/util.c ./util.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/util.c	2008-11-15 14:17:48.000000000 -0800
+++ ./util.c	2009-04-27 19:44:04.000000000 -0700
@@ -23,6 +23,10 @@
 #include "rsync.h"
 #include "ifuncs.h"
 
+#ifdef __OS2__
+#include <os2emx.h>
+#endif
+
 extern int verbose;
 extern int dry_run;
 extern int module_id;
@@ -191,6 +195,10 @@
 	char *p;
 	int ret = 0;
 
+#ifdef __OS2__ // 06 Mar 09 SHL use drive_spec_width
+	fname += drive_spec_width(fname);		/* Bypass drive letter */
+#endif /* __OS2__ */
+
 	while (*fname == '/')
 		fname++;
 	while (strncmp(fname, "./", 2) == 0)
@@ -420,6 +428,8 @@
 {
 	int tries = 4;
 
+	rprintf(FINFO, "* robust_rename %s->%s %s(%u)\n", from, to, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+
 	while (tries--) {
 		if (do_rename(from, to) == 0)
 			return 0;
@@ -444,6 +454,26 @@
 				return -2;
 			do_unlink(from);
 			return 1;
+#ifdef __OS2__ // 27 Apr 09 SHL
+		// libc rename semantics differs from linux
+		// clear readonly if this caused rename to fail
+		case EACCES:
+		{
+			STRUCT_STAT st;
+			int code;
+			rprintf(FINFO, "* robust_rename %s EACCES %s(%u)\n", to, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+			code = do_stat(to, &st);
+			if (!code) {
+				// 27 Apr 09 SHL fixme to use st_mode when libc fixed
+				if (st.st_attr & FILE_READONLY) {
+					st.st_mode |= S_IWUSR;
+					code = do_chmod(to, st.st_mode);
+					if (!code)
+						break;	// Try again
+				}
+			}
+		}
+#endif
 		default:
 			return -1;
 		}
@@ -818,10 +848,18 @@
 {
 	char *limit = name - 1, *t = name, *f = name;
 	int anchored;
+#ifdef __OS2__
+	int drive_letter_adj;	// 0 if not, 2 if yes 15 Dec 08 SHL
+#endif
 
 	if (!name)
 		return 0;
 
+#ifdef __OS2__ // 06 Mar 09 SHL use drive_spec_width...
+	drive_letter_adj = drive_spec_width(name);
+	f += drive_letter_adj;			// Keep drive letter
+	t += drive_letter_adj;
+#endif /* __OS2__ */
 	if ((anchored = *f == '/') != 0) {
 		*t++ = *f++;
 #ifdef __CYGWIN__
@@ -869,10 +907,18 @@
 		while (*f && (*t++ = *f++) != '/') {}
 	}
 
+#ifndef __OS2__ // 06 Feb 09 SHL
 	if (t > name+anchored && t[-1] == '/' && !(flags & CFN_KEEP_TRAILING_SLASH))
 		t--;
 	if (t == name)
 		*t++ = '.';
+#else
+	if (t > name + anchored + drive_letter_adj && t[-1] == '/' && !(flags & CFN_KEEP_TRAILING_SLASH))
+		t--;
+	if (t == name + drive_letter_adj)
+		*t++ = '.';		// Ensure not empty
+#endif
+
 	*t = '\0';
 
 	return t - name;
@@ -906,14 +952,28 @@
 	char *start, *sanp;
 	int rlen = 0, drop_dot_dirs = !relative_paths || !(flags & SP_KEEP_DOT_DIRS);
 
+	// rprintf(FINFO, "sanitize_path p %s %s(%u)\n", p, __FILE__, __LINE__);	// 06 Feb 09 SHL
 	if (dest != p) {
 		int plen = strlen(p);
-		if (*p == '/') {
+		int drive_letter_adj = drive_spec_width(p);	// 0 if not, 2 if yes 15 Dec 08 SHL
+#ifndef __OS2__
+		if (*p == '/')
+#else // 06 Feb 09 SHL use is_abs_path...
+		if (!is_abs_path2(p)) {
+			if (drive_letter_adj)
+				rprintf(FERROR, "relative directory with drive letter not supported %s %s(%u)\n", p, __FILE__, __LINE__);	// 06 Feb 09 SHL
+		} else
+#endif
+		{
 			if (!rootdir)
 				rootdir = module_dir;
 			rlen = strlen(rootdir);
 			depth = 0;
+#ifndef __OS2__
 			p++;
+#else
+			p += drive_spec_width(p) + 1;
+#endif
 		}
 		if (dest) {
 			if (rlen + plen + 1 >= MAXPATHLEN)
@@ -922,13 +982,19 @@
 			out_of_memory("sanitize_path");
 		if (rlen) {
 			memcpy(dest, rootdir, rlen);
+#ifndef __OS2__
 			if (rlen > 1)
 				dest[rlen++] = '/';
+#else
+			if (rlen > 1 + drive_letter_adj)
+				dest[rlen++] = '/';
+#endif
 		}
 	}
 
 	if (drop_dot_dirs) {
-		while (*p == '.' && p[1] == '/')
+		// 06 Mar 09 SHL Use is_path_sep2
+		while (*p == '.' && (is_path_sep2(p + 1)))
 			p += 2;
 	}
 
@@ -937,25 +1003,28 @@
 	 * the start of the name (past any prior slash) for each iteration. */
 	while (*p) {
 		/* discard leading or extra slashes */
-		if (*p == '/') {
+		// 06 Mar 09 SHL
+		if (is_path_sep2(p)) {
 			p++;
 			continue;
 		}
 		if (drop_dot_dirs) {
-			if (*p == '.' && (p[1] == '/' || p[1] == '\0')) {
+			// 06 Mar 09 SHL
+			if (*p == '.' && (is_path_sep2(p + 1) || p[1] == '\0')) {
 				/* skip "." component */
 				p++;
 				continue;
 			}
 		}
-		if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) {
+		if (*p == '.' && p[1] == '.' && (is_path_sep2(p + 2) || p[2] == '\0')) {
 			/* ".." component followed by slash or end */
 			if (depth <= 0 || sanp != start) {
 				p += 2;
 				if (sanp != start) {
 					/* back up sanp one level */
 					--sanp; /* now pointing at slash */
-					while (sanp > start && sanp[-1] != '/')
+					// 06 Mar 09 SHL
+					while (sanp > start && !is_path_sep2(sanp -1))
 						sanp--;
 				}
 				continue;
@@ -966,7 +1035,18 @@
 			start = sanp + 3;
 		}
 		/* copy one component through next slash */
+#ifndef __OS2__
 		while (*p && (*sanp++ = *p++) != '/') {}
+#else
+		while(*p) {
+			char c = *p++;
+			if (c == '\\')
+				c = '/';
+			*sanp++ = c;
+			if (c == '/')
+				break;
+		}
+#endif
 	}
 	if (sanp == dest) {
 		/* ended up with nothing, so put in "." component */
@@ -974,16 +1054,21 @@
 	}
 	*sanp = '\0';
 
+	// rprintf(FINFO, "sanitize_path dest %s %s(%u)\n", dest, __FILE__, __LINE__);	// 06 Feb 09 SHL
+
 	return dest;
 }
 
 /* Like chdir(), but it keeps track of the current directory (in the
  * global "curr_dir"), and ensures that the path size doesn't overflow.
- * Also cleans the path using the clean_fname() function. */
+ * Also cleans the path using the clean_fname() function.
+ * Returns 1 of change OK.  Otherwise 0 */
 int change_dir(const char *dir, int set_path_only)
 {
 	static int initialised;
 	unsigned int len;
+	rprintf(FINFO, "* change_dir dir %s %s(%u)\n", dir ? dir : "(null)", __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+	// rprintf(FLOG, "* change_dir dir %s %s(%u)\n", dir ? dir : "(null)", __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 
 	if (!initialised) {
 		initialised = 1;
@@ -992,6 +1077,7 @@
 			exit_cleanup(RERR_FILESELECT);
 		}
 		curr_dir_len = strlen(curr_dir);
+		rprintf(FLOG, "* change_dir curr_dir %s %s(%u)\n", curr_dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 	}
 
 	if (!dir)	/* this call was probably just to initialize */
@@ -1001,23 +1087,50 @@
 	if (len == 1 && *dir == '.')
 		return 1;
 
-	if (*dir == '/') {
+	// 06 Mar 09 SHL use is_abs_path
+	if (is_abs_path(dir)) {
+		// Absolute path
 		if (len >= sizeof curr_dir) {
 			errno = ENAMETOOLONG;
 			return 0;
 		}
+#ifndef __OS2__ // 28 Jul 08 SHL
 		if (!set_path_only && chdir(dir))
 			return 0;
 		memcpy(curr_dir, dir, len + 1);
+#else
+		if (!set_path_only) {
+			if (chdir(dir)) {
+				rprintf(FERROR, "* change_dir: chdir failed for dir %s %s(%u)\n", dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+				return 0;
+			}
+			// 06 Mar 09 SHL use drive_spec_width
+			if (drive_spec_width(dir) && _chdrive(*dir)) {
+				rprintf(FERROR, "* change_dir: _chdrive failed for dir %s %s(%u)\n", dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+				return 0;
+			}
+		}
+		memcpy(curr_dir, dir, len + 1);
+		// rprintf(FLOG, "* change_dir curr_dir %s %s(%u)\n", curr_dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+#endif
 	} else {
+		// Relative path
 		if (curr_dir_len + 1 + len >= sizeof curr_dir) {
 			errno = ENAMETOOLONG;
 			return 0;
 		}
+#ifdef __OS2__
+		if (drive_spec_width(dir)) {
+			rprintf(FERROR, "relative directory with drive letter not supported %s %s(%u)\n", dir, __FILE__, __LINE__);	// 06 Feb 09 SHL
+			errno = EINVAL;
+			return -1;
+		}
+#endif
 		curr_dir[curr_dir_len] = '/';
 		memcpy(curr_dir + curr_dir_len + 1, dir, len + 1);
 
 		if (!set_path_only && chdir(curr_dir)) {
+			rprintf(FERROR, "* change_dir: chdir failed for curr_dir %s %s(%u)\n", dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 			curr_dir[curr_dir_len] = '\0';
 			return 0;
 		}
@@ -1042,12 +1155,15 @@
 {
 	unsigned int len;
 
-	if (*path != '/') { /* Make path absolute. */
+	// 06 Mar 09 SHL use is_abs_path
+	if (!is_abs_path(path)) { /* Make path absolute. */
 		int len = strlen(path);
+		if (drive_spec_width(path))
+			rprintf(FERROR, "relative directory with drive letter not supported %s %s(%u)\n", path, __FILE__, __LINE__);	// 28 Jul 08 SHL
 		if (curr_dir_len + 1 + len >= sizeof curr_dir)
 			return NULL;
 		curr_dir[curr_dir_len] = '/';
-		memcpy(curr_dir + curr_dir_len + 1, path, len + 1);
+		memcpy(curr_dir + curr_dir_len + 1, path + drive_spec_width(path), len + 1);
 		if (!(path = strdup(curr_dir)))
 			out_of_memory("normalize_path");
 		curr_dir[curr_dir_len] = '\0';
@@ -1078,9 +1194,14 @@
 	if (result)
 		free(result);
 
-	if (*fn == '/')
+	// 06 Mar 09 SHL use is_abs_path
+	if (is_abs_path(fn))
 		p1 = p2 = "";
 	else {
+#ifdef __OS2__
+		if (drive_spec_width(fn))
+			rprintf(FERROR, "relative directory with drive letter not supported %s %s(%u)\n", fn, __FILE__, __LINE__);	// 06 Feb 09 SHL
+#endif
 		p1 = curr_dir + module_dirlen;
 		for (p2 = p1; *p2 == '/'; p2++) {}
 		if (*p2)
Only in .: util.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/xattrs.c ./xattrs.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/xattrs.c	2008-07-24 07:57:56.000000000 -0700
+++ ./xattrs.c	2009-04-27 09:51:18.000000000 -0700
@@ -48,17 +48,28 @@
 #define XSTATE_DONE	2
 #define XSTATE_TODO	3
 
+#ifndef __OS2__
 #define USER_PREFIX "user."
 #define UPRE_LEN ((int)sizeof USER_PREFIX - 1)
 #define SYSTEM_PREFIX "system."
 #define SPRE_LEN ((int)sizeof SYSTEM_PREFIX - 1)
+#else
+#define USER_PREFIX ""
+#define UPRE_LEN ((int)sizeof USER_PREFIX - 1)
+#define SYSTEM_PREFIX ""
+#define SPRE_LEN ((int)sizeof SYSTEM_PREFIX - 1)
+#endif
 
 #ifdef HAVE_LINUX_XATTRS
 #define MIGHT_NEED_RPRE (am_root < 0)
 #define RSYNC_PREFIX USER_PREFIX "rsync."
 #else
 #define MIGHT_NEED_RPRE am_root
+#ifndef __OS2__
 #define RSYNC_PREFIX "rsync."
+#else 
+# define RSYNC_PREFIX ""
+#endif
 #endif
 #define RPRE_LEN ((int)sizeof RSYNC_PREFIX - 1)
 
@@ -108,6 +119,8 @@
 {
 	const rsync_xa *xa1 = x1;
 	const rsync_xa *xa2 = x2;
+	// rprintf(FLOG, "* rsync_xal_compare_names: xa1.name %p xa2.name %p %s:%u\n", xa1->name, xa2->name, __FILE__, __LINE__);	// 28 Jul 08 SHL debug xattrs
+
 	return strcmp(xa1->name, xa2->name);
 }
 
@@ -713,8 +726,10 @@
 		rxa->num = num;
 	}
 
-	if (need_sort && count > 1)
-		qsort(temp_xattr.items, count, sizeof (rsync_xa), rsync_xal_compare_names);
+	// rprintf(FLOG, "* receive_xattr: temp_xattr.items %p count %u %s:%u\n", temp_xattr.items, count, __FILE__, __LINE__);	// 28 Jul 08 SHL debug xattrs
+	// 28 Jul 08 SHL sort used not malloced
+	if (need_sort && temp_xattr.count > 1)
+		qsort(temp_xattr.items, temp_xattr.count, sizeof (rsync_xa), rsync_xal_compare_names);
 
 	ndx = rsync_xal_l.count; /* pre-incremented count */
 	rsync_xal_store(&temp_xattr); /* adds item to rsync_xal_l */
Only in .: xattrs.o
Only in ./zlib: adler32.o
Only in ./zlib: compress.o
Only in ./zlib: crc32.o
Only in ./zlib: ctags.tag
Only in ./zlib: deflate.o
Only in ./zlib: dummy
Only in ./zlib: inffast.o
Only in ./zlib: inflate.o
Only in ./zlib: inftrees.o
Only in ./zlib: trees.o
Only in ./zlib: zutil.o
rsync-3.0.5-20090427-shl.diff (60,134 bytes)   
rsync-3.0.5-20090614-shl.diff (68,522 bytes)   
Only in .: 0_285_secrets
Only in .: 0_copy_from_root
Only in .: 0_preserve_perms
Only in .: Makefile
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/Makefile.in ./Makefile.in
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/Makefile.in	2008-11-15 15:32:02.000000000 -0800
+++ ./Makefile.in	2009-06-14 18:48:54.000000000 -0700
@@ -12,6 +12,7 @@
 CFLAGS=@CFLAGS@
 CPPFLAGS=@CPPFLAGS@
 EXEEXT=@EXEEXT@
+# 14 Jun 09 SHL fixme to do bldlevel strings
 LDFLAGS=@LDFLAGS@
 
 INSTALLCMD=@INSTALL@
@@ -189,9 +190,10 @@
 	yodl2man -o rsyncd.conf.5 $(srcdir)/rsyncd.conf.yo
 	-$(srcdir)/tweak_manpage rsyncd.conf.5
 
+# 06 Feb 09 SHL clean maps
 clean: cleantests
 	rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) \
-		rounding rounding.h *.old
+		rounding rounding.h *.old rsync.map rounding.map
 
 cleantests:
 	rm -rf ./testtmp*
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/access.c ./access.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/access.c	2008-03-01 12:01:40.000000000 -0800
+++ ./access.c	2009-02-06 10:47:20.000000000 -0800
@@ -100,7 +100,9 @@
 	hints.ai_flags = AI_NUMERICHOST;
 #endif
 
-	if (getaddrinfo(addr, NULL, &hints, &resa) != 0) {
+	// if (getaddrinfo(addr, NULL, &hints, &resa) != 0) {
+	if ((gai = getaddrinfo(addr, NULL, &hints, &resa)) != 0) {			// 27 Jul 08 SHL debug
+		// rprintf(FLOG, "* match_address: gai %d %s:%u\n", gai, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		if (p)
 			*p = '/';
 		return 0;
@@ -110,8 +112,8 @@
 	if (p)
 		*p++ = '/';
 	if (gai != 0) {
-		rprintf(FLOG, "error matching address %s: %s\n",
-			tok, gai_strerror(gai));
+		rprintf(FLOG, "* error matching address %s: %s (%d)\n",
+			tok, gai_strerror(gai), gai);
 		freeaddrinfo(resa);
 		return 0;
 	}
@@ -222,7 +224,11 @@
 	if (host)
 		strlower(host);
 
+	// rprintf(FLOG, "* access_match: %s (%s) %s:%u\n", host, addr, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+
 	for (tok = strtok(list2, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
+
+		// rprintf(FLOG, "* access_match: tok %s %s:%u\n", tok, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		if (match_hostname(host, tok) || match_address(addr, tok)) {
 			free(list2);
 			return 1;
Only in .: access.o
Only in .: acls.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/authenticate.c ./authenticate.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/authenticate.c	2008-03-01 12:01:40.000000000 -0800
+++ ./authenticate.c	2009-02-06 10:47:20.000000000 -0800
@@ -173,13 +173,16 @@
 	if (do_stat(filename, &st) == -1) {
 		rsyserr(FWARNING, errno, "stat(%s)", filename);
 		ok = 0;
-	} else if ((st.st_mode & 06) != 0) {
+	}
+#ifndef __OS2__	 /* 12 Jun 08 SHL ignore unsupported mode checks */
+	else if ((st.st_mode & 06) != 0) {
 		rprintf(FWARNING, "password file must not be other-accessible\n");
 		ok = 0;
 	} else if (MY_UID() == 0 && st.st_uid != 0) {
 		rprintf(FWARNING, "password file must be owned by root when running as root\n");
 		ok = 0;
 	}
+#endif /* __OS2__ */
 	if (!ok) {
 		close(fd);
 		rprintf(FWARNING, "continuing without password file\n");
Only in .: authenticate.o
Only in .: backup.o
Only in .: batch.o
Only in .: cfg_shl
Only in .: changes.os2
Only in .: checksum.o
Only in .: chmod.o
Only in .: cleanup.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/clientname.c ./clientname.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/clientname.c	2008-10-11 11:13:42.000000000 -0700
+++ ./clientname.c	2009-02-06 10:47:20.000000000 -0800
@@ -95,8 +95,10 @@
 	struct sockaddr_storage ss;
 	socklen_t ss_len;
 
-	if (initialised)
+	if (initialised) {
+		// rprintf(FLOG, "* client_name: %s %s:%u\n", name_buf, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		return name_buf;
+	}
 
 	strlcpy(name_buf, default_name, sizeof name_buf);
 	initialised = 1;
@@ -148,6 +150,8 @@
 			port_buf, sizeof port_buf) == 0)
 		check_name(fd, &ss, name_buf, sizeof name_buf);
 
+	// rprintf(FLOG, "* client_name: %s %s:%u\n", name_buf, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+
 	return name_buf;
 }
 
@@ -216,14 +220,17 @@
 	int name_err;
 
 	/* reverse lookup */
+	// rprintf(FLOG, "* lookup_name: %s:%u\n", __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 	name_err = getnameinfo((struct sockaddr *) ss, ss_len,
 			       name_buf, name_buf_size,
 			       port_buf, port_buf_size,
 			       NI_NAMEREQD | NI_NUMERICSERV);
 	if (name_err != 0) {
 		strlcpy(name_buf, default_name, name_buf_size);
-		rprintf(FLOG, "name lookup failed for %s: %s\n",
-			client_addr(fd), gai_strerror(name_err));
+		// rprintf(FLOG, "name lookup failed for %s: %s\n",
+		//	client_addr(fd), gai_strerror(name_err));
+		rprintf(FLOG, "* lookup_name: failed for %s: %s (%d)\n",	// 27 Jul 08 SHL debug
+			client_addr(fd), gai_strerror(name_err), name_err);	// 28 Jul 08 SHL debug
 		return name_err;
 	}
 
Only in .: clientname.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/clientserver.c ./clientserver.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/clientserver.c	2008-11-09 18:55:14.000000000 -0800
+++ ./clientserver.c	2009-02-06 17:09:26.000000000 -0800
@@ -428,6 +428,7 @@
 	iconv_opt = NULL;
 #endif
 
+	rprintf(FLOG, "* rsync_module: %s %s %s:%u\n", addr, host, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 	if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
 		rprintf(FLOG, "rsync denied on module %s from %s (%s)\n",
 			name, host, addr);
@@ -481,6 +482,7 @@
 
 	am_root = (MY_UID() == 0);
 
+#ifndef __OS2__
 	if (am_root) {
 		p = lp_uid(i);
 		if (!name_to_uid(p, &uid)) {
@@ -503,6 +505,7 @@
 		}
 	}
 
+#endif
 	/* TODO: If we're not root, but the configuration requests
 	 * that we change to some uid other than the current one, then
 	 * log a warning. */
@@ -511,6 +514,7 @@
 	 * supplementary groups. */
 
 	module_dir = lp_path(i);
+	rprintf(FLOG, "* module_dir %s %s(%u)\n", module_dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 	if (use_chroot) {
 		if ((p = strstr(module_dir, "/./")) != NULL) {
 			*p = '\0'; /* Temporary... */
@@ -533,6 +537,7 @@
 		if (!(module_chdir = normalize_path(module_dir, False, &module_dirlen)))
 			return path_failure(f_out, module_dir, False);
 		full_module_path = module_dir = module_chdir;
+		rprintf(FLOG, "* full_module_path %s %s(%u)\n", full_module_path, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 	}
 
 	if (module_dirlen == 1) {
@@ -679,8 +684,11 @@
 		module_chdir = module_dir;
 	}
 
-	if (!change_dir(module_chdir, CD_NORMAL))
+	if (!change_dir(module_chdir, CD_NORMAL)) {
+		rsyserr(FERROR, errno, "chdir %s failed\n", module_chdir);	// 15 Dec 08 SHL debug
+		rprintf(FLOG, "* module_chdir %s %s(%u)\n", module_chdir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 		return path_failure(f_out, module_chdir, True);
+	}
 	if (module_dirlen || !use_chroot)
 		sanitize_paths = 1;
 
@@ -963,6 +971,8 @@
 #endif
 	SIGACTION(SIGCHLD, remember_children);
 
+	// rprintf(FLOG, "* start_daemon: %s %s %s:%u\n", addr, host, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+
 	return rsync_module(f_in, f_out, i, addr, host);
 }
 
@@ -991,6 +1001,7 @@
 	close(fd);
 }
 
+#ifndef __OS2__
 /* Become a daemon, discarding the controlling terminal. */
 static void become_daemon(void)
 {
@@ -1024,6 +1035,7 @@
 		open("/dev/null", O_RDWR);
 	}
 }
+#endif // __OS2__
 
 int daemon_main(void)
 {
@@ -1046,10 +1058,14 @@
 		exit_cleanup(RERR_SYNTAX);
 	}
 
+#ifndef __OS2__
 	if (no_detach)
 		create_pid_file();
 	else
 		become_daemon();
+#else
+	create_pid_file();
+#endif
 
 	if (rsync_port == 0 && (rsync_port = lp_rsync_port()) == 0)
 		rsync_port = RSYNC_PORT;
Only in .: clientserver.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/compat.c ./compat.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/compat.c	2008-08-02 07:04:54.000000000 -0700
+++ ./compat.c	2009-03-06 10:03:56.000000000 -0800
@@ -198,11 +198,12 @@
 			exit_cleanup(RERR_PROTOCOL);
 		}
 		if (preserve_xattrs && !local_server) {
-			rprintf(FERROR,
-			    "--xattrs requires protocol 30 or higher"
+		  	preserve_xattrs = 0;	// 06 Feb 09 SHL force off for old servers
+			rprintf(FWARNING,
+			    "--xattrs requires protocol 30 or higher - option disabled"
 			    " (negotiated %d).\n",
 			    protocol_version);
-			exit_cleanup(RERR_PROTOCOL);
+			// exit_cleanup(RERR_PROTOCOL);	// 06 Feb 09 SHL
 		}
 	}
 
@@ -291,6 +292,7 @@
 	if (need_unsorted_flist && (!am_sender || inc_recurse))
 		unsort_ndx = ++file_extra_cnt;
 
+	// 16 Feb 09 SHL fixme slash?
 	if (partial_dir && *partial_dir != '/' && (!am_server || local_server)) {
 		int flags = MATCHFLG_NO_PREFIXES | MATCHFLG_DIRECTORY;
 		if (!am_sender || protocol_version >= 30)
Only in .: compat.o
Only in .: config.cache
Only in .: config.h
Only in .: config.log
Only in .: config.status
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/configure.sh ./configure.sh
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/configure.sh	2008-12-28 18:03:34.000000000 -0800
+++ ./configure.sh	2009-03-01 18:33:16.000000000 -0800
@@ -1274,12 +1274,12 @@
   --enable-profile        turn on CPU profiling
   --enable-maintainer-mode
                           turn on extra debug features
+  --enable-xattr-support  enable extended attributes
   --disable-largefile     omit support for large files
   --disable-ipv6          don't even try to use IPv6
   --disable-locale        disable locale features
   --disable-iconv         disable rsync's --iconv option
   --disable-acl-support   disable ACL support
-  --disable-xattr-support disable extended attributes
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -16624,6 +16624,15 @@
 _ACEOF
 
 	;;
+    *os2*)
+	{ echo "$as_me:$LINENO: result: Using OS/2 extattrs" >&5
+echo "${ECHO_T}Using OS/2 extattrs" >&6; }
+	cat >>confdefs.h <<\_ACEOF
+#define SUPPORT_XATTRS 1
+_ACEOF
+
+	;;
+
     *)
 	if test x"$enable_xattr_support" = x"yes"; then
 	    { { echo "$as_me:$LINENO: error: Failed to find extended attribute support" >&5
Only in .: connection.o
Only in .: ctags.tag
Only in .: diff_shl.cmd
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/exclude.c ./exclude.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/exclude.c	2008-07-31 07:57:54.000000000 -0700
+++ ./exclude.c	2009-02-16 23:00:44.000000000 -0800
@@ -298,7 +298,7 @@
 	unsigned int fn_len;
 
 	if (!parent_dirscan && *merge_file != '/') {
-		/* Return the name unchanged it doesn't have any slashes. */
+		/* Return the name unchanged if it doesn't have any slashes. */
 		if (len_ptr) {
 			const char *p = merge_file + *len_ptr;
 			while (--p > merge_file && *p != '/') {}
@@ -310,6 +310,7 @@
 			return (char *)merge_file;
 	}
 
+	// 16 Feb 09 SHL fixme slash
 	fn = *merge_file == '/' ? buf : tmpbuf;
 	if (sanitize_paths) {
 		const char *r = prefix_skip ? "/" : NULL;
@@ -351,6 +352,7 @@
 void set_filter_dir(const char *dir, unsigned int dirlen)
 {
 	unsigned int len;
+	// 16 Feb 09 SHL fixme slash?
 	if (*dir != '/') {
 		memcpy(dirbuf, curr_dir, curr_dir_len);
 		dirbuf[curr_dir_len] = '/';
@@ -548,6 +550,7 @@
 	int ret_match = ex->match_flags & MATCHFLG_NEGATE ? 0 : 1;
 	char *p, *pattern = ex->pattern;
 	const char *strings[16]; /* more than enough */
+	// 16 Feb 09 SHL fixme slash?
 	const char *name = fname + (*fname == '/');
 
 	if (!*name)
Only in .: exclude.o
Only in .: fileio.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/flist.c ./flist.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/flist.c	2008-12-28 17:51:36.000000000 -0800
+++ ./flist.c	2009-05-16 23:11:40.000000000 -0700
@@ -348,8 +348,17 @@
 {
 	if (dirlen < 0) {
 		char *cpy = strdup(dir);
+#ifndef __OS2__ // 06 Mar 09 SHL use is_abs_path...
 		if (*cpy != '/')
 			change_dir(orig_dir, CD_SKIP_CHDIR);
+#else
+		if (!is_abs_path(cpy)) {
+			if (drive_spec_width(cpy))
+				rprintf(FERROR, "relative directory with drive letter not supported %s %s(%u)\n", cpy, __FILE__, __LINE__);	// 06 Feb 09 SHL
+			if (!change_dir(orig_dir, CD_SKIP_CHDIR))
+				rprintf(FLOG, "* [%s] orig_dir %s %s(%u)\n", who_am_i(), orig_dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+	        }
+#endif
 		if (path_is_daemon_excluded(cpy, 0))
 			goto chdir_error;
 		dir = cpy;
@@ -363,8 +372,17 @@
 				dirlen = strlen(dir);
 		} else if (pathname == dir)
 			return 1;
+#ifndef __OS2__ // 06 Mar 09 SHL use is_abs_path...
 		if (dir && *dir != '/')
 			change_dir(orig_dir, CD_SKIP_CHDIR);
+#else
+		if (dir && !is_abs_path(dir)) {
+			if (drive_spec_width(dir))
+				rprintf(FERROR, "relative directory with drive letter not supported %s %s(%u)\n", dir, __FILE__, __LINE__);	// 06 Feb 09 SHL
+			if (!change_dir(orig_dir, CD_SKIP_CHDIR))
+				rprintf(FERROR, "* [%s] orig_dir %s %s(%u)\n", who_am_i(), orig_dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
+		}
+#endif
 	}
 
 	pathname = dir;
@@ -377,8 +395,11 @@
 	  chdir_error:
 		io_error |= IOERR_GENERAL;
 		rsyserr(FERROR_XFER, errno, "change_dir %s failed", full_fname(dir));
-		if (dir != orig_dir)
-			change_dir(orig_dir, CD_NORMAL);
+		rprintf(FERROR_XFER, "* [%s] dir %s %s(%u)\n", who_am_i(), dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
+		if (dir != orig_dir) {
+			if (!change_dir(orig_dir, CD_NORMAL))
+				rprintf(FLOG, "* [%s] orig_dir %s %s(%u)\n", who_am_i(), orig_dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
+		}
 		pathname = NULL;
 		pathname_len = 0;
 		return 0;
@@ -1318,6 +1339,8 @@
 {
 	struct file_struct *file;
 
+	// rprintf(FINFO, "* [%s] send_file_name fname %s %s(%u)\n", who_am_i(), fname, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
+
 	file = make_file(fname, flist, stp, flags, filter_level);
 	if (!file)
 		return NULL;
@@ -1922,6 +1945,7 @@
 	int len, dirlen;
 	STRUCT_STAT st;
 	char *p, *dir;
+	static char* the_root = "/";
 	struct file_list *flist;
 	struct timeval start_tv, end_tv;
 	int64 start_write;
@@ -1965,6 +1989,7 @@
 		if (argv[0] && !change_dir(argv[0], CD_NORMAL)) {
 			rsyserr(FERROR_XFER, errno, "change_dir %s failed",
 				full_fname(argv[0]));
+			rprintf(FERROR_XFER, "* [%s] argv[0] %s %s(%u)\n", who_am_i(), argv[0], __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 			exit_cleanup(RERR_FILESELECT);
 		}
 		use_ff_fd = 1;
@@ -1984,17 +2009,30 @@
 			if (argc-- == 0)
 				break;
 			strlcpy(fbuf, *argv++, MAXPATHLEN);
+			// rprintf(FINFO, "* [%s] send_file_list fbuf %s %s(%u)\n", who_am_i(), fbuf, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 			if (sanitize_paths)
 				sanitize_path(fbuf, fbuf, "", 0, SP_KEEP_DOT_DIRS);
+#if 0 // 16 May 09 SHL fixme to be gone
+#ifdef __OS2__
+			else {
+				// 16 May 09 SHL switch to use normalize_dir_slashes
+				normalize_dir_slashes(fbuf);
+			}
+#endif
+#endif
 		}
 
+		// rprintf(FINFO, "* [%s] send_file_list fbuf %s %s(%u)\n", who_am_i(), fbuf, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
+
 		len = strlen(fbuf);
 		if (relative_paths) {
 			/* We clean up fbuf below. */
 			name_type = NORMAL_NAME;
 		} else if (!len || fbuf[len - 1] == '/') {
-			if (len == 2 && fbuf[0] == '.') {
-				/* Turn "./" into just "." rather than "./." */
+			// Empty path or trailing /
+			// 06 Mar 09 SHL
+			if (len == 2 + drive_spec_width(fbuf) && fbuf[drive_spec_width(fbuf)] == '.') {
+				/* Turn trailing "./" into just "." rather than "./." */
 				fbuf[--len] = '\0';
 			} else {
 				if (len + 1 >= MAXPATHLEN)
@@ -2005,6 +2043,7 @@
 			name_type = DOTDIR_NAME;
 		} else if (len > 1 && fbuf[len-1] == '.' && fbuf[len-2] == '.'
 		    && (len == 2 || fbuf[len-3] == '/')) {
+			// Got ..  or trailing /..
 			if (len + 2 >= MAXPATHLEN)
 				overflow_exit("send_file_list");
 			fbuf[len++] = '/';
@@ -2023,18 +2062,39 @@
 			if (p) {
 				*p = '\0';
 				if (p == fbuf)
-					dir = "/";
+					dir = the_root;
+#ifdef __OS2__
+				// 06 Mar 09 SHL Preserve drive letter
+				else if (p == fbuf + (dirlen = drive_spec_width(fbuf))) {
+					if (!(dir = malloc(dirlen + 2)))
+						out_of_memory("send_file_list");
+					memcpy(dir, fbuf, dirlen);
+					dir[dirlen] = '/';
+					dir[dirlen + 1] = 0;
+				}
+#endif
 				else
 					dir = fbuf;
-				len -= p - fbuf + 1;
-				fn = p + 1;
+				fn = p + 1;		// Point at filename part
+				len -= fn - fbuf;	//  fn length
+				// rprintf(FINFO, "* [%s] send_file_list fn %s len %d %s(%u)\n", who_am_i(), fn, len, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
 			} else
 				fn = fbuf;
 		} else {
 			if ((p = strstr(fbuf, "/./")) != NULL) {
 				*p = '\0';
 				if (p == fbuf)
-					dir = "/";
+					dir = the_root;
+#ifdef __OS2__
+				// 06 Mar 09 SHL Preserve drive letter
+				else if (p == fbuf + (dirlen = drive_spec_width(fbuf))) {
+					if (!(dir = malloc(dirlen + 2)))
+						out_of_memory("send_file_list");
+					memcpy(dir, fbuf, dirlen);
+					dir[dirlen] = '/';
+					dir[dirlen + 1] = 0;
+				}
+#endif
 				else {
 					dir = fbuf;
 					clean_fname(dir, 0);
@@ -2056,6 +2116,8 @@
 			}
 			len = clean_fname(fn, CFN_KEEP_TRAILING_SLASH
 					    | CFN_DROP_TRAILING_DOT_DIR);
+			rprintf(FINFO, "* [%s] send_file_list fn %s len %d %s(%u)\n", who_am_i(), fn, len, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
+			// 06 Mar 09 SHL fixme?
 			if (len == 1) {
 				if (fn[0] == '/') {
 					fn = "/.";
@@ -2088,6 +2150,8 @@
 			name_type = DOTDIR_NAME;
 		}
 
+		// rprintf(FINFO, "* [%s] send_file_list dir %s fn %s len %d %s(%u)\n", who_am_i(), dir ? dir : "(null)", fn, len, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
+
 		dirlen = dir ? strlen(dir) : 0;
 		if (dirlen != lastdir_len || memcmp(lastdir, dir, dirlen) != 0) {
 			if (!change_pathname(NULL, dir, -dirlen))
@@ -2097,9 +2161,16 @@
 		} else if (!change_pathname(NULL, lastdir, lastdir_len))
 			continue;
 
+		// 06 Mar 09 SHL
+		if (dir && dir != the_root && dir != fbuf)
+			free(dir);	// We allocated it
+
 		if (fn != fbuf)
 			memmove(fbuf, fn, len + 1);
 
+		// rprintf(FINFO, "* [%s] send_file_list fn %s %s(%u)\n", who_am_i(), fn, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
+		// rprintf(FINFO, "* [%s] send_file_list fbuf %s len %d %s(%u)\n", who_am_i(), fbuf, len, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
+
 		if (link_stat(fbuf, &st, copy_dirlinks || name_type != NORMAL_NAME) != 0
 		 || (name_type != DOTDIR_NAME && is_daemon_excluded(fbuf, S_ISDIR(st.st_mode)))
 		 || (relative_paths && path_is_daemon_excluded(fbuf, 1))) {
@@ -2120,12 +2191,14 @@
 		}
 
 		if (inc_recurse && relative_paths && *fbuf) {
+			// 06 Mar 09 SHL fixme
 			if ((p = strchr(fbuf+1, '/')) != NULL) {
 				if (p - fbuf == 1 && *fbuf == '.') {
 					if ((fn = strchr(p+1, '/')) != NULL)
 						p = fn;
 				} else
 					fn = p;
+			        // rprintf(FINFO, "* [%s] send_file_list %s %s(%u)\n", who_am_i(), fbuf, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
 				send_implied_dirs(f, flist, fbuf, fbuf, p, flags, name_type);
 				if (fn == p)
 					continue;
@@ -2133,6 +2206,7 @@
 		} else if (implied_dirs && (p=strrchr(fbuf,'/')) && p != fbuf) {
 			/* Send the implied directories at the start of the
 			 * source spec, so we get their permissions right. */
+			// rprintf(FINFO, "* [%s] send_file_list %s %s(%u)\n", who_am_i(), fbuf, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
 			send_implied_dirs(f, flist, fbuf, fbuf, p, flags, 0);
 		}
 
@@ -2141,6 +2215,7 @@
 
 		if (recurse || (xfer_dirs && name_type != NORMAL_NAME)) {
 			struct file_struct *file;
+			// rprintf(FINFO, "* [%s] send_file_list fbuf %s %s(%u)\n", who_am_i(), fbuf, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
 			file = send_file_name(f, flist, fbuf, &st,
 					      FLAG_TOP_DIR | FLAG_CONTENT_DIR | flags,
 					      NO_FILTERS);
@@ -2156,9 +2231,11 @@
 				}
 			} else
 				send_if_directory(f, flist, file, fbuf, len, flags);
-		} else
+		} else {
+			// rprintf(FINFO, "* [%s] send_file_list %s %s(%u)\n", who_am_i(), fbuf, __FILE__, __LINE__);	// 06 Mar 09 SHL debug
 			send_file_name(f, flist, fbuf, &st, flags, NO_FILTERS);
 	}
+	}
 
 	gettimeofday(&end_tv, NULL);
 	stats.flist_buildtime = (int64)(end_tv.tv_sec - start_tv.tv_sec) * 1000
Only in .: flist.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/generator.c ./generator.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/generator.c	2008-11-10 07:46:40.000000000 -0800
+++ ./generator.c	2009-06-13 19:53:38.000000000 -0700
@@ -272,6 +272,7 @@
 	}
 
 	p = fname + dlen;
+	// 16 Feb 09 SHL fixme slash?
 	if (dlen != 1 || *fname != '/')
 		*p++ = '/';
 	remainder = MAXPATHLEN - (p - fname);
@@ -590,7 +591,7 @@
 	} else
 #endif
 	if (preserve_times && cmp_time(sxp->st.st_mtime, file->modtime) != 0)
-		return 0;
+		return 0;		// Changed
 
 	if (preserve_perms) {
 		if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
@@ -622,7 +623,7 @@
 	}
 #endif
 
-	return 1;
+	return 1;			// No change
 }
 
 void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statret,
Only in .: generator.o
Only in .: hashtable.o
Only in .: hlink.o
Only in .: init_shl
Only in .: init_shl.cmd
Only in .: io.o
Only in ./lib: compat.o
Only in ./lib: ctags.tag
Only in ./lib: dummy
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/lib/getaddrinfo.c ./lib/getaddrinfo.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/lib/getaddrinfo.c	2008-10-25 08:39:40.000000000 -0700
+++ ./lib/getaddrinfo.c	2009-02-06 10:47:20.000000000 -0800
@@ -404,12 +404,16 @@
 	int ret = -1;
 	char *p = NULL;
 
+	// rprintf(FLOG, "* gethostnameinfo: NI_NUMERICHOST %u %s:%u\n", flags & NI_NUMERICHOST, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 	if (!(flags & NI_NUMERICHOST)) {
+		// rprintf(FLOG, "* gethostnameinfo: %s:%u\n", __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		struct hostent *hp = gethostbyaddr(
 				(void *)&((struct sockaddr_in *)sa)->sin_addr,
 				sizeof (struct in_addr),
 				sa->sa_family);
+		// rprintf(FLOG, "* gethostnameinfo: hp %p %s:%u\n", hp, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		ret = check_hostent_err(hp);
+		// rprintf(FLOG, "* ret %d %s:%u\n", ret, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		if (ret == 0) {
 			/* Name looked up successfully. */
 			ret = snprintf(node, nodelen, "%s", hp->h_name);
@@ -425,6 +429,7 @@
 			return 0;
 		}
 
+		// rprintf(FLOG, "* %s:%u\n", __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 		if (flags & NI_NAMEREQD) {
 			/* If we require a name and didn't get one,
 			 * automatically fail. */
@@ -432,6 +437,7 @@
 		}
 		/* Otherwise just fall into the numeric host code... */
 	}
+	// rprintf(FLOG, "* %s:%u\n", __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 	p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr);
 	ret = snprintf(node, nodelen, "%s", p);
 	if (ret < 0 || (size_t)ret >= nodelen) {
Only in ./lib: getaddrinfo.o
Only in ./lib: md5.o
Only in ./lib: mdfour.o
Only in ./lib: permstring.o
Only in ./lib: pool_alloc.o
Only in ./lib: snprintf.o
Only in ./lib: sysacls.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/lib/sysxattrs.c ./lib/sysxattrs.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/lib/sysxattrs.c	2008-03-01 12:01:40.000000000 -0800
+++ ./lib/sysxattrs.c	2009-05-17 16:51:24.000000000 -0700
@@ -126,6 +126,396 @@
 	return len;
 }
 
+#elif defined(__OS2__)
+
+#define INCL_LONGLONG
+#define INCL_DOS
+#define INCL_DOSPROCESS
+#define INCL_DOSPROFILE
+#define INCL_DOSMISC
+#define INCL_DOSMODULEMGR
+#define INCL_DOSERRORS
+
+#include <os2.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <types.h>
+
+static void map_os2_apiret(APIRET rc)
+{
+	switch (rc) {
+	case ERROR_SHARING_VIOLATION:
+		errno = EACCES;
+		break;
+	}
+}
+
+ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
+{
+	return unigetxattr(path, 0, name, value, size);
+}
+
+ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
+{
+	return unigetxattr(0, filedes, name, value, size);
+}
+
+int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
+{
+	return unisetxattr (path, 0, name, value, size, 0);
+}
+
+int sys_lremovexattr(const char *path, const char *name)
+{
+	return uniremovexattr (path, 0, name);
+}
+
+ssize_t sys_llistxattr(const char *path, char *list, size_t size)
+{
+	return unilistxattr(path, 0, list, size);
+}
+
+ssize_t unigetxattr (const char *path, int file, const char *name, void *value, size_t size)
+{
+	int rc, namelen;
+	EAOP2       eaop2 = {0,0,0};
+	PGEA2LIST   pgea2list = NULL;
+	PFEA2LIST   pfea2list = NULL;
+	char * p;
+
+	if ((!path && !file) || !name)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	namelen = strlen(name);
+	if (namelen > 0xFF)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	pgea2list = (PGEA2LIST)calloc(sizeof(GEA2LIST) + namelen + 1, 1);
+	pgea2list->list[0].oNextEntryOffset = 0;
+	pgea2list->list[0].cbName = namelen;
+	strcpy(pgea2list->list[0].szName, name);
+	pgea2list->cbList = sizeof(GEA2LIST) + namelen;
+
+	// max ea is 64kb
+	pfea2list = (PFEA2LIST)calloc(sizeof(FEA2LIST) + 0x10000, 1);
+	pfea2list->cbList = sizeof(FEA2LIST) + 0x10000;
+
+	eaop2.fpGEA2List = pgea2list;
+	eaop2.fpFEA2List = pfea2list;
+	eaop2.oError = 0;
+	do
+	{
+		if (path)
+		{
+#if 0 // 16 May 09 SHL fixme to be gone
+			char npath[CCHMAXPATH + 1] = {0};
+			strncpy(npath, path, CCHMAXPATH);
+			for (p = npath; *p; p++)
+			{
+				if (*p == '/') *p = '\\';	// 29 Jul 08 SHL fixme to be gone? - OS/2 does not care?
+			}
+#endif
+			rc = DosQueryPathInfo(path, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2));
+			if (rc)
+				rprintf(FERROR, "* unigetxattr: DosQueryPathInfo(%s, FIL_QUERYEASFROMLIST) failed with error %u %s:%u\n", path, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+			else if (verbose > 2)
+				rprintf(FINFO, "%s has %lu EA bytes\n", path, eaop2.fpFEA2List->cbList);	// 28 Jul 08 SHL
+		}
+		else
+		{
+			rc = DosQueryFileInfo( file, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2));
+			if (rc)
+				rprintf(FERROR, "* unigetxattr: DosQueryFileInfo(%u, FIL_QUERYEASFROMLIST) failed with error %u %s:%u\n", file, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+			else if (verbose > 2)
+				rprintf(FINFO, "Handle %d has %lu EA bytes\n", file, eaop2.fpFEA2List->cbList);	// 28 Jul 08 SHL
+		}
+		if (rc)
+		{
+			break;
+		}
+		if (strnicmp(pfea2list->list[0].szName, name, namelen) || pfea2list->list[0].cbValue == 0)
+		{
+			errno = ENOATTR;
+			rc = -1;
+			break;
+		}
+		rc = pfea2list->list[0].cbValue;
+		if (value)
+		{
+			if ((size_t)rc > size)
+			{
+				errno = ERANGE;
+				rc = -1;
+			}
+			else
+			{
+				p = pfea2list->list[0].szName + pfea2list->list[0].cbName + 1;
+				memcpy(value, p, rc);
+			}
+		}
+	} while (0);
+	if (pgea2list)
+	{
+		free(pgea2list);
+	}
+	if (pgea2list)
+	{
+		free(pfea2list);
+	}
+
+	return rc;
+}
+
+ssize_t unilistxattr (const char *path, int file, char *list, size_t size)
+{
+	ssize_t gotsize = 0;
+	unsigned long ulCount = -1;
+	int rc;
+	char * buf, *p = list;
+	PFEA2 pfea;
+	FILESTATUS4 stat;
+	// char npath[CCHMAXPATH + 1] = {0};	// 17 May 09 SHL fixme to be gone
+	// memset(&stat, 0, sizeof(stat));	// 17 May 09 SHL fixme to be gone
+	if (!path && !file)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	if (path)
+	{
+#if 0 // 16 May 09 SHL fixme to be gone
+		char * p;
+		strncpy(npath, path, CCHMAXPATH);
+		for (p = npath; *p; p++)
+		{
+			if (*p == '/') *p = '\\';
+		}
+#endif
+		rc = DosQueryPathInfo(path, FIL_QUERYEASIZE, &stat, sizeof(stat));
+		if (rc)
+			rprintf(FERROR, "* unilistxattr: DosQueryPathInfo(%s, FIL_QUERYEASIZE) failed with error %u %s:%u\n", path, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		else if (verbose > 2)
+			rprintf(FINFO, "%s has %lu EA bytes\n", path, stat.cbList);	// 28 Jul 08 SHL
+	}
+	else
+	{
+		rc = DosQueryFileInfo( file, FIL_QUERYEASIZE, &stat, sizeof(stat));
+		if (rc)
+			rprintf(FERROR, "* unilistxattr: DosQueryFilInfo(%u, FIL_QUERYEASIZE) failed with error %u %s:%u\n", file, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		else if (verbose > 2)
+			rprintf(FINFO, "Handle %d has %lu EA bytes\n", file, stat.cbList);	// 28 Jul 08 SHL
+	}
+	if (rc)
+	{
+		map_os2_apiret(rc);
+		return -1;
+	}
+	if (stat.cbList <= 4)
+	{
+		// NO ea
+		return 0;
+	}
+	//YD DosEnumAttribute doesn't like high-mem buffers, get a low one.
+	buf = (char *)_tmalloc(stat.cbList * 2);
+	rc = DosEnumAttribute(path ? 1 : 0, path ? (PVOID)path : (PVOID)&file, 1, (PVOID)buf, stat.cbList * 2, &ulCount, 1);
+	if (rc)
+	{
+		map_os2_apiret(rc);	// 16 May 09 SHL added
+		rprintf(FERROR, "* unilistxattr: DosEnumAttribute failed with error %u %s:%u\n", rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug {
+		_tfree(buf);
+		return -1;
+	}
+	else if (verbose > 2) {
+		if (path)
+			rprintf(FINFO, "%s has %lu EA items\n", path, ulCount);	// 28 Jul 08 SHL
+		else
+			rprintf(FINFO, "Handle %d has %lu EA items\n", file, ulCount);	// 28 Jul 08 SHL
+	}
+	if (ulCount > 0) {
+		for (pfea = (PFEA2)buf;;pfea = (PFEA2)((char *)pfea + pfea->oNextEntryOffset))
+		{
+			if (pfea->cbName > 0)
+			{
+				gotsize += pfea->cbName + 1;
+				// Avoid overflow
+				if (p && (size_t)gotsize <= size)
+				{
+					pfea->szName[pfea->cbName] = 0;
+					strcpy(p, pfea->szName);
+					p += strlen(p) + 1;
+				}
+			}
+			if (!pfea->oNextEntryOffset)
+			{
+				break;
+			}
+		}
+	}
+	_tfree(buf);
+	if ((size_t)gotsize > size)
+	{
+		errno = ERANGE;
+		return list ? -1 : gotsize;
+	}
+	if (verbose > 2)
+		rprintf(FINFO, "Returning %ld EA list bytes\n", (unsigned long)gotsize);	// 28 Jul 08 SHL
+	return gotsize;
+}
+
+int uniremovexattr (const char *path, int file, const char *name)
+{
+	int rc, namelen;
+	EAOP2 eaop2 = {0,0,0};
+	PFEA2LIST pfea2list = NULL;
+	char buf[300] = {0};
+
+	if ((!path && !file) || !name)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	namelen = strlen(name);
+	if (namelen > 0xFF)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	pfea2list = (PFEA2LIST)buf;
+	pfea2list->list[0].cbName = namelen;
+	pfea2list->list[0].cbValue = 0;
+	pfea2list->list[0].fEA = 0;
+	strcpy(pfea2list->list[0].szName, name);
+	pfea2list->cbList = sizeof(FEA2LIST) + namelen;
+	eaop2.fpFEA2List = pfea2list;
+
+	if (path)
+	{
+#if 0 // 16 May 09 SHL fixme to be gone
+		char npath[CCHMAXPATH + 1];
+		char * p;
+		strncpy(npath, path, CCHMAXPATH);
+		for (p = npath; *p; p++)
+		{
+			if (*p == '/') *p = '\\';
+		}
+#endif
+		rc = DosSetPathInfo(path, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), DSPI_WRTTHRU);
+		if (rc)
+			rprintf(FERROR, "* uniremovexattr: DosSetPathInfo(%s, FIL_QUERYEASIZE) failed with error %u %s:%u\n", path, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		else if (verbose > 1)
+			rprintf(FINFO, "Deleted EA %s from %s\n", name, path);	// 28 Jul 08 SHL
+	}
+	else
+	{
+		rc = DosSetFileInfo( file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2));
+		if (rc)
+			rprintf(FERROR, "* uniremovexattr: DosFileInfo(%u, FIL_QUERYEASIZE) failed with error %u %s:%u\n", file, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		else if (verbose > 1)
+			rprintf(FINFO, "Deleted EA %s from handle %d \n", name, file);	// 28 Jul 08 SHL
+	}
+	if (rc)
+	{
+		map_os2_apiret(rc);
+		return -1;
+	}
+	return 0;
+}
+
+#ifndef XATTR_CREATE
+#define XATTR_CREATE  1
+#endif
+#ifndef XATTR_REPLACE
+#define XATTR_REPLACE 2
+#endif
+
+int unisetxattr (const char *path, int file, const char *name, const void *value, size_t size, int flags)
+{
+	int rc, namelen, totalsize;
+	EAOP2       eaop2 = {0,0,0};
+	PFEA2LIST   pfea2list = NULL;
+	// char * p;			// 17 May 09 SHL  fixme
+
+	if ((!path && !file) || !name || (!value && size))
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	namelen = strlen(name);
+	if (namelen > 0xFF)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (flags & (XATTR_CREATE | XATTR_REPLACE))
+	{
+		ssize_t esize = unigetxattr(path, file, name, 0, 0);
+		if (flags & XATTR_CREATE && esize > 0)
+		{
+			errno = EEXIST;
+			return -1;
+		}
+		if (flags & XATTR_REPLACE && esize < 0)
+		{
+			errno = ENOATTR;
+			return -1;
+		}
+	}
+
+	totalsize = sizeof(FEA2LIST) + size + namelen + 1;
+
+	pfea2list = (PFEA2LIST)calloc(totalsize, 1);
+	pfea2list->cbList = totalsize;
+	pfea2list->list[0].oNextEntryOffset = 0;
+	pfea2list->list[0].cbName = namelen;
+	pfea2list->list[0].cbValue = size;
+	strcpy(pfea2list->list[0].szName, name);
+	if (value)
+	{
+		memcpy(pfea2list->list[0].szName + namelen + 1, value, size);
+	}
+	eaop2.fpFEA2List = pfea2list;
+
+	if (path)
+	{
+#if 0 // 16 May 09 SHL fixme to be gone
+		char npath[CCHMAXPATH + 1] = {0};
+		strncpy(npath, path, CCHMAXPATH);
+		for (p = npath; *p; p++)
+		{
+			if (*p == '/') *p = '\\';
+		}
+#endif
+		rc = DosSetPathInfo(path, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), DSPI_WRTTHRU);
+		if (rc)
+			rprintf(FERROR, "* unisetxattr: DosSetPathInfo(%s, FIL_QUERYEASIZE) failed with error %u %s:%u\n", path, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		else if (verbose > 1)
+			rprintf(FINFO, "Set EA %s for %s\n", name, path);	// 28 Jul 08 SHL
+	}
+	else
+	{
+		rc = DosSetFileInfo( file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2));
+		if (rc)
+			rprintf(FERROR, "* unisetxattr: DosSetFileInfo(%u, FIL_QUERYEASIZE) failed with error %u %s:%u\n", file, rc, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+		else if (verbose > 1)
+			rprintf(FINFO, "Set EA %s for handle %d\n", name, file);	// 28 Jul 08 SHL
+	}
+	free(pfea2list);
+	if (rc)
+	{
+		map_os2_apiret(rc);
+		return -1;
+	}
+	return 0;
+}
+
 #else
 
 #error You need to create xattr compatibility functions.
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/lib/sysxattrs.h ./lib/sysxattrs.h
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/lib/sysxattrs.h	2007-04-07 10:22:24.000000000 -0700
+++ ./lib/sysxattrs.h	2009-02-06 10:47:20.000000000 -0800
@@ -19,6 +19,13 @@
 int sys_lremovexattr(const char *path, const char *name);
 ssize_t sys_llistxattr(const char *path, char *list, size_t size);
 
+#ifdef __OS2__
+ssize_t unigetxattr (const char *path, int file, const char *name, void *value, size_t size);
+ssize_t unilistxattr (const char *path, int file, char *list, size_t size);
+int uniremovexattr (const char *path, int file, const char *name);
+int unisetxattr (const char *path, int file, const char *name, const void *value, size_t size, int flags);
+#endif
+
 #else
 
 /* No xattrs available */
Only in ./lib: sysxattrs.o
Only in ./lib: wildmatch.o
Only in .: loadparm-20090306-2021.c
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/loadparm.c ./loadparm.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/loadparm.c	2008-02-15 22:19:42.000000000 -0800
+++ ./loadparm.c	2009-05-16 23:06:08.000000000 -0700
@@ -656,10 +656,23 @@
 	    *(char *)dest_ptr = *(char *)src_ptr;
 	    break;
 
+#ifndef __OS2__
 	  case P_PATH:
 	  case P_STRING:
 	    string_set(dest_ptr,*(char **)src_ptr);
 	    break;
+#else
+	  case P_PATH:
+	    string_set(dest_ptr,*(char **)src_ptr);
+	    // 06 Mar 09 SHL Force unix slashes
+	    // 16 May 09 SHL Use normalize_dir_slashes
+	    normalize_dir_slashes(*(char **)dest_ptr);
+	    break;
+
+	  case P_STRING:
+	    string_set(dest_ptr,*(char **)src_ptr);
+	    break;
+#endif
 
 	  default:
 	    break;
@@ -728,7 +741,12 @@
        string_set(parm_ptr,parmvalue);
        if ((cp = *(char**)parm_ptr) != NULL) {
 	   int len = strlen(cp);
+#ifndef __OS2__
 	   while (len > 1 && cp[len-1] == '/') len--;
+#else
+	   int drive_letter_adj = *(cp + 1) == ':' && isalpha(*cp) ? 2 : 0;
+	   while (len > 1 + drive_letter_adj && cp[len-1] == '/') len--;
+#endif
 	   cp[len] = '\0';
        }
        break;
Only in .: loadparm.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/log.c ./log.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/log.c	2008-09-26 21:19:50.000000000 -0700
+++ ./log.c	2009-04-27 19:50:54.000000000 -0700
@@ -371,6 +371,7 @@
 	va_list ap;
 	char buf[BIGPATHBUFLEN];
 	size_t len;
+	int e = errno;			// 27 Apr 09 SHL preserve errno
 
 	va_start(ap, format);
 	len = vsnprintf(buf, sizeof buf, format, ap);
@@ -403,6 +404,7 @@
 	}
 
 	rwrite(code, buf, len, 0);
+	errno = e;
 }
 
 /* This is like rprintf, but it also tries to print some
Only in .: log.o
Only in .: m_shl
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/main.c ./main.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/main.c	2008-10-11 11:14:42.000000000 -0700
+++ ./main.c	2009-05-16 22:49:30.000000000 -0700
@@ -529,8 +529,9 @@
 		/* If the destination is a dir, enter it and use mode 1. */
 		if (S_ISDIR(st.st_mode)) {
 			if (!change_dir(dest_path, CD_NORMAL)) {
-				rsyserr(FERROR, errno, "change_dir#1 %s failed",
+				rsyserr(FERROR, errno, "change_dir %s failed",
 					full_fname(dest_path));
+				rprintf(FLOG, "* dest_path %s %s(%u)\n", dest_path, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 				exit_cleanup(RERR_FILESELECT);
 			}
 			return NULL;
@@ -589,8 +590,9 @@
 		}
 
 		if (!change_dir(dest_path, dry_run > 1 ? CD_SKIP_CHDIR : CD_NORMAL)) {
-			rsyserr(FERROR, errno, "change_dir#2 %s failed",
+			rsyserr(FERROR, errno, "change_dir %s failed",
 				full_fname(dest_path));
+			rprintf(FLOG, "* dest_path %s %s(%u)\n", dest_path, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 			exit_cleanup(RERR_FILESELECT);
 		}
 
@@ -609,8 +611,9 @@
 
 	*cp = '\0';
 	if (!change_dir(dest_path, CD_NORMAL)) {
-		rsyserr(FERROR, errno, "change_dir#3 %s failed",
+		rsyserr(FERROR, errno, "change_dir %s failed",
 			full_fname(dest_path));
+		rprintf(FLOG, "* dest_path %s %s(%u)\n", dest_path, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 		exit_cleanup(RERR_FILESELECT);
 	}
 	*cp = '/';
@@ -702,8 +705,9 @@
 
 	if (!relative_paths) {
 		if (!change_dir(dir, CD_NORMAL)) {
-			rsyserr(FERROR, errno, "change_dir#3 %s failed",
+			rsyserr(FERROR, errno, "change_dir %s failed",
 				full_fname(dir));
+			rprintf(FLOG, "* dir %s %s(%u)\n", dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 			exit_cleanup(RERR_FILESELECT);
 		}
 	}
@@ -874,6 +878,7 @@
 		if (!am_daemon && !change_dir(dir, CD_NORMAL)) {
 			rsyserr(FERROR, errno, "change_dir#4 %s failed",
 				full_fname(dir));
+			rprintf(FLOG, "* dir %s %s(%u)\n", dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 			exit_cleanup(RERR_FILESELECT);
 		}
 	}
@@ -922,12 +927,14 @@
 		struct filter_list_struct *elp = &daemon_filter_list;
 
 		for (dir_p = basis_dir; *dir_p; dir_p++) {
+			// 16 Feb 09 SHL fixme slash?
 			char *dir = *dir_p;
 			if (*dir == '/')
 				dir += module_dirlen;
 			if (check_filter(elp, FLOG, dir, 1) < 0)
 				goto options_rejected;
 		}
+		// 16 Feb 09 SHL fixme slash?
 		if (partial_dir && *partial_dir == '/'
 		 && check_filter(elp, FLOG, partial_dir + module_dirlen, 1) < 0) {
 		    options_rejected:
@@ -1118,6 +1125,14 @@
 	 * command line. */
 	if ((ret = copy_argv(argv)) != 0)
 		return ret;
+#ifdef __OS2__
+	{
+		int i;
+		for (i = 0; i < argc; i++) {
+			normalize_dir_slashes(argv[i]);
+		}
+	}
+#endif
 
 	if (!read_batch) { /* for read_batch, NO source is specified */
 		char *path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
@@ -1441,6 +1456,7 @@
 	 * (implemented by forking "pwd" and reading its output) doesn't
 	 * work when there are other child processes.  Also, on all systems
 	 * that implement getcwd that way "pwd" can't be found after chroot. */
+	// rprintf(FLOG, "* %s %s(%u)\n", "(null)", __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 	change_dir(NULL, CD_NORMAL);
 
 	init_flist();
Only in .: main.o
Only in .: match.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/options.c ./options.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/options.c	2008-11-09 18:55:14.000000000 -0800
+++ ./options.c	2009-06-14 19:49:46.000000000 -0700
@@ -51,7 +51,14 @@
 int preserve_links = 0;
 int preserve_hard_links = 0;
 int preserve_acls = 0;
+#ifndef __OS2__
 int preserve_xattrs = 0;
+#else
+/* OS/2 uses Extended attributes extensively - make preserving them the default */
+int preserve_xattrs = 1;
+// 13 Jun 09 SHL Added
+int os2_perms = 0;
+#endif
 int preserve_perms = 0;
 int preserve_executability = 0;
 int preserve_devices = 0;
@@ -339,6 +346,9 @@
   rprintf(F," -K, --keep-dirlinks         treat symlinked dir on receiver as dir\n");
   rprintf(F," -H, --hard-links            preserve hard links\n");
   rprintf(F," -p, --perms                 preserve permissions\n");
+#ifdef __OS2__
+  rprintf(F," -2, --os2-perms             preserve native OS/2 permissions\n");
+#endif
   rprintf(F," -E, --executability         preserve the file's executability\n");
   rprintf(F,"     --chmod=CHMOD           affect file and/or directory permissions\n");
 #ifdef SUPPORT_ACLS
@@ -481,6 +491,10 @@
   {"perms",           'p', POPT_ARG_VAL,    &preserve_perms, 1, 0, 0 },
   {"no-perms",         0,  POPT_ARG_VAL,    &preserve_perms, 0, 0, 0 },
   {"no-p",             0,  POPT_ARG_VAL,    &preserve_perms, 0, 0, 0 },
+#ifdef __OS2__
+  {"os2-perms",       '2', POPT_ARG_NONE,   0, '2', 0, 0 },
+  {"no-os2-perms",     0,  POPT_ARG_VAL,    &os2_perms, 0, 0, 0 },
+#endif
   {"executability",   'E', POPT_ARG_NONE,   &preserve_executability, 0, 0, 0 },
   {"acls",            'A', POPT_ARG_NONE,   0, 'A', 0, 0 },
   {"no-acls",          0,  POPT_ARG_VAL,    &preserve_acls, 0, 0, 0 },
@@ -1034,6 +1048,7 @@
 		case OPT_EXCLUDE_FROM:
 		case OPT_INCLUDE_FROM:
 			arg = poptGetOptArg(pc);
+			// printf("PS - pc = %s\n",arg);	// 16 Feb 09 SHL fixme debug ps?
 			if (sanitize_paths)
 				arg = sanitize_path(NULL, arg, NULL, 0, SP_DEFAULT);
 			if (daemon_filter_list.head) {
@@ -1043,6 +1058,7 @@
 					out_of_memory("parse_arguments");
 				if (!*cp)
 					goto options_rejected;
+				// 16 Feb 09 SHL fixme slash?
 				dir = cp + (*cp == '/' ? module_dirlen : 0);
 				clean_fname(dir, CFN_COLLAPSE_DOT_DOT_DIRS);
 				rej = check_filter(&daemon_filter_list, FLOG, dir, 0) < 0;
@@ -1141,6 +1157,13 @@
 			}
 			break;
 
+// 14 Jun 09 SHL
+#ifdef __OS2__
+		case '2':
+			os2_perms = 1;
+			preserve_perms = 1;
+			break;
+#endif
 		case OPT_WRITE_BATCH:
 			/* batch_name is already set */
 			write_batch = 1;
@@ -1778,6 +1801,12 @@
 		argstr[x++] = 'p';
 	else if (preserve_executability && am_sender)
 		argstr[x++] = 'E';
+// 13 Jun 09 SHL
+#ifdef __OS2__
+	if (os2_perms)
+		argstr[x++] = '2';
+#endif
+
 #ifdef SUPPORT_ACLS
 	if (preserve_acls)
 		argstr[x++] = 'A';
@@ -2138,7 +2167,11 @@
 
 	*host_ptr = new_array(char, hostlen + 1);
 	strlcpy(*host_ptr, s, hostlen + 1);
-
+#ifdef __OS2__
+	// 16 May 09 SHL fixme to be sure about this?
+	if (p[0] == ':' && (p[1] == '\\' || p[1] == '/'))
+                return NULL;		// Assume drive letter
+#endif
 	if (p[1] == ':') {
 		if (port_ptr && !*port_ptr)
 			*port_ptr = RSYNC_PORT;
Only in .: options.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/params.c ./params.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/params.c	2007-11-22 09:51:20.000000000 -0800
+++ ./params.c	2009-05-16 22:59:38.000000000 -0700
@@ -168,6 +168,7 @@
   while( pos >= 0 && isSpace(line + pos) )
      pos--;
 
+  // 16 May 09 SHL fixme to not be confused by trailing \ in path
   return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
   } /* Continuation */
 
Only in .: params.o
Only in .: patch_shl.cmd
Only in .: patch_shl.out
Only in .: pipe.o
Only in ./popt: ctags.tag
Only in ./popt: dummy
Only in ./popt: findme.o
Only in ./popt: popt.o
Only in ./popt: poptconfig.o
Only in ./popt: popthelp.o
Only in ./popt: poptparse.o
Only in .: progress.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/proto.h ./proto.h
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/proto.h	2008-12-28 18:03:36.000000000 -0800
+++ ./proto.h	2009-05-16 23:47:04.000000000 -0700
@@ -225,6 +225,54 @@
 BOOL lp_load(char *pszFname, int globals_only);
 int lp_numservices(void);
 int lp_number(char *name);
+char *lp_bind_address(void);
+char *lp_motd_file(void);
+char *lp_pid_file(void);
+char *lp_socket_options(void);
+int lp_rsync_port(void);
+char *lp_auth_users(int module_id);
+char *lp_charset(int module_id);
+char *lp_comment(int module_id);
+char *lp_dont_compress(int module_id);
+char *lp_exclude(int module_id);
+char *lp_exclude_from(int module_id);
+char *lp_filter(int module_id);
+char *lp_gid(int module_id);
+char *lp_hosts_allow(int module_id);
+char *lp_hosts_deny(int module_id);
+char *lp_include(int module_id);
+char *lp_include_from(int module_id);
+char *lp_incoming_chmod(int module_id);
+char *lp_lock_file(int module_id);
+char *lp_log_file(int module_id);
+char *lp_log_format(int module_id);
+char *lp_name(int module_id);
+char *lp_outgoing_chmod(int module_id);
+char *lp_path(int module_id);
+char *lp_postxfer_exec(int module_id);
+char *lp_prexfer_exec(int module_id);
+char *lp_refuse_options(int module_id);
+char *lp_secrets_file(int module_id);
+char *lp_temp_dir(int module_id);
+char *lp_uid(int module_id);
+int lp_max_connections(int module_id);
+int lp_max_verbosity(int module_id);
+int lp_syslog_facility(int module_id);
+int lp_timeout(int module_id);
+BOOL lp_fake_super(int module_id);
+BOOL lp_ignore_errors(int module_id);
+BOOL lp_ignore_nonreadable(int module_id);
+BOOL lp_list(int module_id);
+BOOL lp_munge_symlinks(int module_id);
+BOOL lp_numeric_ids(int module_id);
+BOOL lp_read_only(int module_id);
+BOOL lp_strict_modes(int module_id);
+BOOL lp_transfer_logging(int module_id);
+BOOL lp_use_chroot(int module_id);
+BOOL lp_write_only(int module_id);
+BOOL lp_load(char *pszFname, int globals_only);
+int lp_numservices(void);
+int lp_number(char *name);
 void log_init(int restart);
 void logfile_close(void);
 void logfile_reopen(void);
@@ -377,6 +425,8 @@
 int flist_ndx_pop(flist_ndx_list *lp);
 void *expand_item_list(item_list *lp, size_t item_size,
 		       const char *desc, int incr);
+void normalize_dir_slashes(char *path);
+void assert_no_dir_slashes(char *path);
 void free_xattr(stat_x *sxp);
 int get_xattr(const char *fname, stat_x *sxp);
 int copy_xattrs(const char *source, const char *dest);
Only in .: readme.os2
Only in .: receiver.o
Only in .: rounding.exe
Only in .: rounding.h
Only in .: rounding.map
Only in .: rsync-3.0.5-20090206-shl.diff
Only in .: rsync-3.0.5-20090306-before-shl.diff
Only in .: rsync-3.0.5-20090306-shl.diff
Only in .: rsync-3.0.5-20090306-shl_diff.zip
Only in .: rsync-3.0.5-20090410-shl.diff
Only in .: rsync-3.0.5-20090427-shl.diff
Only in .: rsync-3.0.5-20090613-shl.diff
Only in .: rsync-3.0.5-20090614-shl.diff
Only in .: rsync-3.0.5pre2-20090206-shl.diff
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/rsync.c ./rsync.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/rsync.c	2008-10-11 10:16:46.000000000 -0700
+++ ./rsync.c	2009-04-27 19:58:30.000000000 -0700
@@ -386,6 +386,8 @@
 	mode_t new_mode = file->mode;
 	int inherit;
 
+	rprintf(FINFO, "* set_file_attrs fname %s mode %o file %p sxp %p %s(%u)\n", fname, file->mode, file, sxp, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+
 	if (!sxp) {
 		if (dry_run)
 			return 1;
@@ -498,6 +500,7 @@
 
 #ifdef HAVE_CHMOD
 	if (!BITS_EQUAL(sxp->st.st_mode, new_mode, CHMOD_BITS)) {
+		rprintf(FINFO, "* set_file_attrs fname %s sxp->st.st_mode %o new_mode %o %s(%u)\n", fname, sxp->st.st_mode, new_mode, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
 		int ret = am_root < 0 ? 0 : do_chmod(fname, new_mode);
 		if (ret < 0) {
 			rsyserr(FERROR_XFER, errno,
@@ -555,6 +558,7 @@
 		    int overwriting_basis)
 {
 	int ret;
+	// 16 Feb 09 SHL fixme slash?
 	const char *temp_copy_name = partialptr && *partialptr != '/' ? partialptr : NULL;
 
 	if (inplace) {
Only in .: rsync.exe
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/rsync.h ./rsync.h
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/rsync.h	2008-09-26 21:21:52.000000000 -0700
+++ ./rsync.h	2009-05-16 23:30:28.000000000 -0700
@@ -1144,3 +1144,20 @@
 #ifdef MAINTAINER_MODE
 const char *get_panic_action(void);
 #endif
+
+// 05 Mar 09 SHL
+#ifndef __OS2__
+#define drive_spec_width(p) 0
+#define is_path_sep(p) (*(p) == '/')
+// 16 May 09 SHL fixme to be gone
+// #define is_path_sep2(p) (*(p) == '/')
+#define is_abs_path(p) (*(p) == '/')
+// #define is_abs_path2(p) (*(p) == '/')
+#else
+#define drive_spec_width(p) ((isalpha(*(p)) && *((p) + 1) == ':') ? 2 : 0)
+#define is_path_sep(p) (*(p) == '/')	// Unix only
+// #define is_path_sep2(p) (*(p) == '/' || *(p) == '\\')	// Unix or OS/2
+#define is_abs_path(p) (*((p) + drive_spec_width(p)) == '/')	// Unix only
+// Unix or OS/2
+// #define is_abs_path2(p) ((*((p) + drive_spec_width(p)) == '/') || (*((p) + drive_spec_width(p)) == '\\'))
+#endif
Only in .: rsync.map
Only in .: rsync.o
Only in .: rsync_exe-20090306.zip
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/sender.c ./sender.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/sender.c	2008-08-14 07:32:18.000000000 -0700
+++ ./sender.c	2009-03-06 14:07:08.000000000 -0800
@@ -363,7 +363,7 @@
 		make_backups = -make_backups;
 
 	if (verbose > 2)
-		rprintf(FINFO, "send files finished\n");
+		rprintf(FINFO, "send_files finished\n");	// 06 Mar 09 SHL
 
 	match_report();
 
Only in .: sender.o
Only in .: shconfig
Only in .: socket.o
Only in ./support: ctags.tag
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/syscall.c ./syscall.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/syscall.c	2008-03-21 07:26:24.000000000 -0700
+++ ./syscall.c	2009-06-13 20:41:22.000000000 -0700
@@ -28,6 +28,18 @@
 #ifdef HAVE_SYS_ATTR_H
 #include <sys/attr.h>
 #endif
+// 06 Mar 09 SHL libc io.h name conflict with rsync io.h - need to cheat to define setmode
+#if defined HAVE_SETMODE && O_BINARY && __OS2__
+// From gcc io.h
+int setmode (int, int);
+// From gcc os2emx.h
+#endif
+#if defined __OS2__
+// 27 Apr 09 SHL Need definitions for FILE_...
+#define INCL_DOS
+// #include <os2.h>
+#include <os2emx.h>
+#endif
 
 extern int dry_run;
 extern int am_root;
@@ -35,6 +47,10 @@
 extern int list_only;
 extern int preserve_perms;
 extern int preserve_executability;
+// 13 Jun 09 SHL
+#ifdef __OS2__
+extern int os2_perms;
+#endif
 
 #define RETURN_ERROR_IF(x,e) \
 	do { \
@@ -152,6 +168,9 @@
 	int code;
 	if (dry_run) return 0;
 	RETURN_ERROR_IF_RO_OR_LO;
+
+	rprintf(FINFO, "* do_chmod path %s mode %o %s(%u)\n", path, mode, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+
 	if (S_ISLNK(mode)) {
 #ifdef HAVE_LCHMOD
 		code = lchmod(path, mode & CHMOD_BITS);
@@ -167,7 +186,63 @@
 		code = 1;
 #endif
 	} else
+#ifndef __OS2__
 		code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */
+#else
+	{
+		ULONG attributes = 0;
+		if (os2_perms) {
+			// See map_os2_attributes
+			// If not readable by owner, hidden
+			if (~mode & S_IRUSR)
+				attributes |= FILE_HIDDEN;
+			// If writable by group, archived
+			if (mode & S_IWGRP)
+				attributes |= FILE_ARCHIVED;
+			// If readable by group, system
+			if (mode & S_IRGRP)
+				attributes |= FILE_SYSTEM;
+			// Reset group bits to match other bits - hack cough
+			if (mode & S_IROTH)
+				mode |= S_IRGRP;
+			else
+				mode &= ~S_IRGRP;
+			if (mode & S_IWOTH)
+				mode |= S_IWGRP;
+			else
+				mode &= ~S_IWGRP;
+		}
+		code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */
+		if (!code) {
+			// Adjust native attributes not handled by chmod - system, hidden, archived
+			// Maybe libc will do this someday
+			// chmod handles readonly already
+			if ((attributes & ~FILE_ARCHIVED) || (~attributes & FILE_ARCHIVED)) {
+				FILESTATUS3 fs3;
+				APIRET apiret = DosQueryPathInfo((PCSZ)path,
+								 FIL_STANDARD,
+								 &fs3,
+								 sizeof(fs3));
+				if (apiret)
+					rprintf(FERROR, "DosQueryPathInfo(%s) failed with error %lu %s(%u)\n", path, apiret, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+				else {
+					ULONG m = attributes | (fs3.attrFile & ~(FILE_SYSTEM | FILE_HIDDEN | FILE_ARCHIVED));
+					if (m != fs3.attrFile) {
+						fs3.attrFile = m;
+						apiret = DosSetPathInfo((PCSZ)path,
+									 FIL_STANDARD,
+									 &fs3, sizeof(fs3),
+									 0);
+						if (apiret)
+							rprintf(FERROR, "DosSetPathInfo(%s) failed with error %lu %s(%u)\n", path, apiret, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+						else
+							rprintf(FINFO, "* do_chmod path %s attrFile %lx attributes %lx %s(%u)\n", path, fs3.attrFile, attributes, __FILE__, __LINE__);	// 13 Jun 09 SHL debug perms
+					}
+				}
+			}
+		}
+	}
+#endif
 	if (code != 0 && (preserve_perms || preserve_executability))
 		return code;
 	return 0;
@@ -238,12 +313,50 @@
 #endif
 }
 
+#ifdef __OS2__
+
+static void map_os2_attributes(STRUCT_STAT *st)
+{
+	// Map native attributes with sensible mappings
+	// If readonly, writable by none
+	if (st->st_attr & FILE_READONLY)
+		st->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+	// If hidden, readable by none
+	if (st->st_attr & FILE_HIDDEN)
+		st->st_mode &= ~(S_IRUSR | S_IRGRP | S_IROTH);
+
+	// Steal group bits for native attributes without obvious mappings - hack cough
+	// If archived, writable by group
+	if (st->st_attr & FILE_ARCHIVED)
+		st->st_mode |= S_IWGRP;
+	else
+		st->st_mode &= ~S_IWGRP;
+	// If system, readable by group
+	if (st->st_attr & FILE_SYSTEM)
+		st->st_mode |= S_IRGRP;
+	else
+		st->st_mode &= ~S_IRGRP;
+}
+
+#endif
+
 int do_stat(const char *fname, STRUCT_STAT *st)
 {
 #ifdef USE_STAT64_FUNCS
 	return stat64(fname, st);
 #else
+#ifndef __OS2__
 	return stat(fname, st);
+#else
+	int code;
+	code = stat(fname, st);
+	if (!code && os2_perms) {
+		map_os2_attributes(st);
+		// 13 Jun 09 SHL log correctly
+		rprintf(FINFO, "* do_stat fname %s st->st_mode %o st->st_attr %o code %d %s(%u)\n", fname, st->st_mode, st->st_attr, code, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+	}
+	return code;
+#endif
 #endif
 }
 
@@ -253,7 +366,17 @@
 # ifdef USE_STAT64_FUNCS
 	return lstat64(fname, st);
 # else
+#ifndef __OS2__
 	return lstat(fname, st);
+#else
+	// 27 Apr 09 SHL map OS/2 permissions
+	int code = lstat(fname, st);
+	if (!code) {
+		map_os2_attributes(st);
+		rprintf(FINFO, "* do_lstat fname %s st->st_mode %o st->st_attr %o code %d %s(%u)\n", fname, st->st_mode, st->st_attr, code, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+	}
+	return code;
+#endif
 # endif
 #else
 	return do_stat(fname, st);
@@ -265,7 +388,18 @@
 #ifdef USE_STAT64_FUNCS
 	return fstat64(fd, st);
 #else
+#ifndef __OS2__
 	return fstat(fd, st);
+#else
+	int code;
+	code = fstat(fd, st);
+	if (!code && os2_perms) {
+		map_os2_attributes(st);
+		// 13 Jun 09 SHL fixme to use verbose
+		rprintf(FINFO, "* do_fstat fd %d st->st_mode %o st->st_attr %o code %d %s(%u)\n", fd, st->st_mode, st->st_attr, code, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+	}
+	return code;
+#endif
 #endif
 }
 
Only in .: syscall.o
Only in .: token.o
Only in .: uidlist.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/util.c ./util.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/util.c	2008-11-15 14:17:48.000000000 -0800
+++ ./util.c	2009-05-17 10:27:14.000000000 -0700
@@ -23,6 +23,10 @@
 #include "rsync.h"
 #include "ifuncs.h"
 
+#ifdef __OS2__
+#include <os2emx.h>
+#endif
+
 extern int verbose;
 extern int dry_run;
 extern int module_id;
@@ -191,6 +195,10 @@
 	char *p;
 	int ret = 0;
 
+#ifdef __OS2__ // 06 Mar 09 SHL use drive_spec_width
+	fname += drive_spec_width(fname);		/* Bypass drive letter */
+#endif /* __OS2__ */
+
 	while (*fname == '/')
 		fname++;
 	while (strncmp(fname, "./", 2) == 0)
@@ -420,6 +428,8 @@
 {
 	int tries = 4;
 
+	rprintf(FINFO, "* robust_rename %s->%s %s(%u)\n", from, to, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+
 	while (tries--) {
 		if (do_rename(from, to) == 0)
 			return 0;
@@ -444,6 +454,26 @@
 				return -2;
 			do_unlink(from);
 			return 1;
+#ifdef __OS2__ // 27 Apr 09 SHL
+		// libc rename semantics differs from linux
+		// clear readonly if this caused rename to fail
+		case EACCES:
+		{
+			STRUCT_STAT st;
+			int code;
+			rprintf(FINFO, "* robust_rename %s EACCES %s(%u)\n", to, __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
+			code = do_stat(to, &st);
+			if (!code) {
+				// 27 Apr 09 SHL fixme to use st_mode when libc fixed
+				if (st.st_attr & FILE_READONLY) {
+					st.st_mode |= S_IWUSR;
+					code = do_chmod(to, st.st_mode);
+					if (!code)
+						break;	// Try again
+				}
+			}
+		}
+#endif
 		default:
 			return -1;
 		}
@@ -818,10 +848,18 @@
 {
 	char *limit = name - 1, *t = name, *f = name;
 	int anchored;
+#ifdef __OS2__
+	int drive_letter_adj;	// 0 if not, 2 if yes 15 Dec 08 SHL
+#endif
 
 	if (!name)
 		return 0;
 
+#ifdef __OS2__ // 06 Mar 09 SHL use drive_spec_width...
+	drive_letter_adj = drive_spec_width(name);
+	f += drive_letter_adj;			// Keep drive letter
+	t += drive_letter_adj;
+#endif /* __OS2__ */
 	if ((anchored = *f == '/') != 0) {
 		*t++ = *f++;
 #ifdef __CYGWIN__
@@ -869,10 +907,18 @@
 		while (*f && (*t++ = *f++) != '/') {}
 	}
 
+#ifndef __OS2__ // 06 Feb 09 SHL
 	if (t > name+anchored && t[-1] == '/' && !(flags & CFN_KEEP_TRAILING_SLASH))
 		t--;
 	if (t == name)
 		*t++ = '.';
+#else
+	if (t > name + anchored + drive_letter_adj && t[-1] == '/' && !(flags & CFN_KEEP_TRAILING_SLASH))
+		t--;
+	if (t == name + drive_letter_adj)
+		*t++ = '.';		// Ensure not empty
+#endif
+
 	*t = '\0';
 
 	return t - name;
@@ -906,14 +952,28 @@
 	char *start, *sanp;
 	int rlen = 0, drop_dot_dirs = !relative_paths || !(flags & SP_KEEP_DOT_DIRS);
 
+	// rprintf(FINFO, "sanitize_path p %s %s(%u)\n", p, __FILE__, __LINE__);	// 06 Feb 09 SHL
 	if (dest != p) {
 		int plen = strlen(p);
-		if (*p == '/') {
+		int drive_letter_adj = drive_spec_width(p);	// 0 if not, 2 if yes 15 Dec 08 SHL
+#ifndef __OS2__
+		if (*p == '/')
+#else // 06 Feb 09 SHL use is_abs_path...
+		if (!is_abs_path(p)) {
+			if (drive_letter_adj)
+				rprintf(FERROR, "relative directory with drive letter not supported %s %s(%u)\n", p, __FILE__, __LINE__);	// 06 Feb 09 SHL
+		} else
+#endif
+		{
 			if (!rootdir)
 				rootdir = module_dir;
 			rlen = strlen(rootdir);
 			depth = 0;
+#ifndef __OS2__
 			p++;
+#else
+			p += drive_spec_width(p) + 1;
+#endif
 		}
 		if (dest) {
 			if (rlen + plen + 1 >= MAXPATHLEN)
@@ -922,12 +982,19 @@
 			out_of_memory("sanitize_path");
 		if (rlen) {
 			memcpy(dest, rootdir, rlen);
+#ifndef __OS2__
 			if (rlen > 1)
 				dest[rlen++] = '/';
+#else
+			if (rlen > 1 + drive_letter_adj)
+				dest[rlen++] = '/';
+#endif
 		}
 	}
 
 	if (drop_dot_dirs) {
+		// 06 Mar 09 SHL Use is_path_sep2 - fixme to be gone
+		// while (*p == '.' && (is_path_sep2(p + 1)))
 		while (*p == '.' && p[1] == '/')
 			p += 2;
 	}
@@ -937,17 +1004,23 @@
 	 * the start of the name (past any prior slash) for each iteration. */
 	while (*p) {
 		/* discard leading or extra slashes */
+		// 06 Mar 09 SHL - fixme to be gone
+		// if (is_path_sep2(p)) { }
 		if (*p == '/') {
 			p++;
 			continue;
 		}
 		if (drop_dot_dirs) {
+			// 06 Mar 09 SHL - fixme to be gone
+			// if (*p == '.' && (is_path_sep2(p + 1) || p[1] == '\0')) { }
 			if (*p == '.' && (p[1] == '/' || p[1] == '\0')) {
 				/* skip "." component */
 				p++;
 				continue;
 			}
 		}
+		// 16 May 09 SHL fixme to be gone
+		// if (*p == '.' && p[1] == '.' && (is_path_sep2(p + 2) || p[2] == '\0')) { }
 		if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) {
 			/* ".." component followed by slash or end */
 			if (depth <= 0 || sanp != start) {
@@ -955,6 +1028,8 @@
 				if (sanp != start) {
 					/* back up sanp one level */
 					--sanp; /* now pointing at slash */
+					// 06 Mar 09 SHL fixme to be gone
+					// while (sanp > start && !is_path_sep2(sanp -1))
 					while (sanp > start && sanp[-1] != '/')
 						sanp--;
 				}
@@ -967,6 +1042,20 @@
 		}
 		/* copy one component through next slash */
 		while (*p && (*sanp++ = *p++) != '/') {}
+#if 0 // 16 May 09 SHL fixme to be gone
+#ifndef __OS2__
+		while (*p && (*sanp++ = *p++) != '/') {}
+#else
+		while(*p) {
+			char c = *p++;
+			if (c == '\\')
+				c = '/';
+			*sanp++ = c;
+			if (c == '/')
+				break;
+		}
+#endif
+#endif
 	}
 	if (sanp == dest) {
 		/* ended up with nothing, so put in "." component */
@@ -974,16 +1063,23 @@
 	}
 	*sanp = '\0';
 
+	// rprintf(FINFO, "sanitize_path dest %s %s(%u)\n", dest, __FILE__, __LINE__);	// 06 Feb 09 SHL
+
+	// 16 May 09 SHL  fixme to be gone
+	assert_no_dir_slashes(dest);
+
 	return dest;
 }
 
 /* Like chdir(), but it keeps track of the current directory (in the
  * global "curr_dir"), and ensures that the path size doesn't overflow.
- * Also cleans the path using the clean_fname() function. */
+ * Also cleans the path using the clean_fname() function.
+ * Returns 1 of change OK.  Otherwise 0 */
 int change_dir(const char *dir, int set_path_only)
 {
 	static int initialised;
 	unsigned int len;
+	// rprintf(FINFO, "* change_dir dir %s %s(%u)\n", dir ? dir : "(null)", __FILE__, __LINE__);	// 27 Apr 09 SHL debug perms
 
 	if (!initialised) {
 		initialised = 1;
@@ -992,6 +1088,7 @@
 			exit_cleanup(RERR_FILESELECT);
 		}
 		curr_dir_len = strlen(curr_dir);
+		// rprintf(FINFO, "* change_dir curr_dir %s %s(%u)\n", curr_dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 	}
 
 	if (!dir)	/* this call was probably just to initialize */
@@ -1001,23 +1098,50 @@
 	if (len == 1 && *dir == '.')
 		return 1;
 
-	if (*dir == '/') {
+	// 06 Mar 09 SHL use is_abs_path
+	if (is_abs_path(dir)) {
+		// Absolute path
 		if (len >= sizeof curr_dir) {
 			errno = ENAMETOOLONG;
 			return 0;
 		}
+#ifndef __OS2__ // 28 Jul 08 SHL
 		if (!set_path_only && chdir(dir))
 			return 0;
 		memcpy(curr_dir, dir, len + 1);
+#else
+		if (!set_path_only) {
+			if (chdir(dir)) {
+				rprintf(FERROR, "* change_dir: chdir failed for dir %s %s(%u)\n", dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+				return 0;
+			}
+			// 06 Mar 09 SHL use drive_spec_width
+			if (drive_spec_width(dir) && _chdrive(*dir)) {
+				rprintf(FERROR, "* change_dir: _chdrive failed for dir %s %s(%u)\n", dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+				return 0;
+			}
+		}
+		memcpy(curr_dir, dir, len + 1);
+		// rprintf(FLOG, "* change_dir curr_dir %s %s(%u)\n", curr_dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+#endif
 	} else {
+		// Relative path
 		if (curr_dir_len + 1 + len >= sizeof curr_dir) {
 			errno = ENAMETOOLONG;
 			return 0;
 		}
+#ifdef __OS2__
+		if (drive_spec_width(dir)) {
+			rprintf(FERROR, "relative directory with drive letter not supported %s %s(%u)\n", dir, __FILE__, __LINE__);	// 06 Feb 09 SHL
+			errno = EINVAL;
+			return -1;
+		}
+#endif
 		curr_dir[curr_dir_len] = '/';
 		memcpy(curr_dir + curr_dir_len + 1, dir, len + 1);
 
 		if (!set_path_only && chdir(curr_dir)) {
+			rprintf(FERROR, "* change_dir: chdir failed for curr_dir %s %s(%u)\n", dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
 			curr_dir[curr_dir_len] = '\0';
 			return 0;
 		}
@@ -1042,12 +1166,15 @@
 {
 	unsigned int len;
 
-	if (*path != '/') { /* Make path absolute. */
+	// 06 Mar 09 SHL use is_abs_path
+	if (!is_abs_path(path)) { /* Make path absolute. */
 		int len = strlen(path);
+		if (drive_spec_width(path))
+			rprintf(FERROR, "relative directory with drive letter not supported %s %s(%u)\n", path, __FILE__, __LINE__);	// 28 Jul 08 SHL
 		if (curr_dir_len + 1 + len >= sizeof curr_dir)
 			return NULL;
 		curr_dir[curr_dir_len] = '/';
-		memcpy(curr_dir + curr_dir_len + 1, path, len + 1);
+		memcpy(curr_dir + curr_dir_len + 1, path + drive_spec_width(path), len + 1);
 		if (!(path = strdup(curr_dir)))
 			out_of_memory("normalize_path");
 		curr_dir[curr_dir_len] = '\0';
@@ -1078,9 +1205,14 @@
 	if (result)
 		free(result);
 
-	if (*fn == '/')
+	// 06 Mar 09 SHL use is_abs_path
+	if (is_abs_path(fn))
 		p1 = p2 = "";
 	else {
+#ifdef __OS2__
+		if (drive_spec_width(fn))
+			rprintf(FERROR, "relative directory with drive letter not supported %s %s(%u)\n", fn, __FILE__, __LINE__);	// 06 Feb 09 SHL
+#endif
 		p1 = curr_dir + module_dirlen;
 		for (p2 = p1; *p2 == '/'; p2++) {}
 		if (*p2)
@@ -1695,3 +1827,27 @@
 	}
 	return (char*)lp->items + (lp->count++ * item_size);
 }
+
+#ifdef __OS2__ // 16 May 09 SHL added
+/* Convert OS/2 backslashes to unix forward slashes */
+void normalize_dir_slashes(char *path)
+{
+	char *p;
+	if (path && (p = strchr(path, '\\')) != 0) {
+		char ch;
+		*p++ = '/';
+		for (; (ch = *p) != 0; p++)
+		{
+			if (ch == '\\') *p = '/';
+		}
+	}
+}
+
+#if 1
+void assert_no_dir_slashes(char *path)
+{
+	if (path && strchr(path, '\\') != 0)
+		rprintf(FERROR, "unexpected backslash in path %s %s(%u)\n", path, __FILE__, __LINE__);	// 06 Feb 09 SHL
+}
+#endif
+#endif // __OS2__
Only in .: util.o
diff -r -u -w ../../../sla_dev2_browse/rsync/rsync-3.0.5/xattrs.c ./xattrs.c
--- ../../../sla_dev2_browse/rsync/rsync-3.0.5/xattrs.c	2008-07-24 07:57:56.000000000 -0700
+++ ./xattrs.c	2009-05-17 16:56:32.000000000 -0700
@@ -48,17 +48,28 @@
 #define XSTATE_DONE	2
 #define XSTATE_TODO	3
 
+#ifndef __OS2__
 #define USER_PREFIX "user."
 #define UPRE_LEN ((int)sizeof USER_PREFIX - 1)
 #define SYSTEM_PREFIX "system."
 #define SPRE_LEN ((int)sizeof SYSTEM_PREFIX - 1)
+#else
+#define USER_PREFIX ""
+#define UPRE_LEN ((int)sizeof USER_PREFIX - 1)
+#define SYSTEM_PREFIX ""
+#define SPRE_LEN ((int)sizeof SYSTEM_PREFIX - 1)
+#endif
 
 #ifdef HAVE_LINUX_XATTRS
 #define MIGHT_NEED_RPRE (am_root < 0)
 #define RSYNC_PREFIX USER_PREFIX "rsync."
 #else
 #define MIGHT_NEED_RPRE am_root
+#ifndef __OS2__
 #define RSYNC_PREFIX "rsync."
+#else 
+# define RSYNC_PREFIX ""
+#endif
 #endif
 #define RPRE_LEN ((int)sizeof RSYNC_PREFIX - 1)
 
@@ -108,6 +119,8 @@
 {
 	const rsync_xa *xa1 = x1;
 	const rsync_xa *xa2 = x2;
+	// rprintf(FLOG, "* rsync_xal_compare_names: xa1.name %p xa2.name %p %s:%u\n", xa1->name, xa2->name, __FILE__, __LINE__);	// 28 Jul 08 SHL debug xattrs
+
 	return strcmp(xa1->name, xa2->name);
 }
 
@@ -139,6 +152,7 @@
 				fname, arg);
 			return -1;
 		}
+		/* Expand buffer */
 		list_len = sys_llistxattr(fname, NULL, 0);
 		if (list_len < 0) {
 			arg = 0;
@@ -713,8 +727,10 @@
 		rxa->num = num;
 	}
 
-	if (need_sort && count > 1)
-		qsort(temp_xattr.items, count, sizeof (rsync_xa), rsync_xal_compare_names);
+	// rprintf(FLOG, "* receive_xattr: temp_xattr.items %p count %u %s:%u\n", temp_xattr.items, count, __FILE__, __LINE__);	// 28 Jul 08 SHL debug xattrs
+	// 28 Jul 08 SHL sort used not malloced
+	if (need_sort && temp_xattr.count > 1)
+		qsort(temp_xattr.items, temp_xattr.count, sizeof (rsync_xa), rsync_xal_compare_names);
 
 	ndx = rsync_xal_l.count; /* pre-incremented count */
 	rsync_xal_store(&temp_xattr); /* adds item to rsync_xal_l */
Only in .: xattrs.o
Only in ./zlib: adler32.o
Only in ./zlib: compress.o
Only in ./zlib: crc32.o
Only in ./zlib: ctags.tag
Only in ./zlib: deflate.o
Only in ./zlib: dummy
Only in ./zlib: inffast.o
Only in ./zlib: inflate.o
Only in ./zlib: inftrees.o
Only in ./zlib: trees.o
Only in ./zlib: zutil.o
rsync-3.0.5-20090614-shl.diff (68,522 bytes)   

Activities

Steven Levine

2009-06-15 13:12

manager   ~0001324

rsync-3.0.5-20090614-shl.diff implements logic to preserve native os/2 permissions when the source and destination is running OS/2. See --os2-perms. Using this option with a non-OS/2 source or destination will result in complaints about unsupported options.

Steven Levine

2009-07-30 12:23

manager   ~0001381

See http://mantis.smedley.info/view.php?id=366 for diffs that contain the support for this feature.

Issue History

Date Modified Username Field Change
2009-04-28 13:36 Steven Levine New Issue
2009-04-28 13:36 Steven Levine File Added: rsync-3.0.5-20090427-shl.diff
2009-04-28 13:37 Steven Levine Status new => assigned
2009-04-28 13:37 Steven Levine Assigned To => Steven Levine
2009-06-15 13:08 Steven Levine File Added: rsync-3.0.5-20090614-shl.diff
2009-06-15 13:12 Steven Levine Note Added: 0001324
2009-07-30 12:23 Steven Levine Note Added: 0001381
2009-07-30 12:23 Steven Levine Status assigned => resolved
2009-07-30 12:23 Steven Levine Fixed in Version => 3.0.6
2009-07-30 12:23 Steven Levine Resolution open => fixed
2020-08-24 12:44 psmedley Status resolved => closed