X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/8ef246e0b5a3aa9944dab4275353c50aab9f955c..f3d6d4800b35fd65d2395defdb57fed16cea3e85:/receiver.c diff --git a/receiver.c b/receiver.c index 7bf14c7d..26ed3245 100644 --- a/receiver.c +++ b/receiver.c @@ -26,6 +26,7 @@ extern int verbose; extern int do_xfers; extern int am_server; extern int do_progress; +extern int incremental; extern int log_before_transfer; extern int stdout_format_has_i; extern int logfile_format_has_i; @@ -52,7 +53,7 @@ extern char *stdout_format; extern char *tmpdir; extern char *partial_dir; extern char *basis_dir[]; -extern struct file_list *the_file_list; +extern struct file_list *cur_flist, *first_flist; extern struct filter_list_struct server_filter_list; static struct bitbag *delayed_bits = NULL; @@ -60,7 +61,6 @@ static int phase = 0; /* We're either updating the basis file or an identical copy: */ static int updating_basis; - /* * get_tmpname() - create a tmp filename for a given filename * @@ -151,7 +151,7 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r, sum_init(checksum_seed); - if (append_mode) { + if (append_mode > 0) { OFF_T j; sum.flength = (OFF_T)sum.count * sum.blength; if (sum.remainder) @@ -277,16 +277,16 @@ static void discard_receive_data(int f_in, OFF_T length) receive_data(f_in, NULL, -1, 0, NULL, -1, length); } -static void handle_delayed_updates(struct file_list *flist, char *local_name) +static void handle_delayed_updates(char *local_name) { char *fname, *partialptr; int ndx; for (ndx = -1; (ndx = bitbag_next_bit(delayed_bits, ndx)) >= 0; ) { - struct file_struct *file = flist->files[ndx]; + struct file_struct *file = cur_flist->files[ndx]; fname = local_name ? local_name : f_name(file, NULL); if ((partialptr = partial_dir_fname(fname)) != NULL) { - if (make_backups && !make_backup(fname)) + if (make_backups > 0 && !make_backup(fname)) continue; if (verbose > 2) { rprintf(FINFO, "renaming %s to %s\n", @@ -308,28 +308,31 @@ static void handle_delayed_updates(struct file_list *flist, char *local_name) } } -static int get_next_gen_ndx(int batch_gen_fd, int next_gen_ndx, int desired_ndx) +static int get_next_gen_ndx(int fd, int next_gen_ndx, int desired_ndx) { while (next_gen_ndx < desired_ndx) { if (next_gen_ndx >= 0) { rprintf(FINFO, "(No batched update for%s \"%s\")\n", phase ? " resend of" : "", - f_name(the_file_list->files[next_gen_ndx], NULL)); + f_name(cur_flist->files[next_gen_ndx], NULL)); + } + next_gen_ndx = read_int(fd); + if (next_gen_ndx == -1) { + if (incremental) + next_gen_ndx = first_flist->prev->count + first_flist->prev->ndx_start; + else + next_gen_ndx = cur_flist->count; } - next_gen_ndx = read_int(batch_gen_fd); - if (next_gen_ndx == -1) - next_gen_ndx = the_file_list->count; } return next_gen_ndx; } - /** * main routine for receiver process. * * Receiver process runs on the same host as the generator process. */ -int recv_files(int f_in, struct file_list *flist, char *local_name) +int recv_files(int f_in, char *local_name) { int next_gen_ndx = -1; int fd1,fd2; @@ -343,53 +346,49 @@ int recv_files(int f_in, struct file_list *flist, char *local_name) uchar fnamecmp_type; struct file_struct *file; struct stats initial_stats; - int save_make_backups = make_backups; int itemizing = am_server ? logfile_format_has_i : stdout_format_has_i; enum logcode log_code = log_before_transfer ? FLOG : FINFO; int max_phase = protocol_version >= 29 ? 2 : 1; int ndx, recv_ok; if (verbose > 2) - rprintf(FINFO, "recv_files(%d) starting\n", flist->count); + rprintf(FINFO, "recv_files(%d) starting\n", cur_flist->count); if (delay_updates) - delayed_bits = bitbag_create(flist->count); + delayed_bits = bitbag_create(cur_flist->count + 1); updating_basis = inplace; while (1) { cleanup_disable(); - ndx = read_int(f_in); + /* This call also sets cur_flist. */ + ndx = read_ndx_and_attrs(f_in, -1, &iflags, + &fnamecmp_type, xname, &xlen); if (ndx == NDX_DONE) { - if (read_batch) { - get_next_gen_ndx(batch_gen_fd, next_gen_ndx, - flist->count); + if (incremental && first_flist) { + flist_free(first_flist); + if (first_flist) + continue; + } + if (read_batch && cur_flist) { + int high = incremental + ? first_flist->prev->count + first_flist->prev->ndx_start + : cur_flist->count; + get_next_gen_ndx(batch_gen_fd, next_gen_ndx, high); next_gen_ndx = -1; } if (++phase > max_phase) break; - csum_length = SUM_LENGTH; if (verbose > 2) rprintf(FINFO, "recv_files phase=%d\n", phase); if (phase == 2 && delay_updates) - handle_delayed_updates(flist, local_name); + handle_delayed_updates(local_name); send_msg(MSG_DONE, "", 0); - if (keep_partial && !partial_dir) - make_backups = 0; /* prevents double backup */ - if (append_mode) { - append_mode = 0; - sparse_files = 0; - } continue; } - iflags = read_item_attrs(f_in, -1, ndx, &fnamecmp_type, - xname, &xlen); - if (iflags == ITEM_IS_NEW) /* no-op packet */ - continue; - - file = flist->files[ndx]; + file = cur_flist->files[ndx - cur_flist->ndx_start]; fname = local_name ? local_name : f_name(file, fbuf); if (verbose > 2) @@ -406,6 +405,24 @@ int recv_files(int f_in, struct file_list *flist, char *local_name) exit_cleanup(RERR_PROTOCOL); } + if (file->flags & FLAG_FILE_SENT) { + if (csum_length == SHORT_SUM_LENGTH) { + if (keep_partial && !partial_dir) + make_backups = -make_backups; /* prevents double backup */ + append_mode = -append_mode; + sparse_files = -sparse_files; + csum_length = SUM_LENGTH; + } + } else { + if (csum_length != SHORT_SUM_LENGTH) { + if (keep_partial && !partial_dir) + make_backups = -make_backups; + append_mode = -append_mode; + sparse_files = -sparse_files; + csum_length = SHORT_SUM_LENGTH; + } + } + stats.current_file_index = ndx; stats.num_transferred_files++; stats.total_transferred_size += F_LENGTH(file); @@ -483,7 +500,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name) } else { /* Reminder: --inplace && --partial-dir are never * enabled at the same time. */ - if (inplace && make_backups) { + if (inplace && make_backups > 0) { if (!(fnamecmp = get_backup_name(fname))) fnamecmp = fname; } else if (partial_dir && partialptr) @@ -646,7 +663,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name) cleanup_disable(); if (recv_ok > 0) { - if (remove_source_files + if (remove_source_files || incremental || (preserve_hard_links && F_IS_HLINKED(file))) send_msg_int(MSG_SUCCESS, ndx); } else if (!recv_ok) { @@ -670,14 +687,17 @@ int recv_files(int f_in, struct file_list *flist, char *local_name) "%s: %s failed verification -- update %s%s.\n", errstr, fname, keptstr, redostr); } - if (!phase) + if (!phase || incremental) { send_msg_int(MSG_REDO, ndx); + file->flags |= FLAG_FILE_SENT; + } } } - make_backups = save_make_backups; + if (make_backups < 0) + make_backups = -make_backups; if (phase == 2 && delay_updates) /* for protocol_version < 29 */ - handle_delayed_updates(flist, local_name); + handle_delayed_updates(local_name); if (verbose > 2) rprintf(FINFO,"recv_files finished\n");