9base

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