00001
00002
00003 #include <sys/types.h>
00004 #include <fcntl.h>
00005 #include <stdlib.h>
00006 #include <unistd.h>
00007 #include <stdio.h>
00008 #include <string.h>
00009 #include <errno.h>
00010
00011 _PROTOTYPE(void fatal, (char *label));
00012 _PROTOTYPE(int cmp, (int fd1, int fd2));
00013 _PROTOTYPE(void Usage, (void));
00014 _PROTOTYPE(int main, (int argc, char **argv));
00015
00016 #define BLOCK 4096
00017
00018 static int loud = 0, silent = 0;
00019 static char *name1, *name2;
00020
00021 int main(argc, argv)
00022 int argc;
00023 char **argv;
00024 {
00025 int fd1, fd2;
00026
00027
00028 while (argc > 1 && argv[1][0] == '-' && argv[1][1] != 0) {
00029 if (argv[1][2] != 0) Usage();
00030
00031 switch (argv[1][1]) {
00032 case '-':
00033
00034 break;
00035 case 'l':
00036 loud = 1;
00037 break;
00038 case 's':
00039 silent = 1;
00040 break;
00041 default:
00042 Usage();
00043 }
00044 argc--;
00045 argv++;
00046 }
00047 if (argc != 3) Usage();
00048
00049
00050 if (argv[1][0] == '-' && argv[1][1] == 0) {
00051 name1 = "stdin";
00052 fd1 = 0;
00053 } else {
00054 name1 = argv[1];
00055 if ((fd1 = open(name1, 0)) < 0) fatal(name1);
00056 }
00057
00058
00059 if (argv[2][0] == '-' && argv[2][1] == 0) {
00060 name2 = "stdin";
00061 fd2 = 0;
00062 } else {
00063 name2 = argv[2];
00064 if ((fd2 = open(name2, 0)) < 0) fatal(name2);
00065 }
00066
00067 exit(cmp(fd1, fd2));
00068 }
00069
00070 int cmp(fd1, fd2)
00071 int fd1, fd2;
00072 {
00073 static char buf1[BLOCK], buf2[BLOCK];
00074 int n1 = 0, n2 = 0, i1 = 0, i2 = 0, c1, c2;
00075 off_t pos = 0, line = 1;
00076 int eof = 0, differ = 0;
00077
00078 for (;;) {
00079 if (i1 == n1) {
00080 pos += n1;
00081
00082 if ((n1 = read(fd1, buf1, sizeof(buf1))) <= 0) {
00083 if (n1 < 0) fatal(name1);
00084 eof |= 1;
00085 }
00086 i1 = 0;
00087 }
00088 if (i2 == n2) {
00089 if ((n2 = read(fd2, buf2, sizeof(buf2))) <= 0) {
00090 if (n2 < 0) fatal(name2);
00091 eof |= 2;
00092 }
00093 i2 = 0;
00094 }
00095 if (eof != 0) break;
00096
00097 c1 = buf1[i1++];
00098 c2 = buf2[i2++];
00099
00100 if (c1 != c2) {
00101 if (!loud) {
00102 if (!silent) {
00103 printf("%s %s differ: char %ld, line %ld\n",
00104 name1, name2, pos + i1, line);
00105 }
00106 return(1);
00107 }
00108 printf("%10ld %3o %3o\n", pos + i1, c1 & 0xFF, c2 & 0xFF);
00109 differ = 1;
00110 }
00111 if (c1 == '\n') line++;
00112 }
00113 if (eof == (1 | 2)) return(differ);
00114 if (!silent) fprintf(stderr, "cmp: EOF on %s\n", eof == 1 ? name1 : name2);
00115 return(1);
00116 }
00117
00118 void fatal(label)
00119 char *label;
00120 {
00121 if (!silent) fprintf(stderr, "cmp: %s: %s\n", label, strerror(errno));
00122 exit(2);
00123 }
00124
00125 void Usage()
00126 {
00127 fprintf(stderr, "Usage: cmp [-l | -s] file1 file2\n");
00128 exit(2);
00129 }