commit dda01cbe040e648689f4ac3af9fc773628d7f70c Author: hardliner66 Date: Mon Oct 14 23:04:37 2024 +0200 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aac40cb Binary files /dev/null and b/.gitignore differ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..070bdd4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,107 @@ +cmake_minimum_required(VERSION 3.11) +project(DownloadFile) + +cmake_policy(SET CMP0140 NEW) +function(check_file_reachable url) + file(DOWNLOAD "${url}" + RANGE_END 10 + TIMEOUT 2 + INACTIVITY_TIMEOUT 1 + STATUS download_status) + + list(GET download_status 0 download_status_code) + if("${download_status_code}" STREQUAL "0") + set(file_reachable "1") + else() + set(file_reachable "0") + endif() + return(PROPAGATE file_reachable) # File is reachable +endfunction() + +function(download_file_with_hash_check url dest) + set(options REQUIRED) + set(oneValueArgs URL DEST HASH_URL) + cmake_parse_arguments(PARSE_ARGV 0 ARG "${options}" "${oneValueArgs}" "") + + if(ARG_URL) + set(url "${ARG_URL}") + endif() + + if(ARG_DEST) + set(dest "${ARG_DEST}") + endif() + + set(hash_url "${url}.hash") + + if(ARG_HASH_URL) + set(hash_url "${ARG_HASH_URL}") + endif() + message(STATUS "${hash_url}") + + check_file_reachable("${url}") + + if("${file_reachable}" STREQUAL "0") + if(ARG_REQUIRED) + if(NOT EXISTS "${dest}") + message(FATAL_ERROR "File ${dest} could not be downloaded and is not present, even though it was marked as REQUIRED.") + endif() + endif() + return() + endif() + + set(hash_file "${dest}.hash") + set(hash_file_temp "${hash_file}.temp") + + # Download the hash file (if available) + file(DOWNLOAD "${hash_url}" "${hash_file_temp}" + STATUS download_status + TIMEOUT 60) + + list(GET download_status 0 download_status_code) + if(NOT "${download_status_code}" STREQUAL "0") + file(REMOVE "${hash_file_temp}") + # Hash file is not available, just check if the file exists + if(EXISTS "${dest}") + message(STATUS "File ${dest} already exists, no hash file found. Skipping download.") + return() + else() + message(STATUS "File ${dest} not found, downloading without hash check.") + file(DOWNLOAD "${url}" "${dest}" SHOW_PROGRESS TIMEOUT 60) + return() + endif() + endif() + + file(READ "${hash_file_temp}" expected_hash) + string(STRIP "${expected_hash}" expected_hash) + if(NOT "${expected_hash}" STREQUAL "") + file(RENAME "${hash_file_temp}" "${hash_file}") + endif() + + # Hash file downloaded, now read the hash + file(READ "${hash_file}" expected_hash) + string(STRIP "${expected_hash}" expected_hash) # Remove whitespace around hash + if(EXISTS "${dest}") + file(SHA256 "${dest}" actual_hash) + if("${expected_hash}" STREQUAL "${actual_hash}") + message(STATUS "File ${dest} already matches the hash. Skipping download.") + return() + else() + message(WARNING "Hash mismatch for ${dest}. Downloading the file again.") + endif() + else() + message(STATUS "File ${dest} not found. Downloading.") + endif() + + # Download the actual file + file(DOWNLOAD "${url}" "${dest}" SHOW_PROGRESS TIMEOUT 60) + + # Recheck the hash after downloading + file(SHA256 "${dest}" actual_hash) + if(NOT "${expected_hash}" STREQUAL "${actual_hash}") + message(FATAL_ERROR "Downloaded file ${dest} hash mismatch. Expected: ${expected_hash}, got: ${actual_hash}") + else() + message(STATUS "File ${dest} downloaded and verified successfully.") + endif() +endfunction() + +download_file_with_hash_check(URL "http://127.0.0.1:8080/random_file.bin" DEST "${CMAKE_BINARY_DIR}/random_file.bin" REQUIRED)