|
|
1.1 ! root 1: static char *sccsid = "@(#)diffdir.c 4.9 (Berkeley) 8/28/84"; ! 2: ! 3: #include "diff.h" ! 4: /* ! 5: * diff - directory comparison ! 6: */ ! 7: #define d_flags d_ino ! 8: ! 9: #define ONLY 1 /* Only in this directory */ ! 10: #define SAME 2 /* Both places and same */ ! 11: #define DIFFER 4 /* Both places and different */ ! 12: #define DIRECT 8 /* Directory */ ! 13: ! 14: struct dir { ! 15: u_long d_ino; ! 16: short d_reclen; ! 17: short d_namlen; ! 18: char *d_entry; ! 19: }; ! 20: ! 21: struct dir *setupdir(); ! 22: int header; ! 23: char title[2*BUFSIZ], *etitle; ! 24: ! 25: diffdir(argv) ! 26: char **argv; ! 27: { ! 28: register struct dir *d1, *d2; ! 29: struct dir *dir1, *dir2; ! 30: register int i; ! 31: int cmp; ! 32: ! 33: if (opt == D_IFDEF) { ! 34: fprintf(stderr, "diff: can't specify -I with directories\n"); ! 35: done(); ! 36: } ! 37: if (opt == D_EDIT && (sflag || lflag)) ! 38: fprintf(stderr, ! 39: "diff: warning: shouldn't give -s or -l with -e\n"); ! 40: title[0] = 0; ! 41: strcpy(title, "diff "); ! 42: for (i = 1; diffargv[i+2]; i++) { ! 43: if (!strcmp(diffargv[i], "-")) ! 44: continue; /* was -S, dont look silly */ ! 45: strcat(title, diffargv[i]); ! 46: strcat(title, " "); ! 47: } ! 48: for (etitle = title; *etitle; etitle++) ! 49: ; ! 50: setfile(&file1, &efile1, file1); ! 51: setfile(&file2, &efile2, file2); ! 52: argv[0] = file1; ! 53: argv[1] = file2; ! 54: dir1 = setupdir(file1); ! 55: dir2 = setupdir(file2); ! 56: d1 = dir1; d2 = dir2; ! 57: while (d1->d_entry != 0 || d2->d_entry != 0) { ! 58: if (d1->d_entry && useless(d1->d_entry)) { ! 59: d1++; ! 60: continue; ! 61: } ! 62: if (d2->d_entry && useless(d2->d_entry)) { ! 63: d2++; ! 64: continue; ! 65: } ! 66: if (d1->d_entry == 0) ! 67: cmp = 1; ! 68: else if (d2->d_entry == 0) ! 69: cmp = -1; ! 70: else ! 71: cmp = strcmp(d1->d_entry, d2->d_entry); ! 72: if (cmp < 0) { ! 73: if (lflag) ! 74: d1->d_flags |= ONLY; ! 75: else if (opt == 0 || opt == 2) ! 76: only(d1, 1); ! 77: d1++; ! 78: } else if (cmp == 0) { ! 79: compare(d1); ! 80: d1++; ! 81: d2++; ! 82: } else { ! 83: if (lflag) ! 84: d2->d_flags |= ONLY; ! 85: else if (opt == 0 || opt == 2) ! 86: only(d2, 2); ! 87: d2++; ! 88: } ! 89: } ! 90: if (lflag) { ! 91: scanpr(dir1, ONLY, "Only in %.*s", file1, efile1, 0, 0); ! 92: scanpr(dir2, ONLY, "Only in %.*s", file2, efile2, 0, 0); ! 93: scanpr(dir1, SAME, "Common identical files in %.*s and %.*s", ! 94: file1, efile1, file2, efile2); ! 95: scanpr(dir1, DIFFER, "Binary files which differ in %.*s and %.*s", ! 96: file1, efile1, file2, efile2); ! 97: scanpr(dir1, DIRECT, "Common subdirectories of %.*s and %.*s", ! 98: file1, efile1, file2, efile2); ! 99: } ! 100: if (rflag) { ! 101: if (header && lflag) ! 102: printf("\f"); ! 103: for (d1 = dir1; d1->d_entry; d1++) { ! 104: if ((d1->d_flags & DIRECT) == 0) ! 105: continue; ! 106: strcpy(efile1, d1->d_entry); ! 107: strcpy(efile2, d1->d_entry); ! 108: calldiff(0); ! 109: } ! 110: } ! 111: } ! 112: ! 113: setfile(fpp, epp, file) ! 114: char **fpp, **epp; ! 115: char *file; ! 116: { ! 117: register char *cp; ! 118: ! 119: *fpp = malloc(BUFSIZ); ! 120: if (*fpp == 0) { ! 121: fprintf(stderr, "diff: ran out of memory\n"); ! 122: exit(1); ! 123: } ! 124: strcpy(*fpp, file); ! 125: for (cp = *fpp; *cp; cp++) ! 126: continue; ! 127: *cp++ = '/'; ! 128: *epp = cp; ! 129: } ! 130: ! 131: scanpr(dp, test, title, file1, efile1, file2, efile2) ! 132: register struct dir *dp; ! 133: int test; ! 134: char *title, *file1, *efile1, *file2, *efile2; ! 135: { ! 136: int titled = 0; ! 137: ! 138: for (; dp->d_entry; dp++) { ! 139: if ((dp->d_flags & test) == 0) ! 140: continue; ! 141: if (titled == 0) { ! 142: if (header == 0) ! 143: header = 1; ! 144: else ! 145: printf("\n"); ! 146: printf(title, ! 147: efile1 - file1 - 1, file1, ! 148: efile2 - file2 - 1, file2); ! 149: printf(":\n"); ! 150: titled = 1; ! 151: } ! 152: printf("\t%s\n", dp->d_entry); ! 153: } ! 154: } ! 155: ! 156: only(dp, which) ! 157: struct dir *dp; ! 158: int which; ! 159: { ! 160: char *file = which == 1 ? file1 : file2; ! 161: char *efile = which == 1 ? efile1 : efile2; ! 162: ! 163: printf("Only in %.*s: %s\n", efile - file - 1, file, dp->d_entry); ! 164: } ! 165: ! 166: int entcmp(); ! 167: ! 168: struct dir * ! 169: setupdir(cp) ! 170: char *cp; ! 171: { ! 172: register struct dir *dp = 0, *ep; ! 173: register struct direct *rp; ! 174: register int nitems, n; ! 175: DIR *dirp; ! 176: ! 177: dirp = opendir(cp); ! 178: if (dirp == NULL) { ! 179: fprintf(stderr, "diff: "); ! 180: perror(cp); ! 181: done(); ! 182: } ! 183: nitems = 0; ! 184: dp = (struct dir *)malloc(sizeof (struct dir)); ! 185: if (dp == 0) { ! 186: fprintf(stderr, "diff: ran out of memory\n"); ! 187: done(); ! 188: } ! 189: while (rp = readdir(dirp)) { ! 190: ep = &dp[nitems++]; ! 191: ep->d_reclen = rp->d_reclen; ! 192: ep->d_namlen = rp->d_namlen; ! 193: ep->d_entry = 0; ! 194: ep->d_flags = 0; ! 195: if (ep->d_namlen > 0) { ! 196: ep->d_entry = malloc(ep->d_namlen + 1); ! 197: if (ep->d_entry == 0) { ! 198: fprintf(stderr, "diff: out of memory\n"); ! 199: done(); ! 200: } ! 201: strcpy(ep->d_entry, rp->d_name); ! 202: } ! 203: dp = (struct dir *)realloc((char *)dp, ! 204: (nitems + 1) * sizeof (struct dir)); ! 205: if (dp == 0) { ! 206: fprintf(stderr, "diff: ran out of memory\n"); ! 207: done(); ! 208: } ! 209: } ! 210: dp[nitems].d_entry = 0; /* delimiter */ ! 211: closedir(dirp); ! 212: qsort(dp, nitems, sizeof (struct dir), entcmp); ! 213: return (dp); ! 214: } ! 215: ! 216: entcmp(d1, d2) ! 217: struct dir *d1, *d2; ! 218: { ! 219: return (strcmp(d1->d_entry, d2->d_entry)); ! 220: } ! 221: ! 222: compare(dp) ! 223: register struct dir *dp; ! 224: { ! 225: register int i, j; ! 226: int f1, f2, fmt1, fmt2; ! 227: struct stat stb1, stb2; ! 228: int flag = 0; ! 229: char buf1[BUFSIZ], buf2[BUFSIZ]; ! 230: ! 231: strcpy(efile1, dp->d_entry); ! 232: strcpy(efile2, dp->d_entry); ! 233: f1 = open(file1, 0); ! 234: if (f1 < 0) { ! 235: perror(file1); ! 236: return; ! 237: } ! 238: f2 = open(file2, 0); ! 239: if (f2 < 0) { ! 240: perror(file2); ! 241: close(f1); ! 242: return; ! 243: } ! 244: fstat(f1, &stb1); fstat(f2, &stb2); ! 245: fmt1 = stb1.st_mode & S_IFMT; ! 246: fmt2 = stb2.st_mode & S_IFMT; ! 247: if (fmt1 != S_IFREG || fmt2 != S_IFREG) { ! 248: if (fmt1 == fmt2) { ! 249: if (fmt1 != S_IFDIR && stb1.st_rdev == stb2.st_rdev) ! 250: goto same; ! 251: if (fmt1 == S_IFDIR) { ! 252: dp->d_flags = DIRECT; ! 253: if (lflag || opt == D_EDIT) ! 254: goto closem; ! 255: printf("Common subdirectories: %s and %s\n", ! 256: file1, file2); ! 257: goto closem; ! 258: } ! 259: } ! 260: goto notsame; ! 261: } ! 262: if (stb1.st_size != stb2.st_size) ! 263: goto notsame; ! 264: for (;;) { ! 265: i = read(f1, buf1, BUFSIZ); ! 266: j = read(f2, buf2, BUFSIZ); ! 267: if (i < 0 || j < 0 || i != j) ! 268: goto notsame; ! 269: if (i == 0 && j == 0) ! 270: goto same; ! 271: for (j = 0; j < i; j++) ! 272: if (buf1[j] != buf2[j]) ! 273: goto notsame; ! 274: } ! 275: same: ! 276: if (sflag == 0) ! 277: goto closem; ! 278: if (lflag) ! 279: dp->d_flags = SAME; ! 280: else ! 281: printf("Files %s and %s are identical\n", file1, file2); ! 282: goto closem; ! 283: notsame: ! 284: if (!ascii(f1) || !ascii(f2)) { ! 285: if (lflag) ! 286: dp->d_flags |= DIFFER; ! 287: else if (opt == D_NORMAL || opt == D_CONTEXT) ! 288: printf("Binary files %s and %s differ\n", ! 289: file1, file2); ! 290: goto closem; ! 291: } ! 292: close(f1); close(f2); ! 293: anychange = 1; ! 294: if (lflag) ! 295: calldiff(title); ! 296: else { ! 297: if (opt == D_EDIT) { ! 298: printf("ed - %s << '-*-END-*-'\n", dp->d_entry); ! 299: calldiff(0); ! 300: } else { ! 301: printf("%s%s %s\n", title, file1, file2); ! 302: calldiff(0); ! 303: } ! 304: if (opt == D_EDIT) ! 305: printf("w\nq\n-*-END-*-\n"); ! 306: } ! 307: return; ! 308: closem: ! 309: close(f1); close(f2); ! 310: } ! 311: ! 312: char *prargs[] = { "pr", "-h", 0, "-f", 0, 0 }; ! 313: ! 314: calldiff(wantpr) ! 315: char *wantpr; ! 316: { ! 317: int pid, status, status2, pv[2]; ! 318: ! 319: prargs[2] = wantpr; ! 320: fflush(stdout); ! 321: if (wantpr) { ! 322: sprintf(etitle, "%s %s", file1, file2); ! 323: pipe(pv); ! 324: pid = fork(); ! 325: if (pid == -1) { ! 326: fprintf(stderr, "No more processes"); ! 327: done(); ! 328: } ! 329: if (pid == 0) { ! 330: close(0); ! 331: dup(pv[0]); ! 332: close(pv[0]); ! 333: close(pv[1]); ! 334: execv(pr+4, prargs); ! 335: execv(pr, prargs); ! 336: perror(pr); ! 337: done(); ! 338: } ! 339: } ! 340: pid = fork(); ! 341: if (pid == -1) { ! 342: fprintf(stderr, "diff: No more processes\n"); ! 343: done(); ! 344: } ! 345: if (pid == 0) { ! 346: if (wantpr) { ! 347: close(1); ! 348: dup(pv[1]); ! 349: close(pv[0]); ! 350: close(pv[1]); ! 351: } ! 352: execv(diff+4, diffargv); ! 353: execv(diff, diffargv); ! 354: perror(diff); ! 355: done(); ! 356: } ! 357: if (wantpr) { ! 358: close(pv[0]); ! 359: close(pv[1]); ! 360: } ! 361: while (wait(&status) != pid) ! 362: continue; ! 363: while (wait(&status2) != -1) ! 364: continue; ! 365: /* ! 366: if ((status >> 8) >= 2) ! 367: done(); ! 368: */ ! 369: } ! 370: ! 371: #include <a.out.h> ! 372: ! 373: ascii(f) ! 374: int f; ! 375: { ! 376: char buf[BUFSIZ]; ! 377: register int cnt; ! 378: register char *cp; ! 379: ! 380: lseek(f, (long)0, 0); ! 381: cnt = read(f, buf, BUFSIZ); ! 382: if (cnt >= sizeof (struct exec)) { ! 383: struct exec hdr; ! 384: hdr = *(struct exec *)buf; ! 385: if (!N_BADMAG(hdr)) ! 386: return (0); ! 387: } ! 388: cp = buf; ! 389: while (--cnt >= 0) ! 390: if (*cp++ & 0200) ! 391: return (0); ! 392: return (1); ! 393: } ! 394: ! 395: /* ! 396: * THIS IS CRUDE. ! 397: */ ! 398: useless(cp) ! 399: register char *cp; ! 400: { ! 401: ! 402: if (cp[0] == '.') { ! 403: if (cp[1] == '\0') ! 404: return (1); /* directory "." */ ! 405: if (cp[1] == '.' && cp[2] == '\0') ! 406: return (1); /* directory ".." */ ! 407: } ! 408: if (start && strcmp(start, cp) > 0) ! 409: return (1); ! 410: return (0); ! 411: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.