Project

General

Profile

md5_ex1.c

Alexander Moibenko, 01/16/2015 04:05 PM

 
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#include <sys/stat.h>
5
#include <sys/types.h>
6
#include <unistd.h>
7
#include <errno.h>
8
#include <fcntl.h>
9

    
10
#if defined(__APPLE__)
11
#  define COMMON_DIGEST_FOR_OPENSSL
12
#  include <CommonCrypto/CommonDigest.h>
13
#  define SHA1 CC_SHA1
14
#else
15
#  include <openssl/md5.h>
16
#endif
17
#define BUF_SIZE 1048576L
18

    
19
char *f2md5(const char *fname) {
20
    int n;
21
    MD5_CTX c;
22
    unsigned char digest[16];
23
    long buf_size = BUF_SIZE;   /*buffer size for the data blocks*/
24
    unsigned int crc;           /*used to hold the crc as it is updated*/
25
    long nb, rest, i;           /*loop control variables*/
26
    struct stat sb;             /*used with fstat()*/
27
    int fd;                     /*the file descriptor*/
28
    char buf[BUF_SIZE];         /*the data buffer*/
29
    char *out = (char*)malloc(33);
30

    
31
    if((fd = open(fname, O_RDONLY)) < 0)
32
    {
33
        printf("Unable to open file %s: %s\n", fname, strerror(errno));
34
        exit(1);
35
    }
36
    if(fstat(fd, &sb) < 0)
37
    {
38
        printf("Unable to stat file %s: %s\n", fname, strerror(errno));
39
        exit(1);
40
    }
41
    if(!(S_ISREG(sb.st_mode)))
42
    {
43
        printf("Operation permitted only for regular file.\n");
44
        exit(1);
45
    }
46

    
47
    /*Initialize values used looping through reading in the file.*/
48
    nb = sb.st_size / buf_size;
49
    rest = sb.st_size % buf_size;
50

    
51
    MD5_Init(&c);
52

    
53
    /*Read in the file in 'buf_size' sized blocks and calculate CRC.*/
54
    for (i = 0; i < nb; i++){
55
        if(read(fd, buf, buf_size) < 0)
56
        {
57
            printf("Error reading file: %s\n", strerror(errno));
58
            exit(1);
59
        }
60
        MD5_Update(&c, buf, buf_size);
61
    }
62
    if (rest)
63
    {
64
        if(read(fd, buf, rest) < 0)
65
        {
66
            printf("Error reading file: %s\n", strerror(errno));
67
            exit(1);
68
        }
69
        MD5_Update(&c, buf, rest);
70
    }
71

    
72

    
73

    
74
  MD5_Final(digest, &c);
75
    for (n = 0; n < 16; ++n) {
76
        snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
77
    }
78

    
79
    return out;
80
}
81

    
82

    
83
    int main(int argc, char **argv) {
84
        char *output = f2md5(argv[1]);
85
        printf("%s\n", output);
86
        free(output);
87
        return 0;
88
    }