* creates a MD5 hash from * a file specified in "filename" and * returns it as string * (based on Ronald L. Rivest's code * from RFC1321 "The MD5 Message-Digest Algorithm") */
| 101 | * from RFC1321 "The MD5 Message-Digest Algorithm") |
| 102 | */ |
| 103 | std::string md5wrapper::getHashFromFile(std::string filename, uint32_t & length, char * first_kb) |
| 104 | { |
| 105 | FILE *file; |
| 106 | MD5Context context; |
| 107 | |
| 108 | int len; |
| 109 | int saved = 0; |
| 110 | unsigned char buffer[1024], digest[16]; |
| 111 | |
| 112 | //open file |
| 113 | if ((file = fopen (filename.c_str(), "rb")) == NULL) |
| 114 | { |
| 115 | return "file unreadable."; |
| 116 | } |
| 117 | length = 0; |
| 118 | //init md5 |
| 119 | MD5Init (&context); |
| 120 | |
| 121 | //read the filecontent |
| 122 | while (1) |
| 123 | { |
| 124 | errno = 0; |
| 125 | len = fread (buffer, 1, 1024, file); |
| 126 | if(saved < 1024 && first_kb) |
| 127 | { |
| 128 | memcpy(first_kb + saved, buffer, std::min (len, 1024 - saved)); |
| 129 | saved += len; |
| 130 | } |
| 131 | length += len; |
| 132 | if(len != 1024) |
| 133 | { |
| 134 | int err = ferror(file); |
| 135 | //FIXME: check errno here. |
| 136 | if(err) |
| 137 | { |
| 138 | fclose(file); |
| 139 | return strerror(err); |
| 140 | } |
| 141 | if(feof(file)) |
| 142 | { |
| 143 | MD5Update (&context, buffer, len); |
| 144 | break; |
| 145 | } |
| 146 | } |
| 147 | MD5Update (&context, buffer, len); |
| 148 | } |
| 149 | |
| 150 | /* |
| 151 | generate hash, close the file and return the |
| 152 | hash as std::string |
| 153 | */ |
| 154 | MD5Final (digest, &context); |
| 155 | fclose (file); |
| 156 | return convToString(digest); |
| 157 | } |
| 158 | |
| 159 | /* |
| 160 | * EOF |