new exit/cleanup code
authorAndrew Tridgell <tridge@samba.org>
Fri, 28 Jun 1996 13:55:41 +0000 (13:55 +0000)
committerAndrew Tridgell <tridge@samba.org>
Fri, 28 Jun 1996 13:55:41 +0000 (13:55 +0000)
checksum.c
exclude.c
flist.c
io.c
main.c
match.c
rsync.c
rsync.h
util.c

index b656ef9..eac41c4 100644 (file)
 
 #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<argc;i++) {
+    struct stat st;
+    if (stat(argv[i],&st) == 0) {
+      file_checksum(argv[i],sum,st.st_size);
+      for (j=0;j<SUM_LENGTH;j++)
+       printf("%02X",(unsigned char)sum[j]);
+      printf("  %s\n",argv[i]);
+    }
+  }
+}
+#endif
index 1c51607..9a83741 100644 (file)
--- a/exclude.c
+++ b/exclude.c
@@ -122,7 +122,7 @@ char **make_exclude_list(char *fname,char **list1,int fatal)
   if (!f) {
     if (fatal) {
       fprintf(stderr,"%s : %s\n",fname,strerror(errno));
-      exit(1);
+      exit_cleanup(1);
     }
     return list;
   }
diff --git a/flist.c b/flist.c
index a89f6f5..fad433a 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -411,7 +411,7 @@ struct file_list *send_file_list(int f,int recurse,int argc,char *argv[])
     if (dir && *dir) {
       if (getcwd(dbuf,MAXPATHLEN-1) == NULL) {
        fprintf(stderr,"getwd : %s\n",strerror(errno));
-       exit(1);
+       exit_cleanup(1);
       }
       if (chdir(dir) != 0) {
        fprintf(stderr,"chdir %s : %s\n",dir,strerror(errno));
@@ -424,7 +424,7 @@ struct file_list *send_file_list(int f,int recurse,int argc,char *argv[])
       flist_dir = NULL;
       if (chdir(dbuf) != 0) {
        fprintf(stderr,"chdir %s : %s\n",dbuf,strerror(errno));
-       exit(1);
+       exit_cleanup(1);
       }
       continue;
     }
diff --git a/io.c b/io.c
index 40ccc73..c903fa6 100644 (file)
--- a/io.c
+++ b/io.c
@@ -130,7 +130,7 @@ int read_int(int f)
     if (verbose > 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 d0583d6..92103fc 100644 (file)
--- 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 a2121a1..3cd489d 100644 (file)
--- 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 cdf7c3e..bb24980 100644 (file)
--- 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 36e8f5b..3220e46 100644 (file)
--- 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 537ec0b..ff40b88 100644 (file)
--- 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);
 }