13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier 4*219b2ee8SDavid du Colombier #define BUF 65536 53e12c5d1SDavid du Colombier 63e12c5d1SDavid du Colombier int sflag = 0; 73e12c5d1SDavid du Colombier int lflag = 0; 83e12c5d1SDavid du Colombier int Lflag = 0; 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier static void usage(void); 113e12c5d1SDavid du Colombier 123e12c5d1SDavid du Colombier void 133e12c5d1SDavid du Colombier main(int argc, char *argv[]) 143e12c5d1SDavid du Colombier { 153e12c5d1SDavid du Colombier int n, i; 163e12c5d1SDavid du Colombier uchar *p, *q; 173e12c5d1SDavid du Colombier uchar buf1[BUF], buf2[BUF]; 183e12c5d1SDavid du Colombier int f1, f2; 193e12c5d1SDavid du Colombier long nc = 1, o, l = 1; 203e12c5d1SDavid du Colombier char *name1, *name2; 213e12c5d1SDavid du Colombier uchar *b1s, *b1e, *b2s, *b2e; 223e12c5d1SDavid du Colombier 233e12c5d1SDavid du Colombier ARGBEGIN{ 243e12c5d1SDavid du Colombier case 's': sflag = 1; break; 253e12c5d1SDavid du Colombier case 'l': lflag = 1; break; 263e12c5d1SDavid du Colombier case 'L': Lflag = 1; break; 273e12c5d1SDavid du Colombier default: usage(); 283e12c5d1SDavid du Colombier }ARGEND 293e12c5d1SDavid du Colombier if(argc < 2) 303e12c5d1SDavid du Colombier usage(); 313e12c5d1SDavid du Colombier if((f1 = open(name1 = *argv++, OREAD)) == -1){ 323e12c5d1SDavid du Colombier if(!sflag) perror(name1); 333e12c5d1SDavid du Colombier exits("open"); 343e12c5d1SDavid du Colombier } 353e12c5d1SDavid du Colombier if((f2 = open(name2 = *argv++, OREAD)) == -1){ 363e12c5d1SDavid du Colombier if(!sflag) perror(name2); 373e12c5d1SDavid du Colombier exits("open"); 383e12c5d1SDavid du Colombier } 393e12c5d1SDavid du Colombier if(*argv){ 403e12c5d1SDavid du Colombier o = strtol(*argv++, 0, 0); 413e12c5d1SDavid du Colombier if(seek(f1, o, 0) < 0){ 423e12c5d1SDavid du Colombier if(!sflag) perror("cmp: seek by offset1"); 433e12c5d1SDavid du Colombier exits("seek 1"); 443e12c5d1SDavid du Colombier } 453e12c5d1SDavid du Colombier } 463e12c5d1SDavid du Colombier if(*argv){ 473e12c5d1SDavid du Colombier o = strtol(*argv++, 0, 0); 483e12c5d1SDavid du Colombier if(seek(f2, o, 0) < 0){ 493e12c5d1SDavid du Colombier if(!sflag) perror("cmp: seek by offset2"); 503e12c5d1SDavid du Colombier exits("seek 2"); 513e12c5d1SDavid du Colombier } 523e12c5d1SDavid du Colombier } 533e12c5d1SDavid du Colombier if(*argv) 543e12c5d1SDavid du Colombier usage(); 553e12c5d1SDavid du Colombier b1s = b1e = buf1; 563e12c5d1SDavid du Colombier b2s = b2e = buf2; 573e12c5d1SDavid du Colombier for(;;){ 583e12c5d1SDavid du Colombier if(b1s >= b1e){ 593e12c5d1SDavid du Colombier if(b1s >= &buf1[BUF]) 603e12c5d1SDavid du Colombier b1s = buf1; 613e12c5d1SDavid du Colombier n = read(f1, b1s, &buf1[BUF] - b1s); 623e12c5d1SDavid du Colombier b1e = b1s + n; 633e12c5d1SDavid du Colombier } 643e12c5d1SDavid du Colombier if(b2s >= b2e){ 653e12c5d1SDavid du Colombier if(b2s >= &buf2[BUF]) 663e12c5d1SDavid du Colombier b2s = buf2; 673e12c5d1SDavid du Colombier n = read(f2, b2s, &buf2[BUF] - b2s); 683e12c5d1SDavid du Colombier b2e = b2s + n; 693e12c5d1SDavid du Colombier } 703e12c5d1SDavid du Colombier n = b2e - b2s; 713e12c5d1SDavid du Colombier if(n > b1e - b1s) 723e12c5d1SDavid du Colombier n = b1e - b1s; 733e12c5d1SDavid du Colombier if(n <= 0) 743e12c5d1SDavid du Colombier break; 753e12c5d1SDavid du Colombier if(memcmp((void *)b1s, (void *)b2s, n) != 0){ 763e12c5d1SDavid du Colombier if(sflag) 773e12c5d1SDavid du Colombier exits("differ"); 783e12c5d1SDavid du Colombier for(p = b1s, q = b2s, i = 0; i < n; p++, q++, i++) { 793e12c5d1SDavid du Colombier if(*p == '\n') 803e12c5d1SDavid du Colombier l++; 813e12c5d1SDavid du Colombier if(*p != *q){ 823e12c5d1SDavid du Colombier if(!lflag){ 833e12c5d1SDavid du Colombier print("%s %s differ: char %d", 843e12c5d1SDavid du Colombier name1, name2, nc+i); 853e12c5d1SDavid du Colombier print(Lflag?" line %d\n":"\n", l); 863e12c5d1SDavid du Colombier exits("differ"); 873e12c5d1SDavid du Colombier } 883e12c5d1SDavid du Colombier print("%6ld 0x%.2x 0x%.2x\n", nc+i, *p, *q); 893e12c5d1SDavid du Colombier } 903e12c5d1SDavid du Colombier } 913e12c5d1SDavid du Colombier } 923e12c5d1SDavid du Colombier if(Lflag) 933e12c5d1SDavid du Colombier for(p = b1s; p < b1e;) 943e12c5d1SDavid du Colombier if(*p++ == '\n') 953e12c5d1SDavid du Colombier l++; 963e12c5d1SDavid du Colombier nc += n; 973e12c5d1SDavid du Colombier b1s += n; 983e12c5d1SDavid du Colombier b2s += n; 993e12c5d1SDavid du Colombier } 1003e12c5d1SDavid du Colombier if(b1e - b1s == b2e - b2s) 1013e12c5d1SDavid du Colombier exits((char *)0); 1023e12c5d1SDavid du Colombier if(!sflag) 1033e12c5d1SDavid du Colombier print("EOF on %s\n", (b1e - b1s > b2e - b2s)? name2 : name1); 1043e12c5d1SDavid du Colombier exits("differ"); 1053e12c5d1SDavid du Colombier } 1063e12c5d1SDavid du Colombier 1073e12c5d1SDavid du Colombier static void 1083e12c5d1SDavid du Colombier usage(void) 1093e12c5d1SDavid du Colombier { 1103e12c5d1SDavid du Colombier print("Usage: cmp [-ls] file1 file2 [offset1 [offset2] ]\n"); 1113e12c5d1SDavid du Colombier exits("usage"); 1123e12c5d1SDavid du Colombier } 113