Don't let set_perms() re-stat an existing directory or it will not set
[rsync/rsync-patches.git] / keep-dirlinks.diff
CommitLineData
92bf9171 1--- generator.c 18 May 2004 08:50:17 -0000 1.85
e748400b 2+++ generator.c 5 Jun 2004 15:56:04 -0000
92bf9171
WD
3@@ -26,6 +26,7 @@
4 extern int verbose;
5 extern int dry_run;
6 extern int relative_paths;
7+extern int keep_dirlinks;
8 extern int preserve_links;
9 extern int am_root;
10 extern int preserve_devices;
5e549c8f
WD
11@@ -302,6 +303,15 @@ void recv_generator(char *fname, struct
12 return;
13 }
92bf9171 14
5e549c8f
WD
15+#if SUPPORT_LINKS
16+ if (statret == 0 && keep_dirlinks
17+ && S_ISLNK(st.st_mode) && S_ISDIR(file->mode)) {
18+ STRUCT_STAT st2;
19+ if (do_stat(fname, &st2) == 0 && S_ISDIR(st2.st_mode))
20+ st = st2;
21+ }
22+#endif
23+
24 if (statret == 0 &&
25 !preserve_perms &&
26 (S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) {
e748400b
WD
27@@ -329,18 +339,23 @@ void recv_generator(char *fname, struct
28 }
29 statret = -1;
30 }
31- if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
32- if (!(relative_paths && errno == ENOENT
33- && create_directory_path(fname, orig_umask) == 0
34- && do_mkdir(fname, file->mode) == 0)) {
35- rsyserr(FERROR, errno,
36- "recv_generator: mkdir %s failed",
37- full_fname(fname));
38+ if (statret != 0) {
39+ if (do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
40+ if (!(relative_paths && errno == ENOENT
41+ && create_directory_path(fname, orig_umask) == 0
42+ && do_mkdir(fname, file->mode) == 0)) {
43+ rsyserr(FERROR, errno,
44+ "recv_generator: mkdir %s failed",
45+ full_fname(fname));
46+ }
47 }
48+ statret = link_stat(fname, &st);
49+ if (statret != 0)
50+ return;
51 }
52- /* f_out is set to -1 when doing final directory
53- permission and modification time repair */
54- if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
55+ /* f_out is set to -1 when doing final directory-permission
56+ * and modification-time repair. */
57+ if (set_perms(fname, file, &st, 0) && verbose && (f_out != -1))
58 rprintf(FINFO,"%s/\n",fname);
59 return;
60 }
92bf9171 61--- options.c 27 May 2004 21:51:53 -0000 1.153
e748400b 62+++ options.c 5 Jun 2004 15:56:04 -0000
92bf9171
WD
63@@ -38,6 +38,7 @@ int make_backups = 0;
64 int whole_file = -1;
65
66 int archive_mode = 0;
67+int keep_dirlinks = 0;
68 int copy_links = 0;
69 int preserve_links = 0;
70 int preserve_hard_links = 0;
5e549c8f
WD
71@@ -232,6 +233,7 @@ void usage(enum logcode F)
72 rprintf(F," --backup-dir make backups into this directory\n");
92bf9171
WD
73 rprintf(F," --suffix=SUFFIX backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
74 rprintf(F," -u, --update update only (don't overwrite newer files)\n");
92bf9171 75+ rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
5e549c8f 76 rprintf(F," -l, --links copy symlinks as symlinks\n");
92bf9171
WD
77 rprintf(F," -L, --copy-links copy the referent of all symlinks\n");
78 rprintf(F," --copy-unsafe-links copy the referent of \"unsafe\" symlinks\n");
92bf9171
WD
79@@ -338,6 +340,7 @@ static struct poptOption long_options[]
80 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
81 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
82 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
83+ {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
84 {"links", 'l', POPT_ARG_NONE, &preserve_links, 0, 0, 0 },
85 {"copy-links", 'L', POPT_ARG_NONE, &copy_links, 0, 0, 0 },
86 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
87@@ -818,6 +821,8 @@ void server_options(char **args,int *arg
88 argstr[x++] = 'l';
89 if (copy_links)
90 argstr[x++] = 'L';
91+ if (keep_dirlinks && am_sender)
92+ argstr[x++] = 'K';
93
94 if (whole_file > 0)
95 argstr[x++] = 'W';
96--- rsync.yo 21 May 2004 09:44:32 -0000 1.170
e748400b 97+++ rsync.yo 5 Jun 2004 15:56:05 -0000
92bf9171
WD
98@@ -289,6 +289,7 @@ verb(
99 --backup-dir make backups into this directory
100 --suffix=SUFFIX backup suffix (default ~ w/o --backup-dir)
101 -u, --update update only (don't overwrite newer files)
102+ -K, --keep-dirlinks treat symlinked dir on receiver as dir
103 -l, --links copy symlinks as symlinks
104 -L, --copy-links copy the referent of all symlinks
105 --copy-unsafe-links copy the referent of "unsafe" symlinks
106@@ -479,6 +480,10 @@ symlink where the destination has a file
107 regardless of the timestamps. This might change in the future (feel
108 free to comment on this on the mailing list if you have an opinion).
109
110+dit(bf(-K, --keep-dirlinks)) On the receiving side, if a symlink is
111+pointing to a directory, it will be treated as matching a directory
112+from the sender.
113+
114 dit(bf(-l, --links)) When symlinks are encountered, recreate the
115 symlink on the destination.
116