home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / rsync221.zip / checksum.c < prev    next >
C/C++ Source or Header  |  1999-03-04  |  4KB  |  181 lines

  1. /* 
  2.    Copyright (C) Andrew Tridgell 1996
  3.    Copyright (C) Paul Mackerras 1996
  4.    
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2 of the License, or
  8.    (at your option) any later version.
  9.    
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.    
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. #include "rsync.h"
  21.  
  22. int csum_length=2; /* initial value */
  23.  
  24. #define CSUM_CHUNK 64
  25.  
  26. int checksum_seed = 0;
  27. extern int remote_version;
  28.  
  29. /*
  30.   a simple 32 bit checksum that can be upadted from either end
  31.   (inspired by Mark Adler's Adler-32 checksum)
  32.   */
  33. uint32 get_checksum1(char *buf1,int len)
  34. {
  35.     int i;
  36.     uint32 s1, s2;
  37.     schar *buf = (schar *)buf1;
  38.  
  39.     s1 = s2 = 0;
  40.     for (i = 0; i < (len-4); i+=4) {
  41.     s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3] + 
  42.       10*CHAR_OFFSET;
  43.     s1 += (buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3] + 4*CHAR_OFFSET); 
  44.     }
  45.     for (; i < len; i++) {
  46.     s1 += (buf[i]+CHAR_OFFSET); s2 += s1;
  47.     }
  48.     return (s1 & 0xffff) + (s2 << 16);
  49. }
  50.  
  51.  
  52. void get_checksum2(char *buf,int len,char *sum)
  53. {
  54.     int i;
  55.     static char *buf1;
  56.     static int len1;
  57.     struct mdfour m;
  58.  
  59.     if (len > len1) {
  60.         if (buf1) free(buf1);
  61.         buf1 = (char *)malloc(len+4);
  62.         len1 = len;
  63.         if (!buf1) out_of_memory("get_checksum2");
  64.     }
  65.     
  66.     mdfour_begin(&m);
  67.     
  68.     memcpy(buf1,buf,len);
  69.     if (checksum_seed) {
  70.         SIVAL(buf1,len,checksum_seed);
  71.         len += 4;
  72.     }
  73.     
  74.     for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
  75.         mdfour_update(&m, (uchar *)(buf1+i), CSUM_CHUNK);
  76.     }
  77.     if (len - i > 0) {
  78.         mdfour_update(&m, (uchar *)(buf1+i), (len-i));
  79.     }
  80.     
  81.     mdfour_result(&m, (uchar *)sum);
  82. }
  83.  
  84.  
  85. void file_checksum(char *fname,char *sum,OFF_T size)
  86. {
  87.     OFF_T i;
  88.     struct map_struct *buf;
  89.     int fd;
  90.     OFF_T len = size;
  91.     char tmpchunk[CSUM_CHUNK];
  92.     struct mdfour m;
  93.     
  94.     memset(sum,0,csum_length);
  95.     
  96.     fd = open(fname,O_RDONLY);
  97.     if (fd == -1) return;
  98.     
  99.     buf = map_file(fd,size);
  100.     
  101.     mdfour_begin(&m);
  102.  
  103.     for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
  104.         memcpy(tmpchunk, map_ptr(buf,i,CSUM_CHUNK), CSUM_CHUNK);
  105.         mdfour_update(&m, (uchar *)tmpchunk, CSUM_CHUNK);
  106.     }
  107.  
  108.     if (len - i > 0) {
  109.         memcpy(tmpchunk, map_ptr(buf,i,len-i), len-i);
  110.         mdfour_update(&m, (uchar *)tmpchunk, (len-i));
  111.     }
  112.  
  113.     mdfour_result(&m, (uchar *)sum);
  114.  
  115.     close(fd);
  116.     unmap_file(buf);
  117. }
  118.  
  119.  
  120. void checksum_init(void)
  121. {
  122.   if (remote_version >= 14)
  123.     csum_length = 2; /* adaptive */
  124.   else
  125.     csum_length = SUM_LENGTH;
  126. }
  127.  
  128.  
  129.  
  130. static int sumresidue;
  131. static char sumrbuf[CSUM_CHUNK];
  132. static struct mdfour md;
  133.  
  134. void sum_init(void)
  135. {
  136.     char s[4];
  137.     mdfour_begin(&md);
  138.     sumresidue=0;
  139.     SIVAL(s,0,checksum_seed);
  140.     sum_update(s,4);
  141. }
  142.  
  143. void sum_update(char *p,int len)
  144. {
  145.     int i;
  146.     if (len + sumresidue < CSUM_CHUNK) {
  147.         memcpy(sumrbuf+sumresidue, p, len);
  148.         sumresidue += len;
  149.         return;
  150.     }
  151.  
  152.     if (sumresidue) {
  153.         i = MIN(CSUM_CHUNK-sumresidue,len);
  154.         memcpy(sumrbuf+sumresidue,p,i);
  155.         mdfour_update(&md, (uchar *)sumrbuf, (i+sumresidue));
  156.         len -= i;
  157.         p += i;
  158.     }
  159.  
  160.     for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
  161.         memcpy(sumrbuf,p+i,CSUM_CHUNK);
  162.         mdfour_update(&md, (uchar *)sumrbuf, CSUM_CHUNK);
  163.     }
  164.  
  165.     if (len - i > 0) {
  166.         sumresidue = len-i;
  167.         memcpy(sumrbuf,p+i,sumresidue);
  168.     } else {
  169.         sumresidue = 0;    
  170.     }
  171. }
  172.  
  173. void sum_end(char *sum)
  174. {
  175.     if (sumresidue) {
  176.         mdfour_update(&md, (uchar *)sumrbuf, sumresidue);
  177.     }
  178.  
  179.     mdfour_result(&md, (uchar *)sum);
  180. }
  181.