static vector< FileDownloadRecord > getDownloadInfoFromRelease( const Config& config, const IndexEntry& indexEntry, const string& suffix) { auto baseUri = getUriOfIndexEntry(indexEntry); // TODO: make cachefiles::getAlias* functions auto alias = indexEntry.uri + ' ' + indexEntry.distribution; vector< FileDownloadRecord > result; try { auto releaseFilePath = getPathOfMasterReleaseLikeList(config, indexEntry); RequiredFile releaseFile(releaseFilePath, "r"); HashSums::Type currentHashSumType = HashSums::Count; // now we need to find if this variant is present in the release file string line; smatch m; while (!releaseFile.getLine(line).eof()) { if (line.compare(0, 3, "MD5") == 0) { currentHashSumType = HashSums::MD5; } else if (line.compare(0, 4, "SHA1") == 0) { currentHashSumType = HashSums::SHA1; } else if (line.compare(0, 6, "SHA256") == 0) { currentHashSumType = HashSums::SHA256; } else if (line.empty() || !isspace(line[0])) // end of hash sum block { currentHashSumType = HashSums::Count; } else if (currentHashSumType != HashSums::Count && line.find(suffix) != string::npos) { static sregex hashSumsLineRegex = sregex::compile("\\s([[:xdigit:]]+)\\s+(\\d+)\\s+(.*)"); if (!regex_match(line, m, hashSumsLineRegex)) { fatal2(__("malformed line '%s'"), line); } string name = m[3]; if (name.compare(0, suffix.size(), suffix) != 0) { continue; // doesn't start with suffix } // filling result structure string uri = baseUri + '/' + name; bool foundRecord = false; FORIT(recordIt, result) { if (recordIt->uri == uri) { recordIt->hashSums[currentHashSumType] = m[1]; foundRecord = true; break; } } if (!foundRecord) { FileDownloadRecord& record = (result.push_back(FileDownloadRecord()), *(result.rbegin())); record.uri = uri; record.size = string2uint32(m[2]); record.hashSums[currentHashSumType] = m[1]; } } } // checks FORIT(recordIt, result) { if (recordIt->hashSums.empty()) { fatal2(__("no hash sums defined for the index URI '%s'"), recordIt->uri); } } } catch (Exception&) { fatal2("unable to parse the release '%s'", alias); } return result; }
uint32_t string2uint32(pair< string::const_iterator, string::const_iterator > input) { return string2uint32(StringRange{ &*input.first, &*input.second }); }