xref: /plan9/sys/src/cmd/diff/diffdir.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
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*7dd7cddfSDavid du Colombier itemcmp(void *v1, void *v2)
83e12c5d1SDavid du Colombier {
9*7dd7cddfSDavid du Colombier 	char **d1 = v1, **d2 = v2;
10*7dd7cddfSDavid du Colombier 
11bd389b36SDavid du Colombier 	return strcmp(*d1, *d2);
123e12c5d1SDavid du Colombier }
133e12c5d1SDavid du Colombier 
143e12c5d1SDavid du Colombier static char **
153e12c5d1SDavid du Colombier scandir(char *name)
163e12c5d1SDavid du Colombier {
173e12c5d1SDavid du Colombier 	char **cp;
183e12c5d1SDavid du Colombier 	Dir db[32];
193e12c5d1SDavid du Colombier 	int nitems;
203e12c5d1SDavid du Colombier 	int fd, n;
213e12c5d1SDavid du Colombier 
223e12c5d1SDavid du Colombier 	if ((fd = open(name, OREAD)) < 0)
233e12c5d1SDavid du Colombier 		panic(2, "can't open %s\n", name);
243e12c5d1SDavid du Colombier 	cp = 0;
253e12c5d1SDavid du Colombier 	nitems = 0;
263e12c5d1SDavid du Colombier 	while((n = dirread(fd, db, sizeof db)) > 0){
273e12c5d1SDavid du Colombier 		n /= sizeof(Dir);
283e12c5d1SDavid du Colombier 		while (n--) {
293e12c5d1SDavid du Colombier 			cp = REALLOC(cp, char *, (nitems+1));
303e12c5d1SDavid du Colombier 			cp[nitems] = MALLOC(char, strlen(db[n].name)+1);
313e12c5d1SDavid du Colombier 			strcpy(cp[nitems], db[n].name);
323e12c5d1SDavid du Colombier 			nitems++;
333e12c5d1SDavid du Colombier 		}
343e12c5d1SDavid du Colombier 	}
353e12c5d1SDavid du Colombier 	cp = REALLOC(cp, char*, (nitems+1));
363e12c5d1SDavid du Colombier 	cp[nitems] = 0;
373e12c5d1SDavid du Colombier 	close(fd);
383e12c5d1SDavid du Colombier 	qsort((char *)cp, nitems, sizeof(char*), itemcmp);
393e12c5d1SDavid du Colombier 	return cp;
403e12c5d1SDavid du Colombier }
413e12c5d1SDavid du Colombier 
423e12c5d1SDavid du Colombier static int
433e12c5d1SDavid du Colombier isdotordotdot(char *p)
443e12c5d1SDavid du Colombier {
453e12c5d1SDavid du Colombier 	if (*p == '.') {
463e12c5d1SDavid du Colombier 		if (!p[1])
473e12c5d1SDavid du Colombier 			return 1;
483e12c5d1SDavid du Colombier 		if (p[1] == '.' && !p[2])
493e12c5d1SDavid du Colombier 			return 1;
503e12c5d1SDavid du Colombier 	}
513e12c5d1SDavid du Colombier 	return 0;
523e12c5d1SDavid du Colombier }
533e12c5d1SDavid du Colombier 
543e12c5d1SDavid du Colombier void
553e12c5d1SDavid du Colombier diffdir(char *f, char *t, int level)
563e12c5d1SDavid du Colombier {
573e12c5d1SDavid du Colombier 	char  **df, **dt, **dirf, **dirt;
583e12c5d1SDavid du Colombier 	char *from, *to;
593e12c5d1SDavid du Colombier 	int res;
603e12c5d1SDavid du Colombier 	char fb[MAXPATHLEN+1], tb[MAXPATHLEN+1];
613e12c5d1SDavid du Colombier 
62bd389b36SDavid du Colombier 	df = scandir(f);
63bd389b36SDavid du Colombier 	dt = scandir(t);
64bd389b36SDavid du Colombier 	dirf = df;
65bd389b36SDavid du Colombier 	dirt = dt;
663e12c5d1SDavid du Colombier 	while (*df || *dt) {
67bd389b36SDavid du Colombier 		from = *df;
68bd389b36SDavid du Colombier 		to = *dt;
69bd389b36SDavid du Colombier 		if (from && isdotordotdot(from)) {
70bd389b36SDavid du Colombier 			df++;
713e12c5d1SDavid du Colombier 			continue;
72bd389b36SDavid du Colombier 		}
73bd389b36SDavid du Colombier 		if (to && isdotordotdot(to)) {
74bd389b36SDavid du Colombier 			dt++;
753e12c5d1SDavid du Colombier 			continue;
76bd389b36SDavid du Colombier 		}
773e12c5d1SDavid du Colombier 		if (!from)
783e12c5d1SDavid du Colombier 			res = 1;
793e12c5d1SDavid du Colombier 		else if (!to)
803e12c5d1SDavid du Colombier 			res = -1;
813e12c5d1SDavid du Colombier 		else
823e12c5d1SDavid du Colombier 			res = strcmp(from, to);
833e12c5d1SDavid du Colombier 		if (res < 0) {
84*7dd7cddfSDavid du Colombier 			if (mode == 0 || mode == 'n')
853e12c5d1SDavid du Colombier 				Bprint(&stdout, "Only in %s: %s\n", f, from);
86bd389b36SDavid du Colombier 			df++;
873e12c5d1SDavid du Colombier 			continue;
883e12c5d1SDavid du Colombier 		}
893e12c5d1SDavid du Colombier 		if (res > 0) {
90*7dd7cddfSDavid du Colombier 			if (mode == 0 || mode == 'n')
913e12c5d1SDavid du Colombier 				Bprint(&stdout, "Only in %s: %s\n", t, to);
92bd389b36SDavid du Colombier 			dt++;
933e12c5d1SDavid du Colombier 			continue;
943e12c5d1SDavid du Colombier 		}
953e12c5d1SDavid du Colombier 		if (mkpathname(fb, f, from))
963e12c5d1SDavid du Colombier 			continue;
973e12c5d1SDavid du Colombier 		if (mkpathname(tb, t, to))
983e12c5d1SDavid du Colombier 			continue;
993e12c5d1SDavid du Colombier 		diff(fb, tb, level+1);
100bd389b36SDavid du Colombier 		df++; dt++;
1013e12c5d1SDavid du Colombier 	}
1023e12c5d1SDavid du Colombier 	for (df = dirf; *df; df++)
1033e12c5d1SDavid du Colombier 		FREE(*df);
1043e12c5d1SDavid du Colombier 	for (dt = dirt; *dt; dt++)
1053e12c5d1SDavid du Colombier 		FREE(*dt);
1063e12c5d1SDavid du Colombier 	FREE(dirf);
1073e12c5d1SDavid du Colombier 	FREE(dirt);
1083e12c5d1SDavid du Colombier }
109