X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/7bec6a5cd6cabe93163707b901482a6692ca78cf..34ccb63e71367fb1f93530f60147ef6e4ac4e3e4:/checksum.c 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