From 097fb464ed6e83f0ab388f681a2a8c164fb720e3 Mon Sep 17 00:00:00 2001 From: Svyatoslav Krasnov Date: Sat, 25 Jun 2022 19:44:28 +0000 Subject: [PATCH] add check_download_file function --- sched/sched_util_basic.cpp | 55 ++++++++++++++++++++++++++++++++++++++ sched/sched_util_basic.h | 4 +++ 2 files changed, 59 insertions(+) diff --git a/sched/sched_util_basic.cpp b/sched/sched_util_basic.cpp index d52af5d580..2261f2f139 100644 --- a/sched/sched_util_basic.cpp +++ b/sched/sched_util_basic.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -169,6 +170,60 @@ static void filename_hash(const char* filename, int fanout, char* dir) { sprintf(dir, "%x", x % fanout); } +// returns: +// 0 if same file is already there and has correct .md5, we don't need to copy or create .md5 +// 1 if same file is already there and .md5 file is missing, need to create corresponding .md5 file +// 2 if a file isn't there, need to copy and create .md5 +// -1 if a different file is there +// -2 if a file operation failed +// +// file_path - source path to file, dl_hier_path - path to the same file in download hier +// +int check_download_file(const char* file_path, const char* dl_hier_path) { + bool md5_file_exists = false; + char md5_file_path[256]; + char md5_hash_src[33], md5_hash_dst[33]; + double nbytes; + std::string file_content, file_hash; + int file_size; + + int retval = md5_file(file_path, md5_hash_src, nbytes); + if (retval) { + return -2; + } + + sprintf(md5_file_path, "%s.md5", dl_hier_path); + if (boinc_file_exists(md5_file_path)) { + retval = read_file_string(md5_file_path, file_content); + if (retval) { + return -2; + } + std::stringstream stream(file_content); + stream >> file_hash >> file_size; + md5_file_exists = true; + } + + if (!boinc_file_exists(dl_hier_path)) { + return 2; + } + // calculating md5 hash of existing file in dl hier + retval = md5_file(dl_hier_path, md5_hash_dst, nbytes); + if (retval) { + return -2; + } + int hashes_equal = !strcmp(md5_hash_src, md5_hash_dst); + if (md5_file_exists && hashes_equal) { + // the right file with correct .md5 is there + return 0; + } else if (hashes_equal) { + // files are the same, but need to create .md5 + return 1; + } + // if the content of the file in dl hier differs from the source file's content + // then skip staging, consider to manually delete file in dl hier and retry + return -1; +} + // given a filename, compute its path in a directory hierarchy // If create is true, create the directory if needed // diff --git a/sched/sched_util_basic.h b/sched/sched_util_basic.h index d7a9ba8d30..c16a3416ec 100644 --- a/sched/sched_util_basic.h +++ b/sched/sched_util_basic.h @@ -40,6 +40,10 @@ extern void install_stop_signal_handler(); extern int try_fopen(const char* path, FILE*& f, const char* mode); extern int get_log_path(char*, const char*); +// check the status of a file with the given path and its .md5 in download hier +// +extern int check_download_file(const char* file_path, const char* dl_hier_path); + // convert filename to path in a hierarchical directory system // extern int dir_hier_path(