- Changed ITEM_UPDATING to ITEM_TRANSFER.
[rsync/rsync.git] / generator.c
index bd8a672..79b7e63 100644 (file)
@@ -299,21 +299,13 @@ static int unchanged_attrs(struct file_struct *file, STRUCT_STAT *st)
 }
 
 
-#define SID_UPDATING             ITEM_UPDATING
-#define SID_REPORT_CHECKSUM      ITEM_REPORT_CHECKSUM
-#define SID_USING_ALT_BASIS      ITEM_USING_ALT_BASIS
-/* This flag doesn't get sent, so it must be outside 0xffff. */
-#define SID_NO_DEST_AND_NO_UPDATE (1<<16)
-
 static void itemize(struct file_struct *file, int statret, STRUCT_STAT *st,
-                   int32 sflags, int f_out, int ndx)
+                   int32 iflags, int f_out, int ndx)
 {
-       int iflags = sflags & 0xffff;
-
-       if (statret >= 0) {
+       if (statret == 0) {
                if (S_ISREG(file->mode) && file->length != st->st_size)
                        iflags |= ITEM_REPORT_SIZE;
-               if (!(sflags & SID_NO_DEST_AND_NO_UPDATE)) {
+               if (!(iflags & ITEM_NO_DEST_AND_NO_UPDATE)) {
                        int keep_time = !preserve_times ? 0
                            : S_ISDIR(file->mode) ? !omit_dir_times
                            : !S_ISLNK(file->mode);
@@ -332,13 +324,14 @@ static void itemize(struct file_struct *file, int statret, STRUCT_STAT *st,
        } else
                iflags |= ITEM_IS_NEW | ITEM_UPDATING;
 
+       iflags &= 0xffff;
        if ((iflags || verbose > 1) && !read_batch) {
                if (protocol_version >= 29) {
                        if (ndx >= 0)
                                write_int(f_out, ndx);
                        write_shortint(f_out, iflags);
                } else if (ndx >= 0)
-                       log_recv(file, &stats, iflags);
+                       log_item(file, &stats, iflags, NULL);
        }
 }
 
@@ -746,7 +739,7 @@ static void recv_generator(char *fname, struct file_list *flist,
                } else {
                        set_perms(fname,file,NULL,0);
                        if (itemizing) {
-                               itemize(file, statret, &st, SID_UPDATING,
+                               itemize(file, statret, &st, ITEM_UPDATING,
                                        f_out, ndx);
                        }
                        if (code && verbose) {
@@ -781,7 +774,7 @@ static void recv_generator(char *fname, struct file_list *flist,
                        } else {
                                set_perms(fname,file,NULL,0);
                                if (itemizing) {
-                                       itemize(file, statret, &st, SID_UPDATING,
+                                       itemize(file, statret, &st, ITEM_UPDATING,
                                                f_out, ndx);
                                }
                                if (code && verbose) {
@@ -808,6 +801,19 @@ static void recv_generator(char *fname, struct file_list *flist,
                return;
        }
 
+       if (opt_ignore_existing && statret == 0) {
+               if (verbose > 1)
+                       rprintf(FINFO, "%s exists\n", safe_fname(fname));
+               return;
+       }
+
+       if (update_only && statret == 0
+           && cmp_modtime(st.st_mtime, file->modtime) > 0) {
+               if (verbose > 1)
+                       rprintf(FINFO, "%s is newer\n", safe_fname(fname));
+               return;
+       }
+
        fnamecmp = fname;
        fnamecmp_type = FNAMECMP_FNAME;
 
@@ -825,8 +831,6 @@ static void recv_generator(char *fname, struct file_list *flist,
                        case 0:
                                best_match = i;
                                match_level = 1;
-                               if (compare_dest)
-                                       break;
                                /* FALL THROUGH */
                        case 1:
                                if (!unchanged_file(fnamecmpbuf, file, &st))
@@ -844,30 +848,32 @@ static void recv_generator(char *fname, struct file_list *flist,
                        break;
                } while (basis_dir[++i] != NULL);
                if (match_level) {
+                       statret = 0;
                        if (i != best_match) {
                                i = best_match;
                                pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
                                         basis_dir[i], fname);
+                               if (link_stat(fnamecmpbuf, &st, 0) < 0) {
+                                       match_level = 0;
+                                       statret = -1;
+                                       stat_errno = errno;
+                               }
                        }
 #ifdef HAVE_LINK
-                       if (link_dest && match_level == 3 && !dry_run) {
-                               if (do_link(fnamecmpbuf, fname) < 0) {
-                                       if (verbose) {
-                                               rsyserr(FINFO, errno,
-                                                       "link %s => %s",
-                                                       full_fname(fnamecmpbuf),
-                                                       safe_fname(fname));
-                                       }
-                                       fnamecmp = fnamecmpbuf;
-                                       fnamecmp_type = i;
+                       if (link_dest && match_level == 3
+                           && do_link(fnamecmpbuf, fname) < 0) {
+                               if (verbose) {
+                                       rsyserr(FINFO, errno, "link %s => %s",
+                                               full_fname(fnamecmpbuf),
+                                               safe_fname(fname));
                                }
-                       } else
+                               match_level = 2;
+                       }
 #endif
-                       {
+                       if (compare_dest || (match_level && match_level < 3)) {
                                fnamecmp = fnamecmpbuf;
                                fnamecmp_type = i;
                        }
-                       statret = 0;
                }
        }
 
@@ -917,33 +923,23 @@ static void recv_generator(char *fname, struct file_list *flist,
                return;
        }
 
-       if (opt_ignore_existing && fnamecmp_type == FNAMECMP_FNAME) {
-               if (verbose > 1)
-                       rprintf(FINFO, "%s exists\n", safe_fname(fname));
-               return;
-       }
-
-       if (update_only && fnamecmp_type == FNAMECMP_FNAME
-           && cmp_modtime(st.st_mtime, file->modtime) > 0) {
-               if (verbose > 1)
-                       rprintf(FINFO, "%s is newer\n", safe_fname(fname));
-               return;
-       }
-
        if (!compare_dest && fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
                ;
        else if (fnamecmp_type == FNAMECMP_FUZZY)
                ;
        else if (unchanged_file(fnamecmp, file, &st)) {
-               if (itemizing) {
-                       itemize(file, statret, &st,
-                               fnamecmp_type == FNAMECMP_FNAME
-                                              ? 0 : SID_NO_DEST_AND_NO_UPDATE,
+               if (fnamecmp_type == FNAMECMP_FNAME) {
+                       if (itemizing)
+                               itemize(file, statret, &st, 0, f_out, ndx);
+                       set_perms(fname, file, &st, maybe_PERMS_REPORT);
+                       return;
+               }
+               /* Only --compare-dest gets here. */
+               if (unchanged_attrs(file, &st)) {
+                       itemize(file, statret, &st, ITEM_NO_DEST_AND_NO_UPDATE,
                                f_out, ndx);
+                       return;
                }
-               if (fnamecmp_type == FNAMECMP_FNAME)
-                       set_perms(fname, file, &st, maybe_PERMS_REPORT);
-               return;
        }
 
 prepare_to_open:
@@ -954,13 +950,8 @@ prepare_to_open:
                statret = 0;
        }
 
-       if (dry_run || read_batch)
+       if (dry_run || read_batch || whole_file)
                goto notify_others;
-       if (whole_file > 0) {
-               if (statret == 0)
-                       statret = 1;
-               goto notify_others;
-       }
 
        if (fuzzy_basis) {
                int j = flist_find(fuzzy_dirlist, file);
@@ -1020,51 +1011,42 @@ prepare_to_open:
 notify_others:
        write_int(f_out, ndx);
        if (itemizing) {
-               int iflags = SID_UPDATING;
+               int iflags = ITEM_UPDATING;
                if (always_checksum)
-                       iflags |= SID_REPORT_CHECKSUM;
+                       iflags |= ITEM_REPORT_CHECKSUM;
                if (fnamecmp_type != FNAMECMP_FNAME)
-                       iflags |= SID_USING_ALT_BASIS;
+                       iflags |= ITEM_USING_ALT_BASIS;
                itemize(file, statret, &st, iflags, f_out, -1);
        }
        if (f_out_name >= 0) {
                write_byte(f_out_name, fnamecmp_type);
                if (fnamecmp_type == FNAMECMP_FUZZY) {
-                       uchar lenbuf[3], *lb = lenbuf;
-                       int len = strlen(fuzzy_file->basename);
-                       if (len > 0x7F) {
-#if MAXPATHLEN > 0x7FFF
-                               *lb++ = len / 0x10000 + 0x80;
-                               *lb++ = len / 0x100;
-#else
-                               *lb++ = len / 0x100 + 0x80;
-#endif
-                       }
-                       *lb = len;
-                       write_buf(f_out_name, (char*)lenbuf, lb - lenbuf + 1);
-                       write_buf(f_out_name, fuzzy_file->basename, len);
+                       write_vstring(f_out_name, fuzzy_file->basename,
+                                     strlen(fuzzy_file->basename));
                }
        }
 
        if (dry_run || read_batch)
                return;
 
-       if (statret == 0) {
-               generate_and_send_sums(fd, st.st_size, f_out, f_copy);
-
-               if (f_copy >= 0) {
-                       close(f_copy);
-                       set_perms(backupptr, back_file, NULL, 0);
-                       if (verbose > 1) {
-                               rprintf(FINFO, "backed up %s to %s\n",
-                                       safe_fname(fname), safe_fname(backupptr));
-                       }
-                       free(back_file);
+       if (statret != 0 || whole_file) {
+               write_sum_head(f_out, NULL);
+               return;
+       }
+
+       generate_and_send_sums(fd, st.st_size, f_out, f_copy);
+
+       if (f_copy >= 0) {
+               close(f_copy);
+               set_perms(backupptr, back_file, NULL, 0);
+               if (verbose > 1) {
+                       rprintf(FINFO, "backed up %s to %s\n",
+                               safe_fname(fname), safe_fname(backupptr));
                }
+               free(back_file);
+       }
 
-               close(fd);
-       } else
-               write_sum_head(f_out, NULL);
+       close(fd);
 }
 
 
@@ -1109,9 +1091,11 @@ void generate_files(int f_out, struct file_list *flist, char *local_name,
        if (delete_before && !local_name && flist->count > 0)
                do_delete_pass(flist, allowed_lull);
 
+       if (whole_file < 0)
+               whole_file = 0;
        if (verbose >= 2) {
                rprintf(FINFO, "delta-transmission %s\n",
-                       whole_file > 0
+                       whole_file
                        ? "disabled for local transfer or --whole-file"
                        : "enabled");
        }