Annotation of pgp/contrib/md5sum/md5sum.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * md5sum.c    - Generate/check MD5 Message Digests
        !             3:  *
        !             4:  * Compile and link with md5.c.  If you don't have getopt() in your library
        !             5:  * also include getopt.c.  For MSDOS you can also link with the wildcard
        !             6:  * initialization function (wildargs.obj for Turbo C and setargv.obj for MSC)
        !             7:  * so that you can use wildcards on the commandline.
        !             8:  *
        !             9:  * Written March 1993 by Branko Lankester
        !            10:  */
        !            11: #include <stdio.h>
        !            12: #include <string.h>
        !            13: #include "md5.h"
        !            14: 
        !            15: #ifdef UNIX
        !            16: #define        FOPRTXT "r"
        !            17: #define        FOPRBIN "r"
        !            18: #else
        !            19: #ifdef VMS
        !            20: #define        FOPRTXT "r","ctx=stm"
        !            21: #define        FOPRBIN "rb","ctx=stm"
        !            22: #else
        !            23: #define        FOPRTXT "r"
        !            24: #define        FOPRBIN "rb"
        !            25: #endif
        !            26: #endif
        !            27: 
        !            28: extern char *optarg;
        !            29: extern int optind;
        !            30: 
        !            31: void usage();
        !            32: void print_digest();
        !            33: int mdfile(FILE *fp, unsigned char *digest);
        !            34: int do_check(FILE *chkf);
        !            35: 
        !            36: char *progname;
        !            37: int verbose = 0;
        !            38: int bin_mode = 0;
        !            39: 
        !            40: void
        !            41: main(int argc, char **argv)
        !            42: {
        !            43:        int opt, rc = 0;
        !            44:        int check = 0;
        !            45:        FILE *fp;
        !            46:        unsigned char digest[16];
        !            47: 
        !            48:        progname = *argv;
        !            49:        while ((opt = getopt(argc, argv, "cbvp:h")) != EOF) {
        !            50:                switch (opt) {
        !            51:                        case 'c': check = 1; break;
        !            52:                        case 'v': verbose = 1; break;
        !            53:                        case 'b': bin_mode = 1; break;
        !            54:                        default: usage();
        !            55:                }
        !            56:        }
        !            57:        argc -= optind;
        !            58:        argv += optind;
        !            59:        if (check) {
        !            60:                switch (argc) {
        !            61:                        case 0: fp = stdin; break;
        !            62:                        case 1: if ((fp = fopen(*argv, FOPRTXT)) == NULL) {
        !            63:                                        perror(*argv);
        !            64:                                        exit(2);
        !            65:                                }
        !            66:                                break;
        !            67:                        default: usage();
        !            68:                }
        !            69:                exit(do_check(fp));
        !            70:        }
        !            71:        if (argc == 0) {
        !            72:                if (mdfile(stdin, digest)) {
        !            73:                        fprintf(stderr, "%s: read error on stdin\n", progname);
        !            74:                        exit(2);
        !            75:                }
        !            76:                print_digest(digest);
        !            77:                printf("\n");
        !            78:                exit(0);
        !            79:        }
        !            80:        for ( ; argc > 0; --argc, ++argv) {
        !            81:                if (bin_mode)
        !            82:                        fp = fopen(*argv, FOPRBIN);
        !            83:                else
        !            84:                        fp = fopen(*argv, FOPRTXT);
        !            85:                if (fp == NULL) {
        !            86:                        perror(*argv);
        !            87:                        rc = 2;
        !            88:                        continue;
        !            89:                }
        !            90:                if (mdfile(fp, digest)) {
        !            91:                        fprintf(stderr, "%s: error reading %s\n", progname, *argv);
        !            92:                        rc = 2;
        !            93:                } else {
        !            94:                        print_digest(digest);
        !            95:                        printf(" %c%s\n", bin_mode ? '*' : ' ', *argv);
        !            96:                }
        !            97:                fclose(fp);
        !            98:        }
        !            99:        exit(rc);
        !           100: }
        !           101: 
        !           102: void
        !           103: usage()
        !           104: {
        !           105:        fprintf(stderr, "usage: md5sum [-bv] [-c [file]] | [file...]\n");
        !           106:        fprintf(stderr, "Generates or checks MD5 Message Digests\n");
        !           107:        fprintf(stderr, "    -c  check message digests (default is generate)\n");
        !           108:        fprintf(stderr, "    -v  verbose, print file names when checking\n");
        !           109:        fprintf(stderr, "    -b  read files in binary mode\n");
        !           110:        fprintf(stderr, "The input for -c should be the list of message digests and file names\n");
        !           111:        fprintf(stderr, "that is printed on stdout by this program when it generates digests.\n");
        !           112:        exit(2);
        !           113: }
        !           114: 
        !           115: int
        !           116: mdfile(FILE *fp, unsigned char *digest)
        !           117: {
        !           118:        unsigned char buf[1024];
        !           119:        MD5_CTX ctx;
        !           120:        int n;
        !           121: 
        !           122:        MD5Init(&ctx);
        !           123:        while ((n = fread(buf, 1, sizeof(buf), fp)) > 0)
        !           124:                MD5Update(&ctx, buf, n);
        !           125:        MD5Final(&ctx);
        !           126:        memcpy(digest, ctx.digest, 16);
        !           127:        if (ferror(fp))
        !           128:                return -1;
        !           129:        return 0;
        !           130: }
        !           131: 
        !           132: void
        !           133: print_digest(unsigned char *p)
        !           134: {
        !           135:        int i;
        !           136: 
        !           137:        for (i = 0; i < 16; ++i)
        !           138:                printf("%02x", *p++);
        !           139: }
        !           140: 
        !           141: int
        !           142: hex_digit(int c)
        !           143: {
        !           144:        if (c >= '0' && c <= '9')
        !           145:                return c - '0';
        !           146:        if (c >= 'a' && c <= 'f')
        !           147:                return c - 'a' + 10;
        !           148:        return -1;
        !           149: }
        !           150: 
        !           151: int
        !           152: get_md5_line(FILE *fp, unsigned char *digest, char *file)
        !           153: {
        !           154:        char buf[1024];
        !           155:        int i, d1, d2, rc;
        !           156:        char *p = buf;
        !           157: 
        !           158:        if (fgets(buf, sizeof(buf), fp) == NULL)
        !           159:                return -1;
        !           160: 
        !           161:        for (i = 0; i < 16; ++i) {
        !           162:                if ((d1 = hex_digit(*p++)) == -1)
        !           163:                        return 0;
        !           164:                if ((d2 = hex_digit(*p++)) == -1)
        !           165:                        return 0;
        !           166:                *digest++ = d1*16 + d2;
        !           167:        }
        !           168:        if (*p++ != ' ')
        !           169:                return 0;
        !           170:        /*
        !           171:         * next char is an attribute char, space means text file
        !           172:         * if it's a '*' the file should be checked in binary mode.
        !           173:         */
        !           174:        if (*p == ' ')
        !           175:                rc = 1;
        !           176:        else if (*p == '*')
        !           177:                rc = 2;
        !           178:        else {
        !           179:                fprintf(stderr, "%s: unrecognized line: %s", progname, buf);
        !           180:                return 0;
        !           181:        }
        !           182:        ++p;
        !           183:        i = strlen(p);
        !           184:        if (i < 2 || i > 255)
        !           185:                return 0;
        !           186:        p[i-1] = '\0';
        !           187:        strcpy(file, p);
        !           188:        return rc;
        !           189: }
        !           190: 
        !           191: int
        !           192: do_check(FILE *chkf)
        !           193: {
        !           194:        int rc, ex = 0, failed = 0, checked = 0;
        !           195:        unsigned char chk_digest[16], file_digest[16];
        !           196:        char filename[256];
        !           197:        FILE *fp;
        !           198:        int flen = 14;
        !           199: 
        !           200:        while ((rc = get_md5_line(chkf, chk_digest, filename)) >= 0) {
        !           201:                if (rc == 0)    /* not an md5 line */
        !           202:                        continue;
        !           203:                if (verbose) {
        !           204:                        if (strlen(filename) > flen)
        !           205:                                flen = strlen(filename);
        !           206:                        fprintf(stderr, "%-*s ", flen, filename);
        !           207:                }
        !           208:                if (bin_mode || rc == 2)
        !           209:                        fp = fopen(filename, FOPRBIN);
        !           210:                else
        !           211:                        fp = fopen(filename, FOPRTXT);
        !           212:                if (fp == NULL) {
        !           213:                        fprintf(stderr, "%s: can't open %s\n", progname, filename);
        !           214:                        ex = 2;
        !           215:                        continue;
        !           216:                }
        !           217:                if (mdfile(fp, file_digest)) {
        !           218:                        fprintf(stderr, "%s: error reading %s\n", progname, filename);
        !           219:                        ex = 2;
        !           220:                        fclose(fp);
        !           221:                        continue;
        !           222:                }
        !           223:                fclose(fp);
        !           224:                if (memcmp(chk_digest, file_digest, 16) != 0) {
        !           225:                        if (verbose)
        !           226:                                fprintf(stderr, "FAILED\n");
        !           227:                        else
        !           228:                                fprintf(stderr, "%s: MD5 check failed for '%s'\n", progname, filename);
        !           229:                        ++failed;
        !           230:                } else if (verbose)
        !           231:                        fprintf(stderr, "OK\n");
        !           232:                ++checked;
        !           233:        }
        !           234:        if (verbose && failed)
        !           235:                fprintf(stderr, "%s: %d of %d file(s) failed MD5 check\n", progname, failed, checked);
        !           236:        if (!checked) {
        !           237:                fprintf(stderr, "%s: no files checked\n", progname);
        !           238:                return 3;
        !           239:        }
        !           240:        if (!ex && failed)
        !           241:                ex = 1;
        !           242:        return ex;
        !           243: }

unix.superglobalmegacorp.com

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