Annotation of 43BSDReno/usr.bin/cmp/cmp.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1987 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted
        !             6:  * provided that: (1) source distributions retain this entire copyright
        !             7:  * notice and comment, and (2) distributions including binaries display
        !             8:  * the following acknowledgement:  ``This product includes software
        !             9:  * developed by the University of California, Berkeley and its contributors''
        !            10:  * in the documentation or other materials provided with the distribution
        !            11:  * and in all advertising materials mentioning features or use of this
        !            12:  * software. Neither the name of the University nor the names of its
        !            13:  * contributors may be used to endorse or promote products derived
        !            14:  * from this software without specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: char copyright[] =
        !            22: "@(#) Copyright (c) 1987, 1990 Regents of the University of California.\n\
        !            23:  All rights reserved.\n";
        !            24: #endif /* not lint */
        !            25: 
        !            26: #ifndef lint
        !            27: static char sccsid[] = "@(#)cmp.c      5.3 (Berkeley) 6/1/90";
        !            28: #endif /* not lint */
        !            29: 
        !            30: #include <sys/param.h>
        !            31: #include <sys/file.h>
        !            32: #include <sys/stat.h>
        !            33: #include <stdio.h>
        !            34: #include <ctype.h>
        !            35: #include <errno.h>
        !            36: 
        !            37: #define        EXITNODIFF      0
        !            38: #define        EXITDIFF        1
        !            39: #define        EXITERR         2
        !            40: 
        !            41: int    all, fd1, fd2, silent;
        !            42: u_char buf1[MAXBSIZE], buf2[MAXBSIZE];
        !            43: char   *file1, *file2;
        !            44: 
        !            45: main(argc, argv)
        !            46:        int argc;
        !            47:        char *argv[];
        !            48: {
        !            49:        extern char *optarg;
        !            50:        extern int optind;
        !            51:        int ch;
        !            52:        u_long otoi();
        !            53: 
        !            54:        while ((ch = getopt(argc, argv, "-ls")) != EOF)
        !            55:                switch (ch) {
        !            56:                case 'l':               /* print all differences */
        !            57:                        all = 1;
        !            58:                        break;
        !            59:                case 's':               /* silent run */
        !            60:                        silent = 1;
        !            61:                        break;
        !            62:                case '-':               /* must be after any flags */
        !            63:                        --optind;
        !            64:                        goto endargs;
        !            65:                case '?':
        !            66:                default:
        !            67:                        usage();
        !            68:                }
        !            69: endargs:
        !            70:        argv += optind;
        !            71:        argc -= optind;
        !            72: 
        !            73:        if (argc < 2 || argc > 4)
        !            74:                usage();
        !            75: 
        !            76:        if (all && silent) {
        !            77:                fprintf(stderr,
        !            78:                    "cmp: only one of -l and -s may be specified.\n");
        !            79:                exit(EXITERR);
        !            80:        }
        !            81:        if (strcmp(file1 = argv[0], "-") == 0)
        !            82:                fd1 = 0;
        !            83:        else if ((fd1 = open(file1, O_RDONLY, 0)) < 0)
        !            84:                error(file1);
        !            85:        if (strcmp(file2 = argv[1], "-") == 0)
        !            86:                fd2 = 0;
        !            87:        else if ((fd2 = open(file2, O_RDONLY, 0)) < 0)
        !            88:                error(file2);
        !            89:        if (fd1 == fd2) {
        !            90:                fprintf(stderr,
        !            91:                    "cmp: standard input may only be specified once.\n");
        !            92:                exit(EXITERR);
        !            93:        }
        !            94: 
        !            95:        /* handle skip arguments */
        !            96:        if (argc > 2) {
        !            97:                skip(otoi(argv[2]), fd1, file1);
        !            98:                if (argc == 4)
        !            99:                        skip(otoi(argv[3]), fd2, file2);
        !           100:        }
        !           101:        cmp();
        !           102:        /*NOTREACHED*/
        !           103: }
        !           104: 
        !           105: /*
        !           106:  * skip --
        !           107:  *     skip first part of file
        !           108:  */
        !           109: skip(dist, fd, fname)
        !           110:        register u_long dist;
        !           111:        register int fd;
        !           112:        char *fname;
        !           113: {
        !           114:        register int rlen, nread;
        !           115: 
        !           116:        for (; dist; dist -= rlen) {
        !           117:                rlen = MIN(dist, sizeof(buf1));
        !           118:                if ((nread = read(fd, buf1, rlen)) != rlen) {
        !           119:                        if (nread < 0)
        !           120:                                error(fname);
        !           121:                        else
        !           122:                                endoffile(fname);
        !           123:                }
        !           124:        }
        !           125: }
        !           126: 
        !           127: cmp()
        !           128: {
        !           129:        register u_char *p1, *p2;
        !           130:        register int cnt, len1, len2;
        !           131:        register long byte, line;
        !           132:        int dfound = 0;
        !           133: 
        !           134:        for (byte = 0, line = 1; ; ) {
        !           135:                switch (len1 = read(fd1, buf1, MAXBSIZE)) {
        !           136:                case -1:
        !           137:                        error(file1);
        !           138:                case 0:
        !           139:                        /*
        !           140:                         * read of file 1 just failed, find out
        !           141:                         * if there's anything left in file 2
        !           142:                         */
        !           143:                        switch (read(fd2, buf2, 1)) {
        !           144:                                case -1:
        !           145:                                        error(file2);
        !           146:                                        /* NOTREACHED */
        !           147:                                case 0:
        !           148:                                        exit(dfound ? EXITDIFF : EXITNODIFF);
        !           149:                                        /* NOTREACHED */
        !           150:                                default:
        !           151:                                        endoffile(file1);
        !           152:                                        break;
        !           153:                        }
        !           154:                }
        !           155:                /*
        !           156:                 * file1 might be stdio, which means that a read of less than
        !           157:                 * MAXBSIZE might not mean an EOF.  So, read whatever we read
        !           158:                 * from file1 from file2.
        !           159:                 */
        !           160:                if ((len2 = read(fd2, buf2, len1)) == -1)
        !           161:                        error(file2);
        !           162:                if (bcmp(buf1, buf2, len2)) {
        !           163:                        if (silent)
        !           164:                                exit(EXITDIFF);
        !           165:                        if (all) {
        !           166:                                dfound = 1;
        !           167:                                for (p1 = buf1, p2 = buf2, cnt = len2; cnt--;
        !           168:                                    ++p1, ++p2) {
        !           169:                                        ++byte;
        !           170:                                        if (*p1 != *p2)
        !           171:                                                printf("%6ld %3o %3o\n",
        !           172:                                                    byte, *p1, *p2);
        !           173:                                }
        !           174:                        } else for (p1 = buf1, p2 = buf2; ; ++p1, ++p2) {
        !           175:                                ++byte;
        !           176:                                if (*p1 != *p2) {
        !           177:                                        printf("%s %s differ: char %ld, line %ld\n", file1, file2, byte, line);
        !           178:                                        exit(EXITDIFF);
        !           179:                                }
        !           180:                                if (*p1 == '\n')
        !           181:                                        ++line;
        !           182:                        }
        !           183:                } else {
        !           184:                        byte += len2;
        !           185:                        /*
        !           186:                         * here's the real performance problem, we've got to
        !           187:                         * count the stupid lines, which means that -l is a
        !           188:                         * *much* faster version, i.e., unless you really
        !           189:                         * *want* to know the line number, run -s or -l.
        !           190:                         */
        !           191:                        if (!silent && !all)
        !           192:                                for (p1 = buf1, cnt = len2; cnt--; )
        !           193:                                        if (*p1++ == '\n')
        !           194:                                                ++line;
        !           195:                }
        !           196:                /*
        !           197:                 * couldn't read as much from file2 as from file1; checked
        !           198:                 * here because there might be a difference before we got
        !           199:                 * to this point, which would have precedence.
        !           200:                 */
        !           201:                if (len2 < len1)
        !           202:                        endoffile(file2);
        !           203:        }
        !           204: }
        !           205: 
        !           206: /*
        !           207:  * otoi --
        !           208:  *     octal/decimal string to u_long
        !           209:  */
        !           210: u_long
        !           211: otoi(s)
        !           212:        register char *s;
        !           213: {
        !           214:        register u_long val;
        !           215:        register int base;
        !           216: 
        !           217:        base = (*s == '0') ? 8 : 10;
        !           218:        for (val = 0; isdigit(*s); ++s)
        !           219:                val = val * base + *s - '0';
        !           220:        return (val);
        !           221: }
        !           222: 
        !           223: /*
        !           224:  * error --
        !           225:  *     print I/O error message and die
        !           226:  */
        !           227: error(filename)
        !           228:        char *filename;
        !           229: {
        !           230:        extern int errno;
        !           231:        char *strerror();
        !           232: 
        !           233:        if (!silent)
        !           234:                (void) fprintf(stderr, "cmp: %s: %s\n",
        !           235:                    filename, strerror(errno));
        !           236:        exit(EXITERR);
        !           237: }
        !           238: 
        !           239: /*
        !           240:  * endoffile --
        !           241:  *     print end-of-file message and exit indicating the files were different
        !           242:  */
        !           243: endoffile(filename)
        !           244:        char *filename;
        !           245: {
        !           246:        /* 32V put this message on stdout, S5 does it on stderr. */
        !           247:        /* POSIX.2 currently does it on stdout-- Hooray! */
        !           248:        if (!silent)
        !           249:                (void) printf("cmp: EOF on %s\n", filename);
        !           250:        exit(EXITDIFF);
        !           251: }
        !           252: 
        !           253: /*
        !           254:  * usage --
        !           255:  *     print usage and die
        !           256:  */
        !           257: usage()
        !           258: {
        !           259:        fputs("usage: cmp [-ls] file1 file2 [skip1] [skip2]\n", stderr);
        !           260:        exit(EXITERR);
        !           261: }

unix.superglobalmegacorp.com

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