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 --- orig/flist.c 2004-09-21 09:40:27
10 +++ flist.c 2004-07-16 16:58:04
11 @@ -50,6 +50,7 @@ extern int filesfrom_fd;
12 extern int one_file_system;
13 extern int keep_dirlinks;
14 extern int preserve_links;
15 +extern int follow_links_depth;
16 extern int preserve_hard_links;
17 extern int preserve_perms;
18 extern int preserve_devices;
19 @@ -726,6 +727,30 @@ void receive_file_entry(struct file_stru
24 +static int links_depth(char *linkname, STRUCT_STAT *st_ptr)
26 + char buf[MAXPATHLEN];
30 + for (i = 0; i < follow_links_depth; i++) {
31 + /* XXX This doesn't handle relative symlinks! */
32 + if (readlink_stat(linkname, &st, buf) != 0)
35 + if (!S_ISLNK(st.st_mode))
37 + strlcpy(linkname, buf, MAXPATHLEN);
39 + fprintf(stderr, "\n%s:%i [#%i] %s -> %s\n", __FILE__, __LINE__, i, file->u.link, linkname);
48 * Create a file_struct for a named file by reading its stat()
49 * information and performing extensive checks against global
50 @@ -845,7 +870,13 @@ skip_excludes:
51 basename_len = strlen(basename) + 1; /* count the '\0' */
54 - linkname_len = S_ISLNK(st.st_mode) ? strlen(linkname) + 1 : 0;
55 + if (S_ISLNK(st.st_mode)) {
56 + if (follow_links_depth && links_depth(linkname, &st))
59 + linkname_len = strlen(linkname) + 1;
65 --- orig/options.c 2004-09-23 17:42:07
66 +++ options.c 2004-07-16 16:12:29
67 @@ -42,6 +42,7 @@ int archive_mode = 0;
68 int keep_dirlinks = 0;
70 int preserve_links = 0;
71 +int follow_links_depth = 0;
72 int preserve_hard_links = 0;
73 int preserve_perms = 0;
74 int preserve_devices = 0;
75 @@ -244,6 +245,7 @@ void usage(enum logcode F)
76 rprintf(F," --inplace update destination files inplace (SEE MAN PAGE)\n");
77 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
78 rprintf(F," -l, --links copy symlinks as symlinks\n");
79 + rprintf(F," --links-depth=NUM follow symlinks up to NUM depth\n");
80 rprintf(F," -L, --copy-links copy the referent of all symlinks\n");
81 rprintf(F," --copy-unsafe-links copy the referent of \"unsafe\" symlinks\n");
82 rprintf(F," --safe-links ignore \"unsafe\" symlinks\n");
83 @@ -353,6 +355,7 @@ static struct poptOption long_options[]
84 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
85 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
86 {"links", 'l', POPT_ARG_NONE, &preserve_links, 0, 0, 0 },
87 + {"links-depth", 0, POPT_ARG_INT, &follow_links_depth , 0, 0, 0 },
88 {"copy-links", 'L', POPT_ARG_NONE, ©_links, 0, 0, 0 },
89 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
90 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },