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