X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/e78733d9756ba4e0f28931fc9b811a2277cf803c..b315601ce07701c4913c48a269775ab3284b25ba:/receiver.c diff --git a/receiver.c b/receiver.c index 6361d21b..e0c99d10 100644 --- a/receiver.c +++ b/receiver.c @@ -43,7 +43,6 @@ static struct delete_list { } *delete_list; static int dlist_len, dlist_alloc_len; - /* yuck! This function wouldn't have been necessary if I had the sorting algorithm right. Unfortunately fixing the sorting algorithm would introduce a backward incompatibility as file list indexes are sent over the link. @@ -109,11 +108,14 @@ static void delete_files(struct file_list *flist) struct file_list *local_file_list; int i, j; char *name; + extern int module_id; + extern int max_delete; + static int deletion_count; if (cvs_exclude) add_cvs_excludes(); - if (io_error) { + if (io_error && !lp_ignore_errors(module_id)) { rprintf(FINFO,"IO error encountered - skipping file deletion\n"); return; } @@ -136,6 +138,7 @@ static void delete_files(struct file_list *flist) rprintf(FINFO,"deleting in %s\n", name); for (i=local_file_list->count-1;i>=0;i--) { + if (max_delete && deletion_count > max_delete) break; if (!local_file_list->files[i]->basename) continue; if (remote_version < 19 && S_ISDIR(local_file_list->files[i]->mode)) @@ -147,6 +150,7 @@ static void delete_files(struct file_list *flist) (strcmp(f+k,backup_suffix) != 0))) { (void) make_backup(f); } else { + deletion_count++; delete_one(local_file_list->files[i]); } } @@ -221,8 +225,8 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname, extern int cleanup_got_literal; if (verbose > 3) { - rprintf(FINFO,"data recv %d at %d\n", - i,(int)offset); + rprintf(FINFO,"data recv %d at %.0f\n", + i,(double)offset); } stats.literal_data += i; @@ -239,7 +243,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname, } i = -(i+1); - offset2 = i*n; + offset2 = i*(OFF_T)n; len = n; if (i == count-1 && remainder != 0) len = remainder; @@ -247,8 +251,8 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname, stats.matched_data += len; if (verbose > 3) - rprintf(FINFO,"chunk[%d] of size %d at %d offset=%d\n", - i,len,(int)offset2,(int)offset); + rprintf(FINFO,"chunk[%d] of size %d at %.0f offset=%.0f\n", + i,len,(double)offset2,(double)offset); map = map_ptr(buf,offset2,len); @@ -302,14 +306,18 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) int phase=0; int recv_ok; extern struct stats stats; + extern int preserve_perms; + extern int delete_after; struct stats initial_stats; if (verbose > 2) { rprintf(FINFO,"recv_files(%d) starting\n",flist->count); } - if (recurse && delete_mode && !local_name && flist->count>0) { - delete_files(flist); + if (!delete_after) { + if (recurse && delete_mode && !local_name && flist->count>0) { + delete_files(flist); + } } while (1) { @@ -358,14 +366,14 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) fnamecmp = fname; /* open the file */ - fd1 = open(fnamecmp,O_RDONLY); + fd1 = do_open(fnamecmp, O_RDONLY, 0); if ((fd1 == -1) && (compare_dest != NULL)) { /* try the file at compare_dest instead */ slprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s", compare_dest,fname); fnamecmp = fnamecmpbuf; - fd1 = open(fnamecmp,O_RDONLY); + fd1 = do_open(fnamecmp, O_RDONLY, 0); } if (fd1 != -1 && do_fstat(fd1,&st) != 0) { @@ -382,10 +390,17 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) continue; } + if (fd1 != -1 && !preserve_perms) { + /* if the file exists already and we aren't perserving + presmissions then act as though the remote end sent + us the file permissions we already have */ + file->mode = st.st_mode; + } + if (fd1 != -1 && st.st_size > 0) { buf = map_file(fd1,st.st_size); if (verbose > 2) - rprintf(FINFO,"recv mapped %s of size %d\n",fnamecmp,(int)st.st_size); + rprintf(FINFO,"recv mapped %s of size %.0f\n",fnamecmp,(double)st.st_size); } else { buf = NULL; } @@ -456,7 +471,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) finish_transfer(fname, fnametmp, file); cleanup_disable(); - + if (!recv_ok) { if (csum_length == SUM_LENGTH) { rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n", @@ -469,6 +484,12 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) } } + if (delete_after) { + if (recurse && delete_mode && !local_name && flist->count>0) { + delete_files(flist); + } + } + if (preserve_hard_links) do_hard_links(flist);