diff options
author | David Dykstra <dwd@samba.org> | 1999-02-17 19:34:40 +0000 |
---|---|---|
committer | David Dykstra <dwd@samba.org> | 1999-02-17 19:34:40 +0000 |
commit | b53136076392ff881a03baff19232aadc4617f92 (patch) | |
tree | f4a49d1f2f59be4b633503c1262a0f52658ca882 /flist.c | |
parent | b567933566b3b2d5e863685f43f7330b4369b5e9 (diff) | |
download | rsync-b53136076392ff881a03baff19232aadc4617f92.tar.gz rsync-b53136076392ff881a03baff19232aadc4617f92.tar.bz2 rsync-b53136076392ff881a03baff19232aadc4617f92.zip |
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".
Diffstat (limited to 'flist.c')
-rw-r--r-- | flist.c | 50 |
1 files changed, 36 insertions, 14 deletions
@@ -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); } |