From c6e7fcb42bc87660ece8d4dc9a1b10bd1fb7b0c5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Jul 1996 23:27:19 +0000 Subject: [PATCH] *** empty log message *** --- README | 2 +- checksum.c | 4 +-- main.c | 11 ++++++-- match.c | 8 +++--- rsync.c | 61 ++++++++++++++++++++++++++++++++++++--------- rsync.h | 6 ++++- token.c | 6 ++--- util.c | 73 +++++++++++++++++++++++++++--------------------------- 8 files changed, 111 insertions(+), 60 deletions(-) diff --git a/README b/README index b1651cee..6c157989 100644 --- a/README +++ b/README @@ -12,7 +12,7 @@ diffs between two files normally requires local access to both files. A technical report describing the rsync algorithm is included with -this package. +this package. USAGE diff --git a/checksum.c b/checksum.c index 68ce5c99..8d805b6a 100644 --- a/checksum.c +++ b/checksum.c @@ -93,7 +93,7 @@ void file_checksum(char *fname,char *sum,off_t size) { int i; MDstruct MD; - char *buf; + struct map_struct *buf; int fd; int len = size; char tmpchunk[CSUM_CHUNK]; @@ -118,7 +118,7 @@ void file_checksum(char *fname,char *sum,off_t size) sum_put(&MD,sum); close(fd); - unmap_file(buf,size); + unmap_file(buf); } diff --git a/main.c b/main.c index 3efde6d9..038a2d2c 100644 --- a/main.c +++ b/main.c @@ -306,12 +306,19 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) { int pid; int status=0; + int recv_pipe[2]; if (preserve_hard_links) init_hard_links(flist); + if (pipe(recv_pipe) < 0) { + fprintf(FERROR,"pipe failed in do_recv\n"); + exit(1); + } + + if ((pid=fork()) == 0) { - recv_files(f_in,flist,local_name); + recv_files(f_in,flist,local_name,recv_pipe[1]); if (preserve_hard_links) do_hard_links(flist); if (verbose > 2) @@ -319,7 +326,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) exit_cleanup(0); } - generate_files(f_out,flist,local_name); + generate_files(f_out,flist,local_name,recv_pipe[0]); waitpid(pid, &status, 0); diff --git a/match.c b/match.c index 65901785..d7af159b 100644 --- a/match.c +++ b/match.c @@ -88,7 +88,8 @@ static void build_hash_table(struct sum_struct *s) static off_t last_match; -static void matched(int f,struct sum_struct *s,char *buf,off_t len, +static void matched(int f,struct sum_struct *s,struct map_struct *buf, + off_t len, int offset,int i) { int n = offset - last_match; @@ -112,7 +113,8 @@ static void matched(int f,struct sum_struct *s,char *buf,off_t len, } -static void hash_search(int f,struct sum_struct *s,char *buf,off_t len) +static void hash_search(int f,struct sum_struct *s, + struct map_struct *buf,off_t len) { int offset,j,k; int end; @@ -204,7 +206,7 @@ static void hash_search(int f,struct sum_struct *s,char *buf,off_t len) } -void match_sums(int f,struct sum_struct *s,char *buf,off_t len) +void match_sums(int f,struct sum_struct *s,struct map_struct *buf,off_t len) { last_match = 0; false_alarms = 0; diff --git a/rsync.c b/rsync.c index 73589d05..3f3e8f9d 100644 --- a/rsync.c +++ b/rsync.c @@ -26,6 +26,8 @@ extern int am_server; extern int always_checksum; extern time_t starttime; +extern int remote_version; + extern char *backup_suffix; extern int block_size; @@ -81,7 +83,7 @@ static void send_sums(struct sum_struct *s,int f_out) generate approximately one checksum every n bytes */ -static struct sum_struct *generate_sums(char *buf,off_t len,int n) +static struct sum_struct *generate_sums(struct map_struct *buf,off_t len,int n) { int i; struct sum_struct *s; @@ -253,7 +255,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out) { int fd; struct stat st; - char *buf; + struct map_struct *buf; struct sum_struct *s; char sum[SUM_LENGTH]; int statret; @@ -390,14 +392,14 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out) write_flush(f_out); close(fd); - unmap_file(buf,st.st_size); + unmap_file(buf); free_sums(s); } -static void receive_data(int f_in,char *buf,int fd,char *fname) +static void receive_data(int f_in,struct map_struct *buf,int fd,char *fname) { int i,n,remainder,len,count; off_t offset = 0; @@ -498,15 +500,16 @@ void sig_int(void) } -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_gen) { int fd1,fd2; struct stat st; char *fname; char fnametmp[MAXPATHLEN]; - char *buf; + struct map_struct *buf; int i; struct file_struct *file; + int phase=0; if (verbose > 2) { fprintf(FERROR,"recv_files(%d) starting\n",flist->count); @@ -519,7 +522,15 @@ int recv_files(int f_in,struct file_list *flist,char *local_name) while (1) { i = read_int(f_in); - if (i == -1) break; + if (i == -1) { + if (phase==0 && remote_version >= 13) { + phase++; + write_int(f_gen,-1); + write_flush(f_gen); + continue; + } + break; + } file = &flist->files[i]; fname = file->name; @@ -581,7 +592,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name) receive_data(f_in,buf,fd2,fname); if (fd1 != -1) { - unmap_file(buf,st.st_size); + unmap_file(buf); close(fd1); } close(fd2); @@ -621,12 +632,13 @@ off_t send_files(struct file_list *flist,int f_out,int f_in) { int fd; struct sum_struct *s; - char *buf; + struct map_struct *buf; struct stat st; char fname[MAXPATHLEN]; off_t total=0; int i; struct file_struct *file; + int phase = 0; if (verbose > 2) fprintf(FERROR,"send_files starting\n"); @@ -636,7 +648,15 @@ off_t send_files(struct file_list *flist,int f_out,int f_in) while (1) { i = read_int(f_in); - if (i == -1) break; + if (i == -1) { + if (phase==0 && remote_version >= 13) { + phase++; + write_int(f_out,-1); + write_flush(f_out); + continue; + } + break; + } file = &flist->files[i]; @@ -701,7 +721,7 @@ off_t send_files(struct file_list *flist,int f_out,int f_in) match_sums(f_out,s,buf,st.st_size); write_flush(f_out); - unmap_file(buf,st.st_size); + unmap_file(buf); close(fd); free_sums(s); @@ -725,7 +745,7 @@ off_t send_files(struct file_list *flist,int f_out,int f_in) -void generate_files(int f,struct file_list *flist,char *local_name) +void generate_files(int f,struct file_list *flist,char *local_name,int f_recv) { int i; @@ -748,8 +768,25 @@ void generate_files(int f,struct file_list *flist,char *local_name) recv_generator(local_name?local_name:file->name, flist,i,f); } + write_int(f,-1); write_flush(f); + + if (remote_version >= 13) { + /* go to the full checksum if anything has failed so far */ + csum_length = SUM_LENGTH; + + for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) { + struct file_struct *file = &flist->files[i]; + recv_generator(local_name?local_name:file->name, + flist,i,f); + } + + write_int(f,-1); + write_flush(f); + } + + if (verbose > 2) fprintf(FERROR,"generator wrote %d\n",write_total()); } diff --git a/rsync.h b/rsync.h index e27fd4fa..5fcd40c7 100644 --- a/rsync.h +++ b/rsync.h @@ -34,7 +34,7 @@ #define SAME_TIME (1<<7) /* update this if you make incompatible changes */ -#define PROTOCOL_VERSION 12 +#define PROTOCOL_VERSION 13 #define MIN_PROTOCOL_VERSION 10 #define MAX_PROTOCOL_VERSION 20 @@ -213,6 +213,10 @@ struct sum_struct { struct sum_buf *sums; /* points to info for each chunk */ }; +struct map_struct { + char *map,*p; + int fd,size,p_size,p_offset,p_len; +}; #include "byteorder.h" #include "version.h" diff --git a/token.c b/token.c index 630c3932..3d6899ae 100644 --- a/token.c +++ b/token.c @@ -50,7 +50,8 @@ static int simple_recv_token(int f,char **data) /* non-compressing send token */ -static void simple_send_token(int f,int token,char *buf,int offset,int n) +static void simple_send_token(int f,int token, + struct map_struct *buf,int offset,int n) { if (n > 0) { int l = 0; @@ -71,9 +72,8 @@ static void simple_send_token(int f,int token,char *buf,int offset,int n) * transmit a verbatim buffer of length n followed by a token * If token == -1 then we have reached EOF * If n == 0 then don't send a buffer - * Note that "buf" must be used via map_ptr() starting at "offset" */ -void send_token(int f,int token,char *buf,int offset,int n) +void send_token(int f,int token,struct map_struct *buf,int offset,int n) { if (!do_compression) { simple_send_token(f,token,buf,offset,n); diff --git a/util.c b/util.c index f9985ef2..644553e6 100644 --- a/util.c +++ b/util.c @@ -31,73 +31,74 @@ int num_waiting(int fd) return(len); } -static int map_fd = -1; -static off_t map_size = 0; -static char *p = NULL; -static int p_size = 0; -static int p_offset = 0; -static int p_len = 0; - -char *map_file(int fd,off_t len) +struct map_struct *map_file(int fd,off_t len) { - char *ret = NULL; + struct map_struct *ret; + ret = (struct map_struct *)malloc(sizeof(*ret)); + if (!ret) out_of_memory("map_file"); + + ret->map = NULL; + ret->fd = fd; + ret->size = len; + ret->p = NULL; + ret->p_size = 0; + ret->p_offset = 0; + ret->p_len = 0; + #ifdef HAVE_MMAP if (len < MAX_MAP_SIZE) - ret = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0); + ret->map = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0); #endif - map_fd = fd; - map_size = len; return ret; } -char *map_ptr(char *buf,off_t offset,int len) +char *map_ptr(struct map_struct *map,off_t offset,int len) { - if (buf) - return buf+offset; + if (map->map) + return map->map+offset; if (len == 0) return NULL; - len = MIN(len,map_size-offset); + len = MIN(len,map->size-offset); - if (offset >= p_offset && - offset+len <= p_offset+p_len) { - return (p + (offset - p_offset)); + if (offset >= map->p_offset && + offset+len <= map->p_offset+map->p_len) { + return (map->p + (offset - map->p_offset)); } len = MAX(len,CHUNK_SIZE); - len = MIN(len,map_size - offset); + len = MIN(len,map->size - offset); - if (len > p_size) { - if (p) free(p); - p = (char *)malloc(len); - if (!p) out_of_memory("map_ptr"); - p_size = len; + if (len > map->p_size) { + if (map->p) free(map->p); + map->p = (char *)malloc(len); + if (!map->p) out_of_memory("map_ptr"); + map->p_size = len; } - if (lseek(map_fd,offset,SEEK_SET) != offset || - read(map_fd,p,len) != len) { + if (lseek(map->fd,offset,SEEK_SET) != offset || + read(map->fd,map->p,len) != len) { fprintf(FERROR,"EOF in map_ptr!\n"); exit_cleanup(1); } - p_offset = offset; - p_len = len; + map->p_offset = offset; + map->p_len = len; - return p; + return map->p; } -void unmap_file(char *buf,off_t len) +void unmap_file(struct map_struct *map) { #ifdef HAVE_MMAP - if (len > 0 && buf) - munmap(buf,len); + if (map->map) + munmap(map->map,map->size); #endif - map_fd = -1; - map_size = 0; - p_len = 0; + if (map->p) free(map->p); + free(map); } -- 2.34.1