cmp.c 2.4 KB

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