1The attached patch gives the user ability to define how many symbolic 2links rsync should follow before actually adding it to the file list. 3 4The patch has been heavily modified from its original form to work 5with the latest codebase, but even in its original form it didn't 6handle relative symlinks properly, and that has not yet been fixed 7in this modified version. 8 9To use this patch, run these commands for a successful build: 10 11 patch -p1 <patches/links-depth.diff 12 ./configure (optional if already run) 13 make 14 15--- old/flist.c 16+++ new/flist.c 17@@ -41,6 +41,7 @@ extern int one_file_system; 18 extern int copy_dirlinks; 19 extern int keep_dirlinks; 20 extern int preserve_links; 21+extern int follow_links_depth; 22 extern int preserve_hard_links; 23 extern int preserve_devices; 24 extern int preserve_specials; 25@@ -702,6 +703,30 @@ static struct file_struct *receive_file_ 26 return file; 27 } 28 29+#if SUPPORT_LINKS 30+static int links_depth(char *linkname, STRUCT_STAT *st_ptr) 31+{ 32+ char buf[MAXPATHLEN]; 33+ STRUCT_STAT st; 34+ int i; 35+ 36+ for (i = 0; i < follow_links_depth; i++) { 37+ /* XXX This doesn't handle relative symlinks! */ 38+ if (readlink_stat(linkname, &st, buf) != 0) 39+ break; 40+ *st_ptr = st; 41+ if (!S_ISLNK(st.st_mode)) 42+ return 1; 43+ strlcpy(linkname, buf, MAXPATHLEN); 44+#if 0 45+ fprintf(stderr, "\n%s:%i [#%i] %s -> %s\n", __FILE__, __LINE__, i, file->u.link, linkname); 46+#endif 47+ } 48+ 49+ return 0; 50+} 51+#endif 52+ 53 /** 54 * Create a file_struct for a named file by reading its stat() 55 * information and performing extensive checks against global 56@@ -837,7 +862,13 @@ struct file_struct *make_file(char *fnam 57 basename_len = strlen(basename) + 1; /* count the '\0' */ 58 59 #ifdef SUPPORT_LINKS 60- linkname_len = S_ISLNK(st.st_mode) ? strlen(linkname) + 1 : 0; 61+ if (S_ISLNK(st.st_mode)) { 62+ if (follow_links_depth && links_depth(linkname, &st)) 63+ linkname_len = 0; 64+ else 65+ linkname_len = strlen(linkname) + 1; 66+ } else 67+ linkname_len = 0; 68 #else 69 linkname_len = 0; 70 #endif 71--- old/options.c 72+++ new/options.c 73@@ -46,6 +46,7 @@ int keep_dirlinks = 0; 74 int copy_dirlinks = 0; 75 int copy_links = 0; 76 int preserve_links = 0; 77+int follow_links_depth = 0; 78 int preserve_hard_links = 0; 79 int preserve_perms = 0; 80 int preserve_executability = 0; 81@@ -297,6 +298,7 @@ void usage(enum logcode F) 82 rprintf(F," --append append data onto shorter files\n"); 83 rprintf(F," -d, --dirs transfer directories without recursing\n"); 84 rprintf(F," -l, --links copy symlinks as symlinks\n"); 85+ rprintf(F," --links-depth=NUM follow symlinks up to NUM depth\n"); 86 rprintf(F," -L, --copy-links transform symlink into referent file/dir\n"); 87 rprintf(F," --copy-unsafe-links only \"unsafe\" symlinks are transformed\n"); 88 rprintf(F," --safe-links ignore symlinks that point outside the source tree\n"); 89@@ -447,6 +449,7 @@ static struct poptOption long_options[] 90 {"links", 'l', POPT_ARG_VAL, &preserve_links, 1, 0, 0 }, 91 {"no-links", 0, POPT_ARG_VAL, &preserve_links, 0, 0, 0 }, 92 {"no-l", 0, POPT_ARG_VAL, &preserve_links, 0, 0, 0 }, 93+ {"links-depth", 0, POPT_ARG_INT, &follow_links_depth , 0, 0, 0 }, 94 {"copy-links", 'L', POPT_ARG_NONE, ©_links, 0, 0, 0 }, 95 {"copy-unsafe-links",0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 }, 96 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 }, 97--- old/rsync.yo 98+++ new/rsync.yo 99@@ -314,6 +314,7 @@ to the detailed description below for a 100 --append append data onto shorter files 101 -d, --dirs transfer directories without recursing 102 -l, --links copy symlinks as symlinks 103+ --links-depth=NUM follow symlinks up to NUM depth 104 -L, --copy-links transform symlink into referent file/dir 105 --copy-unsafe-links only "unsafe" symlinks are transformed 106 --safe-links ignore symlinks that point outside the tree 107--- old/rsync.1 108+++ new/rsync.1 109@@ -380,6 +380,7 @@ to the detailed description below for a 110 \-\-append append data onto shorter files 111 \-d, \-\-dirs transfer directories without recursing 112 \-l, \-\-links copy symlinks as symlinks 113+ \-\-links\-depth=NUM follow symlinks up to NUM depth 114 \-L, \-\-copy\-links transform symlink into referent file/dir 115 \-\-copy\-unsafe\-links only "unsafe" symlinks are transformed 116 \-\-safe\-links ignore symlinks that point outside the tree 117