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