129 lines
2.3 KiB
C
129 lines
2.3 KiB
C
/* cmp - compare two files Author: Kees J. Bot. */
|
|
|
|
#include <sys/types.h>
|
|
#include <fcntl.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
_PROTOTYPE(void fatal, (char *label));
|
|
_PROTOTYPE(int cmp, (int fd1, int fd2));
|
|
_PROTOTYPE(void Usage, (void));
|
|
_PROTOTYPE(int main, (int argc, char **argv));
|
|
|
|
#define BLOCK 4096
|
|
|
|
static int loud = 0, silent = 0;
|
|
static char *name1, *name2;
|
|
|
|
int main(argc, argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
int fd1, fd2;
|
|
|
|
/* Process the '-l' or '-s' option. */
|
|
while (argc > 1 && argv[1][0] == '-' && argv[1][1] != 0) {
|
|
if (argv[1][2] != 0) Usage();
|
|
|
|
switch (argv[1][1]) {
|
|
case '-':
|
|
/* '--': no-op option. */
|
|
break;
|
|
case 'l':
|
|
loud = 1;
|
|
break;
|
|
case 's':
|
|
silent = 1;
|
|
break;
|
|
default:
|
|
Usage();
|
|
}
|
|
argc--;
|
|
argv++;
|
|
}
|
|
if (argc != 3) Usage();
|
|
|
|
/* Open the first file, '-' means standard input. */
|
|
if (argv[1][0] == '-' && argv[1][1] == 0) {
|
|
name1 = "stdin";
|
|
fd1 = 0;
|
|
} else {
|
|
name1 = argv[1];
|
|
if ((fd1 = open(name1, 0)) < 0) fatal(name1);
|
|
}
|
|
|
|
/* Second file likewise. */
|
|
if (argv[2][0] == '-' && argv[2][1] == 0) {
|
|
name2 = "stdin";
|
|
fd2 = 0;
|
|
} else {
|
|
name2 = argv[2];
|
|
if ((fd2 = open(name2, 0)) < 0) fatal(name2);
|
|
}
|
|
|
|
exit(cmp(fd1, fd2));
|
|
}
|
|
|
|
int cmp(fd1, fd2)
|
|
int fd1, fd2;
|
|
{
|
|
static char buf1[BLOCK], buf2[BLOCK];
|
|
int n1 = 0, n2 = 0, i1 = 0, i2 = 0, c1, c2;
|
|
off_t pos = 0, line = 1;
|
|
int eof = 0, differ = 0;
|
|
|
|
for (;;) {
|
|
if (i1 == n1) {
|
|
pos += n1;
|
|
|
|
if ((n1 = read(fd1, buf1, sizeof(buf1))) <= 0) {
|
|
if (n1 < 0) fatal(name1);
|
|
eof |= 1;
|
|
}
|
|
i1 = 0;
|
|
}
|
|
if (i2 == n2) {
|
|
if ((n2 = read(fd2, buf2, sizeof(buf2))) <= 0) {
|
|
if (n2 < 0) fatal(name2);
|
|
eof |= 2;
|
|
}
|
|
i2 = 0;
|
|
}
|
|
if (eof != 0) break;
|
|
|
|
c1 = buf1[i1++];
|
|
c2 = buf2[i2++];
|
|
|
|
if (c1 != c2) {
|
|
if (!loud) {
|
|
if (!silent) {
|
|
printf("%s %s differ: char %ld, line %ld\n",
|
|
name1, name2, pos + i1, line);
|
|
}
|
|
return(1);
|
|
}
|
|
printf("%10ld %3o %3o\n", pos + i1, c1 & 0xFF, c2 & 0xFF);
|
|
differ = 1;
|
|
}
|
|
if (c1 == '\n') line++;
|
|
}
|
|
if (eof == (1 | 2)) return(differ);
|
|
if (!silent) fprintf(stderr, "cmp: EOF on %s\n", eof == 1 ? name1 : name2);
|
|
return(1);
|
|
}
|
|
|
|
void fatal(label)
|
|
char *label;
|
|
{
|
|
if (!silent) fprintf(stderr, "cmp: %s: %s\n", label, strerror(errno));
|
|
exit(2);
|
|
}
|
|
|
|
void Usage()
|
|
{
|
|
fprintf(stderr, "Usage: cmp [-l | -s] file1 file2\n");
|
|
exit(2);
|
|
}
|