]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/diff/diffdir.c
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / cmd / diff / diffdir.c
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;
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
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
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 }