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