1 #include <u.h> 2 #include <libc.h> 3 #include <ctype.h> 4 5 #define BUF 65536 6 7 int sflag = 0; 8 int lflag = 0; 9 int Lflag = 0; 10 11 static void usage(void); 12 13 char ** 14 seekoff(int fd, char *name, char **argv) 15 { 16 vlong o; 17 18 if(*argv){ 19 if (!isascii(**argv) || !isdigit(**argv)) 20 usage(); 21 o = strtoll(*argv++, 0, 0); 22 if(seek(fd, o, 0) < 0){ 23 if(!sflag) fprint(2, "cmp: %s: seek by %lld: %r\n", 24 name, o); 25 exits("seek"); 26 } 27 } 28 return argv; 29 } 30 31 void 32 main(int argc, char *argv[]) 33 { 34 int n, i; 35 uchar *p, *q; 36 uchar buf1[BUF], buf2[BUF]; 37 int f1, f2; 38 vlong nc = 1, l = 1; 39 char *name1, *name2; 40 uchar *b1s, *b1e, *b2s, *b2e; 41 42 ARGBEGIN{ 43 case 's': sflag = 1; break; 44 case 'l': lflag = 1; break; 45 case 'L': Lflag = 1; break; 46 default: usage(); 47 }ARGEND 48 if(argc < 2 || argc > 4) 49 usage(); 50 if((f1 = open(name1 = *argv++, OREAD)) == -1){ 51 if(!sflag) perror(name1); 52 exits("open"); 53 } 54 if((f2 = open(name2 = *argv++, OREAD)) == -1){ 55 if(!sflag) perror(name2); 56 exits("open"); 57 } 58 argv = seekoff(f1, name1, argv); 59 argv = seekoff(f2, name2, argv); 60 if(*argv) 61 usage(); 62 63 b1s = b1e = buf1; 64 b2s = b2e = buf2; 65 for(;;){ 66 if(b1s >= b1e){ 67 if(b1s >= &buf1[BUF]) 68 b1s = buf1; 69 n = read(f1, b1s, &buf1[BUF] - b1s); 70 b1e = b1s + n; 71 } 72 if(b2s >= b2e){ 73 if(b2s >= &buf2[BUF]) 74 b2s = buf2; 75 n = read(f2, b2s, &buf2[BUF] - b2s); 76 b2e = b2s + n; 77 } 78 n = b2e - b2s; 79 if(n > b1e - b1s) 80 n = b1e - b1s; 81 if(n <= 0) 82 break; 83 if(memcmp((void *)b1s, (void *)b2s, n) != 0){ 84 if(sflag) 85 exits("differ"); 86 for(p = b1s, q = b2s, i = 0; i < n; p++, q++, i++) { 87 if(*p == '\n') 88 l++; 89 if(*p != *q){ 90 if(!lflag){ 91 print("%s %s differ: char %lld", 92 name1, name2, nc+i); 93 print(Lflag?" line %lld\n":"\n", l); 94 exits("differ"); 95 } 96 print("%6lld 0x%.2x 0x%.2x\n", nc+i, *p, *q); 97 } 98 } 99 } 100 if(Lflag) 101 for(p = b1s; p < b1e;) 102 if(*p++ == '\n') 103 l++; 104 nc += n; 105 b1s += n; 106 b2s += n; 107 } 108 if (b1e - b1s < 0 || b2e - b2s < 0) { 109 if (!sflag) { 110 if (b1e - b1s < 0) 111 print("error on %s after %lld bytes\n", 112 name1, nc-1); 113 if (b2e - b2s < 0) 114 print("error on %s after %lld bytes\n", 115 name2, nc-1); 116 } 117 exits("read error"); 118 } 119 if(b1e - b1s == b2e - b2s) 120 exits((char *)0); 121 if(!sflag) 122 print("EOF on %s after %lld bytes\n", 123 (b1e - b1s > b2e - b2s)? name2 : name1, nc-1); 124 exits("EOF"); 125 } 126 127 static void 128 usage(void) 129 { 130 print("usage: cmp [-lLs] file1 file2 [offset1 [offset2] ]\n"); 131 exits("usage"); 132 } 133