-u, --update update only (don't overwrite newer files)
-l, --links preserve soft links
-L, --copy-links treat soft links like regular files
+ --copy-unsafe-links copy links outside the source tree
--safe-links ignore links outside the destination tree
-H, --hard-links preserve hard links
-p, --perms preserve permissions
extern int preserve_times;
extern int relative_paths;
extern int copy_links;
+extern int copy_unsafe_links;
extern int remote_version;
extern int io_error;
+static char topsrcname[MAXPATHLEN];
+
static struct exclude_struct **local_exclude_list;
static void clean_flist(struct file_list *flist, int strip_root);
}
+int readlink_stat(const char *Path, STRUCT_STAT *Buffer, char *Linkbuf)
+{
+#if SUPPORT_LINKS
+ if (copy_links) {
+ return do_stat(Path, Buffer);
+ }
+ if (do_lstat(Path, Buffer) == -1) {
+ return -1;
+ }
+ if (S_ISLNK(Buffer->st_mode)) {
+ int l;
+ if ((l = readlink(Path,Linkbuf,MAXPATHLEN-1)) == -1) {
+ return -1;
+ }
+ Linkbuf[l] = 0;
+ if (copy_unsafe_links && (topsrcname[0] != '\0') &&
+ unsafe_symlink(Linkbuf, topsrcname)) {
+ return do_stat(Path, Buffer);
+ }
+ }
+ return 0;
+#else
+ return do_stat(Path, Buffer);
+#endif
+}
+
int link_stat(const char *Path, STRUCT_STAT *Buffer)
{
#if SUPPORT_LINKS
char sum[SUM_LENGTH];
char *p;
char cleaned_name[MAXPATHLEN];
+ char linkbuf[MAXPATHLEN];
strlcpy(cleaned_name, fname, MAXPATHLEN);
cleaned_name[MAXPATHLEN-1] = 0;
memset(sum,0,SUM_LENGTH);
- if (link_stat(fname,&st) != 0) {
+ if (readlink_stat(fname,&st,linkbuf) != 0) {
io_error = 1;
rprintf(FERROR,"%s: %s\n",
fname,strerror(errno));
#if SUPPORT_LINKS
if (S_ISLNK(st.st_mode)) {
- int l;
- char lnk[MAXPATHLEN];
- if ((l=readlink(fname,lnk,MAXPATHLEN-1)) == -1) {
- io_error=1;
- rprintf(FERROR,"readlink %s : %s\n",
- fname,strerror(errno));
- return NULL;
- }
- lnk[l] = 0;
- file->link = strdup(lnk);
+ file->link = strdup(linkbuf);
}
#endif
}
for (i=0;i<argc;i++) {
- char fname2[MAXPATHLEN];
- char *fname = fname2;
+ char *fname = topsrcname;
strlcpy(fname,argv[i],MAXPATHLEN);
for (p=fname+1; (p=strchr(p,'/')); p++) {
int copy_links_saved = copy_links;
*p = 0;
- copy_links = 0;
+ copy_links = copy_unsafe_links;
send_file_name(f, flist, fname, 0, 0);
copy_links = copy_links_saved;
*p = '/';
}
}
+ topsrcname[0] = '\0';
+
if (f != -1) {
send_file_entry(NULL,f,0);
}
int do_progress=0;
int keep_partial=0;
int safe_symlinks=0;
+int copy_unsafe_links=0;
int block_size=BLOCK_SIZE;
char *backup_suffix = BACKUP_SUFFIX;
rprintf(F," -u, --update update only (don't overwrite newer files)\n");
rprintf(F," -l, --links preserve soft links\n");
rprintf(F," -L, --copy-links treat soft links like regular files\n");
+ rprintf(F," --copy-unsafe-links copy links outside the source tree\n");
rprintf(F," --safe-links ignore links outside the destination tree\n");
rprintf(F," -H, --hard-links preserve hard links\n");
rprintf(F," -p, --perms preserve permissions\n");
OPT_EXCLUDE_FROM,OPT_DELETE,OPT_NUMERIC_IDS,OPT_RSYNC_PATH,
OPT_FORCE,OPT_TIMEOUT,OPT_DAEMON,OPT_CONFIG,OPT_PORT,
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS,
- OPT_SAFE_LINKS, OPT_COMPARE_DEST, OPT_LOG_FORMAT,OPT_PASSWORD_FILE};
+ OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST,
+ OPT_LOG_FORMAT, OPT_PASSWORD_FILE};
static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:z";
{"perms", 0, 0, 'p'},
{"links", 0, 0, 'l'},
{"copy-links", 0, 0, 'L'},
+ {"copy-unsafe-links", 0, 0, OPT_COPY_UNSAFE_LINKS},
{"safe-links", 0, 0, OPT_SAFE_LINKS},
{"whole-file", 0, 0, 'W'},
{"hard-links", 0, 0, 'H'},
add_exclude_file(optarg,1, 1);
break;
+ case OPT_COPY_UNSAFE_LINKS:
+ copy_unsafe_links=1;
+ break;
+
case OPT_SAFE_LINKS:
safe_symlinks=1;
break;
if (force_delete)
args[ac++] = "--force";
+ if (copy_unsafe_links)
+ args[ac++] = "--copy-unsafe-links";
+
if (safe_symlinks)
args[ac++] = "--safe-links";
mailto(rsync-bugs@samba.org)
-manpage(rsync)(1)(15 Feb 1999)()()
+manpage(rsync)(1)(17 Feb 1999)()()
manpagename(rsync)(faster, flexible replacement for rcp)
manpagesynopsis()
-u, --update update only (don't overwrite newer files)
-l, --links preserve soft links
-L, --copy-links treat soft links like regular files
+ --copy-unsafe-links copy links outside the source tree
--safe-links ignore links outside the destination tree
-H, --hard-links preserve hard links
-p, --perms preserve permissions
option, all symbolic links are skipped.
dit(bf(-L, --copy-links)) This tells rsync to treat symbolic links just
-like ordinary files.
+like ordinary files.
+
+dit(bf(--copy-unsafe-links)) This tells rsync to treat symbolic links that
+point outside the source tree like ordinary files. Absolute symlinks are
+also treated like ordinary files, and so are any symlinks in the source
+path itself when --relative is used.
dit(bf(--safe-links)) This tells rsync to ignore any symbolic links
which point outside the destination tree. All absolute symlinks are