Fixes from Matt.
[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
03019e41
WD
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
9a7eef96
WD
15--- old/flist.c
16+++ new/flist.c
206a087d 17@@ -47,6 +47,7 @@ extern int keep_dirlinks;
5ff5e82f
WD
18 extern int preserve_acls;
19 extern int preserve_xattrs;
0143ad24
WD
20 extern int preserve_links;
21+extern int follow_links_depth;
22 extern int preserve_hard_links;
0143ad24 23 extern int preserve_devices;
3731f97b 24 extern int preserve_specials;
206a087d 25@@ -980,6 +981,30 @@ static struct file_struct *recv_file_ent
6849cd84 26 return file;
0143ad24
WD
27 }
28
0143ad24 29+#if SUPPORT_LINKS
1189721b 30+static int links_depth(char *linkname, STRUCT_STAT *st_ptr)
0143ad24
WD
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+
206a087d
WD
53 /* Create a file_struct for a named file by reading its stat() information
54 * and performing extensive checks against global options.
55 *
56@@ -1120,7 +1145,13 @@ struct file_struct *make_file(const char
0143ad24
WD
57 basename_len = strlen(basename) + 1; /* count the '\0' */
58
09fb8f03 59 #ifdef SUPPORT_LINKS
0143ad24
WD
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
9a7eef96
WD
71--- old/options.c
72+++ new/options.c
206a087d 73@@ -46,6 +46,7 @@ int keep_dirlinks = 0;
3731f97b 74 int copy_dirlinks = 0;
0143ad24
WD
75 int copy_links = 0;
76 int preserve_links = 0;
77+int follow_links_depth = 0;
78 int preserve_hard_links = 0;
5ff5e82f
WD
79 int preserve_acls = 0;
80 int preserve_xattrs = 0;
206a087d 81@@ -321,6 +322,7 @@ void usage(enum logcode F)
489b0a72 82 rprintf(F," --append append data onto shorter files\n");
be73a66e 83 rprintf(F," -d, --dirs transfer directories without recursing\n");
0143ad24
WD
84 rprintf(F," -l, --links copy symlinks as symlinks\n");
85+ rprintf(F," --links-depth=NUM follow symlinks up to NUM depth\n");
79f132a1
WD
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");
206a087d 89@@ -496,6 +498,7 @@ static struct poptOption long_options[]
489b0a72
WD
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 },
0143ad24
WD
93+ {"links-depth", 0, POPT_ARG_INT, &follow_links_depth , 0, 0, 0 },
94 {"copy-links", 'L', POPT_ARG_NONE, &copy_links, 0, 0, 0 },
489b0a72
WD
95 {"copy-unsafe-links",0, POPT_ARG_NONE, &copy_unsafe_links, 0, 0, 0 },
96 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
9a7eef96
WD
97--- old/rsync.yo
98+++ new/rsync.yo
206a087d 99@@ -335,6 +335,7 @@ to the detailed description below for a
489b0a72 100 --append append data onto shorter files
79f132a1
WD
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