Annotation of src/usr.bin/diff/diffdir.c, Revision 1.1
1.1 ! deraadt 1: static char *sccsid = "@(#)diffdir.c 4.12 (Berkeley) 4/30/89";
! 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, *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: }