summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--checksum.c98
-rw-r--r--exclude.c2
-rw-r--r--flist.c4
-rw-r--r--io.c10
-rw-r--r--main.c52
-rw-r--r--match.c2
-rw-r--r--rsync.c17
-rw-r--r--rsync.h3
-rw-r--r--util.c16
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<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
diff --git a/exclude.c b/exclude.c
index 1c51607f..9a837411 100644
--- 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 a89f6f5b..fad433a0 100644
--- 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 40ccc735..c903fa6f 100644
--- 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 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);
}