Annotation of 3BSD/cmd/diffdir.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: 
        !             3: /*
        !             4:  * Diffdir - a (first) directory difference program
        !             5:  * Bill Joy UCB March 16, 1978
        !             6:  *
        !             7:  * This is a difference program which operates on the entire contents of
        !             8:  * a directory.  It reports common files which are different, running
        !             9:  * diff if the files are ASCII files.  It also reports files which are
        !            10:  * unique to one of the two directories.
        !            11:  *
        !            12:  * An option "h" (for header) causes diffdir to print each difference
        !            13:  * on a new page (using an appropriate "pr") and to summarize missing
        !            14:  * files and differences in binary files on a final page.
        !            15:  *
        !            16:  * Option "s" causes files which are the same to be reported also.
        !            17:  *
        !            18:  * It would be nice if this were "difftree", and if it knew a few
        !            19:  * more things, e.g to "size" objects which are different or some
        !            20:  * such or at least to not say that "directories are different" calling
        !            21:  * them files, i.e. "Files ex-1.1/temp and ex-1.2/temp are different".
        !            22:  */
        !            23: 
        !            24: typedef        char bool;
        !            25: 
        !            26: struct entry {
        !            27:        char    *name;
        !            28:        int     flags;
        !            29: } *dir1, *dir2;
        !            30: 
        !            31: #define        ONLY    1
        !            32: #define        DIFFER  2
        !            33: 
        !            34: bool   eflg;
        !            35: bool   hflg;
        !            36: bool   vflg;
        !            37: bool   sflg;
        !            38: 
        !            39: #define        vprintf if (vflg) printf
        !            40: #define        diffopt()       (eflg ? "-e" : "")
        !            41: 
        !            42: main(argc, argv)
        !            43:        int argc;
        !            44:        char *argv[];
        !            45: {
        !            46:        register struct entry *d1, *d2;
        !            47:        register char *cp;
        !            48: 
        !            49:        while (argc > 1) {
        !            50:                cp = argv[1];
        !            51:                if (*cp++ != '-')
        !            52:                        break;
        !            53:                while (*cp) switch (*cp++) {
        !            54: 
        !            55:                case 'h':
        !            56:                        hflg++;
        !            57:                        continue;
        !            58: 
        !            59:                case 'v':
        !            60:                        vflg++;
        !            61:                        continue;
        !            62: 
        !            63:                case 's':
        !            64:                        sflg++;
        !            65:                        continue;
        !            66: 
        !            67:                case 'e':
        !            68:                        eflg++;
        !            69:                        printf("#\n");
        !            70:                        continue;
        !            71: 
        !            72:                default:
        !            73: usage:
        !            74:                        panic("Usage: diffdir [ -h ] dir1 dir2");
        !            75:                }
        !            76:                argc--, argv++;
        !            77:        }
        !            78:        if (argc != 3)
        !            79:                goto usage;
        !            80:        setupdir(argv[1], &dir1);
        !            81:        setupdir(argv[2], &dir2);
        !            82:        d1 = dir1; d2 = dir2;
        !            83:        while (d1->name != 0 || d2->name != 0) {
        !            84:                if (useless(d1->name)) {
        !            85:                        d1++;
        !            86:                        continue;
        !            87:                }
        !            88:                if (useless(d2->name)) {
        !            89:                        d2++;
        !            90:                        continue;
        !            91:                }
        !            92:                if (d1->name != 0 && d2->name != 0)
        !            93:                        switch (sgn(strcmp(d1->name, d2->name))) {
        !            94: 
        !            95:                        case -1:
        !            96: onlyin1:
        !            97:                                if (hflg)
        !            98:                                        d1->flags =| ONLY;
        !            99:                                else if (!eflg)
        !           100:                                        printf("Only in %s: %s\n", argv[1], d1->name);
        !           101:                                d1++;
        !           102:                                continue;
        !           103: 
        !           104:                        case 0:
        !           105:                                vprintf("In both: %s\n", d1->name);
        !           106:                                compare(d1, argv[1], argv[2]);
        !           107:                                d1++;
        !           108:                                d2++;
        !           109:                                continue;
        !           110: 
        !           111:                        case 1:
        !           112: onlyin2:                       if (hflg)
        !           113:                                        d2->flags =| ONLY;
        !           114:                                else if (!eflg)
        !           115:                                        printf("Only in %s: %s\n", argv[2], d2->name);
        !           116:                                d2++;
        !           117:                                continue;
        !           118:                        }
        !           119:                if (d1->name != 0)
        !           120:                        goto onlyin1;
        !           121:                else
        !           122:                        goto onlyin2;
        !           123:        }
        !           124:        if (hflg) {
        !           125:                int header = 0;
        !           126: 
        !           127:                for (d1 = dir1; d1->name; d1++)
        !           128:                        if (d1->flags & ONLY) {
        !           129:                                if (header == 0) {
        !           130:                                        printf("\fOnly in %s\n", argv[1]);
        !           131:                                        header = 1;
        !           132:                                }
        !           133:                                printf("\t%s\n", d1->name);
        !           134:                        }
        !           135:                for (d2 = dir2; d2->name != 0; d2++) {
        !           136:                        if (d2->flags & ONLY) {
        !           137:                                if (header == 0)
        !           138:                                        printf("\f");
        !           139:                                if ((header & 2) == 0) {
        !           140:                                        printf("Only in %s\n", argv[2]);
        !           141:                                        header =| 2;
        !           142:                                }
        !           143:                                printf("\t%s\n", d2->name);
        !           144:                        }
        !           145:                }
        !           146:                for (d1 = dir1; d1->name; d1++)
        !           147:                        if (d1->flags & DIFFER) {
        !           148:                                if (header == 0) {
        !           149:                                        printf("\f");
        !           150:                                        header = 1;
        !           151:                                }
        !           152:                                if ((header & 4) == 0) {
        !           153:                                        printf("Non-ascii files which differ:\n");
        !           154:                                        header =| 4;
        !           155:                                }
        !           156:                                printf("\t%s\n", d1->name);
        !           157:                        }
        !           158:        }
        !           159:        exit(0);
        !           160: }
        !           161: 
        !           162: int    entcmp();
        !           163: setupdir(cp, head)
        !           164:        char *cp;
        !           165:        struct entry **head;
        !           166: {
        !           167:        int count = 1;
        !           168:        struct dirent0 {
        !           169:                short ino;
        !           170:                char fname[14];
        !           171:        };
        !           172: 
        !           173:        struct dirent1 {
        !           174:                short ino;
        !           175:                char fname1[16];
        !           176:        } dirent;
        !           177:        register struct entry *hp;
        !           178: 
        !           179:        close(0);
        !           180:        if (open(cp, 0) < 0) {
        !           181:                perror(cp);
        !           182:                exit(1);
        !           183:        }
        !           184:        while (read(0, &dirent, sizeof (struct dirent0)) == sizeof (struct dirent0))
        !           185:        if (dirent.ino)
        !           186:                count++;
        !           187:        lseek(0, (long) 0, 0);
        !           188:        hp = *head = Calloc(count, sizeof **head);
        !           189:        while (read(0, &dirent, sizeof (struct dirent0)) == sizeof (struct dirent0))
        !           190:        if (dirent.ino) {
        !           191:                hp->name = savestr(dirent.fname);
        !           192:                hp++;
        !           193:        }
        !           194:        qsort(*head, count - 1, sizeof **head, entcmp);
        !           195: }
        !           196: 
        !           197: entcmp(ep, ep2)
        !           198:        struct entry *ep, *ep2;
        !           199: {
        !           200: 
        !           201:        return (strcmp(ep->name, ep2->name));
        !           202: }
        !           203: 
        !           204: Calloc(i, n)
        !           205:        int i, n;
        !           206: {
        !           207:        register unsigned mem;
        !           208: 
        !           209:        mem = calloc(i, n);
        !           210:        if (mem == 0)
        !           211:                panic("Ran out of memory");
        !           212:        return (mem);
        !           213: }
        !           214: 
        !           215: savestr(cp)
        !           216:        register char *cp;
        !           217: {
        !           218: 
        !           219:        return (strcpy(calloc(strlen(cp)+1, sizeof (char)), cp));
        !           220: }
        !           221: 
        !           222: panic(cp)
        !           223:        char *cp;
        !           224: {
        !           225: 
        !           226:        fprintf(stderr, "%s\n", cp);
        !           227:        exit(1);
        !           228: }
        !           229: 
        !           230: sgn(i)
        !           231:        int i;
        !           232: {
        !           233:        if (i > 0)
        !           234:                return (1);
        !           235:        else if (i < 0)
        !           236:                return (-1);
        !           237:        return (0);
        !           238: }
        !           239: 
        !           240: compare(dp, d1, d2)
        !           241:        struct entry *dp;
        !           242:        char *d1, *d2;
        !           243: {
        !           244:        register int i;
        !           245:        char path1[100], path2[100];
        !           246:        int t1, t2;
        !           247:        char header[250];
        !           248:        char *name = dp->name;
        !           249: 
        !           250:        if (max(strlen(d1), strlen(d2)) + strlen(name) + 2 >= 100)
        !           251:                panic("Path names too long");
        !           252:        strcat(strcat(strcpy(path1, d1), "/"), name);
        !           253:        strcat(strcat(strcpy(path2, d2), "/"), name);
        !           254:        i = callit("/usr/bin/cmp", "cmp", "-s", path1, path2, 0);
        !           255:        if (i == 0) {
        !           256:                if (sflg)
        !           257:                        printf("Files %s and %s same\n", path1, path2);
        !           258:                return;
        !           259:        }
        !           260:        if (!ascii(path1) || !ascii(path2)) {
        !           261:                if (hflg)
        !           262:                        dp->flags =| DIFFER;
        !           263:                else if (!eflg)
        !           264:                        printf("Files %s and %s differ\n", path1, path2);
        !           265:                return;
        !           266:        }
        !           267:        if (hflg) {
        !           268:                sprintf(header, "diff %s %s %s", diffopt(), path1, path2);
        !           269:                prcallit(header, "/usr/bin/diff", "diff", path1, path2, 0);
        !           270:        } else {
        !           271:                if (eflg) {
        !           272:                        printf("ed - %s << '-*-END-*-'\n", name);
        !           273:                        callit("/usr/bin/diff", "diff", "-e", path1, path2, 0);
        !           274:                } else {
        !           275:                        printf("diff %s %s\n", path1, path2);
        !           276:                        callit("/usr/bin/diff", "diff", path1, path2, 0);
        !           277:                }
        !           278:                if (eflg)
        !           279:                        printf("w\nq\n'-*-END-*-'\n");
        !           280:        }
        !           281: }
        !           282: 
        !           283: prcallit(header, path, av)
        !           284:        char *header, *path;
        !           285: {
        !           286:        int status;
        !           287:        int pid;
        !           288:        int pv[2];
        !           289: 
        !           290:        fflush(stdout);
        !           291:        pipe(pv);
        !           292:        pid = fork();
        !           293:        if (pid == -1)
        !           294:                panic("No more processes");
        !           295:        if (pid == 0) {
        !           296:                close(0);
        !           297:                dup(pv[0]);
        !           298:                close(pv[0]);
        !           299:                close(pv[1]);
        !           300:                execl("/bin/pr", "pr", "-h", header, 0);
        !           301:                execl("/usr/bin/pr", "pr", "-h", header, 0);
        !           302:                perror("/usr/bin/pr");
        !           303:                exit(1);
        !           304:        }
        !           305:        pid = fork();
        !           306:        if (pid == -1)
        !           307:                panic("No more processes");
        !           308:        if (pid == 0) {
        !           309:                close(1);
        !           310:                dup(pv[1]);
        !           311:                close(pv[0]);
        !           312:                close(pv[1]);
        !           313:                execv(path+4, &av);
        !           314:                execv(path, &av);
        !           315:                perror(path);
        !           316:                exit(1);
        !           317:        }
        !           318:        close(pv[0]);
        !           319:        close(pv[1]);
        !           320:        while (wait(&status) != -1)
        !           321:                continue;
        !           322: }
        !           323: 
        !           324: callit(path, av)
        !           325:        char *path;
        !           326: {
        !           327:        int status;
        !           328:        int pid;
        !           329: 
        !           330:        fflush(stdout);
        !           331:        pid = fork();
        !           332:        if (pid == -1)
        !           333:                panic("No more processes");
        !           334:        if (pid == 0) {
        !           335:                execv(path+4, &av);
        !           336:                execv(path, &av);
        !           337:                perror(path);
        !           338:                exit(1);
        !           339:        }
        !           340:        wait(&status);
        !           341:        return (((status >> 8) & 0377) | (status & 0377));
        !           342: }
        !           343: 
        !           344: max(a,b)
        !           345:        int a,b;
        !           346: {
        !           347: 
        !           348:        return (a > b ? a : b);
        !           349: }
        !           350: 
        !           351: ascii(cp)
        !           352:        char *cp;
        !           353: {
        !           354:        int f;
        !           355:        short w;
        !           356: 
        !           357:        f = open(cp, 0);
        !           358:        if (f < 0)
        !           359:                return (0);
        !           360:        if (read(f, &w, sizeof w) != sizeof w) {
        !           361:                close(f);
        !           362:                return (1);
        !           363:        }
        !           364:        close(f);
        !           365:        switch (w) {
        !           366: 
        !           367:        case 0405:      /* Overlay executable */
        !           368:        case 0407:      /* Executable */
        !           369:        case 0410:      /* Pure executable */
        !           370:        case 0411:      /* Separate executable */
        !           371:        case 0413:      /* Demand executable */
        !           372:        case 0177545:   /* Archive */
        !           373:        case 0177555:   /* Old archive */
        !           374:                return (0);
        !           375:        default:
        !           376:                if (w & 0100200)
        !           377:                        return (0);
        !           378:                return (1);
        !           379:        }
        !           380: }
        !           381: 
        !           382: useless(cp)
        !           383:        char *cp;
        !           384: {
        !           385: 
        !           386:        if (strcmp(cp, ".") == 0 || strcmp(cp, "..") == 0)
        !           387:                return (1);
        !           388:        if (cp[0] == '.')
        !           389:                return (1);             /* For now */
        !           390:        return (0);
        !           391: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.