X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/72914a606ec66f61678c6d077e515f08908e76a3..2bca43f6278dcc0aa19a2620c1f1e2387b2e7b07:/flist.c diff --git a/flist.c b/flist.c index c33323ed..8813da7f 100644 --- a/flist.c +++ b/flist.c @@ -49,6 +49,8 @@ extern int io_error; static struct exclude_struct **local_exclude_list; +static void clean_flist(struct file_list *flist, int strip_root); + int link_stat(const char *Path, STRUCT_STAT *Buffer) { #if SUPPORT_LINKS @@ -92,7 +94,7 @@ static void send_directory(int f,struct file_list *flist,char *dir); static char *flist_dir; -void send_file_entry(struct file_struct *file,int f,unsigned base_flags) +static void send_file_entry(struct file_struct *file,int f,unsigned base_flags) { unsigned char flags; static time_t last_time; @@ -225,12 +227,6 @@ static void receive_file_entry(struct file_struct **fptr, clean_fname(thisname); - if (relative_paths && thisname[0] == '/') { - /* strip / off absolute paths in destination */ - memmove(thisname, thisname+1, strlen(thisname)); - if (!thisname[0]) strcpy(thisname,"."); - } - if ((p = strrchr(thisname,'/'))) { static char *lastdir; *p = 0; @@ -436,7 +432,7 @@ static struct file_struct *make_file(char *fname) -static void send_file_name(int f,struct file_list *flist,char *fname, +void send_file_name(int f,struct file_list *flist,char *fname, int recursive, unsigned base_flags) { struct file_struct *file; @@ -502,6 +498,8 @@ static void send_directory(int f,struct file_list *flist,char *dir) } p = fname + strlen(fname); + local_exclude_list = NULL; + if (cvs_exclude) { if (strlen(fname) + strlen(".cvsignore") <= MAXPATHLEN-1) { strcpy(p,".cvsignore"); @@ -521,6 +519,10 @@ static void send_directory(int f,struct file_list *flist,char *dir) send_file_name(f,flist,fname,recurse,0); } + if (local_exclude_list) { + add_exclude_list("!", &local_exclude_list, 0); + } + closedir(d); } @@ -530,7 +532,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) { int i,l; STRUCT_STAT st; - char *p,*dir; + char *p,*dir,*olddir; char lastpath[MAXPATHLEN]=""; struct file_list *flist; int64 start_write; @@ -578,6 +580,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) } dir = NULL; + olddir = NULL; if (!relative_paths) { p = strrchr(fname,'/'); @@ -613,7 +616,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) fname = "."; if (dir && *dir) { - char *olddir = push_dir(dir, 1); + olddir = push_dir(dir, 1); if (!olddir) { io_error=1; @@ -623,21 +626,22 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) } flist_dir = dir; - if (one_file_system) - set_filesystem(fname); + } + + if (one_file_system) + set_filesystem(fname); + + if (!recurse || !send_included_file_names(f,flist)) send_file_name(f,flist,fname,recurse,FLAG_DELETE); + + if (olddir != NULL) { flist_dir = NULL; if (pop_dir(olddir) != 0) { rprintf(FERROR,"pop_dir %s : %s\n", dir,strerror(errno)); exit_cleanup(1); } - continue; } - - if (one_file_system) - set_filesystem(fname); - send_file_name(f,flist,fname,recurse,FLAG_DELETE); } if (f != -1) { @@ -647,7 +651,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) if (verbose && recurse && !am_server && f != -1) rprintf(FINFO,"done\n"); - clean_flist(flist); + clean_flist(flist, 0); /* now send the uid/gid list. This was introduced in protocol version 15 */ @@ -728,7 +732,7 @@ struct file_list *recv_file_list(int f) if (verbose > 2) rprintf(FINFO,"received %d names\n",flist->count); - clean_flist(flist); + clean_flist(flist, relative_paths); if (verbose && recurse && !am_server) { rprintf(FINFO,"done\n"); @@ -826,7 +830,7 @@ void flist_free(struct file_list *flist) * This routine ensures we don't have any duplicate names in our file list. * duplicate names can cause corruption because of the pipelining */ -void clean_flist(struct file_list *flist) +static void clean_flist(struct file_list *flist, int strip_root) { int i; @@ -848,6 +852,37 @@ void clean_flist(struct file_list *flist) free_file(flist->files[i]); } } + + if (strip_root) { + /* we need to strip off the root directory in the case + of relative paths, but this must be done _after_ + the sorting phase */ + for (i=0;icount;i++) { + if (flist->files[i]->dirname && + flist->files[i]->dirname[0] == '/') { + memmove(&flist->files[i]->dirname[0], + &flist->files[i]->dirname[1], + strlen(flist->files[i]->dirname)); + } + + if (flist->files[i]->dirname && + !flist->files[i]->dirname[0]) { + flist->files[i]->dirname = NULL; + } + } + } + + + if (verbose <= 3) return; + + for (i=0;icount;i++) { + rprintf(FINFO,"[%d] i=%d %s %s mode=0%o len=%d\n", + getpid(), i, + flist->files[i]->dirname, + flist->files[i]->basename, + flist->files[i]->mode, + flist->files[i]->length); + } }