merge rsync+ into rsync (was Re: rsync-2.4.7 NEWS file)

Martin Pool mbp at valinux.com
Mon Aug 6 18:34:05 EST 2001


On  6 Aug 2001, Martin Pool <mbp at valinux.com> wrote:
> > Just curious: what about the rsync+ patch?
> 
> Thanks for the reminder.
> 
> I've just committed Jos's rsync+ patch onto the
> "branch_mbp_rsyncplus_merge" branch.  If it works OK and nobody
> screams I will move it across onto the main tree tomorrow or
> Wednesday.

OK, the branch is actually branch-merge-rsync+-2-4-7.  I had to update
the patch a bit to accomodate other changes in 2.4.7pre, in particular
to use popt rather than getopt.  The full patch to the CVS head is
below.

-- 
Martin




Index: Makefile.in
===================================================================
RCS file: /data/cvs/rsync/Makefile.in,v
retrieving revision 1.46
retrieving revision 1.46.4.1
diff -u -7 -r1.46 -r1.46.4.1
--- Makefile.in	2 May 2001 08:33:18 -0000	1.46
+++ Makefile.in	6 Aug 2001 08:21:40 -0000	1.46.4.1
@@ -22,15 +22,15 @@
 .SUFFIXES: .c .o
 
 LIBOBJ=lib/fnmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o
 ZLIBOBJ=zlib/deflate.o zlib/infblock.o zlib/infcodes.o zlib/inffast.o \
 	zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
 	zlib/zutil.o zlib/adler32.o 
 OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o main.o checksum.o match.o syscall.o log.o backup.o
-OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o fileio.o
+OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o fileio.o batch.o
 DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
 popt_OBJS=popt/findme.o  popt/popt.o  popt/poptconfig.o \
 	popt/popthelp.o popt/poptparse.o
 OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
 
 # note that the -I. is needed to handle config.h when using VPATH
 .c.o:
Index: compat.c
===================================================================
RCS file: /data/cvs/rsync/compat.c,v
retrieving revision 1.14
retrieving revision 1.14.4.1
diff -u -7 -r1.14 -r1.14.4.1
--- compat.c	22 Mar 2001 07:36:51 -0000	1.14
+++ compat.c	6 Aug 2001 08:21:40 -0000	1.14.4.1
@@ -32,14 +32,17 @@
 extern int always_checksum;
 extern int checksum_seed;
 
 
 extern int remote_version;
 extern int verbose;
 
+extern int read_batch;  /* dw */
+extern int write_batch;  /* dw */
+
 void setup_protocol(int f_out,int f_in)
 {
 	if (remote_version == 0) {
 		if (am_server) {
 			remote_version = read_int(f_in);
 			write_int(f_out,PROTOCOL_VERSION);
 		} else {
@@ -53,14 +56,17 @@
 		rprintf(FERROR,"protocol version mismatch - is your shell clean?\n");
 		rprintf(FERROR,"(see the rsync man page for an explanation)\n");
 		exit_cleanup(RERR_PROTOCOL);
 	}	
 	
 	if (remote_version >= 12) {
 		if (am_server) {
+		    if (read_batch || write_batch) /* dw */
+			checksum_seed = 32761;
+		    else
 			checksum_seed = time(NULL);
 			write_int(f_out,checksum_seed);
 		} else {
 			checksum_seed = read_int(f_in);
 		}
 	}
 	
Index: flist.c
===================================================================
RCS file: /data/cvs/rsync/flist.c,v
retrieving revision 1.90
retrieving revision 1.90.4.1
diff -u -7 -r1.90 -r1.90.4.1
--- flist.c	2 May 2001 11:13:21 -0000	1.90
+++ flist.c	6 Aug 2001 08:21:40 -0000	1.90.4.1
@@ -43,14 +43,17 @@
 extern int relative_paths;
 extern int copy_links;
 extern int copy_unsafe_links;
 extern int remote_version;
 extern int io_error;
 extern int sanitize_paths;
 
+extern int read_batch;
+extern int write_batch;
+
 static char topsrcname[MAXPATHLEN];
 
 static struct exclude_struct **local_exclude_list;
 
 static struct file_struct null_file;
 
 static void clean_flist(struct file_list *flist, int strip_root);
@@ -609,14 +612,17 @@
 	  flist->files = (struct file_struct **)realloc(flist->files,
 							sizeof(flist->files[0])*
 							flist->malloced);
 	  if (!flist->files)
 		  out_of_memory("send_file_name");
   }
 
+  if (write_batch) /*  dw  */
+    file->flags = FLAG_DELETE;
+
   if (strcmp(file->basename,"")) {
     flist->files[flist->count++] = file;
     send_file_entry(file,f,base_flags);
   }
 
   if (S_ISDIR(file->mode) && recursive) {
 	  struct exclude_struct **last_exclude_list = local_exclude_list;
@@ -837,14 +843,16 @@
 		write_int(f, lp_ignore_errors(module_id)? 0 : io_error);
 	}
 
 	if (f != -1) {
 		io_end_buffering(f);
 		stats.flist_size = stats.total_written - start_write;
 		stats.num_files = flist->count;
+		if (write_batch) /*  dw  */
+		    write_batch_flist_info(flist->count, flist->files);
 	}
 
 	if (verbose > 2)
 		rprintf(FINFO,"send_file_list done\n");
 
 	return flist;
 }
@@ -914,15 +922,15 @@
 
   /* now recv the uid/gid list. This was introduced in protocol version 15 */
   if (f != -1 && remote_version >= 15) {
 	  recv_uid_list(f, flist);
   }
 
   /* if protocol version is >= 17 then recv the io_error flag */
-  if (f != -1 && remote_version >= 17) {
+  if (f != -1 && remote_version >= 17  && !read_batch) {  /* dw-added readbatch */
 	  extern int module_id;
 	  extern int ignore_errors;
 	  if (lp_ignore_errors(module_id) || ignore_errors) {
 		  read_int(f);
 	  } else {
 		  io_error |= read_int(f);
 	  }
Index: main.c
===================================================================
RCS file: /data/cvs/rsync/main.c,v
retrieving revision 1.129
retrieving revision 1.129.4.1
diff -u -7 -r1.129 -r1.129.4.1
--- main.c	17 Jul 2001 10:48:31 -0000	1.129
+++ main.c	6 Aug 2001 08:21:40 -0000	1.129.4.1
@@ -131,16 +131,17 @@
 	char *args[100];
 	int i,argc=0;
 	pid_t ret;
 	char *tok,*dir=NULL;
 	extern int local_server;
 	extern char *rsync_path;
 	extern int blocking_io;
+	extern int read_batch;
 
-	if (!local_server) {
+	if (!read_batch && !local_server) { /* dw -- added read_batch */
 		if (!cmd)
 			cmd = getenv(RSYNC_RSH_ENV);
 		if (!cmd)
 			cmd = RSYNC_RSH;
 		cmd = strdup(cmd);
 		if (!cmd) 
 			goto oom;
@@ -183,14 +184,16 @@
 		rprintf(FINFO,"cmd=");
 		for (i=0;i<argc;i++)
 			rprintf(FINFO,"%s ",args[i]);
 		rprintf(FINFO,"\n");
 	}
 
 	if (local_server) {
+		if (read_batch)
+		    create_flist_from_batch();
 		ret = local_child(argc, args, f_in, f_out);
 	} else {
 		ret = piped_child(args,f_in,f_out);
 	}
 
 	if (dir) free(dir);
 
@@ -394,14 +397,17 @@
 	char *local_name=NULL;
 	char *dir = NULL;
 	extern int delete_mode;
 	extern int delete_excluded;
 	extern int am_daemon;
 	extern int module_id;
 	extern int am_sender;
+	extern int read_batch;   /* dw */
+	extern int write_batch;  /* dw */
+	extern struct file_list *batch_flist;  /* dw */
 
 	if (verbose > 2)
 		rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
 
 	if (am_daemon && lp_read_only(module_id) && !am_sender) {
 		rprintf(FERROR,"ERROR: module is read only\n");
 		exit_cleanup(RERR_SYNTAX);
@@ -419,15 +425,18 @@
 			exit_cleanup(RERR_FILESELECT);
 		}    
 	}
 
 	if (delete_mode && !delete_excluded)
 		recv_exclude_list(f_in);
 
-	flist = recv_file_list(f_in);
+	if (read_batch) /*  dw  */
+	    flist = batch_flist;
+	else
+	    flist = recv_file_list(f_in);
 	if (!flist) {
 		rprintf(FERROR,"server_recv: recv_file_list error\n");
 		exit_cleanup(RERR_FILESELECT);
 	}
 	
 	if (argc > 0) {    
 		if (strcmp(dir,".")) {
@@ -443,27 +452,30 @@
 
 
 void start_server(int f_in, int f_out, int argc, char *argv[])
 {
 	extern int cvs_exclude;
 	extern int am_sender;
 	extern int remote_version;
+	extern int read_batch; /* dw */
 
 	setup_protocol(f_out, f_in);
 
 	set_nonblocking(f_in);
 	set_nonblocking(f_out);
 
 	if (remote_version >= 23)
 		io_start_multiplex_out(f_out);
 
 	if (am_sender) {
-		recv_exclude_list(f_in);
-		if (cvs_exclude)
+		if (!read_batch) { /* dw */
+		    recv_exclude_list(f_in);
+		    if (cvs_exclude)
 			add_cvs_excludes();
+		}
 		do_server_sender(f_in, f_out, argc, argv);
 	} else {
 		do_server_recv(f_in, f_out, argc, argv);
 	}
 	exit_cleanup(0);
 }
 
@@ -476,16 +488,21 @@
 {
 	struct file_list *flist;
 	int status = 0, status2 = 0;
 	char *local_name = NULL;
 	extern int am_sender;
 	extern int remote_version;
 	extern pid_t cleanup_child_pid;
+	extern int write_batch; /* dw */
+	extern int read_batch; /* dw */
+	extern struct file_list *batch_flist; /*  dw */
 
 	cleanup_child_pid = pid;
+	if (read_batch)
+	    flist = batch_flist;  /* dw */
 
 	set_nonblocking(f_in);
 	set_nonblocking(f_out);
 
 	setup_protocol(f_out,f_in);
 
 	if (remote_version >= 23)
@@ -495,15 +512,16 @@
 		extern int cvs_exclude;
 		extern int delete_mode;
 		extern int delete_excluded;
 		if (cvs_exclude)
 			add_cvs_excludes();
 		if (delete_mode && !delete_excluded) 
 			send_exclude_list(f_out);
-		flist = send_file_list(f_out,argc,argv);
+		if (!read_batch) /*  dw -- don't write to pipe */
+		    flist = send_file_list(f_out,argc,argv);
 		if (verbose > 3) 
 			rprintf(FINFO,"file list sent\n");
 
 		send_files(flist,f_out,f_in);
 		if (remote_version >= 24) {
 			/* final goodbye message */		
 			read_int(f_in);
@@ -519,15 +537,16 @@
 	}
 
 	if (argc == 0) {
 		extern int list_only;
 		list_only = 1;
 	}
 	
-	send_exclude_list(f_out);
+	if (!write_batch) /* dw */
+	    send_exclude_list(f_out);
 	
 	flist = recv_file_list(f_in);
 	if (!flist || flist->count == 0) {
 		rprintf(FINFO, "client: nothing to do: "
                         "perhaps you need to specify some filenames or "
                         "the --recursive option?\n");
 		exit_cleanup(0);
@@ -579,14 +598,15 @@
 	int f_in,f_out;
 	extern int local_server;
 	extern int am_sender;
 	extern char *shell_cmd;
 	extern int rsync_port;
 	extern int whole_file;
 	char *argv0 = strdup(argv[0]);
+	extern int read_batch;
 
 	if (strncasecmp(URL_PREFIX, argv0, strlen(URL_PREFIX)) == 0) {
 		char *host, *path;
 
 		host = argv0 + strlen(URL_PREFIX);
 		p = strchr(host,'/');
 		if (p) {
@@ -599,15 +619,16 @@
 		if (p) {
 			rsync_port = atoi(p+1);
 			*p = 0;
 		}
 		return start_socket_client(host, path, argc-1, argv+1);
 	}
 
-	p = find_colon(argv0);
+	if (!read_batch) { /* dw */
+	    p = find_colon(argv[0]);
 
 	if (p) {
 		if (p[1] == ':') {
 			*p = 0;
 			return start_socket_client(argv0, p+2, argc-1, argv+1);
 		}
 
@@ -646,15 +667,20 @@
 		} else {
 			*p = 0;
 			shell_machine = argv[argc-1];
 			shell_path = p+1;
 		}
 		argc--;
 	}
-	
+	} else {
+	    am_sender = 1;  /*  dw */
+	    local_server = 1;  /* dw */
+	    shell_path = argv[argc-1];  /* dw */
+	}
+
 	if (shell_machine) {
 		p = strchr(shell_machine,'@');
 		if (p) {
 			*p = 0;
 			shell_user = shell_machine;
 			shell_machine = p+1;
 		}
@@ -709,14 +735,21 @@
 {       
 	extern int am_root;
 	extern int orig_umask;
 	extern int dry_run;
 	extern int am_daemon;
 	extern int am_server;
 	int ret;
+	extern int read_batch;   /*  dw */
+	extern int write_batch;  /*  dw */
+	extern char *batch_ext;   /*  dw */
+	int i;          /*   dw */
+	int orig_argc;  /* dw */
+
+	orig_argc = argc;   /* dw */
 
 	signal(SIGUSR1, sigusr1_handler);
 	signal(SIGUSR2, sigusr2_handler);
 	signal(SIGCHLD, sigchld_handler);
 
 	starttime = time(NULL);
 	am_root = (getuid() == 0);
@@ -745,14 +778,23 @@
 	signal(SIGTERM,SIGNAL_CAST sig_int);
 
 	/* Initialize push_dir here because on some old systems getcwd
 	   (implemented by forking "pwd" and reading its output) doesn't
 	   work when there are other child processes.  Also, on all systems
 	   that implement getcwd that way "pwd" can't be found after chroot. */
 	push_dir(NULL,0);
+
+	if (write_batch) { /* dw */
+	    create_batch_file_ext();
+	    write_batch_argvs_file(orig_argc, argc, argv);
+	}
+
+	if (read_batch) { /* dw */
+	    set_batch_file_ext(batch_ext);
+	}
 
 	if (am_daemon) {
 		return daemon_main();
 	}
 
 	if (argc < 1) {
 		usage(FERROR);
Index: match.c
===================================================================
RCS file: /data/cvs/rsync/match.c,v
retrieving revision 1.45
retrieving revision 1.45.12.1
diff -u -7 -r1.45 -r1.45.12.1
--- match.c	25 Jan 2000 13:16:42 -0000	1.45
+++ match.c	6 Aug 2001 08:21:40 -0000	1.45.12.1
@@ -256,14 +256,15 @@
 	map_ptr(buf,len-1,1);
 }
 
 
 void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
 {
 	char file_sum[MD4_SUM_LENGTH];
+	extern int write_batch;  /*  dw */
 
 	last_match = 0;
 	false_alarms = 0;
 	tag_hits = 0;
 	matches=0;
 	data_transfer=0;
 
@@ -291,14 +292,16 @@
 
 	sum_end(file_sum);
 
 	if (remote_version >= 14) {
 		if (verbose > 2)
 			rprintf(FINFO,"sending file_sum\n");
 		write_buf(f,file_sum,MD4_SUM_LENGTH);
+		if (write_batch) /* dw */
+		    write_batch_delta_file(file_sum, MD4_SUM_LENGTH);
 	}
 
 	if (targets) {
 		free(targets);
 		targets=NULL;
 	}
 	
Index: options.c
===================================================================
RCS file: /data/cvs/rsync/options.c,v
retrieving revision 1.53
retrieving revision 1.53.4.1
diff -u -7 -r1.53 -r1.53.4.1
--- options.c	12 Jun 2001 19:33:41 -0000	1.53
+++ options.c	6 Aug 2001 08:21:40 -0000	1.53.4.1
@@ -70,14 +70,17 @@
 #ifdef _WIN32
 int modify_window=2;
 #else
 int modify_window=0;
 #endif
 int blocking_io=0;
 
+int read_batch=0;  /* dw */
+int write_batch=0; /* dw */
+
 char *backup_suffix = BACKUP_SUFFIX;
 char *tmpdir = NULL;
 char *compare_dest = NULL;
 char *config_file = RSYNCD_CONF;
 char *shell_cmd = NULL;
 char *log_format = NULL;
 char *password_file = NULL;
@@ -86,14 +89,16 @@
 int rsync_port = RSYNC_PORT;
 
 int verbose = 0;
 int quiet = 0;
 int always_checksum = 0;
 int list_only = 0;
 
+char *batch_ext = NULL;
+
 static int modify_window_set;
 
 
 struct in_addr socket_address = {INADDR_ANY};
 
 
 static void print_rsync_version(int f)
@@ -202,14 +207,16 @@
   rprintf(F,"     --port=PORT             specify alternate rsyncd port number\n");
   rprintf(F,"     --blocking-io           use blocking IO for the remote shell\n");  
   rprintf(F,"     --stats                 give some file transfer stats\n");  
   rprintf(F,"     --progress              show progress during transfer\n");  
   rprintf(F,"     --log-format=FORMAT     log file transfers using specified format\n");  
   rprintf(F,"     --password-file=FILE    get password from FILE\n");
   rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth, KBytes per second\n");
+  rprintf(F," -f  --read-batch=EXT        read batch file\n");
+  rprintf(F," -F  --write-batch           write batch file\n");
   rprintf(F," -h, --help                  show this help screen\n");
 
   rprintf(F,"\n");
 
   rprintf(F,"\nPlease see the rsync(1) and rsyncd.conf(5) man pages for full documentation\n");
   rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
 }
@@ -286,18 +293,19 @@
   {"config",           0,  POPT_ARG_STRING, &config_file},
   {"port",             0,  POPT_ARG_INT,    &rsync_port},
   {"log-format",       0,  POPT_ARG_STRING, &log_format},
   {"bwlimit",          0,  POPT_ARG_INT,    &bwlimit},
   {"address",          0,  POPT_ARG_STRING, 0,               OPT_ADDRESS},
   {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir},
   {"hard-links",      'H', POPT_ARG_NONE,   &preserve_hard_links},
+  {"read-batch",      'f', POPT_ARG_STRING, &batch_ext, 'f'},
+  {"write-batch",     'F', POPT_ARG_NONE,   &write_batch, 0},
   {0,0,0,0}
 };
 
-
 static char err_buf[100];
 
 
 void option_error(void)
 {
 	if (err_buf[0]) {
 		rprintf(FLOG, "%s", err_buf);
@@ -464,14 +472,19 @@
 				struct in_addr *ia;
 				if ((ia = ip_address(optarg))) {
 					socket_address = *ia;
 				}
 			}
 			break;
 
+		case 'f':
+			/* The filename is stored for us by popt */
+			read_batch = 1;
+			break;
+
 		default:
                         /* FIXME: If --daemon is specified, then errors for later
                          * parameters seem to disappear. */
                         snprintf(err_buf, sizeof(err_buf),
                                  "%s%s: %s\n",
                                  am_server ? "on remote machine: " : "",
                                  poptBadOption(pc, POPT_BADOPTION_NOALIAS),
@@ -497,14 +510,15 @@
 	int ac = *argc;
 	static char argstr[50];
 	static char bsize[30];
 	static char iotime[30];
 	static char mdelete[30];
 	static char mwindow[30];
 	static char bw[50];
+	static char fext[20]; /* dw */
 
 	int i, x;
 
 	args[ac++] = "--server";
 
 	if (!am_sender)
 		args[ac++] = "--sender";
@@ -551,14 +565,16 @@
 		argstr[x++] = 'R';
 	if (one_file_system)
 		argstr[x++] = 'x';
 	if (sparse_files)
 		argstr[x++] = 'S';
 	if (do_compression)
 		argstr[x++] = 'z';
+	if (write_batch)
+	    argstr[x++] = 'F'; /* dw */
 
 	/* this is a complete hack - blame Rusty 
 
 	   this is a hack to make the list_only (remote file list)
 	   more useful */
 	if (list_only && !recurse) 
 		argstr[x++] = 'r';
@@ -572,14 +588,19 @@
 		args[ac++] = bsize;
 	}    
 
 	if (max_delete && am_sender) {
 		snprintf(mdelete,sizeof(mdelete),"--max-delete=%d",max_delete);
 		args[ac++] = mdelete;
 	}    
+	
+	if (batch_ext != NULL) {
+		sprintf(fext,"-f%s",batch_ext);
+		args[ac++] = fext;
+	}
 
 	if (io_timeout) {
 		snprintf(iotime,sizeof(iotime),"--timeout=%d",io_timeout);
 		args[ac++] = iotime;
 	}    
 
 	if (bwlimit) {
Index: proto.h
===================================================================
RCS file: /data/cvs/rsync/proto.h,v
retrieving revision 1.126
retrieving revision 1.126.4.1
diff -u -7 -r1.126 -r1.126.4.1
--- proto.h	7 May 2001 08:59:47 -0000	1.126
+++ proto.h	6 Aug 2001 08:21:40 -0000	1.126.4.1
@@ -1,12 +1,32 @@
 /* This file is automatically generated with "make proto". DO NOT EDIT */
 
 int allow_access(char *addr, char *host, char *allow_list, char *deny_list);
 char *auth_server(int fd, int module, char *addr, char *leader);
 void auth_client(int fd, char *user, char *challenge);
+void create_batch_file_ext();
+void set_batch_file_ext(char *ext);
+void write_batch_flist_file(char *buff, int bytes_to_write);
+void write_batch_flist_info(int flist_count, struct file_struct **fptr);
+void write_char_bufs(char *buf);
+void write_batch_argvs_file(int orig_argc, int argc, char **argv);
+struct file_list *create_flist_from_batch();
+int read_batch_flist_file(char *buff, int len);
+unsigned char read_batch_flags();
+void read_batch_flist_info(struct file_struct **fptr);
+void write_batch_csums_file(char *buff, int bytes_to_write);
+void close_batch_csums_file() ;
+void write_batch_csum_info(int *flist_entry, int flist_count, struct sum_struct *s);
+int read_batch_csums_file(char *buff, int len);
+void read_batch_csum_info(int flist_entry, struct sum_struct *s, int *checksums_match);
+void write_batch_delta_file(char *buff, int bytes_to_write);
+void close_batch_delta_file();
+int read_batch_delta_file(char *buff, int len);
+void show_flist(int index, struct file_struct **fptr);
+void show_argvs(int argc, char *argv[]);
 int make_backup(char *fname);
 uint32 get_checksum1(char *buf1,int len);
 void get_checksum2(char *buf,int len,char *sum);
 void file_checksum(char *fname,char *sum,OFF_T size);
 void checksum_init(void);
 void sum_init(void);
 void sum_update(char *p,int len);
Index: rsync.c
===================================================================
RCS file: /data/cvs/rsync/rsync.c,v
retrieving revision 1.117
retrieving revision 1.117.4.1
diff -u -7 -r1.117 -r1.117.4.1
--- rsync.c	7 May 2001 06:59:37 -0000	1.117
+++ rsync.c	6 Aug 2001 08:21:40 -0000	1.117.4.1
@@ -222,14 +222,15 @@
 	}
 	return updated;
 }
 
 
 void sig_int(void)
 {
+	rprintf(FINFO,"\nrsync.c:sig_int() called.\n");
 	exit_cleanup(RERR_SIGNAL);
 }
 
 
 /* finish off a file transfer, renaming the file and setting the permissions
    and ownership */
 void finish_transfer(char *fname, char *fnametmp, struct file_struct *file)
Index: sender.c
===================================================================
RCS file: /data/cvs/rsync/sender.c,v
retrieving revision 1.10
retrieving revision 1.10.12.1
diff -u -7 -r1.10 -r1.10.12.1
--- sender.c	19 Aug 2000 15:25:05 -0000	1.10
+++ sender.c	6 Aug 2001 08:21:40 -0000	1.10.12.1
@@ -89,14 +89,22 @@
 	STRUCT_STAT st;
 	char fname[MAXPATHLEN];  
 	int i;
 	struct file_struct *file;
 	int phase = 0;
 	extern struct stats stats;		
 	struct stats initial_stats;
+	extern int write_batch;   /* dw */
+	int negative_one;  /* dw */
+	extern int read_batch;    /* dw */
+	int checksums_match;   /* dw */
+	int buff_len;  /* dw */
+	char buff[CHUNK_SIZE];    /* dw */
+	int j;   /* dw */
+	int done;   /* dw */
 
 	if (verbose > 2)
 		rprintf(FINFO,"send_files starting\n");
 
 	while (1) {
 		int offset=0;
 
@@ -148,20 +156,23 @@
 			write_int(f_out,i);
 			continue;
 		}
 
 		initial_stats = stats;
 
 		s = receive_sums(f_in);
+		if (write_batch) /* dw */
+		    write_batch_csum_info(&i,flist->count,s);
 		if (!s) {
 			io_error = 1;
 			rprintf(FERROR,"receive_sums failed\n");
 			return;
 		}
 	  
+		if (!read_batch) {
 		fd = do_open(fname, O_RDONLY, 0);
 		if (fd == -1) {
 			io_error = 1;
 			rprintf(FERROR,"send_files failed to open %s: %s\n",
 				fname,strerror(errno));
 			free_sums(s);
 			continue;
@@ -181,48 +192,103 @@
 		} else {
 			buf = NULL;
 		}
 	  
 		if (verbose > 2)
 			rprintf(FINFO,"send_files mapped %s of size %.0f\n",
 				fname,(double)st.st_size);
+		}
 
-		write_int(f_out,i);
+		if (!read_batch) { /* dw */
+		    write_int(f_out,i);
 	  
-		write_int(f_out,s->count);
-		write_int(f_out,s->n);
-		write_int(f_out,s->remainder);
+		    if (write_batch)
+			write_batch_delta_file((char *)&i,sizeof(i));
+
+		    write_int(f_out,s->count);
+		    write_int(f_out,s->n);
+		    write_int(f_out,s->remainder);
+		}
 	  
 		if (verbose > 2)
-			rprintf(FINFO,"calling match_sums %s\n",fname);
+			if (!read_batch)
+			    rprintf(FINFO,"calling match_sums %s\n",fname);
 	  
 		if (!am_server) {
 			log_transfer(file, fname+offset);
 		}
 
 		set_compression(fname);
-	  
-		match_sums(f_out,s,buf,st.st_size);
 
-		log_send(file, &initial_stats);
-	  	  
-		if (buf) unmap_file(buf);
-		close(fd);
+                if (read_batch) { /* dw */
+                   /* read checksums originally computed on sender side */
+                   read_batch_csum_info(i, s, &checksums_match);
+                   if (checksums_match) {
+                       read_batch_delta_file( (char *) &j, sizeof(int) );
+                       if (j != i) {    /* if flist index entries don't match*/ 
+                          rprintf(FINFO,"index mismatch in send_files\n");
+                          rprintf(FINFO,"read index = %d flist ndx = %d\n",j,i);
+                          close_batch_delta_file();
+                          close_batch_csums_file();
+                          exit_cleanup(1);
+                       }
+                       else {
+                         write_int(f_out,j);
+                         write_int(f_out,s->count);
+                         write_int(f_out,s->n);
+                         write_int(f_out,s->remainder);
+                         done=0;
+                         while (!done) {
+                            read_batch_delta_file( (char *) &buff_len, sizeof(int) );
+                            write_int(f_out,buff_len);
+                            if (buff_len == 0) {
+                               done = 1;
+                            }
+                            else {
+                               if (buff_len > 0) {
+                                  read_batch_delta_file(buff, buff_len);
+                                  write_buf(f_out,buff,buff_len);
+                               }
+                            }
+                         }  /* end while  */
+                         read_batch_delta_file( buff, MD4_SUM_LENGTH);
+                         write_buf(f_out, buff, MD4_SUM_LENGTH);
+
+                       }  /* j=i */
+                   } else {  /* not checksum match */
+                      rprintf(FINFO,"readbatch & checksums don't match\n");
+                      rprintf(FINFO,"filename=%s is being skipped\n");
+                      continue;
+                   }
+                } else  {
+		    match_sums(f_out,s,buf,st.st_size);
+		    log_send(file, &initial_stats);
+                }
+
+		if (!read_batch) { /* dw */
+		    if (buf) unmap_file(buf);
+		    close(fd);
+		}
 	  
 		free_sums(s);
 	  
 		if (verbose > 2)
 			rprintf(FINFO,"sender finished %s\n",fname);
 	}
 
 	if (verbose > 2)
 		rprintf(FINFO,"send files finished\n");
 
 	match_report();
 
 	write_int(f_out,-1);
+	if (write_batch || read_batch) { /* dw */
+	    close_batch_csums_file();
+	    close_batch_delta_file();
+	}
+
 }
 
 
 
 
 
Index: token.c
===================================================================
RCS file: /data/cvs/rsync/token.c,v
retrieving revision 1.20
retrieving revision 1.20.12.1
diff -u -7 -r1.20 -r1.20.12.1
--- token.c	25 Nov 1998 15:37:51 -0000	1.20
+++ token.c	6 Aug 2001 08:21:40 -0000	1.20.12.1
@@ -86,26 +86,37 @@
 }
 
 
 /* non-compressing send token */
 static void simple_send_token(int f,int token,
 			      struct map_struct *buf,OFF_T offset,int n)
 {
+	extern int write_batch; /* dw */
+	int hold_int; /* dw */
+
 	if (n > 0) {
 		int l = 0;
 		while (l < n) {
 			int n1 = MIN(CHUNK_SIZE,n-l);
 			write_int(f,n1);
 			write_buf(f,map_ptr(buf,offset+l,n1),n1);
+			if (write_batch) {
+			    write_batch_delta_file( (char *) &n1, sizeof(int) );
+			    write_batch_delta_file(map_ptr(buf,offset+l,n1),n1);
+			}
 			l += n1;
 		}
 	}
 	/* a -2 token means to send data only and no token */
 	if (token != -2) {
 		write_int(f,-(token+1));
+		if (write_batch) {
+		    hold_int = -(token+1);
+		    write_batch_delta_file( (char *) &hold_int, sizeof(int) );
+		}
 	}
 }
 
 
 /* Flag bytes in compressed stream are encoded as follows: */
 #define END_FLAG	0	/* that's all folks */
 #define TOKEN_LONG	0x20	/* followed by 32-bit token number */
@@ -130,14 +141,16 @@
 /* Send a deflated token */
 static void
 send_deflated_token(int f, int token,
 		    struct map_struct *buf, OFF_T offset, int nb, int toklen)
 {
 	int n, r;
 	static int init_done, flush_pending;
+	extern int write_batch;  /* dw */
+	char temp_byte;   /* dw */
 
 	if (last_token == -1) {
 		/* initialization */
 		if (!init_done) {
 			tx_strm.next_in = NULL;
 			tx_strm.zalloc = NULL;
 			tx_strm.zfree = NULL;
@@ -162,21 +175,35 @@
 	} else if (nb != 0 || token != last_token + 1
 		   || token >= run_start + 65536) {
 		/* output previous run */
 		r = run_start - last_run_end;
 		n = last_token - run_start;
 		if (r >= 0 && r <= 63) {
 			write_byte(f, (n==0? TOKEN_REL: TOKENRUN_REL) + r);
+			if (write_batch) { /* dw */
+			    temp_byte = (char)( (n==0? TOKEN_REL: TOKENRUN_REL) + r);
+			    write_batch_delta_file(&temp_byte,sizeof(char));
+			}
 		} else {
 			write_byte(f, (n==0? TOKEN_LONG: TOKENRUN_LONG));
 			write_int(f, run_start);
+			if (write_batch) { /* dw */
+			    temp_byte = (char)(n==0? TOKEN_LONG: TOKENRUN_LONG);
+			    write_batch_delta_file(&temp_byte,sizeof(temp_byte));
+			    write_batch_delta_file((char *)&run_start,sizeof(run_start));
+			}
 		}
 		if (n != 0) {
 			write_byte(f, n);
 			write_byte(f, n >> 8);
+			if (write_batch) { /* dw */
+			    write_batch_delta_file((char *)&n,sizeof(char));
+			    temp_byte = (char) n >> 8;
+			    write_batch_delta_file(&temp_byte,sizeof(temp_byte));
+			}
 		}
 		last_run_end = last_token;
 		run_start = token;
 	}
 
 	last_token = token;
 
@@ -227,23 +254,29 @@
 					 */
 					n -= 4;
 				}
 				if (n > 0) {
 					obuf[0] = DEFLATED_DATA + (n >> 8);
 					obuf[1] = n;
 					write_buf(f, obuf, n+2);
+					if (write_batch) /* dw */
+					    write_batch_delta_file(obuf,n+2);
 				}
 			}
 		} while (nb != 0 || tx_strm.avail_out == 0);
 		flush_pending = token == -2;
 	}
 
 	if (token == -1) {
 		/* end of file - clean up */
 		write_byte(f, END_FLAG);
+		if (write_batch) { /* dw */
+		    temp_byte = END_FLAG;
+		    write_batch_delta_file((char *)&temp_byte,sizeof(temp_byte));
+		}
 
 	} else if (token != -2) {
 		/* add the data in the current block to the compressor's
 		   history and hash table */
 		tx_strm.next_in = (Bytef *) map_ptr(buf, offset, toklen);
 		tx_strm.avail_in = toklen;
 		tx_strm.next_out = (Bytef *) obuf;
Index: util.c
===================================================================
RCS file: /data/cvs/rsync/util.c,v
retrieving revision 1.89
retrieving revision 1.89.4.1
diff -u -7 -r1.89 -r1.89.4.1
--- util.c	7 May 2001 06:59:37 -0000	1.89
+++ util.c	6 Aug 2001 08:21:40 -0000	1.89.4.1
@@ -149,14 +149,15 @@
 }
 
 pid_t local_child(int argc, char **argv,int *f_in,int *f_out)
 {
 	pid_t pid;
 	int to_child_pipe[2];
 	int from_child_pipe[2];
+	extern int read_batch;  /* dw */
 
 	if (fd_pair(to_child_pipe) < 0 ||
 	    fd_pair(from_child_pipe) < 0) {
 		rprintf(FERROR,"pipe: %s\n",strerror(errno));
 		exit_cleanup(RERR_IPC);
 	}
 
@@ -167,15 +168,18 @@
 		exit_cleanup(RERR_IPC);
 	}
 
 	if (pid == 0) {
 		extern int am_sender;
 		extern int am_server;
 
-		am_sender = !am_sender;
+		if (read_batch)
+		    am_sender = 0;
+		else
+		    am_sender = !am_sender;
 		am_server = 1;		
 
 		if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
 		    close(to_child_pipe[1]) < 0 ||
 		    close(from_child_pipe[0]) < 0 ||
 		    dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
 			rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));




More information about the rsync mailing list