Commit b5313607 authored by David Dykstra's avatar David Dykstra

Added --copy-unsafe-links option which is like --copy-links except it is

only for symlinks that point outside the source tree.  Suggested by Charles
Hines <chuck_hines@VNET.IBM.COM> in PR#1376.  Also apply the option to any
symbolic links in the source portion of a path when --relative is used,
as suggested by Francis Montagnac <Francis.Montagnac@sophia.inria.fr> on
the rsync mailing list in a message titled "New option: --copy-parent-links".
parent b5679335
......@@ -44,6 +44,7 @@ Options
-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
......
......@@ -44,9 +44,12 @@ extern int preserve_gid;
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);
......@@ -85,6 +88,32 @@ static void list_file_entry(struct file_struct *f)
}
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
......@@ -373,6 +402,7 @@ static struct file_struct *make_file(char *fname)
char sum[SUM_LENGTH];
char *p;
char cleaned_name[MAXPATHLEN];
char linkbuf[MAXPATHLEN];
strlcpy(cleaned_name, fname, MAXPATHLEN);
cleaned_name[MAXPATHLEN-1] = 0;
......@@ -381,7 +411,7 @@ static struct file_struct *make_file(char *fname)
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));
......@@ -437,16 +467,7 @@ static struct file_struct *make_file(char *fname)
#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
......@@ -609,8 +630,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
}
for (i=0;i<argc;i++) {
char fname2[MAXPATHLEN];
char *fname = fname2;
char *fname = topsrcname;
strlcpy(fname,argv[i],MAXPATHLEN);
......@@ -653,7 +673,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
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 = '/';
......@@ -695,6 +715,8 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
}
}
topsrcname[0] = '\0';
if (f != -1) {
send_file_entry(NULL,f,0);
}
......
......@@ -59,6 +59,7 @@ int do_stats=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;
......@@ -104,6 +105,7 @@ void usage(int F)
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");
......@@ -152,7 +154,8 @@ enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
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";
......@@ -187,6 +190,7 @@ static struct option long_options[] = {
{"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'},
......@@ -321,6 +325,10 @@ int parse_arguments(int argc, char *argv[], int frommain)
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;
......@@ -584,6 +592,9 @@ void server_options(char **args,int *argc)
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()
......@@ -233,6 +233,7 @@ Options
-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
......@@ -349,7 +350,12 @@ remote system to be the same as the local system. Without this
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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment