X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/ef55c686bcb61d8c83e79eb73ed15639e4345d5c..d2094cc33dd87229f453176918e4ae2c2536f88e:/receiver.c diff --git a/receiver.c b/receiver.c index b10f7c61..2f679b17 100644 --- a/receiver.c +++ b/receiver.c @@ -1,5 +1,6 @@ -/* - Copyright (C) Andrew Tridgell 1996 +/* -*- c-file-style: "linux" -*- + + Copyright (C) 1996-2000 by Andrew Tridgell Copyright (C) Paul Mackerras 1996 This program is free software; you can redistribute it and/or modify @@ -82,14 +83,15 @@ static void delete_one(struct file_struct *f) { if (!S_ISDIR(f->mode)) { if (robust_unlink(f_name(f)) != 0) { - rprintf(FERROR,"unlink %s : %s\n",f_name(f),strerror(errno)); + rprintf(FERROR,"delete_one: unlink %s: %s\n",f_name(f),strerror(errno)); } else if (verbose) { rprintf(FINFO,"deleting %s\n",f_name(f)); } } else { if (do_rmdir(f_name(f)) != 0) { if (errno != ENOTEMPTY && errno != EEXIST) - rprintf(FERROR,"rmdir %s : %s\n",f_name(f),strerror(errno)); + rprintf(FERROR,"delete_one: rmdir %s: %s\n", + f_name(f), strerror(errno)); } else if (verbose) { rprintf(FINFO,"deleting directory %s\n",f_name(f)); } @@ -177,7 +179,7 @@ static int get_tmpname(char *fnametmp, char *fname) rprintf(FERROR,"filename too long\n"); return 0; } - slprintf(fnametmp,MAXPATHLEN, "%s/.%s.XXXXXX",tmpdir,f); + snprintf(fnametmp,MAXPATHLEN, "%s/.%s.XXXXXX",tmpdir,f); return 1; } @@ -190,11 +192,11 @@ static int get_tmpname(char *fnametmp, char *fname) if (f) { *f = 0; - slprintf(fnametmp,MAXPATHLEN,"%s/.%s.XXXXXX", + snprintf(fnametmp,MAXPATHLEN,"%s/.%s.XXXXXX", fname,f+1); *f = '/'; } else { - slprintf(fnametmp,MAXPATHLEN,".%s.XXXXXX",fname); + snprintf(fnametmp,MAXPATHLEN,".%s.XXXXXX",fname); } return 1; @@ -302,6 +304,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) int fd1,fd2; STRUCT_STAT st; char *fname; + char template[MAXPATHLEN]; char fnametmp[MAXPATHLEN]; char *fnamecmp; char fnamecmpbuf[MAXPATHLEN]; @@ -369,7 +372,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,"%s/%s", + snprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s", compare_dest,fname); fnamecmp = fnamecmpbuf; fd1 = do_open(fnamecmp, O_RDONLY, 0); @@ -410,17 +413,7 @@ 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); - if (buf) unmap_file(buf); - if (fd1 != -1) close(fd1); - continue; - } + strlcpy(template, fnametmp, sizeof(template)); /* we initially set the perms without the setuid/setgid bits to ensure that there is no race @@ -428,16 +421,21 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) the lchown. Thanks to snabb@epipe.fi for pointing this out. We also set it initially without group access because of a similar race condition. */ - fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL, - file->mode & INITACCESSPERMS); + fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS); + if (fd2 == -1) { + rprintf(FERROR,"mkstemp %s failed\n",fnametmp); + receive_data(f_in,buf,-1,NULL,file->length); + if (buf) unmap_file(buf); + continue; + } /* in most cases parent directories will already exist because their information should have been previously transferred, but that may not be the case with -R */ if (fd2 == -1 && relative_paths && errno == ENOENT && create_directory_path(fnametmp) == 0) { - fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL, - file->mode & INITACCESSPERMS); + strlcpy(fnametmp, template, sizeof(fnametmp)); + fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS); } if (fd2 == -1) { rprintf(FERROR,"cannot create %s : %s\n",fnametmp,strerror(errno));