|
|
1.1 root 1: static char *sccsid = "@(#)diffdir.c 4.5 (Berkeley) 81/02/28";
2:
3: #include "diff.h"
4: /*
5: * diff - directory comparison
6: */
7: #define d_flags d_ino
8:
9: #define ONLY 1 /* Only in this directory */
10: #define SAME 2 /* Both places and same */
11: #define DIFFER 4 /* Both places and different */
12: #define DIRECT 8 /* Directory */
13:
14: struct direct *setupdir();
15: int header;
16: char title[2*BUFSIZ], *etitle;
17:
18: diffdir(argv)
19: char **argv;
20: {
21: register struct direct *d1, *d2;
22: struct direct *dir1, *dir2;
23: register int i;
24: int cmp;
25:
26: if (opt == D_EDIT && sflag)
27: fprintf(stderr,
28: "diff: warning: shouldn't give -s with -e\n");
29: title[0] = 0;
30: strcpy(title, "diff ");
31: for (i = 1; diffargv[i+2]; i++) {
32: if (strcmp(diffargv[i], "-") == 0)
33: continue; /* was -S, dont look silly */
34: strcat(title, diffargv[i]);
35: strcat(title, " ");
36: }
37: for (etitle = title; *etitle; etitle++)
38: ;
39: setfile(&file1, &efile1, file1);
40: setfile(&file2, &efile2, file2);
41: argv[0] = file1;
42: argv[1] = file2;
43: dir1 = setupdir(file1);
44: dir2 = setupdir(file2);
45: d1 = dir1; d2 = dir2;
46: while (d1->d_name[0] != 0 || d2->d_name[0] != 0) {
47: if (d1->d_name[0] && isdotordotdot(d1->d_name)) {
48: d1++;
49: continue;
50: }
51: if (d2->d_name[0] && isdotordotdot(d2->d_name)) {
52: d2++;
53: continue;
54: }
55: if (d1->d_name[0] == 0)
56: cmp = 1;
57: else if (d2->d_name[0] == 0)
58: cmp = -1;
59: else
60: cmp = strncmp(d1->d_name, d2->d_name, DIRSIZ);
61: if (cmp < 0) {
62: if (opt == 0 || opt == 2) {
63: only(d1, 1);
64: printf(": %.*s\n", DIRSIZ, d1->d_name);
65: }
66: d1++;
67: } else if (cmp == 0) {
68: compare(d1);
69: d1++;
70: d2++;
71: } else {
72: if (opt == 0 || opt == 2) {
73: only(d2, 2);
74: printf(": %.*s\n", DIRSIZ, d2->d_name);
75: }
76: d2++;
77: }
78: }
79: if (rflag) {
80: for (d1 = dir1; d1->d_name[0]; d1++) {
81: if ((d1->d_flags & DIRECT) == 0)
82: continue;
83: strncpy(efile1, d1->d_name, DIRSIZ);
84: strncpy(efile2, d1->d_name, DIRSIZ);
85: calldiff();
86: }
87: }
88: }
89:
90: setfile(fpp, epp, file)
91: char **fpp, **epp;
92: char *file;
93: {
94: register char *cp;
95:
96: *fpp = malloc(BUFSIZ);
97: if (*fpp == 0) {
98: fprintf(stderr, "diff: ran out of memory\n");
99: exit(1);
100: }
101: strcpy(*fpp, file);
102: for (cp = *fpp; *cp; cp++)
103: continue;
104: *cp++ = '/';
105: *epp = cp;
106: }
107:
108: only(dp, which)
109: struct direct *dp;
110: int which;
111: {
112: char *file = which == 1 ? file1 : file2;
113: char *efile = which == 1 ? efile1 : efile2;
114:
115: printf("Only in %.*s", efile - file - 1, file, DIRSIZ, dp->d_name);
116: }
117:
118: ptname(dp)
119: struct direct *dp;
120: {
121: printf("\t%.*s\n", DIRSIZ, dp->d_name);
122: }
123:
124: int entcmp();
125:
126: struct direct *
127: setupdir(cp)
128: char *cp;
129: {
130: struct stat stb;
131: register struct direct *dp, *ep;
132:
133: close(0);
134: if (open(cp, 0) < 0) {
135: fprintf(stderr, "diff: ");
136: perror(cp);
137: done();
138: }
139: fstat(0, &stb);
140: dp = (struct direct *)malloc((unsigned) stb.st_size + sizeof (struct direct));
141: if (dp == 0) {
142: fprintf(stderr, "diff: ran out of memory\n");
143: done();
144: }
145: if (read(0, (char *)dp, (int)stb.st_size) != (int)stb.st_size) {
146: fprintf(stderr, "diff: ");
147: perror(cp);
148: done();
149: }
150: qsort(dp, (int) stb.st_size / sizeof (struct direct),
151: sizeof (struct direct), entcmp);
152: ep = &dp[stb.st_size / sizeof (struct direct)];
153: ep->d_name[0] = 0;
154: while (--ep >= dp && ep->d_ino == 0)
155: ep->d_name[0] = 0;
156: for (; ep >= dp; ep--)
157: ep->d_flags = 0;
158: return (dp);
159: }
160:
161: entcmp(d1, d2)
162: struct direct *d1, *d2;
163: {
164:
165: if (d1->d_ino == 0)
166: return (1);
167: if (d2->d_ino == 0)
168: return (-1);
169: return (strncmp(d1->d_name, d2->d_name, DIRSIZ));
170: }
171:
172: compare(dp)
173: register struct direct *dp;
174: {
175: register int i, j;
176: int f1, f2, fmt1, fmt2;
177: struct stat stb1, stb2;
178: int flag = 0;
179: char buf1[BUFSIZ], buf2[BUFSIZ];
180:
181: strncpy(efile1, dp->d_name, DIRSIZ);
182: strncpy(efile2, dp->d_name, DIRSIZ);
183: f1 = open(file1, 0);
184: if (f1 < 0) {
185: perror(file1);
186: return;
187: }
188: f2 = open(file2, 0);
189: if (f2 < 0) {
190: perror(file2);
191: close(f1);
192: return;
193: }
194: fstat(f1, &stb1); fstat(f2, &stb2);
195: fmt1 = stb1.st_mode & S_IFMT;
196: fmt2 = stb2.st_mode & S_IFMT;
197: if (fmt1 != S_IFREG || fmt2 != S_IFREG) {
198: if (fmt1 == fmt2) {
199: if (fmt1 != S_IFDIR && stb1.st_rdev == stb2.st_rdev)
200: goto same;
201: if (fmt1 == S_IFDIR) {
202: dp->d_flags = DIRECT;
203: if (opt == D_EDIT)
204: goto closem;
205: printf("Common subdirectories: %s and %s\n",
206: file1, file2);
207: goto closem;
208: }
209: }
210: goto notsame;
211: }
212: if (stb1.st_size != stb2.st_size)
213: goto notsame;
214: for (;;) {
215: i = read(f1, buf1, BUFSIZ);
216: j = read(f2, buf2, BUFSIZ);
217: if (i < 0 || j < 0 || i != j)
218: goto notsame;
219: if (i == 0 && j == 0)
220: goto same;
221: for (j = 0; j < i; j++)
222: if (buf1[j] != buf2[j])
223: goto notsame;
224: }
225: same:
226: if (sflag == 0)
227: goto closem;
228: printf("Files %s and %s are identical\n", file1, file2);
229: goto closem;
230: notsame:
231: if (!ascii(f1) || !ascii(f2)) {
232: if (opt == D_NORMAL || opt == D_CONTEXT)
233: printf("Binary files %s and %s differ\n",
234: file1, file2);
235: goto closem;
236: }
237: close(f1); close(f2);
238: anychange = 1;
239: if (opt == D_EDIT) {
240: printf("ed - %.*s << '-*-END-*-'\n", DIRSIZ, dp->d_name);
241: calldiff();
242: } else {
243: printf("%s%s %s\n", title, file1, file2);
244: calldiff();
245: }
246: if (opt == D_EDIT)
247: printf("w\nq\n-*-END-*-\n");
248: return;
249: closem:
250: close(f1); close(f2);
251: }
252:
253: calldiff()
254: {
255: int pid, status, status2, pv[2];
256:
257: fflush(stdout);
258: pid = fork();
259: if (pid == -1) {
260: fprintf(stderr, "diff: No more processes\n");
261: done();
262: }
263: if (pid == 0) {
264: execv(diff+4, diffargv);
265: execv(diff, diffargv);
266: perror(diff);
267: done();
268: }
269: close(pv[0]);
270: close(pv[1]);
271: while (wait(&status) != pid)
272: continue;
273: while (wait(&status2) != -1)
274: continue;
275: }
276:
277: #include <a.out.h>
278:
279: ascii(f)
280: int f;
281: {
282: char buf[BUFSIZ];
283: register int cnt;
284: register char *cp;
285:
286: lseek(f, (long)0, 0);
287: cnt = read(f, buf, BUFSIZ);
288: if (cnt >= sizeof (struct exec)) {
289: struct exec hdr;
290: hdr = *(struct exec *)buf;
291: if (!N_BADMAG(hdr))
292: return (0);
293: }
294: cp = buf;
295: while (--cnt >= 0)
296: if (*cp++ & 0200)
297: return (0);
298: return (1);
299: }
300:
301: isdotordotdot(p)
302: register char *p;
303: {
304: if (*p == '.') {
305: if (*(p+1) == '\0')
306: return 1;
307: if (*(p+1) == '.' && *(p+2) == '\0')
308: return 1;
309: }
310: return 0;
311: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.