X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/d4ebe7a7b1378fed5340bcc2acf27b758cf815ef..4c36ddbeecdde407c870109d70527640ca127ace:/rsync.c diff --git a/rsync.c b/rsync.c index 9d11b722..555c009a 100644 --- a/rsync.c +++ b/rsync.c @@ -111,10 +111,7 @@ static int delete_file(char *fname) if (strcmp(dname,".")==0 || strcmp(dname,"..")==0) continue; - strlcpy(buf, fname, (MAXPATHLEN-strlen(dname))-2); - strcat(buf, "/"); - strcat(buf, dname); - buf[MAXPATHLEN-1] = 0; + slprintf(buf, sizeof(buf)-1, "%s/%s", fname, dname); if (verbose > 0) rprintf(FINFO,"deleting %s\n", buf); if (delete_file(buf) != 0) { @@ -150,7 +147,6 @@ static void send_sums(struct sum_struct *s,int f_out) write_int(f_out,s->sums[i].sum1); write_buf(f_out,s->sums[i].sum2,csum_length); } - write_flush(f_out); } @@ -270,6 +266,7 @@ static int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st, { int updated = 0; STRUCT_STAT st2; + extern int am_daemon; if (dry_run) return 0; @@ -303,8 +300,9 @@ static int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st, } #endif - if ((am_root && preserve_uid && st->st_uid != file->uid) || - (preserve_gid && st->st_gid != file->gid)) { + if ((am_root || !am_daemon) && + ((am_root && preserve_uid && st->st_uid != file->uid) || + (preserve_gid && st->st_gid != file->gid))) { if (do_lchown(fname, (am_root&&preserve_uid)?file->uid:-1, preserve_gid?file->gid:-1) != 0) { @@ -529,7 +527,6 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out) write_int(f_out,i); send_sums(s,f_out); - write_flush(f_out); close(fd); if (buf) unmap_file(buf); @@ -697,7 +694,8 @@ static void delete_files(struct file_list *flist) if (!S_ISDIR(flist->files[j]->mode) || !(flist->files[j]->flags & FLAG_DELETE)) continue; - if (delete_already_done(flist, j)) continue; + if (remote_version < 19 && + delete_already_done(flist, j)) continue; name = strdup(f_name(flist->files[j])); @@ -711,7 +709,8 @@ static void delete_files(struct file_list *flist) for (i=local_file_list->count-1;i>=0;i--) { if (!local_file_list->files[i]->basename) continue; - if (S_ISDIR(local_file_list->files[i]->mode)) + if (remote_version < 19 && + S_ISDIR(local_file_list->files[i]->mode)) add_delete_entry(local_file_list->files[i]); if (-1 == flist_find(flist,local_file_list->files[i])) { delete_one(local_file_list->files[i]); @@ -726,6 +725,7 @@ static char *cleanup_fname; void exit_cleanup(int code) { + io_flush(); if (cleanup_fname) do_unlink(cleanup_fname); signal(SIGUSR1, SIG_IGN); @@ -771,7 +771,6 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) if (verbose > 2) rprintf(FINFO,"recv_files phase=%d\n",phase); write_int(f_gen,-1); - write_flush(f_gen); continue; } break; @@ -831,8 +830,10 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) close(fd1); continue; } - sprintf(fnametmp,"%s/.%s.XXXXXX",tmpdir,f); + slprintf(fnametmp,sizeof(fnametmp)-1, "%s/.%s.XXXXXX",tmpdir,f); } else { + char *f = strrchr(fname,'/'); + if (strlen(fname)+9 > MAXPATHLEN) { rprintf(FERROR,"filename too long\n"); if (buf) unmap_file(buf); @@ -840,7 +841,13 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) continue; } - sprintf(fnametmp,".%s.XXXXXX",fname); + if (f) { + *f = 0; + slprintf(fnametmp,sizeof(fnametmp)-1,"%s/.%s.XXXXXX",fname,f+1); + *f = '/'; + } else { + slprintf(fnametmp,sizeof(fnametmp)-1,".%s.XXXXXX",fname); + } } if (NULL == do_mktemp(fnametmp)) { rprintf(FERROR,"mktemp %s failed\n",fnametmp); @@ -885,7 +892,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) rprintf(FERROR,"backup filename too long\n"); continue; } - sprintf(fnamebak,"%s%s",fname,backup_suffix); + slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix); if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) { rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno)); continue; @@ -934,7 +941,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) /* now we need to fix any directory permissions that were modified during the transfer */ for (i = 0; i < flist->count; i++) { - struct file_struct *file = flist->files[i]; + file = flist->files[i]; if (!file->basename || !S_ISDIR(file->mode)) continue; recv_generator(f_name(file),flist,i,-1); } @@ -962,7 +969,7 @@ void send_files(struct file_list *flist,int f_out,int f_in) if (verbose > 2) rprintf(FINFO,"send_files starting\n"); - setup_nonblocking(f_in,f_out); + setup_readbuffer(f_in); while (1) { i = read_int(f_in); @@ -971,7 +978,6 @@ void send_files(struct file_list *flist,int f_out,int f_in) phase++; csum_length = SUM_LENGTH; write_int(f_out,-1); - write_flush(f_out); if (verbose > 2) rprintf(FINFO,"send_files phase=%d\n",phase); continue; @@ -990,10 +996,10 @@ void send_files(struct file_list *flist,int f_out,int f_in) fname); return; } - strcat(fname,"/"); + strlcat(fname,"/",MAXPATHLEN-1); offset = strlen(file->basedir)+1; } - strncat(fname,f_name(file),MAXPATHLEN-strlen(fname)); + strlcat(fname,f_name(file),MAXPATHLEN-strlen(fname)); if (verbose > 2) rprintf(FINFO,"send_files(%d,%s)\n",i,fname); @@ -1053,7 +1059,6 @@ void send_files(struct file_list *flist,int f_out,int f_in) printf("%s\n",fname+offset); match_sums(f_out,s,buf,st.st_size); - write_flush(f_out); if (buf) unmap_file(buf); close(fd); @@ -1070,7 +1075,6 @@ void send_files(struct file_list *flist,int f_out,int f_in) match_report(); write_int(f_out,-1); - write_flush(f_out); } @@ -1110,7 +1114,6 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv) rprintf(FINFO,"generate_files phase=%d\n",phase); write_int(f,-1); - write_flush(f); /* we expect to just sit around now, so don't exit on a timeout. If we really get a timeout then the other process should exit */ @@ -1130,7 +1133,6 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv) rprintf(FINFO,"generate_files phase=%d\n",phase); write_int(f,-1); - write_flush(f); }