13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier
4*9a747e4fSDavid du Colombier typedef ulong Sumfn(ulong, void*, uvlong);
53e12c5d1SDavid du Colombier extern Sumfn sumr, sum5, sum32;
63e12c5d1SDavid du Colombier char *sumfile(char*, Sumfn*);
73e12c5d1SDavid du Colombier
83e12c5d1SDavid du Colombier void
usage(void)93e12c5d1SDavid du Colombier usage(void)
103e12c5d1SDavid du Colombier {
117dd7cddfSDavid du Colombier fprint(2, "Usage: %s [-r5] [files]\n", argv0);
123e12c5d1SDavid du Colombier exits("usage");
133e12c5d1SDavid du Colombier }
143e12c5d1SDavid du Colombier
153e12c5d1SDavid du Colombier void
main(int argc,char ** argv)163e12c5d1SDavid du Colombier main(int argc, char **argv)
173e12c5d1SDavid du Colombier {
183e12c5d1SDavid du Colombier Sumfn *fn = sum32;
193e12c5d1SDavid du Colombier char *exitstr=0, *s;
203e12c5d1SDavid du Colombier
213e12c5d1SDavid du Colombier ARGBEGIN{
223e12c5d1SDavid du Colombier case 'r':
233e12c5d1SDavid du Colombier fn = sumr;
243e12c5d1SDavid du Colombier break;
253e12c5d1SDavid du Colombier case '5':
263e12c5d1SDavid du Colombier fn = sum5;
273e12c5d1SDavid du Colombier break;
283e12c5d1SDavid du Colombier default:
293e12c5d1SDavid du Colombier usage();
303e12c5d1SDavid du Colombier break;
313e12c5d1SDavid du Colombier }ARGEND
323e12c5d1SDavid du Colombier if(*argv){
333e12c5d1SDavid du Colombier while(*argv)
343e12c5d1SDavid du Colombier if(s = sumfile(*argv++, fn)) /* assign = */
353e12c5d1SDavid du Colombier exitstr = s;
363e12c5d1SDavid du Colombier }else
373e12c5d1SDavid du Colombier exitstr = sumfile(0, fn);
383e12c5d1SDavid du Colombier exits(exitstr);
393e12c5d1SDavid du Colombier }
403e12c5d1SDavid du Colombier
413e12c5d1SDavid du Colombier char*
sumfile(char * file,Sumfn * fn)423e12c5d1SDavid du Colombier sumfile(char *file, Sumfn *fn)
433e12c5d1SDavid du Colombier {
443e12c5d1SDavid du Colombier int fd;
453e12c5d1SDavid du Colombier int n;
463e12c5d1SDavid du Colombier ulong sum;
47*9a747e4fSDavid du Colombier uvlong fsize;
483e12c5d1SDavid du Colombier char buf[8*1024];
493e12c5d1SDavid du Colombier
503e12c5d1SDavid du Colombier if(file){
513e12c5d1SDavid du Colombier if((fd = open(file, OREAD)) < 0){
52*9a747e4fSDavid du Colombier errstr(buf, sizeof buf);
533e12c5d1SDavid du Colombier fprint(2, "%s: %s: %s\n", argv0, file, buf);
543e12c5d1SDavid du Colombier return "can't open";
553e12c5d1SDavid du Colombier }
563e12c5d1SDavid du Colombier }else
573e12c5d1SDavid du Colombier fd = 0;
583e12c5d1SDavid du Colombier fsize = 0;
593e12c5d1SDavid du Colombier sum = 0;
603e12c5d1SDavid du Colombier while((n=read(fd, buf, sizeof buf)) > 0){
613e12c5d1SDavid du Colombier fsize += n;
623e12c5d1SDavid du Colombier sum = (*fn)(sum, buf, n);
633e12c5d1SDavid du Colombier }
643e12c5d1SDavid du Colombier if(n < 0){
65*9a747e4fSDavid du Colombier errstr(buf, sizeof buf);
663e12c5d1SDavid du Colombier fprint(2, "%s: %s: read error: %s\n", argv0, file? file:"<stdin>", buf);
673e12c5d1SDavid du Colombier if(file)
683e12c5d1SDavid du Colombier close(fd);
693e12c5d1SDavid du Colombier return "read error";
703e12c5d1SDavid du Colombier }
713e12c5d1SDavid du Colombier if(file)
723e12c5d1SDavid du Colombier close(fd);
733e12c5d1SDavid du Colombier (*fn)(sum, (char*)0, fsize);
743e12c5d1SDavid du Colombier if(file)
753e12c5d1SDavid du Colombier print(" %s", file);
763e12c5d1SDavid du Colombier print("\n");
773e12c5d1SDavid du Colombier return 0;
783e12c5d1SDavid du Colombier }
793e12c5d1SDavid du Colombier
803e12c5d1SDavid du Colombier #define VBSIZE 512 /* system v */
813e12c5d1SDavid du Colombier
823e12c5d1SDavid du Colombier ulong
sum5(ulong sum,void * buf,uvlong uvn)83*9a747e4fSDavid du Colombier sum5(ulong sum, void *buf, uvlong uvn)
843e12c5d1SDavid du Colombier {
853e12c5d1SDavid du Colombier uchar *s, *send;
86*9a747e4fSDavid du Colombier int n;
873e12c5d1SDavid du Colombier
883e12c5d1SDavid du Colombier if(buf == 0){
893e12c5d1SDavid du Colombier sum = ((sum>>16)+sum) & 0xFFFF;
90*9a747e4fSDavid du Colombier print("%.5lud%6lld", sum, (uvn+(VBSIZE-1))/VBSIZE);
913e12c5d1SDavid du Colombier return 0;
923e12c5d1SDavid du Colombier }
93*9a747e4fSDavid du Colombier n = uvn;
943e12c5d1SDavid du Colombier for(s=buf, send=s+n; s<send; s++)
953e12c5d1SDavid du Colombier sum += 0xffff & *s;
963e12c5d1SDavid du Colombier return sum;
973e12c5d1SDavid du Colombier }
983e12c5d1SDavid du Colombier
993e12c5d1SDavid du Colombier #define RBSIZE 1024 /* research */
1003e12c5d1SDavid du Colombier
1013e12c5d1SDavid du Colombier ulong
sumr(ulong sum,void * buf,uvlong uvn)102*9a747e4fSDavid du Colombier sumr(ulong sum, void *buf, uvlong uvn)
1033e12c5d1SDavid du Colombier {
1043e12c5d1SDavid du Colombier uchar *s, *send;
105*9a747e4fSDavid du Colombier int n;
1063e12c5d1SDavid du Colombier
1073e12c5d1SDavid du Colombier if(buf == 0){
1083e12c5d1SDavid du Colombier sum &= 0xFFFF;
109*9a747e4fSDavid du Colombier print("%.5lud%6lld", sum, (uvn+(RBSIZE-1))/RBSIZE);
1103e12c5d1SDavid du Colombier return 0;
1113e12c5d1SDavid du Colombier }
112*9a747e4fSDavid du Colombier n = uvn;
1133e12c5d1SDavid du Colombier for(s=buf, send=s+n; s<send; s++)
1143e12c5d1SDavid du Colombier if(sum & 1)
1153e12c5d1SDavid du Colombier sum = 0xffff & ((sum>>1)+*s+0x8000);
1163e12c5d1SDavid du Colombier else
1173e12c5d1SDavid du Colombier sum = 0xffff & ((sum>>1)+*s);
1183e12c5d1SDavid du Colombier return sum;
1193e12c5d1SDavid du Colombier }
1203e12c5d1SDavid du Colombier
1213e12c5d1SDavid du Colombier extern ulong crc_table[256];
1223e12c5d1SDavid du Colombier
1233e12c5d1SDavid du Colombier ulong
sum32(ulong lcrc,void * buf,uvlong uvn)124*9a747e4fSDavid du Colombier sum32(ulong lcrc, void *buf, uvlong uvn)
1253e12c5d1SDavid du Colombier {
1263e12c5d1SDavid du Colombier uchar *s = buf;
1273e12c5d1SDavid du Colombier ulong crc = lcrc;
128*9a747e4fSDavid du Colombier int n;
1293e12c5d1SDavid du Colombier
130*9a747e4fSDavid du Colombier n = uvn;
1313e12c5d1SDavid du Colombier if(buf == 0){
1323e12c5d1SDavid du Colombier char x[4];
1333e12c5d1SDavid du Colombier
1343e12c5d1SDavid du Colombier x[0] = (n>>24)^0xCC; /* encode the length but make n==0 not 0 */
1353e12c5d1SDavid du Colombier x[1] = (n>>16)^0x55;
1363e12c5d1SDavid du Colombier x[2] = (n>>8)^0xCC;
1373e12c5d1SDavid du Colombier x[3] = (n)^0x55;
1383e12c5d1SDavid du Colombier crc = sum32(lcrc, x, 4);
139*9a747e4fSDavid du Colombier print("%.8lux %6lld", crc, uvn);
1403e12c5d1SDavid du Colombier return 0;
1413e12c5d1SDavid du Colombier }
1423e12c5d1SDavid du Colombier while(n-- > 0)
1433e12c5d1SDavid du Colombier crc = crc_table[(crc^*s++)&0xff] ^ (crc>>8);
1443e12c5d1SDavid du Colombier return crc;
1453e12c5d1SDavid du Colombier }
1463e12c5d1SDavid du Colombier
1473e12c5d1SDavid du Colombier /*
1483e12c5d1SDavid du Colombier * CRC 035556101440
1493e12c5d1SDavid du Colombier */
1503e12c5d1SDavid du Colombier ulong crc_table[256] = {
1513e12c5d1SDavid du Colombier 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
1523e12c5d1SDavid du Colombier 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
1533e12c5d1SDavid du Colombier 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
1543e12c5d1SDavid du Colombier 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
1553e12c5d1SDavid du Colombier 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
1563e12c5d1SDavid du Colombier 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
1573e12c5d1SDavid du Colombier 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
1583e12c5d1SDavid du Colombier 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
1593e12c5d1SDavid du Colombier 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
1603e12c5d1SDavid du Colombier 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
1613e12c5d1SDavid du Colombier 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
1623e12c5d1SDavid du Colombier 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
1633e12c5d1SDavid du Colombier 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
1643e12c5d1SDavid du Colombier 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
1653e12c5d1SDavid du Colombier 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
1663e12c5d1SDavid du Colombier 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
1673e12c5d1SDavid du Colombier 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
1683e12c5d1SDavid du Colombier 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
1693e12c5d1SDavid du Colombier 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
1703e12c5d1SDavid du Colombier 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
1713e12c5d1SDavid du Colombier 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
1723e12c5d1SDavid du Colombier 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
1733e12c5d1SDavid du Colombier 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
1743e12c5d1SDavid du Colombier 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
1753e12c5d1SDavid du Colombier 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
1763e12c5d1SDavid du Colombier 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
1773e12c5d1SDavid du Colombier 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
1783e12c5d1SDavid du Colombier 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
1793e12c5d1SDavid du Colombier 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
1803e12c5d1SDavid du Colombier 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
1813e12c5d1SDavid du Colombier 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
1823e12c5d1SDavid du Colombier 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
1833e12c5d1SDavid du Colombier 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
1843e12c5d1SDavid du Colombier 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
1853e12c5d1SDavid du Colombier 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
1863e12c5d1SDavid du Colombier 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
1873e12c5d1SDavid du Colombier 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
1883e12c5d1SDavid du Colombier 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
1893e12c5d1SDavid du Colombier 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
1903e12c5d1SDavid du Colombier 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
1913e12c5d1SDavid du Colombier 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
1923e12c5d1SDavid du Colombier 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
1933e12c5d1SDavid du Colombier 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
1943e12c5d1SDavid du Colombier 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
1953e12c5d1SDavid du Colombier 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
1963e12c5d1SDavid du Colombier 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
1973e12c5d1SDavid du Colombier 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
1983e12c5d1SDavid du Colombier 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
1993e12c5d1SDavid du Colombier 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
2003e12c5d1SDavid du Colombier 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
2013e12c5d1SDavid du Colombier 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
2023e12c5d1SDavid du Colombier 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
2033e12c5d1SDavid du Colombier 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
2043e12c5d1SDavid du Colombier 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
2053e12c5d1SDavid du Colombier 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
2063e12c5d1SDavid du Colombier 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
2073e12c5d1SDavid du Colombier 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
2083e12c5d1SDavid du Colombier 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
2093e12c5d1SDavid du Colombier 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
2103e12c5d1SDavid du Colombier 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
2113e12c5d1SDavid du Colombier 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
2123e12c5d1SDavid du Colombier 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
2133e12c5d1SDavid du Colombier 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
2143e12c5d1SDavid du Colombier 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
2153e12c5d1SDavid du Colombier };
216