summaryrefslogtreecommitdiff
path: root/receiver.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2006-12-28 07:54:31 +0000
committerWayne Davison <wayned@samba.org>2006-12-28 07:54:31 +0000
commitf3d6d4800b35fd65d2395defdb57fed16cea3e85 (patch)
tree4e945a8fc85e366f6c4f9a070989722121cb79dd /receiver.c
parent8ef246e0b5a3aa9944dab4275353c50aab9f955c (diff)
downloadrsync-f3d6d4800b35fd65d2395defdb57fed16cea3e85.tar.gz
rsync-f3d6d4800b35fd65d2395defdb57fed16cea3e85.tar.bz2
rsync-f3d6d4800b35fd65d2395defdb57fed16cea3e85.zip
Handle the new incremental-recursion mode.
Diffstat (limited to 'receiver.c')
-rw-r--r--receiver.c98
1 files changed, 59 insertions, 39 deletions
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");