(注:これは、実際に尋ねられた質問ではなく、尋ねられるべきだったと思う質問への回答です。https://meta.stackexchange.com/questions/66377/what-is-the-xy-problemを参照してください)
C ライブラリの内部をいじる代わりに、独自のユーザーデータを libcurl に提供する必要があります。CURLOPT_WRITEDATA
転送を初期化するときにオプションでユーザーデータを設定できます。
libcurl が単に FILE* を渡す代わりに、独自のユーザーデータを設定する可能性を提供するのは、まさにこの種のアプリケーションのためです。
大まかに言えば、コードは次のようになります。
// All error checking has been omitted; don't use this code as is.
// This is the userdata you'll be using
typedef struct FileWithMD5 {
FILE* file;
MD5_CTX md5_ctx;
} FileWIthMD5;
// The transfer function we'll be using
size_t write_with_md5(char *ptr, size_t size, size_t nmemb,
void *userdata);
// This function is called before the transfer is started.
// The return value needs to be passed to the finalize function.
FileWithMD5* initialize_transfer(CURL *handle, const char* filename) {
// Allocate a userdata
FileWithMD5* userdata = malloc(sizeof(*userdata));
userdata->file = fopen(filename, "w");
MD5Init(&userdata->md5_ctx);
curl_easy_setopt(handle, CURL_WRITEDATA, userdata);
curl_easy_setopt(handle, CURL_WRITEFUNCTION, write_with_md5);
return userdata;
}
// This function is called after the transfer is finished.
void finalize_transfer_and_extract_md5(CURL *handle,
FileWithMD5* userdata,
u_int8_t md5[MD5_DIGEST_LENGTH]) {
// Close the file, extract the MD5, and get rid of the userdata
close(userdata->file);
MD5Final(md5, &userdata->md5_ctx);
free(userdata);
curl_easy_setopt(handle, CURL_WRITEDATA, 0);
}
// Callback function
size_t write_with_md5(char *ptr, size_t size, size_t nmemb,
void *vuserdata) {
FileWithMD5* userdata = vuserdata;
// Write the data and update the MD5
size_t written = fwrite(ptr, size, nmemb, userdata->file);
MD5Update(&userdata->md5_ctx, (const u_int8_t*)ptr, written);
return written;
}