xref: /plan9/sys/src/cmd/diff/diffdir.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "diff.h"
5 
6 static int
7 itemcmp(char **d1, char **d2)
8 {
9 	return strcmp(*d1, *d2);
10 }
11 
12 static char **
13 scandir(char *name)
14 {
15 	char **cp;
16 	Dir db[32];
17 	int nitems;
18 	int fd, n;
19 
20 	if ((fd = open(name, OREAD)) < 0)
21 		panic(2, "can't open %s\n", name);
22 	cp = 0;
23 	nitems = 0;
24 	while((n = dirread(fd, db, sizeof db)) > 0){
25 		n /= sizeof(Dir);
26 		while (n--) {
27 			cp = REALLOC(cp, char *, (nitems+1));
28 			cp[nitems] = MALLOC(char, strlen(db[n].name)+1);
29 			strcpy(cp[nitems], db[n].name);
30 			nitems++;
31 		}
32 	}
33 	cp = REALLOC(cp, char*, (nitems+1));
34 	cp[nitems] = 0;
35 	close(fd);
36 	qsort((char *)cp, nitems, sizeof(char*), itemcmp);
37 	return cp;
38 }
39 
40 static int
41 isdotordotdot(char *p)
42 {
43 	if (*p == '.') {
44 		if (!p[1])
45 			return 1;
46 		if (p[1] == '.' && !p[2])
47 			return 1;
48 	}
49 	return 0;
50 }
51 
52 void
53 diffdir(char *f, char *t, int level)
54 {
55 	char  **df, **dt, **dirf, **dirt;
56 	char *from, *to;
57 	int res;
58 	char fb[MAXPATHLEN+1], tb[MAXPATHLEN+1];
59 
60 	df = scandir(f);
61 	dt = scandir(t);
62 	dirf = df;
63 	dirt = dt;
64 	while (*df || *dt) {
65 		from = *df;
66 		to = *dt;
67 		if (from && isdotordotdot(from)) {
68 			df++;
69 			continue;
70 		}
71 		if (to && isdotordotdot(to)) {
72 			dt++;
73 			continue;
74 		}
75 		if (!from)
76 			res = 1;
77 		else if (!to)
78 			res = -1;
79 		else
80 			res = strcmp(from, to);
81 		if (res < 0) {
82 			if (mode == 0)
83 				Bprint(&stdout, "Only in %s: %s\n", f, from);
84 			df++;
85 			continue;
86 		}
87 		if (res > 0) {
88 			if (mode == 0)
89 				Bprint(&stdout, "Only in %s: %s\n", t, to);
90 			dt++;
91 			continue;
92 		}
93 		if (mkpathname(fb, f, from))
94 			continue;
95 		if (mkpathname(tb, t, to))
96 			continue;
97 		diff(fb, tb, level+1);
98 		df++; dt++;
99 	}
100 	for (df = dirf; *df; df++)
101 		FREE(*df);
102 	for (dt = dirt; *dt; dt++)
103 		FREE(*dt);
104 	FREE(dirf);
105 	FREE(dirt);
106 }
107