X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/3b3a2fbcf058b90d9116f48ba26ad9528d450134..13dc412d7670934e2bc9b80f3d42bb9e9ccfc93c:/rsync.c diff --git a/rsync.c b/rsync.c index 673f1414..ea15ac84 100644 --- a/rsync.c +++ b/rsync.c @@ -29,6 +29,7 @@ extern time_t starttime; extern int remote_version; extern char *backup_suffix; +extern char *tmpdir; extern int whole_file; extern int block_size; @@ -744,7 +745,17 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) close(fd1); continue; } - sprintf(fnametmp,"%s.XXXXXX",fname); + if (tmpdir) { + char *f; + f = strrchr(fname,'/'); + if (f == NULL) + f = fname; + else + f++; + sprintf(fnametmp,"%s/%s.XXXXXX",tmpdir,f); + } else { + sprintf(fnametmp,"%s.XXXXXX",fname); + } if (NULL == mktemp(fnametmp)) { fprintf(FERROR,"mktemp %s failed\n",fnametmp); receive_data(f_in,buf,-1,NULL); @@ -752,10 +763,10 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) close(fd1); continue; } - fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode); + fd2 = open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode); if (fd2 == -1 && relative_paths && errno == ENOENT && create_directory_path(fnametmp) == 0) { - fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode); + fd2 = open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode); } if (fd2 == -1) { fprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno)); @@ -797,14 +808,27 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) /* move tmp file over real file */ if (rename(fnametmp,fname) != 0) { - fprintf(FERROR,"rename %s -> %s : %s\n", - fnametmp,fname,strerror(errno)); - unlink(fnametmp); + if (errno == EXDEV) { + /* rename failed on cross-filesystem link. + Copy the file instead. */ + if (copy_file(fnametmp,fname, file->mode)) { + fprintf(FERROR,"copy %s -> %s : %s\n", + fnametmp,fname,strerror(errno)); + } else { + set_perms(fname,file,NULL,0); + } + unlink(fnametmp); + } else { + fprintf(FERROR,"rename %s -> %s : %s\n", + fnametmp,fname,strerror(errno)); + unlink(fnametmp); + } + } else { + set_perms(fname,file,NULL,0); } cleanup_fname = NULL; - set_perms(fname,file,NULL,0); if (!recv_ok) { if (verbose > 1)