We make sure that the rsync_acl objects never have a forced
[rsync/rsync-patches.git] / links-depth.diff
CommitLineData
0143ad24
WD
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
9a7eef96
WD
9--- old/flist.c
10+++ new/flist.c
3731f97b
WD
11@@ -45,6 +45,7 @@ extern int one_file_system;
12 extern int copy_dirlinks;
0143ad24
WD
13 extern int keep_dirlinks;
14 extern int preserve_links;
15+extern int follow_links_depth;
16 extern int preserve_hard_links;
0143ad24 17 extern int preserve_devices;
3731f97b
WD
18 extern int preserve_specials;
19@@ -715,6 +716,30 @@ static struct file_struct *receive_file_
6849cd84 20 return file;
0143ad24
WD
21 }
22
0143ad24 23+#if SUPPORT_LINKS
1189721b 24+static int links_depth(char *linkname, STRUCT_STAT *st_ptr)
0143ad24
WD
25+{
26+ char buf[MAXPATHLEN];
27+ STRUCT_STAT st;
28+ int i;
29+
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)
33+ break;
34+ *st_ptr = st;
35+ if (!S_ISLNK(st.st_mode))
36+ return 1;
37+ strlcpy(linkname, buf, MAXPATHLEN);
38+#if 0
39+ fprintf(stderr, "\n%s:%i [#%i] %s -> %s\n", __FILE__, __LINE__, i, file->u.link, linkname);
40+#endif
41+ }
42+
43+ return 0;
44+}
45+#endif
46+
47 /**
48 * Create a file_struct for a named file by reading its stat()
49 * information and performing extensive checks against global
3731f97b 50@@ -849,7 +874,13 @@ struct file_struct *make_file(char *fnam
0143ad24
WD
51 basename_len = strlen(basename) + 1; /* count the '\0' */
52
09fb8f03 53 #ifdef SUPPORT_LINKS
0143ad24
WD
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))
57+ linkname_len = 0;
58+ else
59+ linkname_len = strlen(linkname) + 1;
60+ } else
61+ linkname_len = 0;
62 #else
63 linkname_len = 0;
64 #endif
9a7eef96
WD
65--- old/options.c
66+++ new/options.c
3731f97b
WD
67@@ -44,6 +44,7 @@ int keep_dirlinks = 0;
68 int copy_dirlinks = 0;
0143ad24
WD
69 int copy_links = 0;
70 int preserve_links = 0;
71+int follow_links_depth = 0;
72 int preserve_hard_links = 0;
73 int preserve_perms = 0;
9a7eef96 74 int preserve_executability = 0;
afcb578c 75@@ -287,6 +288,7 @@ void usage(enum logcode F)
489b0a72 76 rprintf(F," --append append data onto shorter files\n");
be73a66e 77 rprintf(F," -d, --dirs transfer directories without recursing\n");
0143ad24
WD
78 rprintf(F," -l, --links copy symlinks as symlinks\n");
79+ rprintf(F," --links-depth=NUM follow symlinks up to NUM depth\n");
79f132a1
WD
80 rprintf(F," -L, --copy-links transform symlink into referent file/dir\n");
81 rprintf(F," --copy-unsafe-links only \"unsafe\" symlinks are transformed\n");
82 rprintf(F," --safe-links ignore symlinks that point outside the source tree\n");
3731f97b 83@@ -432,6 +434,7 @@ static struct poptOption long_options[]
489b0a72
WD
84 {"links", 'l', POPT_ARG_VAL, &preserve_links, 1, 0, 0 },
85 {"no-links", 0, POPT_ARG_VAL, &preserve_links, 0, 0, 0 },
86 {"no-l", 0, POPT_ARG_VAL, &preserve_links, 0, 0, 0 },
0143ad24
WD
87+ {"links-depth", 0, POPT_ARG_INT, &follow_links_depth , 0, 0, 0 },
88 {"copy-links", 'L', POPT_ARG_NONE, &copy_links, 0, 0, 0 },
489b0a72
WD
89 {"copy-unsafe-links",0, POPT_ARG_NONE, &copy_unsafe_links, 0, 0, 0 },
90 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
9a7eef96
WD
91--- old/rsync.yo
92+++ new/rsync.yo
3731f97b 93@@ -313,6 +313,7 @@ to the detailed description below for a
489b0a72 94 --append append data onto shorter files
79f132a1
WD
95 -d, --dirs transfer directories without recursing
96 -l, --links copy symlinks as symlinks
97+ --links-depth=NUM follow symlinks up to NUM depth
98 -L, --copy-links transform symlink into referent file/dir
99 --copy-unsafe-links only "unsafe" symlinks are transformed
100 --safe-links ignore symlinks that point outside the tree