static char *sccsid
= "@(#)cmp.c 4.4 (Berkeley) %G%";
#define DIFF 1 /* found differences */
#define ERR 2 /* error during run */
#define NO 0 /* no/false */
#define OK 0 /* didn't find differences */
#define YES 1 /* yes/true */
static int fd1
, /* descriptor, file 1 */
fd2
, /* descriptor, file 2 */
silent
= NO
; /* if silent on error */
static short all
= NO
; /* if report all differences */
static u_char buf1
[MAXBSIZE
], /* read buffers */
static char *file1
, /* name, file 1 */
*file2
; /* name, file 2 */
extern char *optarg
; /* getopt externals */
while ((ch
= getopt(argc
,argv
,"ls")) != EOF
)
case 'l': /* print all differences */
case 's': /* silent return */
if (argc
< 2 || argc
> 4)
/* open up files; "-" is stdin */
if (strcmp(file1
,"-") && (fd1
= open(file1
,O_RDONLY
)) < 0) {
if ((fd2
= open(file2
,O_RDONLY
)) < 0) {
/* handle skip arguments */
skip(otoi(argv
[2]),fd1
,file1
);
skip(otoi(argv
[3]),fd2
,file2
);
* skip first part of file
register u_long dist
; /* length in bytes, to skip */
register int fd
; /* file descriptor */
char *fname
; /* file name for error */
register int rlen
; /* read length */
for (;dist
;dist
-= rlen
) {
rlen
= MIN(dist
,sizeof(buf1
));
if (read(fd
,buf1
,rlen
) != rlen
) {
printf("cmp: EOF on %s\n",fname
);
register u_char
*C1
, /* traveling pointers */
register int cnt
, /* counter */
len1
, /* read length 1 */
len2
; /* read length 2 */
register long byte
, /* byte count */
short dfound
= NO
; /* if difference found */
for (byte
= 0,line
= 1;;) {
switch(len1
= read(fd1
,buf1
,MAXBSIZE
)) {
* read of file 1 just failed, find out
* if there's anything left in file 2
switch(read(fd2
,buf2
,1)) {
exit(dfound
? DIFF
: OK
);
printf("cmp: EOF on %s\n",file1
);
* file1 might be stdio, which means that a read of less than
* MAXBSIZE might not mean an EOF. So, read whatever we read
if ((len2
= read(fd2
,buf2
,len1
)) == -1) {
if (bcmp(buf1
,buf2
,len2
)) {
for (C1
= buf1
,C2
= buf2
,cnt
= len2
;cnt
--;++C1
,++C2
) {
printf("%6ld %3o %3o\n",byte
,*C1
,*C2
);
for (C1
= buf1
,C2
= buf2
;;++C1
,++C2
) {
printf("%s %s differ: char %ld, line %ld\n",file1
,file2
,byte
,line
);
* here's the real performance problem, we've got to
* count the stupid lines, which means that -l is a
* *much* faster version, i.e., unless you really
* *want* to know the line number, run -sl.
for (C1
= buf1
,cnt
= len2
;cnt
--;)
* couldn't read as much from file2 as from file1; checked
* here because there might be a difference before we got
* to this point, which would have precedence.
printf("cmp: EOF on %s\n",file2
);
* octal/decimal string to u_long
register char *C
; /* argument string */
register u_long val
; /* return value */
register int base
; /* number base */
base
= (*C
== '0') ? 8 : 10;
for (val
= 0;isdigit(*C
);++C
)
val
= val
* base
+ *C
- '0';
fputs("usage: cmp [-ls] file1 file2 [skip1] [skip2]\n",stderr
);