diffdir.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include "diff.h"
  5. static int
  6. itemcmp(void *v1, void *v2)
  7. {
  8. char **d1 = v1, **d2 = v2;
  9. return strcmp(*d1, *d2);
  10. }
  11. static char **
  12. scandir(char *name)
  13. {
  14. char **cp;
  15. Dir *db;
  16. int nitems;
  17. int fd, n;
  18. if ((fd = open(name, OREAD)) < 0) {
  19. fprint(2, "%s: can't open %s: %r\n", argv0, name);
  20. /* fake an empty directory */
  21. cp = MALLOC(char*, 1);
  22. cp[0] = 0;
  23. return cp;
  24. }
  25. cp = 0;
  26. nitems = 0;
  27. if((n = dirreadall(fd, &db)) > 0){
  28. while (n--) {
  29. cp = REALLOC(cp, char *, (nitems+1));
  30. cp[nitems] = MALLOC(char, strlen((db+n)->name)+1);
  31. strcpy(cp[nitems], (db+n)->name);
  32. nitems++;
  33. }
  34. free(db);
  35. }
  36. cp = REALLOC(cp, char*, (nitems+1));
  37. cp[nitems] = 0;
  38. close(fd);
  39. qsort((char *)cp, nitems, sizeof(char*), itemcmp);
  40. return cp;
  41. }
  42. static int
  43. isdotordotdot(char *p)
  44. {
  45. if (*p == '.') {
  46. if (!p[1])
  47. return 1;
  48. if (p[1] == '.' && !p[2])
  49. return 1;
  50. }
  51. return 0;
  52. }
  53. void
  54. diffdir(char *f, char *t, int level)
  55. {
  56. char **df, **dt, **dirf, **dirt;
  57. char *from, *to;
  58. int res;
  59. char fb[MAXPATHLEN+1], tb[MAXPATHLEN+1];
  60. df = scandir(f);
  61. dt = scandir(t);
  62. dirf = df;
  63. dirt = dt;
  64. while (*df || *dt) {
  65. from = *df;
  66. to = *dt;
  67. if (from && isdotordotdot(from)) {
  68. df++;
  69. continue;
  70. }
  71. if (to && isdotordotdot(to)) {
  72. dt++;
  73. continue;
  74. }
  75. if (!from)
  76. res = 1;
  77. else if (!to)
  78. res = -1;
  79. else
  80. res = strcmp(from, to);
  81. if (res < 0) {
  82. if (mode == 0 || mode == 'n')
  83. Bprint(&stdout, "Only in %s: %s\n", f, from);
  84. df++;
  85. continue;
  86. }
  87. if (res > 0) {
  88. if (mode == 0 || mode == 'n')
  89. Bprint(&stdout, "Only in %s: %s\n", t, to);
  90. dt++;
  91. continue;
  92. }
  93. if (mkpathname(fb, f, from))
  94. continue;
  95. if (mkpathname(tb, t, to))
  96. continue;
  97. diff(fb, tb, level+1);
  98. df++; dt++;
  99. }
  100. for (df = dirf; *df; df++)
  101. FREE(*df);
  102. for (dt = dirt; *dt; dt++)
  103. FREE(*dt);
  104. FREE(dirf);
  105. FREE(dirt);
  106. }