URI: 
       diffdir.c - 9base - revived minimalist port of Plan 9 userland to Unix
  HTML git clone git://git.suckless.org/9base
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       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 }