X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/e7aea3985734af1702fde6e2b0af90b992425334..bda94cb8432b3905f5757e92573fd16e73cb183f:/apt-pkg/acquire-item.cc?ds=inline diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 8973eedde..cf88ded7b 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -33,6 +32,7 @@ #include #include #include +#include /*}}}*/ using namespace std; @@ -139,7 +139,8 @@ void pkgAcquire::Item::Rename(string From,string To) } } /*}}}*/ - +// Acquire::Item::ReportMirrorFailure /*{{{*/ +// --------------------------------------------------------------------- void pkgAcquire::Item::ReportMirrorFailure(string FailCode) { // we only act if a mirror was used at all @@ -181,7 +182,152 @@ void pkgAcquire::Item::ReportMirrorFailure(string FailCode) _config->Find("Methods::Mirror::ProblemReporting").c_str()); } } + /*}}}*/ +// AcqSubIndex::AcqSubIndex - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* Get the Index file first and see if there are languages available + * If so, create a pkgAcqIndexTrans for the found language(s). + */ +pkgAcqSubIndex::pkgAcqSubIndex(pkgAcquire *Owner, string const &URI, + string const &URIDesc, string const &ShortDesc, + HashString const &ExpectedHash) + : Item(Owner), ExpectedHash(ExpectedHash) +{ + Debug = _config->FindB("Debug::pkgAcquire::SubIndex",false); + + DestFile = _config->FindDir("Dir::State::lists") + "partial/"; + DestFile += URItoFileName(URI); + + Desc.URI = URI; + Desc.Description = URIDesc; + Desc.Owner = this; + Desc.ShortDesc = ShortDesc; + + QueueURI(Desc); + + if(Debug) + std::clog << "pkgAcqSubIndex: " << Desc.URI << std::endl; +} + /*}}}*/ +// AcqSubIndex::Custom600Headers - Insert custom request headers /*{{{*/ +// --------------------------------------------------------------------- +/* The only header we use is the last-modified header. */ +string pkgAcqSubIndex::Custom600Headers() +{ + string Final = _config->FindDir("Dir::State::lists"); + Final += URItoFileName(Desc.URI); + + struct stat Buf; + if (stat(Final.c_str(),&Buf) != 0) + return "\nIndex-File: true\nFail-Ignore: true\n"; + return "\nIndex-File: true\nFail-Ignore: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); +} + /*}}}*/ +void pkgAcqSubIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/ +{ + if(Debug) + std::clog << "pkgAcqSubIndex failed: " << Desc.URI << std::endl; + + Complete = false; + Status = StatDone; + Dequeue(); + + // No good Index is provided, so try guessing + std::vector langs = APT::Configuration::getLanguages(true); + for (std::vector::const_iterator l = langs.begin(); + l != langs.end(); ++l) + { + if (*l == "none") continue; + string const file = "Translation-" + *l; + new pkgAcqIndexTrans(Owner, Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file), + Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file), + file); + } +} + /*}}}*/ +void pkgAcqSubIndex::Done(string Message,unsigned long Size,string Md5Hash, /*{{{*/ + pkgAcquire::MethodConfig *Cnf) +{ + if(Debug) + std::clog << "pkgAcqSubIndex::Done(): " << Desc.URI << std::endl; + + string FileName = LookupTag(Message,"Filename"); + if (FileName.empty() == true) + { + Status = StatError; + ErrorText = "Method gave a blank filename"; + return; + } + + if (FileName != DestFile) + { + Local = true; + Desc.URI = "copy:" + FileName; + QueueURI(Desc); + return; + } + + Item::Done(Message,Size,Md5Hash,Cnf); + + string FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(Desc.URI); + + // sucess in downloading the index + // rename the index + if(Debug) + std::clog << "Renaming: " << DestFile << " -> " << FinalFile << std::endl; + Rename(DestFile,FinalFile); + chmod(FinalFile.c_str(),0644); + DestFile = FinalFile; + + if(ParseIndex(DestFile) == false) + return Failed("", NULL); + + Complete = true; + Status = StatDone; + Dequeue(); + return; +} + /*}}}*/ +bool pkgAcqSubIndex::ParseIndex(string const &IndexFile) /*{{{*/ +{ + indexRecords SubIndexParser; + if (FileExists(IndexFile) == false || SubIndexParser.Load(IndexFile) == false) + return false; + + std::vector lang = APT::Configuration::getLanguages(true); + for (std::vector::const_iterator l = lang.begin(); + l != lang.end(); ++l) + { + if (*l == "none") + continue; + + string file = "Translation-" + *l; + indexRecords::checkSum const *Record = SubIndexParser.Lookup(file); + HashString expected; + if (Record == NULL) + { + // FIXME: the Index file provided by debian currently only includes bz2 records + Record = SubIndexParser.Lookup(file + ".bz2"); + if (Record == NULL) + continue; + } + else + { + expected = Record->Hash; + if (expected.empty() == true) + continue; + } + IndexTarget target; + target.Description = Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file); + target.MetaKey = file; + target.ShortDesc = file; + target.URI = Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file); + new pkgAcqIndexTrans(Owner, &target, expected, &SubIndexParser); + } + return true; +} + /*}}}*/ // AcqDiffIndex::AcqDiffIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* Get the DiffIndex file first and see if there are patches availabe @@ -295,7 +441,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ else { if(Debug) - std::clog << "SHA1-Current: " << ServerSha1 << std::endl; + std::clog << "SHA1-Current: " << ServerSha1 << " and we start at "<< fd.Name() << " " << fd.Size() << " " << local_sha1 << std::endl; // check the historie and see what patches we need string const history = Tags.FindS("SHA1-History"); @@ -568,24 +714,7 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash, /* FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(RealURI); // sucess in downloading a diff, enter ApplyDiff state - if(State == StateFetchDiff) - { - - if(Debug) - std::clog << "Sending to gzip method: " << FinalFile << std::endl; - - string FileName = LookupTag(Message,"Filename"); - State = StateUnzipDiff; - Local = true; - Desc.URI = "gzip:" + FileName; - DestFile += ".decomp"; - QueueURI(Desc); - Mode = "gzip"; - return; - } - - // sucess in downloading a diff, enter ApplyDiff state - if(State == StateUnzipDiff) + if(State == StateFetchDiff) { // rred excepts the patch as $FinalFile.ed @@ -637,29 +766,61 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, HashString ExpectedHash, string comprExt) : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash) { + if(comprExt.empty() == true) + { + // autoselect the compression method + std::vector types = APT::Configuration::getCompressionTypes(); + for (std::vector::const_iterator t = types.begin(); t != types.end(); ++t) + comprExt.append(*t).append(" "); + if (comprExt.empty() == false) + comprExt.erase(comprExt.end()-1); + } + CompressionExtension = comprExt; + + Init(URI, URIDesc, ShortDesc); +} +pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, IndexTarget const *Target, + HashString const &ExpectedHash, indexRecords const *MetaIndexParser) + : Item(Owner), RealURI(Target->URI), ExpectedHash(ExpectedHash) +{ + // autoselect the compression method + std::vector types = APT::Configuration::getCompressionTypes(); + CompressionExtension = ""; + if (ExpectedHash.empty() == false) + { + for (std::vector::const_iterator t = types.begin(); t != types.end(); ++t) + if (*t == "uncompressed" || MetaIndexParser->Exists(string(Target->MetaKey).append(".").append(*t)) == true) + CompressionExtension.append(*t).append(" "); + } + else + { + for (std::vector::const_iterator t = types.begin(); t != types.end(); ++t) + CompressionExtension.append(*t).append(" "); + } + if (CompressionExtension.empty() == false) + CompressionExtension.erase(CompressionExtension.end()-1); + + Init(Target->URI, Target->Description, Target->ShortDesc); +} + /*}}}*/ +// AcqIndex::Init - defered Constructor /*{{{*/ +void pkgAcqIndex::Init(string const &URI, string const &URIDesc, string const &ShortDesc) { Decompression = false; Erase = false; DestFile = _config->FindDir("Dir::State::lists") + "partial/"; DestFile += URItoFileName(URI); - if(comprExt.empty()) - { - // autoselect the compression method - std::vector types = APT::Configuration::getCompressionTypes(); - if (types.empty() == true) - comprExt = "plain"; - else - comprExt = "." + types[0]; - } - CompressionExtension = ((comprExt == "plain" || comprExt == ".") ? "" : comprExt); - - Desc.URI = URI + CompressionExtension; + std::string const comprExt = CompressionExtension.substr(0, CompressionExtension.find(' ')); + if (comprExt == "uncompressed") + Desc.URI = URI; + else + Desc.URI = URI + '.' + comprExt; Desc.Description = URIDesc; Desc.Owner = this; Desc.ShortDesc = ShortDesc; - + QueueURI(Desc); } /*}}}*/ @@ -670,46 +831,35 @@ string pkgAcqIndex::Custom600Headers() { string Final = _config->FindDir("Dir::State::lists"); Final += URItoFileName(RealURI); + if (_config->FindB("Acquire::GzipIndexes",false)) + Final += ".gz"; + string msg = "\nIndex-File: true"; + // FIXME: this really should use "IndexTarget::IsOptional()" but that + // seems to be difficult without breaking ABI + if (ShortDesc().find("Translation") != 0) + msg += "\nFail-Ignore: true"; struct stat Buf; if (stat(Final.c_str(),&Buf) != 0) - return "\nIndex-File: true"; - return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); + msg += "\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); + + return msg; } /*}}}*/ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/ { - std::vector types = APT::Configuration::getCompressionTypes(); - - for (std::vector::const_iterator t = types.begin(); - t != types.end(); t++) + size_t const nextExt = CompressionExtension.find(' '); + if (nextExt != std::string::npos) { - // jump over all already tried compression types - const unsigned int nameLen = Desc.URI.size() - (*t).size(); - if(Desc.URI.substr(nameLen) != *t) - continue; - - // we want to try it with the next extension (and make sure to - // not skip over the end) - t++; - if (t == types.end()) - break; - - // queue new download - Desc.URI = Desc.URI.substr(0, nameLen) + *t; - new pkgAcqIndex(Owner, RealURI, Desc.Description, Desc.ShortDesc, - ExpectedHash, string(".").append(*t)); - - Status = StatDone; - Complete = false; - Dequeue(); + CompressionExtension = CompressionExtension.substr(nextExt+1); + Init(RealURI, Desc.Description, Desc.ShortDesc); return; } // on decompression failure, remove bad versions in partial/ - if(Decompression && Erase) { + if (Decompression && Erase) { string s = _config->FindDir("Dir::State::lists") + "partial/"; - s += URItoFileName(RealURI); + s.append(URItoFileName(RealURI)); unlink(s.c_str()); } @@ -786,28 +936,41 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash, Status = StatError; ErrorText = "Method gave a blank filename"; } - + + std::string const compExt = CompressionExtension.substr(0, CompressionExtension.find(' ')); + // The files timestamp matches - if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true) + if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true) { + if (_config->FindB("Acquire::GzipIndexes",false) && compExt == "gz") + // Update DestFile for .gz suffix so that the clean operation keeps it + DestFile += ".gz"; return; + } if (FileName == DestFile) Erase = true; else Local = true; - string compExt = flExtension(flNotDir(URI(Desc.URI).Path)); string decompProg; + // If we enable compressed indexes and already have gzip, keep it + if (_config->FindB("Acquire::GzipIndexes",false) && compExt == "gz" && !Local) { + string FinalFile = _config->FindDir("Dir::State::lists"); + FinalFile += URItoFileName(RealURI) + ".gz"; + Rename(DestFile,FinalFile); + chmod(FinalFile.c_str(),0644); + + // Update DestFile for .gz suffix so that the clean operation keeps it + DestFile = _config->FindDir("Dir::State::lists") + "partial/"; + DestFile += URItoFileName(RealURI) + ".gz"; + return; + } + // get the binary name for your used compression type decompProg = _config->Find(string("Acquire::CompressionTypes::").append(compExt),""); if(decompProg.empty() == false); - // flExtensions returns the full name if no extension is found - // this is why we have this complicated compare operation here - // FIMXE: add a new flJustExtension() that return "" if no - // extension is found and use that above so that it can - // be tested against "" - else if(compExt == flNotDir(URI(Desc.URI).Path)) + else if(compExt == "uncompressed") decompProg = "copy"; else { _error->Error("Unsupported extension: %s", compExt.c_str()); @@ -828,13 +991,24 @@ pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner, string URI,string URIDesc,string ShortDesc) : pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashString(), "") { +} +pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner, IndexTarget const *Target, + HashString const &ExpectedHash, indexRecords const *MetaIndexParser) + : pkgAcqIndex(Owner, Target, ExpectedHash, MetaIndexParser) +{ } /*}}}*/ // AcqIndexTrans::Custom600Headers - Insert custom request headers /*{{{*/ // --------------------------------------------------------------------- string pkgAcqIndexTrans::Custom600Headers() { - return "\nFail-Ignore: true"; + string Final = _config->FindDir("Dir::State::lists"); + Final += URItoFileName(RealURI); + + struct stat Buf; + if (stat(Final.c_str(),&Buf) != 0) + return "\nFail-Ignore: true\nIndex-File: true"; + return "\nFail-Ignore: true\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); } /*}}}*/ // AcqIndexTrans::Failed - Silence failure messages for missing files /*{{{*/ @@ -842,6 +1016,15 @@ string pkgAcqIndexTrans::Custom600Headers() /* */ void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf) { + size_t const nextExt = CompressionExtension.find(' '); + if (nextExt != std::string::npos) + { + CompressionExtension = CompressionExtension.substr(nextExt+1); + Init(RealURI, Desc.Description, Desc.ShortDesc); + Status = StatIdle; + return; + } + if (Cnf->LocalOnly == true || StringToBool(LookupTag(Message,"Transient-Failure"),false) == false) { @@ -851,7 +1034,7 @@ void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf) Dequeue(); return; } - + Item::Failed(Message,Cnf); } /*}}}*/ @@ -1032,12 +1215,6 @@ void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash, /*{{{* // all cool, move Release file into place Complete = true; - - string FinalFile = _config->FindDir("Dir::State::lists"); - FinalFile += URItoFileName(RealURI); - Rename(DestFile,FinalFile); - chmod(FinalFile.c_str(),0644); - DestFile = FinalFile; } else { @@ -1064,8 +1241,20 @@ void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash, /*{{{* Desc.URI = "gpgv:" + SigFile; QueueURI(Desc); Mode = "gpgv"; + return; } } + + if (Complete == true) + { + string FinalFile = _config->FindDir("Dir::State::lists"); + FinalFile += URItoFileName(RealURI); + if (SigFile == DestFile) + SigFile = FinalFile; + Rename(DestFile,FinalFile); + chmod(FinalFile.c_str(),0644); + DestFile = FinalFile; + } } /*}}}*/ void pkgAcqMetaIndex::RetrievalDone(string Message) /*{{{*/ @@ -1095,6 +1284,8 @@ void pkgAcqMetaIndex::RetrievalDone(string Message) /*{{{*/ { string FinalFile = _config->FindDir("Dir::State::lists"); FinalFile += URItoFileName(RealURI); + if (SigFile == DestFile) + SigFile = FinalFile; DestFile = FinalFile; } Complete = true; @@ -1126,6 +1317,10 @@ void pkgAcqMetaIndex::AuthDone(string Message) /*{{{*/ // Download further indexes with verification QueueIndexes(true); + // is it a clearsigned MetaIndex file? + if (DestFile == SigFile) + return; + // Done, move signature file into position string VerifiedSigFile = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI) + ".gpg"; @@ -1142,65 +1337,58 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/ HashString ExpectedIndexHash; if (verify) { - const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey); - if (!Record) - { - Status = StatAuthError; - ErrorText = "Unable to find expected entry " - + (*Target)->MetaKey + " in Meta-index file (malformed Release file?)"; - return; - } - ExpectedIndexHash = Record->Hash; - if (_config->FindB("Debug::pkgAcquire::Auth", false)) - { - std::cerr << "Queueing: " << (*Target)->URI << std::endl; - std::cerr << "Expected Hash: " << ExpectedIndexHash.toStr() << std::endl; - } - if (ExpectedIndexHash.empty()) - { - Status = StatAuthError; - ErrorText = "Unable to find hash sum for " - + (*Target)->MetaKey + " in Meta-index file"; - return; - } + const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey); + if (Record == NULL) + { + if ((*Target)->IsOptional() == false) + { + Status = StatAuthError; + strprintf(ErrorText, _("Unable to find expected entry '%s' in Release file (Wrong sources.list entry or malformed file)"), (*Target)->MetaKey.c_str()); + return; + } + } + else + { + ExpectedIndexHash = Record->Hash; + if (_config->FindB("Debug::pkgAcquire::Auth", false)) + { + std::cerr << "Queueing: " << (*Target)->URI << std::endl; + std::cerr << "Expected Hash: " << ExpectedIndexHash.toStr() << std::endl; + } + if (ExpectedIndexHash.empty() == true && (*Target)->IsOptional() == false) + { + Status = StatAuthError; + strprintf(ErrorText, _("Unable to find hash sum for '%s' in Release file"), (*Target)->MetaKey.c_str()); + return; + } + } } - - // Queue Packages file (either diff or full packages files, depending - // on the users option) - if(_config->FindB("Acquire::PDiffs", true) == true) + + if ((*Target)->IsOptional() == true) + { + if ((*Target)->IsSubIndex() == true) + new pkgAcqSubIndex(Owner, (*Target)->URI, (*Target)->Description, + (*Target)->ShortDesc, ExpectedIndexHash); + else + new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser); + continue; + } + + /* Queue Packages file (either diff or full packages files, depending + on the users option) - we also check if the PDiff Index file is listed + in the Meta-Index file. Ideal would be if pkgAcqDiffIndex would test this + instead, but passing the required info to it is to much hassle */ + if(_config->FindB("Acquire::PDiffs",true) == true && (verify == false || + MetaIndexParser->Exists(string((*Target)->MetaKey).append(".diff/Index")) == true)) new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description, (*Target)->ShortDesc, ExpectedIndexHash); - else - new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description, - (*Target)->ShortDesc, ExpectedIndexHash); + else + new pkgAcqIndex(Owner, *Target, ExpectedIndexHash, MetaIndexParser); } } /*}}}*/ bool pkgAcqMetaIndex::VerifyVendor(string Message) /*{{{*/ { -// // Maybe this should be made available from above so we don't have -// // to read and parse it every time? -// pkgVendorList List; -// List.ReadMainList(); - -// const Vendor* Vndr = NULL; -// for (std::vector::const_iterator I = GPGVOutput.begin(); I != GPGVOutput.end(); I++) -// { -// string::size_type pos = (*I).find("VALIDSIG "); -// if (_config->FindB("Debug::Vendor", false)) -// std::cerr << "Looking for VALIDSIG in \"" << (*I) << "\": pos " << pos -// << std::endl; -// if (pos != std::string::npos) -// { -// string Fingerprint = (*I).substr(pos+sizeof("VALIDSIG")); -// if (_config->FindB("Debug::Vendor", false)) -// std::cerr << "Looking for \"" << Fingerprint << "\" in vendor..." << -// std::endl; -// Vndr = List.FindVendor(Fingerprint) != ""; -// if (Vndr != NULL); -// break; -// } -// } string::size_type pos; // check for missing sigs (that where not fatal because otherwise we had @@ -1236,6 +1424,17 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message) /*{{{*/ Transformed = ""; } + if (_config->FindB("Acquire::Check-Valid-Until", true) == true && + MetaIndexParser->GetValidUntil() > 0) { + time_t const invalid_since = time(NULL) - MetaIndexParser->GetValidUntil(); + if (invalid_since > 0) + // TRANSLATOR: The first %s is the URL of the bad Release file, the second is + // the time since then the file is invalid - formated in the same way as in + // the download progress display (e.g. 7d 3h 42min 1s) + return _error->Error(_("Release file expired, ignoring %s (invalid since %s)"), + RealURI.c_str(), TimeToStr(invalid_since).c_str()); + } + if (_config->FindB("Debug::pkgAcquire::Auth", false)) { std::cerr << "Got Codename: " << MetaIndexParser->GetDist() << std::endl; @@ -1253,7 +1452,7 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message) /*{{{*/ // return false; if (!Transformed.empty()) { - _error->Warning("Conflicting distribution: %s (expected %s but got %s)", + _error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"), Desc.Description.c_str(), Transformed.c_str(), MetaIndexParser->GetDist().c_str()); @@ -1271,17 +1470,24 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) if (AuthPass == true) { // gpgv method failed, if we have a good signature - string LastGoodSigFile = _config->FindDir("Dir::State::lists") + - "partial/" + URItoFileName(RealURI) + ".gpg.reverify"; + string LastGoodSigFile = _config->FindDir("Dir::State::lists"); + if (DestFile == SigFile) + LastGoodSigFile.append(URItoFileName(RealURI)); + else + LastGoodSigFile.append("partial/").append(URItoFileName(RealURI)).append(".gpg.reverify"); + if(FileExists(LastGoodSigFile)) { - string VerifiedSigFile = _config->FindDir("Dir::State::lists") + - URItoFileName(RealURI) + ".gpg"; - Rename(LastGoodSigFile,VerifiedSigFile); + if (DestFile != SigFile) + { + string VerifiedSigFile = _config->FindDir("Dir::State::lists") + + URItoFileName(RealURI) + ".gpg"; + Rename(LastGoodSigFile,VerifiedSigFile); + } Status = StatTransientNetworkError; _error->Warning(_("A error occurred during the signature " "verification. The repository is not updated " - "and the previous index files will be used." + "and the previous index files will be used. " "GPG error: %s: %s\n"), Desc.Description.c_str(), LookupTag(Message,"Message").c_str()); @@ -1301,6 +1507,50 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) QueueIndexes(false); } /*}}}*/ +pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire *Owner, /*{{{*/ + string const &URI, string const &URIDesc, string const &ShortDesc, + string const &MetaIndexURI, string const &MetaIndexURIDesc, string const &MetaIndexShortDesc, + string const &MetaSigURI, string const &MetaSigURIDesc, string const &MetaSigShortDesc, + const vector* IndexTargets, + indexRecords* MetaIndexParser) : + pkgAcqMetaIndex(Owner, URI, URIDesc, ShortDesc, "", IndexTargets, MetaIndexParser), + MetaIndexURI(MetaIndexURI), MetaIndexURIDesc(MetaIndexURIDesc), MetaIndexShortDesc(MetaIndexShortDesc), + MetaSigURI(MetaSigURI), MetaSigURIDesc(MetaSigURIDesc), MetaSigShortDesc(MetaSigShortDesc) +{ + SigFile = DestFile; +} + /*}}}*/ +// pkgAcqMetaClearSig::Custom600Headers - Insert custom request headers /*{{{*/ +// --------------------------------------------------------------------- +// FIXME: this can go away once the InRelease file is used widely +string pkgAcqMetaClearSig::Custom600Headers() +{ + string Final = _config->FindDir("Dir::State::lists"); + Final += URItoFileName(RealURI); + + struct stat Buf; + if (stat(Final.c_str(),&Buf) != 0) + return "\nIndex-File: true\nFail-Ignore: true\n"; + + return "\nIndex-File: true\nFail-Ignore: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); +} + /*}}}*/ +void pkgAcqMetaClearSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/ +{ + if (AuthPass == false) + { + new pkgAcqMetaSig(Owner, + MetaSigURI, MetaSigURIDesc, MetaSigShortDesc, + MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc, + IndexTargets, MetaIndexParser); + if (Cnf->LocalOnly == true || + StringToBool(LookupTag(Message, "Transient-Failure"), false) == false) + Dequeue(); + } + else + pkgAcqMetaIndex::Failed(Message, Cnf); +} + /*}}}*/ // AcqArchive::AcqArchive - Constructor /*{{{*/ // --------------------------------------------------------------------- /* This just sets up the initial fetch environment and queues the first @@ -1668,7 +1918,7 @@ void pkgAcqFile::Done(string Message,unsigned long Size,string CalcHash, if(!ExpectedHash.empty() && ExpectedHash.toStr() != CalcHash) { Status = StatError; - ErrorText = "Hash Sum mismatch"; + ErrorText = _("Hash Sum mismatch"); Rename(DestFile,DestFile + ".FAILED"); return; } @@ -1747,3 +1997,13 @@ string pkgAcqFile::Custom600Headers() return ""; } /*}}}*/ +bool IndexTarget::IsOptional() const { + if (strncmp(ShortDesc.c_str(), "Translation", 11) != 0) + return false; + return true; +} +bool IndexTarget::IsSubIndex() const { + if (ShortDesc != "TranslationIndex") + return false; + return true; +}