X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/8bf737494f17ca384b30db13b4bc31a5158f3646..e92338c82deba1576d23f22e11d95b0b34432e08:/rsync.c diff --git a/rsync.c b/rsync.c index b19681ca..ea05f1e0 100644 --- a/rsync.c +++ b/rsync.c @@ -46,6 +46,7 @@ extern int recurse; extern int delete_mode; extern int cvs_exclude; extern int am_root; +extern int relative_paths; /* free a sums struct @@ -146,7 +147,6 @@ static struct sum_struct *receive_sums(int f) struct sum_struct *s; int i; off_t offset = 0; - int block_len; s = (struct sum_struct *)malloc(sizeof(*s)); if (!s) out_of_memory("receive_sums"); @@ -160,8 +160,6 @@ static struct sum_struct *receive_sums(int f) fprintf(FERROR,"count=%d n=%d rem=%d\n", s->count,s->n,s->remainder); - block_len = s->n; - if (s->count == 0) return(s); @@ -277,8 +275,14 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out) } statret = -1; } - if (statret != 0 && mkdir(fname,file->mode) != 0 && errno != EEXIST) - fprintf(FERROR,"mkdir %s : %s\n",fname,strerror(errno)); + if (statret != 0 && mkdir(fname,file->mode) != 0 && errno != EEXIST) { + if (!(relative_paths && errno==ENOENT && + create_directory_path(fname)==0 && + mkdir(fname,file->mode)==0)) { + fprintf(FERROR,"mkdir %s : %s (2)\n", + fname,strerror(errno)); + } + } if (set_perms(fname,file,NULL,0) && verbose) fprintf(FINFO,"%s/\n",fname); return; @@ -523,23 +527,38 @@ static void delete_one(struct file_struct *f) } +/* this deletes any files on the receiving side that are not present + on the sending side. For version 1.6.4 I have changed the behaviour + to match more closely what most people seem to expect of this option */ static void delete_files(struct file_list *flist) { struct file_list *local_file_list; char *dot="."; - int i; + int i, j; + char *last_name=NULL; if (cvs_exclude) add_cvs_excludes(); - if (!(local_file_list = send_file_list(-1,1,&dot))) - return; - - for (i=local_file_list->count;i>=0;i--) { - if (!local_file_list->files[i].name) continue; - if (-1 == flist_find(flist,&local_file_list->files[i])) { - delete_one(&local_file_list->files[i]); - } + for (j=0;jcount;j++) { + if (!S_ISDIR(flist->files[j].mode)) continue; + if (strcmp(flist->files[j].name,".")==0) continue; + if (last_name && + flist->files[j].name[strlen(last_name)] == '/' && + strncmp(flist->files[j].name,last_name, strlen(last_name))==0) + continue; + last_name = flist->files[j].name; + if (verbose > 1) + fprintf(FINFO,"deleting in %s\n", last_name); + if (!(local_file_list = send_file_list(-1,1,&last_name))) + return; + + for (i=local_file_list->count-1;i>=0;i--) { + if (!local_file_list->files[i].name) continue; + if (-1 == flist_find(flist,&local_file_list->files[i])) { + delete_one(&local_file_list->files[i]); + } + } } } @@ -644,6 +663,10 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) continue; } fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode); + if (relative_paths && errno == ENOENT && + create_directory_path(fnametmp) == 0) { + fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode); + } if (fd2 == -1) { fprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno)); receive_data(f_in,buf,-1,NULL);