Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}