diffdir.c 2.3 KB

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