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