+++ /dev/null
-Added a pipe from the generator to the receiver that communicates
-what basis file we used to generate the file data (if it was not
-the default name). This optimizes away the basis-file search in
-the receiver and makes future options that do more basis-file
-searching more efficient (such as the --fuzzy option and the
-support for multiple --compare-dest options).
-
-You must run "make proto" before compiling.
-
---- orig/generator.c 2004-10-06 00:12:16
-+++ generator.c 2004-11-03 20:12:24
-@@ -254,14 +254,15 @@ static void generate_and_send_sums(int f
- * out. It might be wrong.
- */
- static void recv_generator(char *fname, struct file_struct *file, int i,
-- int f_out)
-+ int f_out, int f_out_name)
- {
-- int fd, f_copy;
-+ int fd = -1, f_copy = -1;
- STRUCT_STAT st, partial_st;
-- struct file_struct *back_file;
-+ struct file_struct *back_file = NULL;
- int statret, stat_errno;
-- char *fnamecmp, *partialptr, *backupptr;
-+ char *fnamecmp, *partialptr, *backupptr = NULL;
- char fnamecmpbuf[MAXPATHLEN];
-+ uchar fnamecmp_type;
-
- if (list_only)
- return;
-@@ -421,6 +422,7 @@ static void recv_generator(char *fname,
- }
-
- fnamecmp = fname;
-+ fnamecmp_type = FNAMECMP_FNAME;
-
- if (statret == -1 && compare_dest != NULL) {
- /* try the file at compare_dest instead */
-@@ -437,10 +439,14 @@ static void recv_generator(char *fname,
- safe_fname(fname));
- }
- fnamecmp = fnamecmpbuf;
-+ fnamecmp_type = FNAMECMP_CMPDEST;
- }
- } else
- #endif
-+ {
- fnamecmp = fnamecmpbuf;
-+ fnamecmp_type = FNAMECMP_CMPDEST;
-+ }
- statret = 0;
- }
- }
-@@ -463,11 +469,9 @@ static void recv_generator(char *fname,
- if (statret == -1) {
- if (preserve_hard_links && hard_link_check(file, HL_SKIP))
- return;
-- if (stat_errno == ENOENT) {
-- write_int(f_out,i);
-- if (!dry_run && !read_batch)
-- write_sum_head(f_out, NULL);
-- } else if (verbose > 1) {
-+ if (stat_errno == ENOENT)
-+ goto notify_others;
-+ if (verbose > 1) {
- rsyserr(FERROR, stat_errno,
- "recv_generator: failed to stat %s",
- full_fname(fname));
-@@ -475,13 +479,13 @@ static void recv_generator(char *fname,
- return;
- }
-
-- if (opt_ignore_existing && fnamecmp == fname) {
-+ if (opt_ignore_existing && fnamecmp_type == FNAMECMP_FNAME) {
- if (verbose > 1)
- rprintf(FINFO, "%s exists\n", safe_fname(fname));
- return;
- }
-
-- if (update_only && fnamecmp == fname
-+ 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));
-@@ -489,26 +493,23 @@ static void recv_generator(char *fname,
- }
-
- if (skip_file(fnamecmp, file, &st)) {
-- if (fnamecmp == fname)
-+ if (fnamecmp_type == FNAMECMP_FNAME)
- set_perms(fname, file, &st, PERMS_REPORT);
- return;
- }
-
- prepare_to_open:
-- if (dry_run || read_batch) {
-- write_int(f_out,i);
-- return;
-- }
--
-- if (whole_file > 0) {
-- write_int(f_out,i);
-- write_sum_head(f_out, NULL);
-- return;
-+ if (dry_run || whole_file > 0) {
-+ statret = -1;
-+ goto notify_others;
- }
-+ if (read_batch)
-+ goto notify_others;
-
- if (partialptr) {
- st = partial_st;
- fnamecmp = partialptr;
-+ fnamecmp_type = FNAMECMP_PARTIAL_DIR;
- }
-
- /* open the file */
-@@ -521,9 +522,8 @@ prepare_to_open:
- /* pretend the file didn't exist */
- if (preserve_hard_links && hard_link_check(file, HL_SKIP))
- return;
-- write_int(f_out,i);
-- write_sum_head(f_out, NULL);
-- return;
-+ statret = -1;
-+ goto notify_others;
- }
-
- if (inplace && make_backups) {
-@@ -550,10 +550,7 @@ prepare_to_open:
- close(fd);
- return;
- }
-- } else {
-- backupptr = NULL;
-- back_file = NULL;
-- f_copy = -1;
-+ fnamecmp_type = FNAMECMP_BACKUP;
- }
-
- if (verbose > 3) {
-@@ -564,22 +561,35 @@ prepare_to_open:
- if (verbose > 2)
- rprintf(FINFO, "generating and sending sums for %d\n", i);
-
-- write_int(f_out,i);
-- 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", fname, backupptr);
-- free(back_file);
-- }
-+notify_others:
-+ write_int(f_out, i);
-+ if (f_out_name >= 0)
-+ write_byte(f_out_name, fnamecmp_type);
-+
-+ 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",
-+ fname, backupptr);
-+ }
-+ free(back_file);
-+ }
-
-- close(fd);
-+ close(fd);
-+ } else
-+ write_sum_head(f_out, NULL);
- }
-
-
--void generate_files(int f_out, struct file_list *flist, char *local_name)
-+void generate_files(int f_out, struct file_list *flist, char *local_name,
-+ int f_out_name)
- {
- int i;
- int phase = 0;
-@@ -620,7 +630,7 @@ void generate_files(int f_out, struct fi
- }
-
- recv_generator(local_name ? local_name : f_name_to(file, fbuf),
-- file, i, f_out);
-+ file, i, f_out, f_out_name);
- }
-
- phase++;
-@@ -637,7 +647,7 @@ void generate_files(int f_out, struct fi
- while ((i = get_redo_num()) != -1) {
- struct file_struct *file = flist->files[i];
- recv_generator(local_name ? local_name : f_name_to(file, fbuf),
-- file, i, f_out);
-+ file, i, f_out, f_out_name);
- }
-
- phase++;
-@@ -656,7 +666,7 @@ void generate_files(int f_out, struct fi
- if (!file->basename || !S_ISDIR(file->mode))
- continue;
- recv_generator(local_name ? local_name : f_name(file),
-- file, i, -1);
-+ file, i, -1, -1);
- }
-
- if (verbose > 2)
---- orig/io.c 2004-08-02 02:44:26
-+++ io.c 2004-11-03 19:49:36
-@@ -857,6 +857,11 @@ static void writefd_unbuffered(int fd,ch
- if (msg_fd_in > maxfd)
- maxfd = msg_fd_in;
- }
-+ if (fd != sock_f_out && iobuf_out_cnt && no_flush == 1) {
-+ FD_SET(sock_f_out, &w_fds);
-+ if (sock_f_out > maxfd)
-+ maxfd = sock_f_out;
-+ }
-
- tv.tv_sec = select_timeout;
- tv.tv_usec = 0;
-@@ -875,8 +880,14 @@ static void writefd_unbuffered(int fd,ch
- if (msg_fd_in >= 0 && FD_ISSET(msg_fd_in, &r_fds))
- read_msg_fd();
-
-- if (!FD_ISSET(fd, &w_fds))
-+ if (!FD_ISSET(fd, &w_fds)) {
-+ if (fd != sock_f_out && iobuf_out_cnt) {
-+ no_flush--;
-+ io_flush(NORMAL_FLUSH);
-+ no_flush++;
-+ }
- continue;
-+ }
-
- n = len - total;
- if (bwlimit && n > bwlimit_writemax)
---- orig/main.c 2004-10-08 20:16:26
-+++ main.c 2004-11-03 16:07:53
-@@ -59,6 +59,7 @@ extern int filesfrom_fd;
- extern pid_t cleanup_child_pid;
- extern char *files_from;
- extern char *remote_filesfrom_file;
-+extern char *compare_dest;
- extern char *rsync_path;
- extern char *shell_cmd;
- extern char *batch_name;
-@@ -461,7 +462,8 @@ static int do_recv(int f_in,int f_out,st
- {
- int pid;
- int status = 0;
-- int error_pipe[2];
-+ int error_pipe[2], name_pipe[2];
-+ BOOL need_name_pipe = compare_dest && !dry_run;
-
- /* The receiving side mustn't obey this, or an existing symlink that
- * points to an identical file won't be replaced by the referent. */
-@@ -476,7 +478,8 @@ static int do_recv(int f_in,int f_out,st
- delete_files(flist);
- }
-
-- if (fd_pair(error_pipe) < 0) {
-+ if (fd_pair(error_pipe) < 0
-+ || (need_name_pipe && fd_pair(name_pipe) < 0)) {
- rsyserr(FERROR, errno, "pipe failed in do_recv");
- exit_cleanup(RERR_SOCKETIO);
- }
-@@ -485,6 +488,11 @@ static int do_recv(int f_in,int f_out,st
-
- if ((pid = do_fork()) == 0) {
- close(error_pipe[0]);
-+ if (need_name_pipe) {
-+ close(name_pipe[1]);
-+ set_blocking(name_pipe[0]);
-+ } else
-+ name_pipe[0] = -1;
- if (f_in != f_out)
- close(f_out);
-
-@@ -494,7 +502,7 @@ static int do_recv(int f_in,int f_out,st
- /* set place to send errors */
- set_msg_fd_out(error_pipe[1]);
-
-- recv_files(f_in,flist,local_name);
-+ recv_files(f_in, flist, local_name, name_pipe[0]);
- io_flush(FULL_FLUSH);
- report(f_in);
-
-@@ -513,6 +521,11 @@ static int do_recv(int f_in,int f_out,st
- stop_write_batch();
-
- close(error_pipe[1]);
-+ if (need_name_pipe) {
-+ close(name_pipe[0]);
-+ set_nonblocking(name_pipe[1]);
-+ } else
-+ name_pipe[1] = -1;
- if (f_in != f_out)
- close(f_in);
-
-@@ -520,7 +533,7 @@ static int do_recv(int f_in,int f_out,st
-
- set_msg_fd_in(error_pipe[0]);
-
-- generate_files(f_out, flist, local_name);
-+ generate_files(f_out, flist, local_name, name_pipe[1]);
-
- get_redo_num(); /* Read final MSG_DONE and any prior messages. */
- report(-1);
---- orig/receiver.c 2004-11-03 11:56:04
-+++ receiver.c 2004-11-03 20:16:38
-@@ -30,6 +30,7 @@ extern int dry_run;
- extern int read_batch;
- extern int batch_gen_fd;
- extern int am_server;
-+extern int protocol_version;
- extern int relative_paths;
- extern int keep_dirlinks;
- extern int preserve_hard_links;
-@@ -329,7 +330,8 @@ static void discard_receive_data(int f_i
- * 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, struct file_list *flist, char *local_name,
-+ int f_in_name)
- {
- int next_gen_i = -1;
- int fd1,fd2;
-@@ -358,8 +360,13 @@ int recv_files(int f_in, struct file_lis
- i = read_int(f_in);
- if (i == -1) {
- if (read_batch) {
-- if (next_gen_i != flist->count)
-- while (read_int(batch_gen_fd) != -1) {}
-+ if (next_gen_i != flist->count) {
-+ do {
-+ if (f_in_name >= 0
-+ && next_gen_i >= 0)
-+ read_byte(f_in_name);
-+ } while (read_int(batch_gen_fd) != -1);
-+ }
- next_gen_i = -1;
- }
-
-@@ -407,6 +414,8 @@ int recv_files(int f_in, struct file_lis
-
- if (read_batch) {
- while (i > next_gen_i) {
-+ if (f_in_name >= 0 && next_gen_i >= 0)
-+ read_byte(f_in_name);
- next_gen_i = read_int(batch_gen_fd);
- if (next_gen_i == -1)
- next_gen_i = flist->count;
-@@ -417,6 +426,7 @@ int recv_files(int f_in, struct file_lis
- discard_receive_data(f_in, file->length);
- continue;
- }
-+ next_gen_i = -1;
- }
-
- if (server_exclude_list.head
-@@ -426,35 +436,32 @@ int recv_files(int f_in, struct file_lis
- exit_cleanup(RERR_PROTOCOL);
- }
-
-- if (partial_dir) {
-- if ((partialptr = partial_dir_fname(fname)) != NULL)
-- fnamecmp = partialptr;
-- else
-+ partialptr = partial_dir ? partial_dir_fname(fname) : fname;
-+
-+ if (f_in_name >= 0) {
-+ switch (read_byte(f_in_name)) {
-+ case FNAMECMP_FNAME:
- fnamecmp = fname;
-+ break;
-+ case FNAMECMP_PARTIAL_DIR:
-+ fnamecmp = partialptr ? partialptr : fname;
-+ break;
-+ case FNAMECMP_BACKUP:
-+ fnamecmp = get_backup_name(fname);
-+ break;
-+ case FNAMECMP_CMPDEST:
-+ default:
-+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
-+ compare_dest, fname);
-+ fnamecmp = fnamecmpbuf;
-+ break;
-+ }
- } else
-- fnamecmp = partialptr = fname;
--
-- if (inplace && make_backups) {
-- if (!(fnamecmp = get_backup_name(fname)))
-- fnamecmp = partialptr;
-- }
-+ fnamecmp = fname;
-
- /* open the file */
- fd1 = do_open(fnamecmp, O_RDONLY, 0);
-
-- if (fd1 == -1 && fnamecmp != fname) {
-- fnamecmp = fname;
-- fd1 = do_open(fnamecmp, O_RDONLY, 0);
-- }
--
-- if (fd1 == -1 && compare_dest != NULL) {
-- /* try the file at compare_dest instead */
-- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
-- compare_dest, fname);
-- fnamecmp = fnamecmpbuf;
-- fd1 = do_open(fnamecmp, O_RDONLY, 0);
-- }
--
- if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
- rsyserr(FERROR, errno, "fstat %s failed",
- full_fname(fnamecmp));
---- orig/rsync.h 2004-10-09 03:21:56
-+++ rsync.h 2004-11-03 20:11:34
-@@ -119,6 +119,11 @@
- #define PDIR_CREATE 1
- #define PDIR_DELETE 0
-
-+#define FNAMECMP_CMPDEST 0x00
-+#define FNAMECMP_FNAME 0x80
-+#define FNAMECMP_PARTIAL_DIR 0x81
-+#define FNAMECMP_BACKUP 0x82
-+
-
- /* Log-message categories. FLOG is only used on the daemon side to
- * output messages to the log file. */