Doc.
[rsync.git] / receiver.c
index bf0877b3ee18d8a82ae314c065944e02e45d9c57..5776ff28b18f69d0a00fd1911212f43ea7584c36 100644 (file)
@@ -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
@@ -37,8 +38,8 @@ extern int make_backups;
 extern char *backup_suffix;
 
 static struct delete_list {
-       dev_t dev;
-       INO_T inode;
+       DEV64_T dev;
+       INO64_T inode;
 } *delete_list;
 static int dlist_len, dlist_alloc_len;
 
@@ -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));      
                }
@@ -108,13 +110,14 @@ void delete_files(struct file_list *flist)
        int i, j;
        char *name;
        extern int module_id;
+       extern int ignore_errors;
        extern int max_delete;
        static int deletion_count;
 
        if (cvs_exclude)
                add_cvs_excludes();
 
-       if (io_error && !lp_ignore_errors(module_id)) {
+       if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) {
                rprintf(FINFO,"IO error encountered - skipping file deletion\n");
                return;
        }
@@ -176,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;
        } 
 
@@ -189,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;
@@ -203,7 +206,8 @@ static int get_tmpname(char *fnametmp, char *fname)
 static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
                        OFF_T total_size)
 {
-       int i,n,remainder,len,count;
+       int i;
+       unsigned int n,remainder,len,count;
        OFF_T offset = 0;
        OFF_T offset2;
        char *data;
@@ -269,7 +273,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
                offset += len;
        }
 
-       end_progress();
+       end_progress(total_size);
 
        if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
                rprintf(FERROR,"write failed on %s : %s\n",
@@ -301,6 +305,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];
@@ -368,7 +373,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);
@@ -409,17 +414,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
@@ -427,16 +422,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));
@@ -489,7 +489,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
        }
 
        if (preserve_hard_links)
-               do_hard_links(flist);
+               do_hard_links();
 
        /* now we need to fix any directory permissions that were 
           modified during the transfer */