Changed rprintf() calls that included strerror() to use rsyserr().
[rsync/rsync.git] / generator.c
index b325a3b..4a6d82e 100644 (file)
@@ -43,6 +43,14 @@ extern int protocol_version;
 extern int always_checksum;
 extern char *compare_dest;
 extern int link_dest;
+extern int whole_file;
+extern int local_server;
+extern int read_batch;
+extern int write_batch;
+extern int list_only;
+extern int only_existing;
+extern int orig_umask;
+extern int safe_symlinks;
 
 
 /* choose whether to skip a particular file */
@@ -53,7 +61,7 @@ static int skip_file(char *fname, struct file_struct *file, STRUCT_STAT *st)
        }
        if (link_dest) {
                if (preserve_perms
-                   && (st->st_mode & ~_S_IFMT) != (file->mode & ~_S_IFMT))
+                   && (st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
                        return 0;
 
                if (am_root && preserve_uid && st->st_uid != file->uid)
@@ -72,8 +80,8 @@ static int skip_file(char *fname, struct file_struct *file, STRUCT_STAT *st)
 
                if (compare_dest != NULL) {
                        if (access(fname, 0) != 0) {
-                               snprintf(fnamecmpdest,MAXPATHLEN,"%s/%s",
-                                        compare_dest,fname);
+                               pathjoin(fnamecmpdest, sizeof fnamecmpdest,
+                                        compare_dest, fname);
                                fname = fnamecmpdest;
                        }
                }
@@ -101,7 +109,7 @@ void write_sum_head(int f, struct sum_struct *sum)
 {
        static struct sum_struct null_sum;
 
-       if (sum == (struct sum_struct *)NULL)
+       if (sum == NULL)
                sum = &null_sum;
 
        write_int(f, sum->count);
@@ -204,13 +212,9 @@ static void sum_sizes_sqroot(struct sum_struct *sum, uint64 len)
  * Whew. */
 static BOOL disable_deltas_p(void)
 {
-       extern int whole_file;
-       extern int local_server;
-       extern int write_batch;
-
        if (whole_file > 0)
                return True;
-       if (whole_file == 0 || write_batch)
+       if (whole_file == 0 || write_batch || read_batch)
                return False;
        return local_server;
 }
@@ -270,10 +274,6 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
        int statret;
        char *fnamecmp;
        char fnamecmpbuf[MAXPATHLEN];
-       extern char *compare_dest;
-       extern int list_only;
-       extern int only_existing;
-       extern int orig_umask;
 
        if (list_only)
                return;
@@ -295,7 +295,8 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
                /* if the file exists already and we aren't perserving
                 * permissions then act as though the remote end sent
                 * us the file permissions we already have */
-               file->mode = (file->mode & _S_IFMT) | (st.st_mode & ~_S_IFMT);
+               file->mode = (file->mode & ~CHMOD_BITS)
+                          | (st.st_mode & CHMOD_BITS);
        }
 
        if (S_ISDIR(file->mode)) {
@@ -334,7 +335,6 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
 #if SUPPORT_LINKS
                char lnk[MAXPATHLEN];
                int l;
-               extern int safe_symlinks;
 
                if (safe_symlinks && unsafe_symlink(file->u.link, fname)) {
                        if (verbose) {
@@ -351,7 +351,8 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
                                 * right place -- no further action
                                 * required. */
                                if (strcmp(lnk,file->u.link) == 0) {
-                                       set_perms(fname,file,&st,1);
+                                       set_perms(fname, file, &st,
+                                                 PERMS_REPORT);
                                        return;
                                }
                        }
@@ -377,7 +378,7 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
        if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
                if (statret != 0 ||
                    st.st_mode != file->mode ||
-                   (DEV64_T)st.st_rdev != file->u.rdev) {
+                   st.st_rdev != file->u.rdev) {
                        delete_file(fname);
                        if (verbose > 2)
                                rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
@@ -391,19 +392,14 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
                                        rprintf(FINFO,"%s\n",fname);
                        }
                } else {
-                       set_perms(fname,file,&st,1);
+                       set_perms(fname, file, &st, PERMS_REPORT);
                }
                return;
        }
 #endif
 
-       if (preserve_hard_links && file->link_u.links && file->F_HEAD != file) {
-               if (verbose > 1) {
-                       rprintf(FINFO, "recv_generator: \"%s\" is a hard link\n",
-                               f_name(file));
-               }
+       if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
                return;
-       }
 
        if (!S_ISREG(file->mode)) {
                rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
@@ -412,10 +408,10 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
 
        fnamecmp = fname;
 
-       if ((statret == -1) && (compare_dest != NULL)) {
+       if (statret == -1 && compare_dest != NULL) {
                /* try the file at compare_dest instead */
                int saveerrno = errno;
-               snprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname);
+               pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest, fname);
                statret = link_stat(fnamecmpbuf,&st);
                if (!S_ISREG(st.st_mode))
                        statret = -1;
@@ -438,6 +434,8 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
        }
 
        if (statret == -1) {
+               if (preserve_hard_links && hard_link_check(file, HL_SKIP))
+                       return;
                if (errno == ENOENT) {
                        write_int(f_out,i);
                        if (!dry_run) write_sum_head(f_out, NULL);
@@ -455,6 +453,8 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
                }
 
                /* now pretend the file didn't exist */
+               if (preserve_hard_links && hard_link_check(file, HL_SKIP))
+                       return;
                write_int(f_out,i);
                if (!dry_run) write_sum_head(f_out, NULL);
                return;
@@ -474,7 +474,7 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
 
        if (skip_file(fname, file, &st)) {
                if (fnamecmp == fname)
-                       set_perms(fname,file,&st,1);
+                       set_perms(fname, file, &st, PERMS_REPORT);
                return;
        }
 
@@ -496,6 +496,8 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
                rprintf(FERROR, "failed to open %s, continuing: %s\n",
                        full_fname(fnamecmp), strerror(errno));
                /* pretend the file didn't exist */
+               if (preserve_hard_links && hard_link_check(file, HL_SKIP))
+                       return;
                write_int(f_out,i);
                write_sum_head(f_out, NULL);
                return;
@@ -528,9 +530,10 @@ void generate_files(int f, struct file_list *flist, char *local_name)
        int phase=0;
        char fbuf[MAXPATHLEN];
 
-       if (verbose > 2)
-               rprintf(FINFO,"generator starting pid=%d count=%d\n",
-                       (int)getpid(),flist->count);
+       if (verbose > 2) {
+               rprintf(FINFO, "generator starting pid=%ld count=%d\n",
+                       (long)getpid(), flist->count);
+       }
 
        if (verbose >= 2) {
                rprintf(FINFO,
@@ -561,8 +564,8 @@ void generate_files(int f, struct file_list *flist, char *local_name)
                        file = ©
                }
 
-               recv_generator(local_name? local_name
-                            : f_name_to(file,fbuf,sizeof fbuf), file, i, f);
+               recv_generator(local_name ? local_name : f_name_to(file, fbuf),
+                              file, i, f);
        }
 
        phase++;
@@ -578,8 +581,8 @@ void generate_files(int f, struct file_list *flist, char *local_name)
         * to catch initial checksum errors */
        while ((i = get_redo_num()) != -1) {
                struct file_struct *file = flist->files[i];
-               recv_generator(local_name? local_name
-                            : f_name_to(file,fbuf,sizeof fbuf), file, i, f);
+               recv_generator(local_name ? local_name : f_name_to(file, fbuf),
+                              file, i, f);
        }
 
        phase++;
@@ -587,4 +590,19 @@ void generate_files(int f, struct file_list *flist, char *local_name)
                rprintf(FINFO,"generate_files phase=%d\n",phase);
 
        write_int(f,-1);
+
+       if (preserve_hard_links)
+               do_hard_links();
+
+       /* 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];
+               if (!file->basename || !S_ISDIR(file->mode)) continue;
+               recv_generator(local_name ? local_name : f_name(file),
+                              file, i, -1);
+       }
+
+       if (verbose > 2)
+               rprintf(FINFO,"generate_files finished\n");
 }