The attached patch gives the user ability to define how many symbolic links rsync should follow before actually adding it to the file list. The patch has been heavily modified from its original form to work with the latest codebase, but even in its original form it didn't handle relative symlinks properly, and that has not yet been fixed in this modified version. To use this patch, run these commands for a successful build: patch -p1 %s\n", __FILE__, __LINE__, i, file->u.link, linkname); +#endif + } + + return 0; +} +#endif + /* Create a file_struct for a named file by reading its stat() information * and performing extensive checks against global options. * @@ -1120,7 +1145,13 @@ struct file_struct *make_file(const char basename_len = strlen(basename) + 1; /* count the '\0' */ #ifdef SUPPORT_LINKS - linkname_len = S_ISLNK(st.st_mode) ? strlen(linkname) + 1 : 0; + if (S_ISLNK(st.st_mode)) { + if (follow_links_depth && links_depth(linkname, &st)) + linkname_len = 0; + else + linkname_len = strlen(linkname) + 1; + } else + linkname_len = 0; #else linkname_len = 0; #endif --- old/options.c +++ new/options.c @@ -46,6 +46,7 @@ int keep_dirlinks = 0; int copy_dirlinks = 0; int copy_links = 0; int preserve_links = 0; +int follow_links_depth = 0; int preserve_hard_links = 0; int preserve_acls = 0; int preserve_xattrs = 0; @@ -321,6 +322,7 @@ void usage(enum logcode F) rprintf(F," --append append data onto shorter files\n"); rprintf(F," -d, --dirs transfer directories without recursing\n"); rprintf(F," -l, --links copy symlinks as symlinks\n"); + rprintf(F," --links-depth=NUM follow symlinks up to NUM depth\n"); rprintf(F," -L, --copy-links transform symlink into referent file/dir\n"); rprintf(F," --copy-unsafe-links only \"unsafe\" symlinks are transformed\n"); rprintf(F," --safe-links ignore symlinks that point outside the source tree\n"); @@ -496,6 +498,7 @@ static struct poptOption long_options[] {"links", 'l', POPT_ARG_VAL, &preserve_links, 1, 0, 0 }, {"no-links", 0, POPT_ARG_VAL, &preserve_links, 0, 0, 0 }, {"no-l", 0, POPT_ARG_VAL, &preserve_links, 0, 0, 0 }, + {"links-depth", 0, POPT_ARG_INT, &follow_links_depth , 0, 0, 0 }, {"copy-links", 'L', POPT_ARG_NONE, ©_links, 0, 0, 0 }, {"copy-unsafe-links",0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 }, {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 }, --- old/rsync.yo +++ new/rsync.yo @@ -335,6 +335,7 @@ to the detailed description below for a --append append data onto shorter files -d, --dirs transfer directories without recursing -l, --links copy symlinks as symlinks + --links-depth=NUM follow symlinks up to NUM depth -L, --copy-links transform symlink into referent file/dir --copy-unsafe-links only "unsafe" symlinks are transformed --safe-links ignore symlinks that point outside the tree