[BACK]Return to diffdir.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / diff

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: }