X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/f7632fc60d69c8dabed600ede87f0b91319a3b7f..17d31b380b7c748837b30e7e0c54ab17974f7ab6:/flist.c diff --git a/flist.c b/flist.c index 664f26e4..2ec04c88 100644 --- a/flist.c +++ b/flist.c @@ -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); @@ -58,6 +61,10 @@ static void list_file_entry(struct file_struct *f) char *perm_map = "rwxrwxrwx"; int i; + if (!f->basename) + /* this can happen if duplicate names were removed */ + return; + for (i=0;i<9;i++) { if (f->mode & (1<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 @@ -230,7 +263,7 @@ static void send_file_entry(struct file_struct *file,int f,unsigned base_flags) last_gid = file->gid; last_time = file->modtime; - strlcpy(lastname,fname,MAXPATHLEN-1); + strlcpy(lastname,fname,MAXPATHLEN); lastname[MAXPATHLEN-1] = 0; } @@ -265,11 +298,11 @@ static void receive_file_entry(struct file_struct **fptr, if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry"); - strlcpy(thisname,lastname,l1); + strlcpy(thisname,lastname,l1+1); read_sbuf(f,&thisname[l1],l2); thisname[l1+l2] = 0; - strlcpy(lastname,thisname,MAXPATHLEN-1); + strlcpy(lastname,thisname,MAXPATHLEN); lastname[MAXPATHLEN-1] = 0; clean_fname(thisname); @@ -369,15 +402,16 @@ 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-1); + strlcpy(cleaned_name, fname, MAXPATHLEN); cleaned_name[MAXPATHLEN-1] = 0; clean_fname(cleaned_name); fname = cleaned_name; 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)); @@ -433,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 @@ -531,7 +556,7 @@ static void send_directory(int f,struct file_list *flist,char *dir) return; } - strlcpy(fname,dir,MAXPATHLEN-1); + strlcpy(fname,dir,MAXPATHLEN); l = strlen(fname); if (fname[l-1] != '/') { if (l == MAXPATHLEN-1) { @@ -540,7 +565,7 @@ static void send_directory(int f,struct file_list *flist,char *dir) closedir(d); return; } - strlcat(fname,"/", MAXPATHLEN-1); + strlcat(fname,"/", MAXPATHLEN); l++; } p = fname + strlen(fname); @@ -562,7 +587,7 @@ static void send_directory(int f,struct file_list *flist,char *dir) if (strcmp(dname,".")==0 || strcmp(dname,"..")==0) continue; - strlcpy(p,dname,MAXPATHLEN-(l+1)); + strlcpy(p,dname,MAXPATHLEN-l); send_file_name(f,flist,fname,recurse,0); } @@ -605,14 +630,13 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) } for (i=0;idirname) { - strlcpy(p, f->dirname, MAXPATHLEN-1); - strlcat(p, "/", MAXPATHLEN-1); - strlcat(p, f->basename, MAXPATHLEN-1); + strlcpy(p, f->dirname, MAXPATHLEN); + strlcat(p, "/", MAXPATHLEN); + strlcat(p, f->basename, MAXPATHLEN); } else { - strlcpy(p, f->basename, MAXPATHLEN-1); + strlcpy(p, f->basename, MAXPATHLEN); } return p;