! \brief * Calculate a MD5 digest over a file. * This function assumes 32 bytes in the destination buffer. * \param dest destination * \param file_name file for that the digest should be calculated * \return zero on success, negative on errors */
| 69 | * \return zero on success, negative on errors |
| 70 | */ |
| 71 | int MD5File(char *dest, const char *file_name) |
| 72 | { |
| 73 | if (!dest || !file_name) { |
| 74 | LM_ERR("invalid parameter value\n"); |
| 75 | return -1; |
| 76 | } |
| 77 | |
| 78 | MD5_CTX context; |
| 79 | FILE *input; |
| 80 | char buffer[32768]; |
| 81 | char hash[16]; |
| 82 | unsigned int counter, size; |
| 83 | |
| 84 | struct stat stats; |
| 85 | if (stat(file_name, &stats) != 0) { |
| 86 | LM_ERR("could not stat file %s\n", file_name); |
| 87 | return -1; |
| 88 | } |
| 89 | size = stats.st_size; |
| 90 | |
| 91 | MD5Init(&context); |
| 92 | if((input = fopen(file_name, "rb")) == NULL) { |
| 93 | LM_ERR("could not open file %s\n", file_name); |
| 94 | return -1; |
| 95 | } |
| 96 | |
| 97 | while(size) { |
| 98 | counter = (size > sizeof(buffer)) ? sizeof(buffer) : size; |
| 99 | if ((counter = fread(buffer, 1, counter, input)) <= 0) { |
| 100 | fclose(input); |
| 101 | return -1; |
| 102 | } |
| 103 | MD5Update(&context, buffer, counter); |
| 104 | size -= counter; |
| 105 | } |
| 106 | fclose(input); |
| 107 | MD5Final(hash, &context); |
| 108 | |
| 109 | string2hex(hash, 16, dest); |
| 110 | LM_DBG("MD5 calculated: %.*s for file %s\n", MD5_LEN, dest, file_name); |
| 111 | |
| 112 | return 0; |
| 113 | } |
no test coverage detected