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 } 114