X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/1a016bfdec2823c6d4e78a3dcc253cdfc30a10af..4b957c22381cf1848ff6a5e59249bb71ba79e9fa:/flist.c diff --git a/flist.c b/flist.c index cf401519..78b2c859 100644 --- a/flist.c +++ b/flist.c @@ -21,12 +21,13 @@ #include "rsync.h" +extern struct stats stats; + extern int csum_length; extern int verbose; extern int am_server; extern int always_checksum; -extern int64 total_size; extern int cvs_exclude; @@ -46,7 +47,7 @@ extern int copy_links; extern int remote_version; extern int io_error; -static char **local_exclude_list; +static struct exclude_struct **local_exclude_list; int link_stat(const char *Path, STRUCT_STAT *Buffer) { @@ -67,7 +68,7 @@ int link_stat(const char *Path, STRUCT_STAT *Buffer) */ static int match_file_name(char *fname,STRUCT_STAT *st) { - if (check_exclude(fname,local_exclude_list)) { + if (check_exclude(fname,local_exclude_list,st)) { if (verbose > 2) rprintf(FINFO,"excluding file %s\n",fname); return 0; @@ -90,49 +91,6 @@ static void send_directory(int f,struct file_list *flist,char *dir); static char *flist_dir; -static void clean_fname(char *name) -{ - char *p; - int l; - int modified = 1; - - if (!name) return; - - while (modified) { - modified = 0; - - if ((p=strstr(name,"/./"))) { - modified = 1; - while (*p) { - p[0] = p[2]; - p++; - } - } - - if ((p=strstr(name,"//"))) { - modified = 1; - while (*p) { - p[0] = p[1]; - p++; - } - } - - if (strncmp(p=name,"./",2) == 0) { - modified = 1; - do { - p[0] = p[2]; - } while (*p++); - } - - l = strlen(p=name); - if (l > 1 && p[l-1] == '/') { - modified = 1; - p[l-1] = 0; - } - } -} - - void send_file_entry(struct file_struct *file,int f,unsigned base_flags) { @@ -163,12 +121,17 @@ void send_file_entry(struct file_struct *file,int f,unsigned base_flags) if (file->gid == last_gid) flags |= SAME_GID; if (file->modtime == last_time) flags |= SAME_TIME; - for (l1=0;lastname[l1] && fname[l1] == lastname[l1];l1++) ; + for (l1=0;lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255);l1++) ; l2 = strlen(fname) - l1; if (l1 > 0) flags |= SAME_NAME; if (l2 > 255) flags |= LONG_NAME; + /* we must make sure we don't send a zero flags byte or the other + end will terminate the flist transfer */ + if (flags == 0 && !S_ISDIR(file->mode)) flags |= FLAG_DELETE; + if (flags == 0) flags |= LONG_NAME; + write_byte(f,flags); if (flags & SAME_NAME) write_byte(f,l1); @@ -248,7 +211,7 @@ static void receive_file_entry(struct file_struct **fptr, file = (struct file_struct *)malloc(sizeof(*file)); if (!file) out_of_memory("receive_file_entry"); - bzero((char *)file,sizeof(*file)); + memset((char *)file, 0, sizeof(*file)); (*fptr) = file; if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry"); @@ -262,6 +225,12 @@ 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; @@ -356,7 +325,7 @@ static struct file_struct *make_file(char *fname) clean_fname(cleaned_name); fname = cleaned_name; - bzero(sum,SUM_LENGTH); + memset(sum,0,SUM_LENGTH); if (link_stat(fname,&st) != 0) { io_error = 1; @@ -383,7 +352,7 @@ static struct file_struct *make_file(char *fname) file = (struct file_struct *)malloc(sizeof(*file)); if (!file) out_of_memory("make_file"); - bzero((char *)file,sizeof(*file)); + memset((char *)file,0,sizeof(*file)); if ((p = strrchr(fname,'/'))) { static char *lastdir; @@ -453,7 +422,7 @@ static struct file_struct *make_file(char *fname) } if (!S_ISDIR(st.st_mode)) - total_size += st.st_size; + stats.total_size += st.st_size; return file; } @@ -487,10 +456,10 @@ static void send_file_name(int f,struct file_list *flist,char *fname, } if (S_ISDIR(file->mode) && recursive) { - char **last_exclude_list = local_exclude_list; - send_directory(f,flist,f_name(file)); - local_exclude_list = last_exclude_list; - return; + struct exclude_struct **last_exclude_list = local_exclude_list; + send_directory(f,flist,f_name(file)); + local_exclude_list = last_exclude_list; + return; } } @@ -507,7 +476,7 @@ static void send_directory(int f,struct file_list *flist,char *dir) d = opendir(dir); if (!d) { io_error = 1; - rprintf(FERROR,"%s: %s\n", + rprintf(FERROR,"opendir(%s): %s\n", dir,strerror(errno)); return; } @@ -529,7 +498,7 @@ static void send_directory(int f,struct file_list *flist,char *dir) if (cvs_exclude) { if (strlen(fname) + strlen(".cvsignore") <= MAXPATHLEN-1) { strcpy(p,".cvsignore"); - local_exclude_list = make_exclude_list(fname,NULL,0); + local_exclude_list = make_exclude_list(fname,NULL,0,0); } else { io_error = 1; rprintf(FINFO,"cannot cvs-exclude in long-named directory %s\n",fname); @@ -542,7 +511,7 @@ static void send_directory(int f,struct file_list *flist,char *dir) strcmp(dname,"..")==0) continue; strlcpy(p,dname,MAXPATHLEN-(l+1)); - send_file_name(f,flist,fname,recurse,FLAG_DELETE); + send_file_name(f,flist,fname,recurse,0); } closedir(d); @@ -555,15 +524,17 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) int i,l; STRUCT_STAT st; char *p,*dir; - char dbuf[MAXPATHLEN]; char lastpath[MAXPATHLEN]=""; struct file_list *flist; + int64 start_write; if (verbose && recurse && !am_server && f != -1) { rprintf(FINFO,"building file list ... "); rflush(FINFO); } + start_write = stats.total_written; + flist = (struct file_list *)malloc(sizeof(flist[0])); if (!flist) out_of_memory("send_file_list"); @@ -619,8 +590,11 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) strlcpy(lastpath, fname, sizeof(lastpath)-1); *p = '/'; for (p=fname+1; (p=strchr(p,'/')); p++) { + int copy_links_saved = copy_links; *p = 0; + copy_links = 0; send_file_name(f, flist, fname, 0, 0); + copy_links = copy_links_saved; *p = '/'; } } else { @@ -632,24 +606,23 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) fname = "."; if (dir && *dir) { - if (getcwd(dbuf,MAXPATHLEN-1) == NULL) { - rprintf(FERROR,"getwd : %s\n",strerror(errno)); - exit_cleanup(1); - } - if (chdir(dir) != 0) { + char *olddir = push_dir(dir, 1); + + if (!olddir) { io_error=1; - rprintf(FERROR,"chdir %s : %s\n", + rprintf(FERROR,"push_dir %s : %s\n", dir,strerror(errno)); continue; } + flist_dir = dir; if (one_file_system) set_filesystem(fname); send_file_name(f,flist,fname,recurse,FLAG_DELETE); flist_dir = NULL; - if (chdir(dbuf) != 0) { - rprintf(FERROR,"chdir %s : %s\n", - dbuf,strerror(errno)); + if (pop_dir(olddir) != 0) { + rprintf(FERROR,"pop_dir %s : %s\n", + dir,strerror(errno)); exit_cleanup(1); } continue; @@ -682,7 +655,8 @@ struct file_list *send_file_list(int f,int argc,char *argv[]) if (f != -1) { io_end_buffering(f); - write_flush(f); + stats.flist_size = stats.total_written - start_write; + stats.num_files = flist->count; } if (verbose > 2) @@ -696,12 +670,15 @@ struct file_list *recv_file_list(int f) { struct file_list *flist; unsigned char flags; + int64 start_read; if (verbose && recurse && !am_server) { rprintf(FINFO,"receiving file list ... "); rflush(FINFO); } + start_read = stats.total_read; + flist = (struct file_list *)malloc(sizeof(flist[0])); if (!flist) goto oom; @@ -732,7 +709,7 @@ struct file_list *recv_file_list(int f) receive_file_entry(&flist->files[i],flags,f); if (S_ISREG(flist->files[i]->mode)) - total_size += flist->files[i]->length; + stats.total_size += flist->files[i]->length; flist->count++; @@ -763,6 +740,9 @@ struct file_list *recv_file_list(int f) if (verbose > 2) rprintf(FINFO,"recv_file_list done\n"); + stats.flist_size = stats.total_read - start_read; + stats.num_files = flist->count; + return flist; oom: @@ -777,8 +757,8 @@ int file_compare(struct file_struct **f1,struct file_struct **f2) if (!(*f1)->basename) return -1; if (!(*f2)->basename) return 1; if ((*f1)->dirname == (*f2)->dirname) - return strcmp((*f1)->basename, (*f2)->basename); - return strcmp(f_name(*f1),f_name(*f2)); + return u_strcmp((*f1)->basename, (*f2)->basename); + return u_strcmp(f_name(*f1),f_name(*f2)); } @@ -814,7 +794,7 @@ static void free_file(struct file_struct *file) if (file->basename) free(file->basename); if (file->link) free(file->link); if (file->sum) free(file->sum); - bzero((char *)file, sizeof(*file)); + memset((char *)file, 0, sizeof(*file)); } @@ -828,9 +808,9 @@ void flist_free(struct file_list *flist) free_file(flist->files[i]); free(flist->files[i]); } - bzero((char *)flist->files, sizeof(flist->files[0])*flist->count); + memset((char *)flist->files, 0, sizeof(flist->files[0])*flist->count); free(flist->files); - bzero((char *)flist, sizeof(*flist)); + memset((char *)flist, 0, sizeof(*flist)); free(flist); }