X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/654175798bdbdd6403e10c8fa74e8586b3612ea1..d1be231290b3867648ee417fad341fdf1caaa94b:/receiver.c diff --git a/receiver.c b/receiver.c index 189aa417..e7a164b9 100644 --- a/receiver.c +++ b/receiver.c @@ -33,6 +33,8 @@ extern int cvs_exclude; extern int io_error; extern char *tmpdir; extern char *compare_dest; +extern int make_backups; +extern char *backup_suffix; static struct delete_list { @@ -139,8 +141,15 @@ static void delete_files(struct file_list *flist) 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]); - } + char *f = f_name(local_file_list->files[i]); + int k = strlen(f) - strlen(backup_suffix); + if (make_backups && ((k <= 0) || + (strcmp(f+k,backup_suffix) != 0))) { + (void) make_backup(f); + } else { + delete_one(local_file_list->files[i]); + } + } } flist_free(local_file_list); free(name); @@ -163,7 +172,7 @@ static int get_tmpname(char *fnametmp, char *fname) rprintf(FERROR,"filename too long\n"); return 0; } - slprintf(fnametmp,MAXPATHLEN-1, "%s/.%s.XXXXXX",tmpdir,f); + slprintf(fnametmp,MAXPATHLEN, "%s/.%s.XXXXXX",tmpdir,f); return 1; } @@ -176,11 +185,11 @@ static int get_tmpname(char *fnametmp, char *fname) if (f) { *f = 0; - slprintf(fnametmp,MAXPATHLEN-1,"%s/.%s.XXXXXX", + slprintf(fnametmp,MAXPATHLEN,"%s/.%s.XXXXXX", fname,f+1); *f = '/'; } else { - slprintf(fnametmp,MAXPATHLEN-1,".%s.XXXXXX",fname); + slprintf(fnametmp,MAXPATHLEN,".%s.XXXXXX",fname); } return 1; @@ -353,7 +362,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) if ((fd1 == -1) && (compare_dest != NULL)) { /* try the file at compare_dest instead */ - slprintf(fnamecmpbuf,MAXPATHLEN-1,"%s/%s", + slprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s", compare_dest,fname); fnamecmp = fnamecmpbuf; fd1 = open(fnamecmp,O_RDONLY); @@ -387,6 +396,10 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) continue; } + /* mktemp is deliberately used here instead of mkstemp. + because O_EXCL is used on the open, the race condition + is not a problem or a security hole, and we want to + control the access permissions on the created file. */ if (NULL == do_mktemp(fnametmp)) { rprintf(FERROR,"mktemp %s failed\n",fnametmp); receive_data(f_in,buf,-1,NULL,file->length);