X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/7308bd66e0d5e5d2d04e41b0052879b4f3283109..71c4617611ca07d7c249faa2dfd2cfc5cb32b836:/rsync.c diff --git a/rsync.c b/rsync.c index 45604551..2ef416db 100644 --- a/rsync.c +++ b/rsync.c @@ -60,6 +60,75 @@ static void free_sums(struct sum_struct *s) } +/* + * delete a file or directory. If force_delet is set then delete + * recursively + */ +static int delete_file(char *fname) +{ + DIR *d; + struct dirent *di; + char buf[MAXPATHLEN]; + extern int force_delete; + struct stat st; + int ret; + + if (do_unlink(fname) == 0 || errno == ENOENT) return 0; + +#if SUPPORT_LINKS + ret = lstat(fname, &st); +#else + ret = stat(fname, &st); +#endif + if (ret) { + fprintf(FERROR,"stat(%s) : %s\n", fname, strerror(errno)); + return -1; + } + + if (!S_ISDIR(st.st_mode)) { + fprintf(FERROR,"unlink(%s) : %s\n", fname, strerror(errno)); + return -1; + } + + if (do_rmdir(fname) == 0 || errno == ENOENT) return 0; + if (!force_delete || errno != ENOTEMPTY) { + fprintf(FERROR,"rmdir(%s) : %s\n", fname, strerror(errno)); + return -1; + } + + /* now we do a recsursive delete on the directory ... */ + d = opendir(fname); + if (!d) { + fprintf(FERROR,"opendir(%s): %s\n", + fname,strerror(errno)); + return -1; + } + + for (di=readdir(d); di; di=readdir(d)) { + if (strcmp(di->d_name,".")==0 || + strcmp(di->d_name,"..")==0) + continue; + strncpy(buf, fname, (MAXPATHLEN-strlen(di->d_name))-2); + strcat(buf, "/"); + strcat(buf, di->d_name); + buf[MAXPATHLEN-1] = 0; + if (verbose > 0) + fprintf(FINFO,"deleting %s\n", buf); + if (delete_file(buf) != 0) { + closedir(d); + return -1; + } + } + + closedir(d); + + if (do_rmdir(fname) != 0) { + fprintf(FERROR,"rmdir(%s) : %s\n", fname, strerror(errno)); + return -1; + } + + return 0; +} /* send a sums struct down a fd @@ -337,7 +406,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out) } } } - do_unlink(fname); + delete_file(fname); if (do_symlink(file->link,fname) != 0) { fprintf(FERROR,"link %s -> %s : %s\n", fname,file->link,strerror(errno)); @@ -356,7 +425,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out) if (statret != 0 || st.st_mode != file->mode || st.st_rdev != file->rdev) { - do_unlink(fname); + delete_file(fname); if (verbose > 2) fprintf(FERROR,"mknod(%s,0%o,0x%x)\n", fname,(int)file->mode,(int)file->rdev); @@ -397,15 +466,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out) } if (!S_ISREG(st.st_mode)) { - /* its not a regular file on the receiving end, but it is on the - sending end. If its a directory then skip it (too dangerous to - do a recursive deletion??) otherwise try to unlink it */ - if (S_ISDIR(st.st_mode)) { - fprintf(FERROR,"ERROR: %s is a directory\n",fname); - return; - } - if (do_unlink(fname) != 0) { - fprintf(FERROR,"%s : not a regular file (generator)\n",fname); + if (delete_file(fname) != 0) { return; } @@ -868,17 +929,17 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) -off_t send_files(struct file_list *flist,int f_out,int f_in) +void send_files(struct file_list *flist,int f_out,int f_in) { int fd; struct sum_struct *s; struct map_struct *buf; struct stat st; char fname[MAXPATHLEN]; - off_t total=0; int i; struct file_struct *file; int phase = 0; + int offset=0; if (verbose > 2) fprintf(FERROR,"send_files starting\n"); @@ -909,9 +970,10 @@ off_t send_files(struct file_list *flist,int f_out,int f_in) if (strlen(fname) == MAXPATHLEN-1) { fprintf(FERROR, "send_files failed on long-named directory %s\n", fname); - return -1; + return; } strcat(fname,"/"); + offset = strlen(file->basedir)+1; } strncat(fname,f_name(file),MAXPATHLEN-strlen(fname)); @@ -928,7 +990,7 @@ off_t send_files(struct file_list *flist,int f_out,int f_in) s = receive_sums(f_in); if (!s) { fprintf(FERROR,"receive_sums failed\n"); - return -1; + return; } fd = open(fname,O_RDONLY); @@ -944,7 +1006,7 @@ off_t send_files(struct file_list *flist,int f_out,int f_in) fprintf(FERROR,"fstat failed : %s\n",strerror(errno)); free_sums(s); close(fd); - return -1; + return; } if (st.st_size > 0) { @@ -967,7 +1029,7 @@ off_t send_files(struct file_list *flist,int f_out,int f_in) fprintf(FERROR,"calling match_sums %s\n",fname); if (!am_server && verbose) - printf("%s\n",fname); + printf("%s\n",fname+offset); match_sums(f_out,s,buf,st.st_size); write_flush(f_out); @@ -979,8 +1041,6 @@ off_t send_files(struct file_list *flist,int f_out,int f_in) if (verbose > 2) fprintf(FERROR,"sender finished %s\n",fname); - - total += st.st_size; } if (verbose > 2) @@ -990,8 +1050,6 @@ off_t send_files(struct file_list *flist,int f_out,int f_in) write_int(f_out,-1); write_flush(f_out); - - return total; }