xref: /plan9/sys/src/cmd/sum.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
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