Updated o apply cleanly.
[rsync/rsync-patches.git] / links-depth.diff
... / ...
CommitLineData
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
9--- orig/flist.c 2005-02-20 00:16:35
10+++ flist.c 2004-07-16 16:58:04
11@@ -45,6 +45,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@@ -733,6 +734,30 @@ static struct file_struct *receive_file_
20 }
21
22
23+#if SUPPORT_LINKS
24+static int links_depth(char *linkname, STRUCT_STAT *st_ptr)
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
50@@ -858,7 +883,13 @@ skip_filters:
51 basename_len = strlen(basename) + 1; /* count the '\0' */
52
53 #ifdef SUPPORT_LINKS
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
65--- orig/options.c 2005-02-20 01:12:42
66+++ options.c 2005-01-28 19:33:24
67@@ -43,6 +43,7 @@ int archive_mode = 0;
68 int keep_dirlinks = 0;
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;
74 int preserve_devices = 0;
75@@ -269,6 +270,7 @@ void usage(enum logcode F)
76 rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
77 rprintf(F," -d, --dirs transfer directories without recursing\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 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");
83@@ -392,6 +394,7 @@ static struct poptOption long_options[]
84 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
85 {"dirs", 'd', POPT_ARG_VAL, &xfer_dirs, 2, 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, &copy_links, 0, 0, 0 },
89 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
90 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
91--- orig/rsync.yo 2005-02-20 01:12:43
92+++ rsync.yo 2005-01-28 19:33:40
93@@ -311,6 +311,7 @@ to the detailed description below for a
94 --inplace update destination files in-place
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