View Issue Details

IDProjectCategoryView StatusLast Update
0000304RsyncBugpublic2020-08-24 03:14
ReporterPWeilbacher Assigned ToSteven Levine  
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Product Version3.0.4 
Summary0000304: Working directory influences synced tree
DescriptionI am starting my backups in a directory G:\Backups where my scripts are. One of the scripts uses rsync like this

   rsync -va --delete --exclude="tmp/*" --exclude=".svn/*" G:/ O:/Data/

The result is that only the files below G:\Backup are actually synced to O:\Data instead of the whole G: disk.

I now modified my script to do

   cd G:\
   rsync ...
   cd G:\Backups

and then it works.
TagsNo tags attached.
Attached Files
rsync-3.0.5-20090206-shl.diff (39,352 bytes)   
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 .: 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-02-06 10:47:20.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
+			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
 		}
 	}
 
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-02-06 10:47:20.000000000 -0800
@@ -1274,12 +1274,12 @@
   --enable-profile        turn on CPU profiling
   --enable-maintainer-mode
                           turn on extra debug features
+  --enable-xattr-support  disable 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
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-02-06 18:04:32.000000000 -0800
@@ -346,10 +346,21 @@
  * value checked to ensure that it is not daemon-excluded. */
 int change_pathname(struct file_struct *file, const char *dir, int dirlen)
 {
+	int drive_letter_adj;		// 06 Feb 09 SHL
 	if (dirlen < 0) {
 		char *cpy = strdup(dir);
+#ifndef __OS2__ // 28 Jul 08 SHL
 		if (*cpy != '/')
 			change_dir(orig_dir, CD_SKIP_CHDIR);
+#else
+		drive_letter_adj = *(cpy + 1) == ':' && isalpha(*cpy) ? 2 : 0;	// 06 Feb 09 SHL
+		if ((*(cpy + drive_letter_adj) != '/')) {
+			if (drive_letter_adj)
+				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, "* orig_dir %s %s(%u)\n", orig_dir, __FILE__, __LINE__);	// 28 Jul 08 SHL debug
+	        }
+#endif
 		if (path_is_daemon_excluded(cpy, 0))
 			goto chdir_error;
 		dir = cpy;
@@ -363,8 +374,18 @@
 				dirlen = strlen(dir);
 		} else if (pathname == dir)
 			return 1;
+#ifndef __OS2__ // 28 Jul 08 SHL
 		if (dir && *dir != '/')
 			change_dir(orig_dir, CD_SKIP_CHDIR);
+#else
+		drive_letter_adj = dir && *(dir + 1) == ':' && isalpha(*dir) ? 2 : 0;	// 06 Feb 09 SHL
+		if (dir && *(dir + drive_letter_adj) != '/' ) {
+			if (drive_letter_adj)
+				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, "* orig_dir %s %s(%u)\n", orig_dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
+		}
+#endif
 	}
 
 	pathname = dir;
@@ -377,8 +398,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, "* dir %s %s(%u)\n", dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
+		if (dir != orig_dir) {
+			if (!change_dir(orig_dir, CD_NORMAL))
+				rprintf(FLOG, "* orig_dir %s %s(%u)\n", orig_dir, __FILE__, __LINE__);	// 06 Feb 09 SHL debug
+		}
 		pathname = NULL;
 		pathname_len = 0;
 		return 0;
@@ -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, "* argv[0] %s %s(%u)\n", argv[0], __FILE__, __LINE__);	// 06 Feb 09 SHL debug
 			exit_cleanup(RERR_FILESELECT);
 		}
 		use_ff_fd = 1;
Only in .: flist.o
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-02-06 10:47:20.000000000 -0800
@@ -126,6 +126,371 @@
 	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 why - 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 > 1)
+				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 > 1)
+				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 = {0};			// Warning expected
+	char npath[CCHMAXPATH + 1] = {0};
+	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 > 1)
+			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 > 1)
+			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 > 1) {
+		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;
+	}
+	rprintf(FINFO, "Returning %ld EA list bytes\n", 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-02-06 15:52:40.000000000 -0800
@@ -728,7 +728,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
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-06 15:14:02.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);
 		}
 	}
@@ -1441,6 +1446,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-02-06 10:47:20.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);
 			if (sanitize_paths)
 				arg = sanitize_path(NULL, arg, NULL, 0, SP_DEFAULT);
 			if (daemon_filter_list.head) {
@@ -2138,7 +2144,11 @@
 
 	*host_ptr = new_array(char, hostlen + 1);
 	strlcpy(*host_ptr, s, hostlen + 1);
-
+#ifdef __EMX__
+	if ((p[0] == ':')&&((p[1] == '\\')||(p[1] == '/'))) {
+                return NULL;
+        }
+#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 .: 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.5pre2-20090206-shl.diff
Only in .: rsync.exe
Only in .: rsync.map
Only in .: rsync.o
Only in .: sender.o
Only in .: shconfig
Only in .: socket.o
Only in ./support: ctags.tag
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-02-06 17:17:24.000000000 -0800
@@ -191,6 +191,11 @@
 	char *p;
 	int ret = 0;
 
+#ifdef __OS2__ /* 25 Sep 07 */
+	if (*(fname + 1) == ':' && isalpha(*fname))
+		fname += 2;		/* Bypass drive letter */
+#endif /* __OS2__ */
+
 	while (*fname == '/')
 		fname++;
 	while (strncmp(fname, "./", 2) == 0)
@@ -818,10 +823,20 @@
 {
 	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__ /* 25 Sep 07 SHL */
+	drive_letter_adj = *(f + 1) == ':' && isalpha(*f) ? 2 : 0;
+	if (drive_letter_adj) {
+		f += 2;			// Keep drive letter
+		t += 2;
+	}
+#endif /* __OS2__ */
 	if ((anchored = *f == '/') != 0) {
 		*t++ = *f++;
 #ifdef __CYGWIN__
@@ -869,10 +884,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++ = '.';
+#endif
+
 	*t = '\0';
 
 	return t - name;
@@ -908,12 +931,25 @@
 
 	if (dest != p) {
 		int plen = strlen(p);
+#ifndef __OS2__
 		if (*p == '/') {
+#else // 06 Feb 09 SHL
+		int drive_letter_adj;	// 0 if not, 2 if yes 15 Dec 08 SHL
+		drive_letter_adj = *(p + 1) == ':' && isalpha(*p) ? 2 : 0;
+		if (*(p + drive_letter_adj) != '/') {
+			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_letter_adj + 1;
+#endif
 		}
 		if (dest) {
 			if (rlen + plen + 1 >= MAXPATHLEN)
@@ -922,7 +958,11 @@
 			out_of_memory("sanitize_path");
 		if (rlen) {
 			memcpy(dest, rootdir, rlen);
+#ifndef __OS2__
 			if (rlen > 1)
+#else
+			if (rlen > 1 + drive_letter_adj)
+#endif
 				dest[rlen++] = '/';
 		}
 	}
@@ -974,16 +1014,23 @@
 	}
 	*sanp = '\0';
 
+	// rprintf(FLOG, "santize_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;
+#ifdef __OS2__
+	unsigned int drive_letter_adj;	// 0 if not, 2 if yes 15 Dec 08 SHL
+#endif
+	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 +1039,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 +1049,56 @@
 	if (len == 1 && *dir == '.')
 		return 1;
 
+#ifndef __OS2__
 	if (*dir == '/') {
+#else
+	// 15 Dec 08 SHL detect drive letters
+	drive_letter_adj = *(dir + 1) == ':' && isalpha(*dir) ? 2 : 0;
+
+	if (*(dir + drive_letter_adj) == '/') {
+#endif
+		// 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;
+			}
+			// 15 Dec 08 SHL
+			if (drive_letter_adj && _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_letter_adj) {
+			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;
 		}
@@ -1041,13 +1122,17 @@
 char *normalize_path(char *path, BOOL force_newbuf, unsigned int *len_ptr)
 {
 	unsigned int len;
+	unsigned int drive_letter_adj;	// 0 if not, 2 if yes 15 Dec 08 SHL
 
-	if (*path != '/') { /* Make path absolute. */
+	drive_letter_adj = *(path + 1) == ':' && isalpha(*path) ? 2 : 0;
+	if (*(path + drive_letter_adj) != '/') { /* Make path absolute. */
 		int len = strlen(path);
+		if (drive_letter_adj)
+			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_letter_adj, len + 1);
 		if (!(path = strdup(curr_dir)))
 			out_of_memory("normalize_path");
 		curr_dir[curr_dir_len] = '\0';
@@ -1080,6 +1165,12 @@
 
 	if (*fn == '/')
 		p1 = p2 = "";
+#ifdef __OS2__ /* 25 Sep 07 SHL */
+	else if (*(fn + 1) == ':' &&
+		 *(fn + 2) == '/' &&
+		 isalpha(*fn))
+		p1 = p2 = "";	/* Got d:/ */
+#endif
 	else {
 		p1 = curr_dir + module_dirlen;
 		for (p2 = p1; *p2 == '/'; 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-02-06 10:47:20.000000000 -0800
@@ -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
+
 	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
+	// 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-20090206-shl.diff (39,352 bytes)   
rsync_exe-20090306.zip (199,396 bytes)

Activities

Steven Levine

2008-12-31 17:34

manager   ~0001086

Hi,

FWIW, Roderick and I noted this and I am working on a fix. The general issue is that pathspecs referencing the root are not handled properly.

Attempting

 rsync rsync://drivec i:\tmp

with the daemon configuration

[drivec]
        path = C:/
        comment = cdrive
        refuse options = delete
        hosts allow = localhost
        auth users = whome

has the same issue.

Most likely, I need to add a _chdrive call when I figure out where it is missing.

Steven Levine

2009-02-08 03:33

manager   ~0001116

rsync-3.0.5-20090206-shl.diff patches rsync 3.0.5 and resolves this issue among others. Rsync contains a lot of code that handles absolute vs. relative path references. None of them know what a drive letter is.

Steven Levine

2009-02-13 03:40

manager   ~0001124

Ticket http://mantis.smedley.info/view.php?id=285 contains a binary build with this diff applied.

PWeilbacher

2009-02-15 22:44

reporter   ~0001134

Thanks for the first try, Steven. Haven't looked at the patch but the binary does yet do what I expect. It gives some error messages at least. This should be self explanatory:

[K:\bla]rsync -va k:/ f:/z_old_system_disk/
sending incremental file list
relative directory with drive letter not supported k: flist.c(359)
relative directory with drive letter not supported k: util.c(1092)

sent 26 bytes received 12 bytes 76.00 bytes/sec
total size is 0 speedup is 0.00

[K:\bla]rsync -va k: f:/z_old_system_disk/
rsync: connection unexpectedly closed (0 bytes received so far) [receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(600) [receiver=3.0.5]

[K:\bla]rsync -va k:\ f:\z_old_system_disk\
sending incremental file list
relative directory with drive letter not supported f:\z_old_system_disk\ util.c(
1092)

sent 101972 bytes received 354 bytes 22739.11 bytes/sec
total size is 406760469 speedup is 3975.14

[K:\bla]rsync -va k:\ f:\z_old_system_disk
sending incremental file list
relative directory with drive letter not supported f:\z_old_system_disk util.c(1092)

sent 101972 bytes received 354 bytes 29236.00 bytes/sec
total size is 406760469 speedup is 3975.14

Steven Levine

2009-02-17 06:57

manager   ~0001139

Hi Peter,

This syntax should work

  rsync -va k:/ f:/z_old_system_disk/

but it appears I've got yet more patching to do. Backslashes are pretty much sure to fail. I its on my list normalize all backslashes to slashes. For now, stick with forward slashes.

I'll add a note to this ticket when a fix is ready.

Steven Levine

2009-03-07 08:13

manager   ~0001232

Hi Peter,

I spent some quality time on the drive letter handling. The results are in the 20090306 version uploaded to this ticket.

Testing so far indicates this build handles drive letters and backslashes correctly.

Note that rsync does not recurse by default, so if you want a full backup of the volume you need to add --recurse. To backup a single directory, -m -d seems to help.

Issue History

Date Modified Username Field Change
2008-12-31 10:24 PWeilbacher New Issue
2008-12-31 17:34 Steven Levine Note Added: 0001086
2009-02-06 19:05 Steven Levine Status new => assigned
2009-02-06 19:05 Steven Levine Assigned To => Steven Levine
2009-02-08 03:31 Steven Levine File Added: rsync-3.0.5-20090206-shl.diff
2009-02-08 03:33 Steven Levine Note Added: 0001116
2009-02-13 03:40 Steven Levine Note Added: 0001124
2009-02-15 22:44 PWeilbacher Note Added: 0001134
2009-02-17 06:57 Steven Levine Note Added: 0001139
2009-03-07 07:52 Steven Levine File Added: rsync_exe-20090306.zip
2009-03-07 07:53 Steven Levine File Added: rsync-3.0.5-20090306-shl_diff.zip
2009-03-07 08:13 Steven Levine Note Added: 0001232
2009-05-04 10:39 psmedley Status assigned => resolved
2009-05-04 10:39 psmedley Resolution open => fixed
2020-08-24 03:14 psmedley Status resolved => closed