David Rothenberger
2008-Nov-15 21:15 UTC
[PATCH] Don't strip two leading slashes from paths.
rsync 3.0.4 will transform a path like '//machine/share/dir' to '/machine/share/dir' when the --protect flag is provided. This causes a problem with Cygwin, where the two leading slashes are meaningful (access of a remote Windows share). [[[ % rsync -s localhost://tela/downloads rsync: link_stat "/tela/downloads" failed: No such file or directory (2) rsync error: some files/attrs were not transferred (see previous errors) (code 23) at /home/lapo/packaging/rsync-3.0.4-1/src/rsync-3.0.4/main.c(1506) [receiver=3.0.4] ]]] http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap04.html#tag_04_11 mentions that "[a] pathname that begins with two successive slashes may be interpreted in an implementation-defined manner, although more than two leading slashes shall be treated as a single slash." The attached patch prevents two leading slashes from being converted to one and works fine for me with Cygwin: [[[ % rsync -s localhost://tela/downloads drwxr-xr-x 0 2008/01/14 09:46:23 downloads ]]] Unfortunately, it doesn't fully conform to the POSIX specification because it also translates '///' to '//' instead of '/' as required. Does this patch (or a modified version that conforms to POSIX) stand a chance of being accepted? Should I create a bugzilla issue and attach it there? Should I work on modifying the patch to conform to POSIX? -- David Rothenberger ---- daveroth@acm.org -------------- next part -------------- Index: util.c ==================================================================--- util.c.orig +++ util.c @@ -821,8 +821,12 @@ unsigned int clean_fname(char *name, int if (!name) return 0; - if ((anchored = *f == '/') != 0) + if ((anchored = *f == '/') != 0) { *t++ = *f++; + /* keep "//" */ + if (*f == '/') + *t++ = *f++; + } else if (flags & CFN_KEEP_DOT_DIRS && *f == '.' && f[1] == '/') { *t++ = *f++; *t++ = *f++;
On Sat, Nov 15, 2008 at 01:09:20PM -0800, David Rothenberger wrote:> Unfortunately, it doesn't fully conform to the POSIX specification because > it also translates '///' to '//' instead of '/' as required.An easy fix for that is to change your newly added "if" to this: if (*f == '/' && f[1] != '/') The one thing I wonder about with this is if "//" (with nothing else) should be interpreted as "//" or "/"? If it should collapse to "/", we could use this: if (*f == '/' && f[1] != '/' && f[1] != '\0') Is there a need to use "//" for something special? I'm thinking I'll go ahead an preserve it, just in case. Thanks for your patch! ..wayne..
On Sat, Nov 15, 2008 at 01:09:20PM -0800, David Rothenberger wrote:> Does this patch (or a modified version that conforms to POSIX) stand a > chance of being accepted?There's a problem with including this in the mainstream version: if we don't turn //some/path into /some/path, it won't match a daemon-config exclusion of "/some/path". So, this would need to be conditionally compiled into the code so that it only affects systems that treat a leading "//" as a different path from a leading "/". ..wayne..