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

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

unix.superglobalmegacorp.com

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