From 34ccb63e71367fb1f93530f60147ef6e4ac4e3e4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 28 Jun 1996 13:55:41 +0000 Subject: [PATCH] new exit/cleanup code --- checksum.c | 98 ++++++++++++++++++++++++++++++++++++++++++------------ exclude.c | 2 +- flist.c | 4 +-- io.c | 10 +++--- main.c | 52 +++++++++++++++-------------- match.c | 2 +- rsync.c | 17 ++++++---- rsync.h | 3 +- util.c | 16 ++++----- 9 files changed, 133 insertions(+), 71 deletions(-) diff --git a/checksum.c b/checksum.c index b656ef90..eac41c4e 100644 --- a/checksum.c +++ b/checksum.c @@ -19,7 +19,12 @@ #include "rsync.h" -extern int csum_length; +int csum_length=SUM_LENGTH; + +#define CSUM_CHUNK 64 + +static char *tmpchunk = NULL; + /* a simple 32 bit checksum that can be upadted from either end @@ -31,52 +36,103 @@ uint32 get_checksum1(char *buf,int len) uint32 s1, s2; s1 = s2 = 0; - for (i = 0; i < len; i++) { - s1 += buf[i]; - s2 += s1; + for (i = 0; i < (len-4); i+=4) { + s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3]; + s1 += (buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3]); + } + for (; i < len; i++) { + s1 += buf[i]; s2 += s1; } return (s1 & 0xffff) + (s2 << 16); } +static void sum_put(MDstruct *md,char *sum) +{ + SIVAL(sum,0,md->buffer[0]); + if (csum_length <= 4) return; + SIVAL(sum,4,md->buffer[1]); + if (csum_length <= 8) return; + SIVAL(sum,8,md->buffer[2]); + if (csum_length <= 12) return; + SIVAL(sum,12,md->buffer[3]); +} + + void get_checksum2(char *buf,int len,char *sum) { - char buf2[64]; int i; MDstruct MD; MDbegin(&MD); - for(i = 0; i + 64 <= len; i += 64) { - bcopy(buf+i,buf2,64); - MDupdate(&MD, buf2, 512); + + for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) { + bcopy(buf+i,tmpchunk,CSUM_CHUNK); + MDupdate(&MD, tmpchunk, CSUM_CHUNK*8); } - bcopy(buf+i,buf2,len-i); - MDupdate(&MD, buf2, (len-i)*8); - SIVAL(sum,0,MD.buffer[0]); - if (csum_length <= 4) return; - SIVAL(sum,4,MD.buffer[1]); - if (csum_length <= 8) return; - SIVAL(sum,8,MD.buffer[2]); - if (csum_length <= 12) return; - SIVAL(sum,12,MD.buffer[3]); + + bcopy(buf+i,tmpchunk,len-i); + MDupdate(&MD, tmpchunk, (len-i)*8); + + sum_put(&MD,sum); } + void file_checksum(char *fname,char *sum,off_t size) { + int i; + MDstruct MD; char *buf; int fd; + int len = size; + bzero(sum,csum_length); fd = open(fname,O_RDONLY); if (fd == -1) return; buf = map_file(fd,size); - if (!buf) { - close(fd); - return; + + MDbegin(&MD); + + for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) { + bcopy(map_ptr(buf,i,CSUM_CHUNK),tmpchunk,CSUM_CHUNK); + MDupdate(&MD, tmpchunk, CSUM_CHUNK*8); } - get_checksum2(buf,size,sum); + bcopy(map_ptr(buf,i,len-i),tmpchunk,len-i); + MDupdate(&MD, tmpchunk, (len-i)*8); + + sum_put(&MD,sum); + close(fd); unmap_file(buf,size); } + + +void checksum_init(void) +{ + tmpchunk = (char *)malloc(CSUM_CHUNK); + if (!tmpchunk) out_of_memory("checksum_init"); +} + + +#ifdef CHECKSUM_MAIN + int main(int argc,char *argv[]) +{ + char sum[SUM_LENGTH]; + int i,j; + + checksum_init(); + + for (i=1;i 1) fprintf(stderr,"Error reading %d bytes : %s\n", 4,ret==-1?strerror(errno):"EOF"); - exit(1); + exit_cleanup(1); } total_read += 4; return IVAL(b,0); @@ -143,7 +143,7 @@ void read_buf(int f,char *buf,int len) if (verbose > 1) fprintf(stderr,"Error reading %d bytes : %s\n", len,ret==-1?strerror(errno):"EOF"); - exit(1); + exit_cleanup(1); } total_read += len; } @@ -196,7 +196,7 @@ int write_sparse(int f,char *buf,int len) int read_write(int fd_in,int fd_out,int size) { static char *buf=NULL; - static int bufsize = WRITE_BLOCK_SIZE; + static int bufsize = CHUNK_SIZE; int total=0; if (!buf) { @@ -258,7 +258,7 @@ void write_int(int f,int x) if ((ret=writefd(f,b,4)) != 4) { fprintf(stderr,"write_int failed : %s\n", ret==-1?strerror(errno):"EOF"); - exit(1); + exit_cleanup(1); } total_written += 4; } @@ -269,7 +269,7 @@ void write_buf(int f,char *buf,int len) if ((ret=writefd(f,buf,len)) != len) { fprintf(stderr,"write_buf failed : %s\n", ret==-1?strerror(errno):"EOF"); - exit(1); + exit_cleanup(1); } total_written += len; } diff --git a/main.c b/main.c index d0583d69..92103fc7 100644 --- a/main.c +++ b/main.c @@ -44,7 +44,7 @@ int ignore_times=0; int delete_mode=0; int one_file_system=0; int remote_version=0; -int csum_length=SUM_LENGTH; +extern int csum_length; int am_server = 0; static int sender = 0; @@ -223,13 +223,13 @@ static char *get_local_name(struct file_list *flist,char *name) if (S_ISDIR(st.st_mode)) { if (chdir(name) != 0) { fprintf(stderr,"chdir %s : %s\n",name,strerror(errno)); - exit(1); + exit_cleanup(1); } return NULL; } if (flist->count > 1) { fprintf(stderr,"ERROR: destination must be a directory when copying more than 1 file\n"); - exit(1); + exit_cleanup(1); } return name; } @@ -242,14 +242,14 @@ static char *get_local_name(struct file_list *flist,char *name) if (mkdir(name,0777) != 0) { fprintf(stderr,"mkdir %s : %s\n",name,strerror(errno)); - exit(1); + exit_cleanup(1); } else { fprintf(am_server?stderr:stdout,"created directory %s\n",name); } if (chdir(name) != 0) { fprintf(stderr,"chdir %s : %s\n",name,strerror(errno)); - exit(1); + exit_cleanup(1); } return NULL; @@ -269,7 +269,7 @@ void do_server_sender(int argc,char *argv[]) if (chdir(dir) != 0) { fprintf(stderr,"chdir %s: %s\n",dir,strerror(errno)); - exit(1); + exit_cleanup(1); } argc--; argv++; @@ -290,7 +290,7 @@ void do_server_sender(int argc,char *argv[]) flist = send_file_list(STDOUT_FILENO,recurse,argc,argv); send_files(flist,STDOUT_FILENO,STDIN_FILENO); report(STDOUT_FILENO); - exit(0); + exit_cleanup(0); } @@ -311,7 +311,7 @@ void do_server_recv(int argc,char *argv[]) argv++; if (chdir(dir) != 0) { fprintf(stderr,"chdir %s : %s\n",dir,strerror(errno)); - exit(1); + exit_cleanup(1); } } @@ -321,7 +321,7 @@ void do_server_recv(int argc,char *argv[]) flist = recv_file_list(STDIN_FILENO); if (!flist || flist->count == 0) { fprintf(stderr,"nothing to do\n"); - exit(1); + exit_cleanup(1); } if (argc > 0) { @@ -336,13 +336,13 @@ void do_server_recv(int argc,char *argv[]) recv_files(STDIN_FILENO,flist,local_name); if (verbose > 2) fprintf(stderr,"receiver read %d\n",read_total()); - exit(0); + exit_cleanup(0); } generate_files(STDOUT_FILENO,flist,local_name); waitpid(pid, &status, 0); - exit(status); + exit_cleanup(status); } @@ -436,6 +436,8 @@ int main(int argc,char *argv[]) starttime = time(NULL); + checksum_init(); + while ((opt = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1) { @@ -444,7 +446,7 @@ int main(int argc,char *argv[]) case OPT_VERSION: printf("rsync version %s protocol version %d\n", VERSION,PROTOCOL_VERSION); - exit(0); + exit_cleanup(0); case OPT_SUFFIX: backup_suffix = optarg; @@ -481,7 +483,7 @@ int main(int argc,char *argv[]) case 'h': usage(stdout); - exit(0); + exit_cleanup(0); case 'b': make_backups=1; @@ -514,7 +516,7 @@ int main(int argc,char *argv[]) preserve_uid=1; } else { fprintf(stderr,"-o only allowed for root\n"); - exit(1); + exit_cleanup(1); } break; @@ -527,7 +529,7 @@ int main(int argc,char *argv[]) preserve_devices=1; } else { fprintf(stderr,"-D only allowed for root\n"); - exit(1); + exit_cleanup(1); } break; @@ -564,7 +566,7 @@ int main(int argc,char *argv[]) case OPT_SENDER: if (!am_server) { usage(stderr); - exit(1); + exit_cleanup(1); } sender = 1; break; @@ -583,7 +585,7 @@ int main(int argc,char *argv[]) default: fprintf(stderr,"bad option -%c\n",opt); - exit(1); + exit_cleanup(1); } } @@ -600,7 +602,7 @@ int main(int argc,char *argv[]) if (remote_version < MIN_PROTOCOL_VERSION || remote_version > MAX_PROTOCOL_VERSION) { fprintf(stderr,"protocol version mismatch - is your shell clean?\n"); - exit(1); + exit_cleanup(1); } write_int(STDOUT_FILENO,PROTOCOL_VERSION); write_flush(STDOUT_FILENO); @@ -615,12 +617,12 @@ int main(int argc,char *argv[]) } else { do_server_recv(argc,argv); } - exit(0); + exit_cleanup(0); } if (argc < 2) { usage(stderr); - exit(1); + exit_cleanup(1); } p = strchr(argv[0],':'); @@ -674,7 +676,7 @@ int main(int argc,char *argv[]) if (!sender && argc != 1) { usage(stderr); - exit(1); + exit_cleanup(1); } pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,&f_in,&f_out); @@ -686,7 +688,7 @@ int main(int argc,char *argv[]) if (remote_version < MIN_PROTOCOL_VERSION || remote_version > MAX_PROTOCOL_VERSION) { fprintf(stderr,"protocol version mismatch - is your shell clean?\n"); - exit(1); + exit_cleanup(1); } } @@ -709,7 +711,7 @@ int main(int argc,char *argv[]) fprintf(stderr,"waiting on %d\n",pid); waitpid(pid, &status, 0); report(-1); - exit(status); + exit_cleanup(status); } send_exclude_list(f_out); @@ -717,7 +719,7 @@ int main(int argc,char *argv[]) flist = recv_file_list(f_in); if (!flist || flist->count == 0) { fprintf(stderr,"nothing to do\n"); - exit(0); + exit_cleanup(0); } local_name = get_local_name(flist,argv[0]); @@ -726,7 +728,7 @@ int main(int argc,char *argv[]) recv_files(f_in,flist,local_name); if (verbose > 1) fprintf(stderr,"receiver read %d\n",read_total()); - exit(0); + exit_cleanup(0); } generate_files(f_out,flist,local_name); diff --git a/match.c b/match.c index a2121a17..3cd489d0 100644 --- a/match.c +++ b/match.c @@ -103,7 +103,7 @@ static void matched(int f,struct sum_struct *s,char *buf,off_t len, int l = 0; write_int(f,n); while (l < n) { - int n1 = MIN(WRITE_BLOCK_SIZE,n-l); + int n1 = MIN(CHUNK_SIZE,n-l); write_buf(f,map_ptr(buf,last_match+l,n1),n1); l += n1; } diff --git a/rsync.c b/rsync.c index cdf7c3ec..bb249800 100644 --- a/rsync.c +++ b/rsync.c @@ -406,7 +406,7 @@ static void receive_data(int f_in,char *buf,int fd,char *fname) if (read_write(f_in,fd,i) != i) { fprintf(stderr,"write failed on %s : %s\n",fname,strerror(errno)); - exit(1); + exit_cleanup(1); } offset += i; } else { @@ -422,7 +422,7 @@ static void receive_data(int f_in,char *buf,int fd,char *fname) if (write_sparse(fd,map_ptr(buf,offset2,len),len) != len) { fprintf(stderr,"write failed on %s : %s\n",fname,strerror(errno)); - exit(1); + exit_cleanup(1); } offset += len; } @@ -430,7 +430,7 @@ static void receive_data(int f_in,char *buf,int fd,char *fname) if (offset > 0 && sparse_end(fd) != 0) { fprintf(stderr,"write failed on %s : %s\n",fname,strerror(errno)); - exit(1); + exit_cleanup(1); } } @@ -476,11 +476,16 @@ static void delete_files(struct file_list *flist) static char *cleanup_fname = NULL; -void sig_int(void) +void exit_cleanup(int code) { if (cleanup_fname) unlink(cleanup_fname); - exit(1); + exit(code); +} + +void sig_int(void) +{ + exit_cleanup(1); } @@ -578,7 +583,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name) sprintf(fnamebak,"%s%s",fname,backup_suffix); if (rename(fname,fnamebak) != 0 && errno != ENOENT) { fprintf(stderr,"rename %s %s : %s\n",fname,fnamebak,strerror(errno)); - exit(1); + exit_cleanup(1); } } diff --git a/rsync.h b/rsync.h index 36e8f5bd..3220e462 100644 --- a/rsync.h +++ b/rsync.h @@ -38,8 +38,7 @@ #define MIN_PROTOCOL_VERSION 10 #define MAX_PROTOCOL_VERSION 20 -/* block size to write files in */ -#define WRITE_BLOCK_SIZE (32*1024) +#define CHUNK_SIZE (32*1024) #define MAX_MAP_SIZE (4*1024*1024) #define BLOCKING_TIMEOUT 10 diff --git a/util.c b/util.c index 537ec0b6..ff40b884 100644 --- a/util.c +++ b/util.c @@ -66,7 +66,7 @@ char *map_ptr(char *buf,off_t offset,int len) return (p + (offset - p_offset)); } - len = MAX(len,WRITE_BLOCK_SIZE); + len = MAX(len,CHUNK_SIZE); len = MIN(len,map_size - offset); if (len > p_size) { @@ -79,7 +79,7 @@ char *map_ptr(char *buf,off_t offset,int len) if (lseek(map_fd,offset,SEEK_SET) != offset || read(map_fd,p,len) != len) { fprintf(stderr,"EOF in map_ptr!\n"); - exit(1); + exit_cleanup(1); } p_offset = offset; @@ -111,14 +111,14 @@ int piped_child(char **command,int *f_in,int *f_out) if (pipe(to_child_pipe) < 0 || pipe(from_child_pipe) < 0) { fprintf(stderr,"pipe: %s\n",strerror(errno)); - exit(1); + exit_cleanup(1); } pid = fork(); if (pid < 0) { fprintf(stderr,"fork: %s\n",strerror(errno)); - exit(1); + exit_cleanup(1); } if (pid == 0) @@ -128,18 +128,18 @@ int piped_child(char **command,int *f_in,int *f_out) close(from_child_pipe[0]) < 0 || dup2(from_child_pipe[1], STDOUT_FILENO) < 0) { fprintf(stderr,"Failed to dup/close : %s\n",strerror(errno)); - exit(1); + exit_cleanup(1); } execvp(command[0], command); fprintf(stderr,"Failed to exec %s : %s\n", command[0],strerror(errno)); - exit(1); + exit_cleanup(1); } if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0) { fprintf(stderr,"Failed to close : %s\n",strerror(errno)); - exit(1); + exit_cleanup(1); } *f_in = from_child_pipe[0]; @@ -152,7 +152,7 @@ int piped_child(char **command,int *f_in,int *f_out) void out_of_memory(char *str) { fprintf(stderr,"out of memory in %s\n",str); - exit(1); + exit_cleanup(1); } -- 2.34.1