1 #include <u.h> 2 #include <libc.h> 3 4 typedef ulong Sumfn(ulong, void*, int); 5 extern Sumfn sumr, sum5, sum32; 6 char *sumfile(char*, Sumfn*); 7 8 void 9 usage(void) 10 { 11 fprint(2, "Usage: %s [-ir5] [files]\n", argv0); 12 exits("usage"); 13 } 14 15 void 16 main(int argc, char **argv) 17 { 18 Sumfn *fn = sum32; 19 char *exitstr=0, *s; 20 21 ARGBEGIN{ 22 case 'r': 23 fn = sumr; 24 break; 25 case '5': 26 fn = sum5; 27 break; 28 default: 29 usage(); 30 break; 31 }ARGEND 32 if(*argv){ 33 while(*argv) 34 if(s = sumfile(*argv++, fn)) /* assign = */ 35 exitstr = s; 36 }else 37 exitstr = sumfile(0, fn); 38 exits(exitstr); 39 } 40 41 char* 42 sumfile(char *file, Sumfn *fn) 43 { 44 int fd; 45 int n; 46 ulong sum; 47 int fsize; 48 char buf[8*1024]; 49 50 if(file){ 51 if((fd = open(file, OREAD)) < 0){ 52 errstr(buf); 53 fprint(2, "%s: %s: %s\n", argv0, file, buf); 54 return "can't open"; 55 } 56 }else 57 fd = 0; 58 fsize = 0; 59 sum = 0; 60 while((n=read(fd, buf, sizeof buf)) > 0){ 61 fsize += n; 62 sum = (*fn)(sum, buf, n); 63 } 64 if(n < 0){ 65 errstr(buf); 66 fprint(2, "%s: %s: read error: %s\n", argv0, file? file:"<stdin>", buf); 67 if(file) 68 close(fd); 69 return "read error"; 70 } 71 if(file) 72 close(fd); 73 (*fn)(sum, (char*)0, fsize); 74 if(file) 75 print(" %s", file); 76 print("\n"); 77 return 0; 78 } 79 80 #define VBSIZE 512 /* system v */ 81 82 ulong 83 sum5(ulong sum, void *buf, int n) 84 { 85 uchar *s, *send; 86 87 if(buf == 0){ 88 sum = ((sum>>16)+sum) & 0xFFFF; 89 print("%.5ud%6ld", sum, (n+(VBSIZE-1))/VBSIZE); 90 return 0; 91 } 92 for(s=buf, send=s+n; s<send; s++) 93 sum += 0xffff & *s; 94 return sum; 95 } 96 97 #define RBSIZE 1024 /* research */ 98 99 ulong 100 sumr(ulong sum, void *buf, int n) 101 { 102 uchar *s, *send; 103 104 if(buf == 0){ 105 sum &= 0xFFFF; 106 print("%.5ud%6ld", sum, (n+(RBSIZE-1))/RBSIZE); 107 return 0; 108 } 109 for(s=buf, send=s+n; s<send; s++) 110 if(sum & 1) 111 sum = 0xffff & ((sum>>1)+*s+0x8000); 112 else 113 sum = 0xffff & ((sum>>1)+*s); 114 return sum; 115 } 116 117 extern ulong crc_table[256]; 118 119 ulong 120 sum32(ulong lcrc, void *buf, int n) 121 { 122 uchar *s = buf; 123 ulong crc = lcrc; 124 125 if(buf == 0){ 126 char x[4]; 127 128 x[0] = (n>>24)^0xCC; /* encode the length but make n==0 not 0 */ 129 x[1] = (n>>16)^0x55; 130 x[2] = (n>>8)^0xCC; 131 x[3] = (n)^0x55; 132 crc = sum32(lcrc, x, 4); 133 print("%.8lux %6ld", crc, n); 134 return 0; 135 } 136 while(n-- > 0) 137 crc = crc_table[(crc^*s++)&0xff] ^ (crc>>8); 138 return crc; 139 } 140 141 /* 142 * CRC 035556101440 143 */ 144 ulong crc_table[256] = { 145 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 146 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 147 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 148 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 149 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 150 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 151 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 152 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 153 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 154 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 155 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 156 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 157 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 158 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 159 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 160 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 161 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 162 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 163 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 164 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 165 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 166 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 167 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 168 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 169 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 170 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 171 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 172 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 173 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 174 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 175 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 176 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 177 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 178 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 179 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 180 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 181 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 182 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 183 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 184 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 185 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 186 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 187 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 188 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 189 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 190 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 191 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 192 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 193 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 194 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 195 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 196 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 197 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 198 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 199 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 200 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 201 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 202 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 203 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 204 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 205 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 206 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 207 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 208 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, 209 }; 210