1 The attached patch gives the user ability to define how many symbolic
2 links rsync should follow before actually adding it to the file list.
4 The patch has been heavily modified from its original form to work
5 with the latest codebase, but even in its original form it didn't
6 handle relative symlinks properly, and that has not yet been fixed
7 in this modified version.
9 To use this patch, run these commands for a successful build:
11 patch -p1 <patches/links-depth.diff
12 ./configure (optional if already run)
17 @@ -47,6 +47,7 @@ extern int keep_dirlinks;
18 extern int preserve_acls;
19 extern int preserve_xattrs;
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 @@ -980,6 +981,30 @@ static struct file_struct *recv_file_ent
30 +static int links_depth(char *linkname, STRUCT_STAT *st_ptr)
32 + char buf[MAXPATHLEN];
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)
41 + if (!S_ISLNK(st.st_mode))
43 + strlcpy(linkname, buf, MAXPATHLEN);
45 + fprintf(stderr, "\n%s:%i [#%i] %s -> %s\n", __FILE__, __LINE__, i, file->u.link, linkname);
53 /* Create a file_struct for a named file by reading its stat() information
54 * and performing extensive checks against global options.
56 @@ -1120,7 +1145,13 @@ struct file_struct *make_file(const char
57 basename_len = strlen(basename) + 1; /* count the '\0' */
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))
65 + linkname_len = strlen(linkname) + 1;
73 @@ -46,6 +46,7 @@ int keep_dirlinks = 0;
74 int copy_dirlinks = 0;
76 int preserve_links = 0;
77 +int follow_links_depth = 0;
78 int preserve_hard_links = 0;
79 int preserve_acls = 0;
80 int preserve_xattrs = 0;
81 @@ -321,6 +322,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 @@ -496,6 +498,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 },
99 @@ -335,6 +335,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