xref: /plan9/sys/src/cmd/diff/diffdir.c (revision bd389b369d90320ffee8121f40c4c30619f88097)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
43e12c5d1SDavid du Colombier #include "diff.h"
53e12c5d1SDavid du Colombier 
63e12c5d1SDavid du Colombier static int
7*bd389b36SDavid du Colombier itemcmp(char **d1, char **d2)
83e12c5d1SDavid du Colombier {
9*bd389b36SDavid du Colombier 	return strcmp(*d1, *d2);
103e12c5d1SDavid du Colombier }
113e12c5d1SDavid du Colombier 
123e12c5d1SDavid du Colombier static char **
133e12c5d1SDavid du Colombier scandir(char *name)
143e12c5d1SDavid du Colombier {
153e12c5d1SDavid du Colombier 	char **cp;
163e12c5d1SDavid du Colombier 	Dir db[32];
173e12c5d1SDavid du Colombier 	int nitems;
183e12c5d1SDavid du Colombier 	int fd, n;
193e12c5d1SDavid du Colombier 
203e12c5d1SDavid du Colombier 	if ((fd = open(name, OREAD)) < 0)
213e12c5d1SDavid du Colombier 		panic(2, "can't open %s\n", name);
223e12c5d1SDavid du Colombier 	cp = 0;
233e12c5d1SDavid du Colombier 	nitems = 0;
243e12c5d1SDavid du Colombier 	while((n = dirread(fd, db, sizeof db)) > 0){
253e12c5d1SDavid du Colombier 		n /= sizeof(Dir);
263e12c5d1SDavid du Colombier 		while (n--) {
273e12c5d1SDavid du Colombier 			cp = REALLOC(cp, char *, (nitems+1));
283e12c5d1SDavid du Colombier 			cp[nitems] = MALLOC(char, strlen(db[n].name)+1);
293e12c5d1SDavid du Colombier 			strcpy(cp[nitems], db[n].name);
303e12c5d1SDavid du Colombier 			nitems++;
313e12c5d1SDavid du Colombier 		}
323e12c5d1SDavid du Colombier 	}
333e12c5d1SDavid du Colombier 	cp = REALLOC(cp, char*, (nitems+1));
343e12c5d1SDavid du Colombier 	cp[nitems] = 0;
353e12c5d1SDavid du Colombier 	close(fd);
363e12c5d1SDavid du Colombier 	qsort((char *)cp, nitems, sizeof(char*), itemcmp);
373e12c5d1SDavid du Colombier 	return cp;
383e12c5d1SDavid du Colombier }
393e12c5d1SDavid du Colombier 
403e12c5d1SDavid du Colombier static int
413e12c5d1SDavid du Colombier isdotordotdot(char *p)
423e12c5d1SDavid du Colombier {
433e12c5d1SDavid du Colombier 	if (*p == '.') {
443e12c5d1SDavid du Colombier 		if (!p[1])
453e12c5d1SDavid du Colombier 			return 1;
463e12c5d1SDavid du Colombier 		if (p[1] == '.' && !p[2])
473e12c5d1SDavid du Colombier 			return 1;
483e12c5d1SDavid du Colombier 	}
493e12c5d1SDavid du Colombier 	return 0;
503e12c5d1SDavid du Colombier }
513e12c5d1SDavid du Colombier 
523e12c5d1SDavid du Colombier void
533e12c5d1SDavid du Colombier diffdir(char *f, char *t, int level)
543e12c5d1SDavid du Colombier {
553e12c5d1SDavid du Colombier 	char  **df, **dt, **dirf, **dirt;
563e12c5d1SDavid du Colombier 	char *from, *to;
573e12c5d1SDavid du Colombier 	int res;
583e12c5d1SDavid du Colombier 	char fb[MAXPATHLEN+1], tb[MAXPATHLEN+1];
593e12c5d1SDavid du Colombier 
60*bd389b36SDavid du Colombier 	df = scandir(f);
61*bd389b36SDavid du Colombier 	dt = scandir(t);
62*bd389b36SDavid du Colombier 	dirf = df;
63*bd389b36SDavid du Colombier 	dirt = dt;
643e12c5d1SDavid du Colombier 	while (*df || *dt) {
65*bd389b36SDavid du Colombier 		from = *df;
66*bd389b36SDavid du Colombier 		to = *dt;
67*bd389b36SDavid du Colombier 		if (from && isdotordotdot(from)) {
68*bd389b36SDavid du Colombier 			df++;
693e12c5d1SDavid du Colombier 			continue;
70*bd389b36SDavid du Colombier 		}
71*bd389b36SDavid du Colombier 		if (to && isdotordotdot(to)) {
72*bd389b36SDavid du Colombier 			dt++;
733e12c5d1SDavid du Colombier 			continue;
74*bd389b36SDavid du Colombier 		}
753e12c5d1SDavid du Colombier 		if (!from)
763e12c5d1SDavid du Colombier 			res = 1;
773e12c5d1SDavid du Colombier 		else if (!to)
783e12c5d1SDavid du Colombier 			res = -1;
793e12c5d1SDavid du Colombier 		else
803e12c5d1SDavid du Colombier 			res = strcmp(from, to);
813e12c5d1SDavid du Colombier 		if (res < 0) {
823e12c5d1SDavid du Colombier 			if (mode == 0)
833e12c5d1SDavid du Colombier 				Bprint(&stdout, "Only in %s: %s\n", f, from);
84*bd389b36SDavid du Colombier 			df++;
853e12c5d1SDavid du Colombier 			continue;
863e12c5d1SDavid du Colombier 		}
873e12c5d1SDavid du Colombier 		if (res > 0) {
883e12c5d1SDavid du Colombier 			if (mode == 0)
893e12c5d1SDavid du Colombier 				Bprint(&stdout, "Only in %s: %s\n", t, to);
90*bd389b36SDavid du Colombier 			dt++;
913e12c5d1SDavid du Colombier 			continue;
923e12c5d1SDavid du Colombier 		}
933e12c5d1SDavid du Colombier 		if (mkpathname(fb, f, from))
943e12c5d1SDavid du Colombier 			continue;
953e12c5d1SDavid du Colombier 		if (mkpathname(tb, t, to))
963e12c5d1SDavid du Colombier 			continue;
973e12c5d1SDavid du Colombier 		diff(fb, tb, level+1);
98*bd389b36SDavid du Colombier 		df++; dt++;
993e12c5d1SDavid du Colombier 	}
1003e12c5d1SDavid du Colombier 	for (df = dirf; *df; df++)
1013e12c5d1SDavid du Colombier 		FREE(*df);
1023e12c5d1SDavid du Colombier 	for (dt = dirt; *dt; dt++)
1033e12c5d1SDavid du Colombier 		FREE(*dt);
1043e12c5d1SDavid du Colombier 	FREE(dirf);
1053e12c5d1SDavid du Colombier 	FREE(dirt);
1063e12c5d1SDavid du Colombier }
107