std::string get_file_hash(const Files::Filesystem& fs, const fs::path& path, const std::string& hash_type) { const std::string digest_size = get_digest_size(hash_type); Checks::check_exit(VCPKG_LINE_INFO, fs.exists(path), "File %s does not exist", path.u8string()); // Try hash-specific tools, like sha512sum { const auto ec_data = System::cmd_execute_and_capture_output( Strings::format(R"(sha%ssum "%s")", digest_size, path.u8string())); if (ec_data.exit_code == 0) { return parse_shasum_output(ec_data.output); } } // Try shasum { const auto ec_data = System::cmd_execute_and_capture_output( Strings::format(R"(shasum -a %s "%s")", digest_size, path.u8string())); if (ec_data.exit_code == 0) { return parse_shasum_output(ec_data.output); } } Checks::exit_with_message(VCPKG_LINE_INFO, "Could not hash file %s with %s", path.u8string(), hash_type); } std::string get_string_hash(const std::string& s, const std::string& hash_type) { const std::string digest_size = get_digest_size(hash_type); verify_has_only_allowed_chars(s); // Try hash-specific tools, like sha512sum { const auto ec_data = System::cmd_execute_and_capture_output(Strings::format(R"(echo -n "%s" | sha%ssum)", s, digest_size)); if (ec_data.exit_code == 0) { return parse_shasum_output(ec_data.output); } } // Try shasum { const auto ec_data = System::cmd_execute_and_capture_output( Strings::format(R"(echo -n "%s" | shasum -a %s)", s, digest_size)); if (ec_data.exit_code == 0) { return parse_shasum_output(ec_data.output); } } Checks::exit_with_message(VCPKG_LINE_INFO, "Could not hash input string with %s", hash_type); } #endif }
/* Calculates the digest of a file, if needed. */ static int get_file_digest(File* file) { FILE* stream; size_t size; char buffer[BUFFER_SIZE]; if (file->status == HASHED) return 0; init_digest(); if (file->status == SAMPLED && file->size <= SAMPLE_SIZE) update_digest(file->sample, file->size); else if (file->size > 0) { stream = fopen(file->path, "rb"); if (!stream) { if (!quiet_flag) warning("%s: %s", file->path, strerror(errno)); file->status = INVALID; return -1; } for (;;) { size = fread(buffer, 1, sizeof(buffer), stream); if (ferror(stream)) { if (!quiet_flag) warning("%s: %s", file->path, strerror(errno)); fclose(stream); file->status = INVALID; return -1; } if (size == 0) break; update_digest(buffer, size); } fclose(stream); } file->digest = malloc(get_digest_size()); finish_digest(file->digest); file->status = HASHED; return 0; }
/* Compares the digests of two files, calculating them if neccessary. */ static int compare_file_digests(File* first, File* second) { if (get_file_digest(first) != 0) return -1; if (get_file_digest(second) != 0) return -1; if (memcmp(first->digest, second->digest, get_digest_size()) != 0) return -1; return 0; }