Fixed a failed hunk.
[rsync/rsync-patches.git] / trust-append.diff
1 This patch adds a --trust-append option that, in combination with --append,
2 makes rsync exclude the portion of a transferred file that was already on the
3 receiver from the post-transfer checksum.  In my limited testing, it seems to
4 work.
5
6 -- Matt McCutchen <hashproduct@gmail.com>
7
8 --- old/match.c
9 +++ new/match.c
10 @@ -25,6 +25,7 @@ extern int verbose;
11  extern int do_progress;
12  extern int checksum_seed;
13  extern int append_mode;
14 +extern int trust_append;
15  
16  int updating_basis_file;
17  
18 @@ -315,21 +316,23 @@ void match_sums(int f, struct sum_struct
19         sum_init(checksum_seed);
20  
21         if (append_mode > 0) {
22 -               OFF_T j = 0;
23 -               for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
24 -                       if (buf && do_progress)
25 -                               show_progress(last_match, buf->file_size);
26 -                       sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
27 -                                  CHUNK_SIZE);
28 -                       last_match = j;
29 -               }
30 -               if (last_match < s->flength) {
31 -                       int32 n = (int32)(s->flength - last_match);
32 -                       if (buf && do_progress)
33 -                               show_progress(last_match, buf->file_size);
34 -                       sum_update(map_ptr(buf, last_match, n), n);
35 -                       last_match = s->flength;
36 +               if (!trust_append) {
37 +                       OFF_T j = 0;
38 +                       for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
39 +                               if (buf && do_progress)
40 +                                       show_progress(last_match, buf->file_size);
41 +                               sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
42 +                                          CHUNK_SIZE);
43 +                               last_match = j;
44 +                       }
45 +                       if (last_match < s->flength) {
46 +                               int32 n = (int32)(s->flength - last_match);
47 +                               if (buf && do_progress)
48 +                                       show_progress(last_match, buf->file_size);
49 +                               sum_update(map_ptr(buf, last_match, n), n);
50 +                       }
51                 }
52 +               last_match = s->flength;
53                 s->count = 0;
54         }
55  
56 --- old/options.c
57 +++ new/options.c
58 @@ -41,6 +41,7 @@ int make_backups = 0;
59  int whole_file = -1;
60  
61  int append_mode = 0;
62 +int trust_append = 0;
63  int keep_dirlinks = 0;
64  int copy_dirlinks = 0;
65  int copy_links = 0;
66 @@ -313,6 +314,7 @@ void usage(enum logcode F)
67    rprintf(F," -u, --update                skip files that are newer on the receiver\n");
68    rprintf(F,"     --inplace               update destination files in-place (SEE MAN PAGE)\n");
69    rprintf(F,"     --append                append data onto shorter files\n");
70 +  rprintf(F,"     --trust-append          ... and don't checksum portion already on dest\n");
71    rprintf(F," -d, --dirs                  transfer directories without recursing\n");
72    rprintf(F," -l, --links                 copy symlinks as symlinks\n");
73    rprintf(F," -L, --copy-links            transform symlink into referent file/dir\n");
74 @@ -517,6 +519,7 @@ static struct poptOption long_options[] 
75    {"sparse",          'S', POPT_ARG_NONE,   &sparse_files, 0, 0, 0 },
76    {"inplace",          0,  POPT_ARG_NONE,   &inplace, 0, 0, 0 },
77    {"append",           0,  POPT_ARG_VAL,    &append_mode, 1, 0, 0 },
78 +  {"trust-append",     0,  POPT_ARG_NONE,   &trust_append, 0, 0, 0 },
79    {"del",              0,  POPT_ARG_NONE,   &delete_during, 0, 0, 0 },
80    {"delete",           0,  POPT_ARG_NONE,   &delete_mode, 0, 0, 0 },
81    {"delete-before",    0,  POPT_ARG_NONE,   &delete_before, 0, 0, 0 },
82 @@ -1898,9 +1901,11 @@ void server_options(char **args,int *arg
83                 }
84         }
85  
86 -       if (append_mode)
87 +       if (append_mode) {
88                 args[ac++] = "--append";
89 -       else if (inplace)
90 +               if (trust_append)
91 +                       args[ac++] = "--trust-append";
92 +       } else if (inplace)
93                 args[ac++] = "--inplace";
94  
95         if (files_from && (!am_sender || filesfrom_host)) {
96 --- old/receiver.c
97 +++ new/receiver.c
98 @@ -44,6 +44,7 @@ extern int make_backups;
99  extern int cleanup_got_literal;
100  extern int remove_source_files;
101  extern int append_mode;
102 +extern int trust_append;
103  extern int sparse_files;
104  extern int keep_partial;
105  extern int checksum_seed;
106 @@ -157,20 +158,22 @@ static int receive_data(int f_in, char *
107                 sum.flength = (OFF_T)sum.count * sum.blength;
108                 if (sum.remainder)
109                         sum.flength -= sum.blength - sum.remainder;
110 -               for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) {
111 -                       if (do_progress)
112 -                               show_progress(offset, total_size);
113 -                       sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE),
114 -                                  CHUNK_SIZE);
115 -                       offset = j;
116 -               }
117 -               if (offset < sum.flength) {
118 -                       int32 len = (int32)(sum.flength - offset);
119 -                       if (do_progress)
120 -                               show_progress(offset, total_size);
121 -                       sum_update(map_ptr(mapbuf, offset, len), len);
122 -                       offset = sum.flength;
123 +               if (!trust_append) {
124 +                       for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) {
125 +                               if (do_progress)
126 +                                       show_progress(offset, total_size);
127 +                               sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE),
128 +                                          CHUNK_SIZE);
129 +                               offset = j;
130 +                       }
131 +                       if (offset < sum.flength) {
132 +                               int32 len = (int32)(sum.flength - offset);
133 +                               if (do_progress)
134 +                                       show_progress(offset, total_size);
135 +                               sum_update(map_ptr(mapbuf, offset, len), len);
136 +                       }
137                 }
138 +               offset = sum.flength;
139                 if (fd != -1 && (j = do_lseek(fd, offset, SEEK_SET)) != offset) {
140                         rsyserr(FERROR, errno, "lseek of %s returned %.0f, not %.0f",
141                                 full_fname(fname), (double)j, (double)offset);
142 --- old/rsync.yo
143 +++ new/rsync.yo
144 @@ -318,6 +318,7 @@ to the detailed description below for a 
145   -u, --update                skip files that are newer on the receiver
146       --inplace               update destination files in-place
147       --append                append data onto shorter files
148 +     --trust-append          ... and don't checksum portion already on dest
149   -d, --dirs                  transfer directories without recursing
150   -l, --links                 copy symlinks as symlinks
151   -L, --copy-links            transform symlink into referent file/dir
152 @@ -709,6 +710,12 @@ Implies bf(--inplace), but does not conf
153  bf(--sparse) option will be auto-disabled if a resend of the already-existing
154  data is required).
155  
156 +dit(bf(--trust-append)) In combination with bf(--append), this option excludes
157 +the portion of a transferred file that was already on the receiver from the
158 +post-transfer checksum.  You can use this option to improve performance if you
159 +are certain that the receiver's file is identical to the start of the sender's
160 +file.
161 +
162  dit(bf(-d, --dirs)) Tell the sending side to include any directories that
163  are encountered.  Unlike bf(--recursive), a directory's contents are not copied
164  unless the directory name specified is "." or ends with a trailing slash