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