| 1 | --- orig/batch.c 2004-05-15 20:10:13 |
| 2 | +++ batch.c 2004-07-03 20:20:27 |
| 3 | @@ -172,6 +172,7 @@ void close_batch_csums_file(void) |
| 4 | |
| 5 | /** |
| 6 | * Write csum info to batch file |
| 7 | + * If flist_entry < 0, just open the file |
| 8 | * |
| 9 | * @todo This will break if s->count is ever larger than maxint. The |
| 10 | * batch code should probably be changed to consistently use the |
| 11 | @@ -198,6 +199,9 @@ void write_batch_csum_info(int *flist_en |
| 12 | } |
| 13 | } |
| 14 | |
| 15 | + if (*flist_entry < 0) |
| 16 | + return; |
| 17 | + |
| 18 | write_batch_csums_file(flist_entry, sizeof (int)); |
| 19 | int_count = s ? (int) s->count : 0; |
| 20 | write_batch_csums_file(&int_count, sizeof int_count); |
| 21 | @@ -285,6 +289,9 @@ void write_batch_delta_file(char *buff, |
| 22 | } |
| 23 | } |
| 24 | |
| 25 | + if (!buff) |
| 26 | + return; |
| 27 | + |
| 28 | if (write(f_delta, buff, bytes_to_write) < 0) { |
| 29 | rsyserr(FERROR, errno, "Batch file %s write error", filename); |
| 30 | close(f_delta); |
| 31 | --- orig/flist.c 2004-06-18 16:23:07 |
| 32 | +++ flist.c 2004-07-03 20:20:27 |
| 33 | @@ -950,7 +950,7 @@ void send_file_name(int f, struct file_l |
| 34 | |
| 35 | flist_expand(flist); |
| 36 | |
| 37 | - if (write_batch) |
| 38 | + if (write_batch) /* TODO: why? remove and test. */ |
| 39 | file->flags |= FLAG_TOP_DIR; |
| 40 | |
| 41 | if (file->basename[0]) { |
| 42 | @@ -1308,6 +1308,18 @@ struct file_list *recv_file_list(int f) |
| 43 | else |
| 44 | io_error |= read_int(f); |
| 45 | } |
| 46 | + if (write_batch) { |
| 47 | + /* TODO: remove this FLAG_TOP_DIR stuff and test |
| 48 | + * CAS: I'm not sure what the FLAG_TOP_DIR does, |
| 49 | + * but we set it here, just so it matches what |
| 50 | + * happens for write_batch on the sender paths. |
| 51 | + */ |
| 52 | + int i; |
| 53 | + for (i = 0; i < flist->count; i++) |
| 54 | + flist->files[i]->flags |= FLAG_TOP_DIR; |
| 55 | + |
| 56 | + write_batch_flist_info(flist->count, flist->files); |
| 57 | + } |
| 58 | } |
| 59 | |
| 60 | if (verbose > 3) |
| 61 | --- orig/generator.c 2004-06-30 07:24:45 |
| 62 | +++ generator.c 2004-07-03 20:20:27 |
| 63 | @@ -48,6 +48,7 @@ extern int whole_file; |
| 64 | extern int local_server; |
| 65 | extern int read_batch; |
| 66 | extern int write_batch; |
| 67 | +extern int read_batch; |
| 68 | extern int list_only; |
| 69 | extern int only_existing; |
| 70 | extern int orig_umask; |
| 71 | @@ -224,16 +225,27 @@ static BOOL disable_deltas_p(void) |
| 72 | * Generate and send a stream of signatures/checksums that describe a buffer |
| 73 | * |
| 74 | * Generate approximately one checksum every block_len bytes. |
| 75 | + * |
| 76 | + * The flist_idx arg is only for the purpose of being able to call |
| 77 | + * write_batch_csum_info(). Another (better?) way would be to instead |
| 78 | + * return a pointer to a sum_struct, and then call write_batch_csum_info() |
| 79 | + * outside. |
| 80 | */ |
| 81 | -static void generate_and_send_sums(struct map_struct *buf, size_t len, int f_out) |
| 82 | +static void generate_and_send_sums(struct map_struct *buf, size_t len, int f_out, |
| 83 | + int flist_idx) |
| 84 | { |
| 85 | - size_t i; |
| 86 | + size_t i, j; |
| 87 | struct sum_struct sum; |
| 88 | OFF_T offset = 0; |
| 89 | |
| 90 | sum_sizes_sqroot(&sum, len); |
| 91 | |
| 92 | write_sum_head(f_out, &sum); |
| 93 | + if (write_batch) { /* save all the sums to write out */ |
| 94 | + sum.sums = new_array(struct sum_buf, sum.count); |
| 95 | + if (!sum.sums) |
| 96 | + out_of_memory("generate_and_send_sums"); |
| 97 | + } |
| 98 | |
| 99 | for (i = 0; i < sum.count; i++) { |
| 100 | unsigned int n1 = MIN(len, sum.blength); |
| 101 | @@ -253,10 +265,30 @@ static void generate_and_send_sums(struc |
| 102 | write_buf(f_out, sum2, sum.s2length); |
| 103 | len -= n1; |
| 104 | offset += n1; |
| 105 | + |
| 106 | + if (write_batch) { /* we're receiver */ |
| 107 | + /* we only have to save the sums |
| 108 | + * if we want to write them out */ |
| 109 | + sum.sums[i].sum1 = sum1; |
| 110 | + for (j = 0; j < SUM_LENGTH ; j++) |
| 111 | + sum.sums[i].sum2[j] = sum2[j]; |
| 112 | + } |
| 113 | + } |
| 114 | + if (write_batch) { |
| 115 | + write_batch_csum_info(&flist_idx, &sum); |
| 116 | + free(sum.sums); |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | |
| 121 | +void write_null_sum(int f_out, int i) |
| 122 | +{ |
| 123 | + write_int(f_out, i); |
| 124 | + if (!dry_run) |
| 125 | + write_sum_head(f_out, NULL); |
| 126 | + if (write_batch) |
| 127 | + write_batch_csum_info(&i, NULL); |
| 128 | +} |
| 129 | |
| 130 | /* |
| 131 | * Acts on file number @p i from @p flist, whose name is @p fname. |
| 132 | @@ -452,9 +484,7 @@ static void recv_generator(char *fname, |
| 133 | if (preserve_hard_links && hard_link_check(file, HL_SKIP)) |
| 134 | return; |
| 135 | if (errno == ENOENT) { |
| 136 | - write_int(f_out,i); |
| 137 | - if (!dry_run) |
| 138 | - write_sum_head(f_out, NULL); |
| 139 | + write_null_sum(f_out, i); |
| 140 | } else if (verbose > 1) { |
| 141 | rsyserr(FERROR, errno, |
| 142 | "recv_generator: failed to open %s", |
| 143 | @@ -471,9 +501,7 @@ static void recv_generator(char *fname, |
| 144 | /* now pretend the file didn't exist */ |
| 145 | if (preserve_hard_links && hard_link_check(file, HL_SKIP)) |
| 146 | return; |
| 147 | - write_int(f_out,i); |
| 148 | - if (!dry_run) |
| 149 | - write_sum_head(f_out, NULL); |
| 150 | + write_null_sum(f_out, i); |
| 151 | return; |
| 152 | } |
| 153 | |
| 154 | @@ -502,8 +530,7 @@ static void recv_generator(char *fname, |
| 155 | } |
| 156 | |
| 157 | if (disable_deltas_p()) { |
| 158 | - write_int(f_out,i); |
| 159 | - write_sum_head(f_out, NULL); |
| 160 | + write_null_sum(f_out, i); |
| 161 | return; |
| 162 | } |
| 163 | |
| 164 | @@ -516,8 +543,7 @@ static void recv_generator(char *fname, |
| 165 | /* pretend the file didn't exist */ |
| 166 | if (preserve_hard_links && hard_link_check(file, HL_SKIP)) |
| 167 | return; |
| 168 | - write_int(f_out,i); |
| 169 | - write_sum_head(f_out, NULL); |
| 170 | + write_null_sum(f_out, i); |
| 171 | return; |
| 172 | } |
| 173 | |
| 174 | @@ -535,7 +561,7 @@ static void recv_generator(char *fname, |
| 175 | rprintf(FINFO, "generating and sending sums for %d\n", i); |
| 176 | |
| 177 | write_int(f_out,i); |
| 178 | - generate_and_send_sums(mapbuf, st.st_size, f_out); |
| 179 | + generate_and_send_sums(mapbuf, st.st_size, f_out, i); |
| 180 | |
| 181 | close(fd); |
| 182 | if (mapbuf) |
| 183 | --- orig/main.c 2004-06-30 07:24:30 |
| 184 | +++ main.c 2004-07-03 20:20:27 |
| 185 | @@ -1039,6 +1039,10 @@ int main(int argc,char *argv[]) |
| 186 | |
| 187 | if (write_batch && !am_server) { |
| 188 | write_batch_argvs_file(orig_argc, orig_argv); |
| 189 | + /* initialize static fds */ |
| 190 | + ret = -1; |
| 191 | + write_batch_csum_info(&ret, NULL); |
| 192 | + write_batch_delta_file(NULL, 0); |
| 193 | } |
| 194 | |
| 195 | if (am_daemon && !am_server) |
| 196 | --- orig/options.c 2004-06-20 19:30:00 |
| 197 | +++ options.c 2004-07-03 20:20:27 |
| 198 | @@ -643,6 +643,15 @@ int parse_arguments(int *argc, const cha |
| 199 | "write-batch and read-batch can not be used together\n"); |
| 200 | exit_cleanup(RERR_SYNTAX); |
| 201 | } |
| 202 | + if ((write_batch || read_batch) && am_server) { |
| 203 | + rprintf(FERROR, |
| 204 | + "batch-mode is incompatible with server mode\n"); |
| 205 | + write_batch = 0; |
| 206 | + read_batch = 0; |
| 207 | + /* We don't actually exit_cleanup(), so that we can still |
| 208 | + * service older version clients that send batch args to |
| 209 | + * the server. */ |
| 210 | + } |
| 211 | if (batch_prefix && strlen(batch_prefix) > MAX_BATCH_PREFIX_LEN) { |
| 212 | rprintf(FERROR, |
| 213 | "the batch-file prefix must be %d characters or less.\n", |
| 214 | @@ -884,13 +893,6 @@ void server_options(char **args,int *arg |
| 215 | args[ac++] = arg; |
| 216 | } |
| 217 | |
| 218 | - if (batch_prefix) { |
| 219 | - char *r_or_w = write_batch ? "write" : "read"; |
| 220 | - if (asprintf(&arg, "--%s-batch=%s", r_or_w, batch_prefix) < 0) |
| 221 | - goto oom; |
| 222 | - args[ac++] = arg; |
| 223 | - } |
| 224 | - |
| 225 | if (io_timeout) { |
| 226 | if (asprintf(&arg, "--timeout=%d", io_timeout) < 0) |
| 227 | goto oom; |
| 228 | --- orig/pipe.c 2004-06-18 16:00:09 |
| 229 | +++ pipe.c 2004-07-03 20:20:27 |
| 230 | @@ -26,6 +26,7 @@ extern int am_server; |
| 231 | extern int blocking_io; |
| 232 | extern int orig_umask; |
| 233 | extern int read_batch; |
| 234 | +extern int write_batch; |
| 235 | extern int filesfrom_fd; |
| 236 | |
| 237 | /** |
| 238 | @@ -117,6 +118,13 @@ pid_t local_child(int argc, char **argv, |
| 239 | am_sender = read_batch ? 0 : !am_sender; |
| 240 | am_server = 1; |
| 241 | |
| 242 | + /* There is write_batch code on both the receiver and |
| 243 | + * sender sides. In local_child, both are local processes, |
| 244 | + * so we must make sure that only one actually writes. It |
| 245 | + * shouldn't matter which one -- here we prevent the server |
| 246 | + * from writing. */ |
| 247 | + write_batch = 0; |
| 248 | + |
| 249 | if (!am_sender) |
| 250 | filesfrom_fd = -1; |
| 251 | |
| 252 | --- orig/receiver.c 2004-07-02 18:23:01 |
| 253 | +++ receiver.c 2004-07-03 20:20:27 |
| 254 | @@ -46,6 +46,7 @@ extern int cleanup_got_literal; |
| 255 | extern int module_id; |
| 256 | extern int ignore_errors; |
| 257 | extern int orig_umask; |
| 258 | +extern int write_batch; |
| 259 | extern int keep_partial; |
| 260 | extern int checksum_seed; |
| 261 | |
| 262 | @@ -277,6 +278,8 @@ static int receive_data(int f_in,struct |
| 263 | sum_end(file_sum1); |
| 264 | |
| 265 | read_buf(f_in,file_sum2,MD4_SUM_LENGTH); |
| 266 | + if (write_batch) |
| 267 | + write_batch_delta_file(file_sum2, MD4_SUM_LENGTH); |
| 268 | if (verbose > 2) |
| 269 | rprintf(FINFO,"got file_sum\n"); |
| 270 | if (fd != -1 && memcmp(file_sum1, file_sum2, MD4_SUM_LENGTH) != 0) |
| 271 | @@ -329,6 +332,9 @@ int recv_files(int f_in,struct file_list |
| 272 | continue; |
| 273 | } |
| 274 | |
| 275 | + if (write_batch) |
| 276 | + write_batch_delta_file((char *) &i, sizeof i); |
| 277 | + |
| 278 | if (i < 0 || i >= flist->count) { |
| 279 | rprintf(FERROR,"Invalid file index %d in recv_files (count=%d)\n", |
| 280 | i, flist->count); |
| 281 | --- orig/token.c 2004-06-18 16:20:45 |
| 282 | +++ token.c 2004-07-03 20:20:27 |
| 283 | @@ -80,6 +80,8 @@ static int simple_recv_token(int f,char |
| 284 | |
| 285 | if (residue == 0) { |
| 286 | int i = read_int(f); |
| 287 | + if (write_batch) |
| 288 | + write_batch_delta_file((char *) &i, sizeof(int)); |
| 289 | if (i <= 0) |
| 290 | return i; |
| 291 | residue = i; |
| 292 | @@ -89,6 +91,8 @@ static int simple_recv_token(int f,char |
| 293 | n = MIN(CHUNK_SIZE,residue); |
| 294 | residue -= n; |
| 295 | read_buf(f,buf,n); |
| 296 | + if (write_batch) |
| 297 | + write_batch_delta_file(buf, n); |
| 298 | return n; |
| 299 | } |
| 300 | |