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