X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/019dfaedcc169837f88cc0b971fd8897828d93bf..fce69e7a0f38299c57ef96ae1c1dd9a5379bfd5a:/cmdline/apt-get.cc diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 3003c1971..6e9d3bf68 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -15,7 +15,7 @@ upgrade - Smart-Download the newest versions of all packages dselect-upgrade - Follows dselect's changes to the Status: field and installes new and removes old packages - dist-upgrade - Powerfull upgrader designed to handle the issues with + dist-upgrade - Powerful upgrader designed to handle the issues with a new distribution. install - Download and install a given package (by name, not by .deb) check - Update the package cache and check for broken packages @@ -63,6 +63,8 @@ #include #include +#include + #include #include @@ -132,6 +134,63 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, return true; } /*}}}*/ + + +// helper that can go wit hthe next ABI break +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) +std::string MetaIndexFileNameOnDisk(metaIndex *metaindex) +{ + // FIXME: this cast is the horror, the horror + debReleaseIndex *r = (debReleaseIndex*)metaindex; + + // see if we have a InRelease file + std::string PathInRelease = r->MetaIndexFile("InRelease"); + if (FileExists(PathInRelease)) + return PathInRelease; + + // and if not return the normal one + if (FileExists(PathInRelease)) + return r->MetaIndexFile("Release"); + + return ""; +} +#endif + +// GetReleaseForSourceRecord - Return Suite for the given srcrecord /*{{{*/ +// --------------------------------------------------------------------- +/* */ +std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, + pkgSrcRecords::Parser *Parse) +{ + // try to find release + const pkgIndexFile& CurrentIndexFile = Parse->Index(); + + for (pkgSourceList::const_iterator S = SrcList->begin(); + S != SrcList->end(); ++S) + { + vector *Indexes = (*S)->GetIndexFiles(); + for (vector::const_iterator IF = Indexes->begin(); + IF != Indexes->end(); ++IF) + { + if (&CurrentIndexFile == (*IF)) + { +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) + std::string path = MetaIndexFileNameOnDisk(*S); +#else + std::string path = (*S)->LocalFileName(); +#endif + if (path != "") + { + indexRecords records; + records.Load(path); + return records.GetSuite(); + } + } + } + } + return ""; +} + /*}}}*/ // FindSrc - Find a source record /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -139,18 +198,31 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgSrcRecords &SrcRecs,string &Src, CacheFile &CacheFile) { - string VerTag; - string DefRel = _config->Find("APT::Default-Release"); + string VerTag, UserRequestedVerTag; + string ArchTag = ""; + string RelTag = _config->Find("APT::Default-Release"); string TmpSrc = Name; pkgDepCache *Cache = CacheFile.GetDepCache(); - // extract the version/release from the pkgname - const size_t found = TmpSrc.find_last_of("/="); - if (found != string::npos) { - if (TmpSrc[found] == '/') - DefRel = TmpSrc.substr(found+1); - else - VerTag = TmpSrc.substr(found+1); + // extract release + size_t found = TmpSrc.find_last_of("/"); + if (found != string::npos) + { + RelTag = TmpSrc.substr(found+1); + TmpSrc = TmpSrc.substr(0,found); + } + // extract the version + found = TmpSrc.find_last_of("="); + if (found != string::npos) + { + VerTag = UserRequestedVerTag = TmpSrc.substr(found+1); + TmpSrc = TmpSrc.substr(0,found); + } + // extract arch + found = TmpSrc.find_last_of(":"); + if (found != string::npos) + { + ArchTag = TmpSrc.substr(found+1); TmpSrc = TmpSrc.substr(0,found); } @@ -158,10 +230,25 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, install a version and determine the source package name, then look in the archive for a source package of the same name. */ bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source"); - const pkgCache::PkgIterator Pkg = Cache->FindPkg(TmpSrc); + pkgCache::PkgIterator Pkg; + if (ArchTag != "") + Pkg = Cache->FindPkg(TmpSrc, ArchTag); + else + Pkg = Cache->FindPkg(TmpSrc); + + // if we can't find a package but the user qualified with a arch, + // error out here + if (Pkg.end() && ArchTag != "") + { + Src = Name; + _error->Error(_("Can not find a package for architecture '%s'"), + ArchTag.c_str()); + return 0; + } + if (MatchSrcOnly == false && Pkg.end() == false) { - if(VerTag.empty() == false || DefRel.empty() == false) + if(VerTag != "" || RelTag != "" || ArchTag != "") { bool fuzzy = false; // we have a default release, try to locate the pkg. we do it like @@ -181,6 +268,17 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, if (Ver.end() == true) break; } + + // ignore arches that are not for us + if (ArchTag != "" && Ver.Arch() != ArchTag) + continue; + + // pick highest version for the arch unless the user wants + // something else + if (ArchTag != "" && VerTag == "" && RelTag == "") + if(Cache->VS().CmpVersion(VerTag, Ver.VerStr()) < 0) + VerTag = Ver.VerStr(); + // We match against a concrete version (or a part of this version) if (VerTag.empty() == false && (fuzzy == true || Cache->VS().CmpVersion(VerTag, Ver.VerStr()) != 0) && // exact match @@ -201,8 +299,8 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, // or we match against a release if(VerTag.empty() == false || - (VF.File().Archive() != 0 && VF.File().Archive() == DefRel) || - (VF.File().Codename() != 0 && VF.File().Codename() == DefRel)) + (VF.File().Archive() != 0 && VF.File().Archive() == RelTag) || + (VF.File().Codename() != 0 && VF.File().Codename() == RelTag)) { pkgRecords::Parser &Parse = Recs.Lookup(VF); Src = Parse.SourcePkg(); @@ -220,23 +318,27 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, if (Src.empty() == false) break; } -#if 0 - if (Src.empty() == true) - { - // Sources files have no codename information - if (VerTag.empty() == true && DefRel.empty() == false) - { - _error->Warning(_("Ignore unavailable target release '%s' of package '%s'"), DefRel.c_str(), TmpSrc.c_str()); - return 0; - } - } -#endif } + + if (Src == "" && ArchTag != "") + { + if (VerTag != "") + _error->Error(_("Can not find a package '%s' with version '%s'"), + Pkg.FullName().c_str(), VerTag.c_str()); + if (RelTag != "") + _error->Error(_("Can not find a package '%s' with release '%s'"), + Pkg.FullName().c_str(), RelTag.c_str()); + Src = Name; + return 0; + } + + if (Src.empty() == true) { // if we don't have found a fitting package yet so we will // choose a good candidate and proceed with that. // Maybe we will find a source later on with the right VerTag + // or RelTag pkgCache::VerIterator Ver = Cache->GetCandidateVer(Pkg); if (Ver.end() == false) { @@ -249,7 +351,9 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, } if (Src.empty() == true) + { Src = TmpSrc; + } else { /* if we have a source pkg name, make sure to only search @@ -267,7 +371,7 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgSrcRecords::Parser *Last = 0; unsigned long Offset = 0; string Version; - string FoundRel; + pkgSourceList *SrcList = CacheFile.GetSourceList(); /* Iterate over all of the hits, which includes the resulting binary packages in the search */ @@ -279,41 +383,18 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, { const string Ver = Parse->Version(); - - // find release - const pkgIndexFile& SI = Parse->Index(); - pkgSourceList *SrcList = CacheFile.GetSourceList(); - for (pkgSourceList::const_iterator S = SrcList->begin(); - S != SrcList->end(); ++S) + // See if we need to look for a specific release tag + if (RelTag != "" && UserRequestedVerTag == "") { - vector *Indexes = (*S)->GetIndexFiles(); - for (vector::const_iterator IF = Indexes->begin(); - IF != Indexes->end(); ++IF) + const string Rel = GetReleaseForSourceRecord(SrcList, Parse); + + if (Rel == RelTag) { - if (&SI == (*IF)) - { - std::string dirname = _config->FindDir("Dir::State::lists"); - std::string path; - path = dirname + URItoFileName((*S)->GetURI()) + "dists_" + (*S)->GetDist() + "_Release"; - if (!FileExists(path)) - path = dirname + URItoFileName((*S)->GetURI()) + "dists_" + (*S)->GetDist() + "_InRelease"; - indexRecords records; - records.Load(path); - if (records.GetSuite() == DefRel) - { - ioprintf(clog, "Selectied version '%s' (%s) for %s\n", - Ver.c_str(), DefRel.c_str(), Src.c_str()); - Last = Parse; - Offset = Parse->Offset(); - Version = Ver; - FoundRel = DefRel; - break; - } - } + Last = Parse; + Offset = Parse->Offset(); + Version = Ver; } } - if (DefRel.empty() == false && (DefRel == FoundRel)) - break; // Ignore all versions which doesn't fit if (VerTag.empty() == false && @@ -327,14 +408,18 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, Version = Ver; } - // was the version check above an exact match? If so, we don't need to look further + // was the version check above an exact match? + // If so, we don't need to look further if (VerTag.empty() == false && (VerTag == Ver)) - { break; - } } + if (UserRequestedVerTag == "" && Version != "" && RelTag != "") + ioprintf(c1out, "Selected version '%s' (%s) for %s\n", + Version.c_str(), RelTag.c_str(), Src.c_str()); + if (Last != 0 || VerTag.empty() == true) break; + _error->Error(_("Can not find version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str()); return 0; } @@ -428,7 +513,7 @@ bool DoDSelectUpgrade(CommandLine &CmdL) } /* Resolve any problems that dselect created, allupgrade cannot handle - such things. We do so quite agressively too.. */ + such things. We do so quite aggressively too.. */ if (Cache->BrokenCount() != 0) { pkgProblemResolver Fix(Cache); @@ -545,8 +630,8 @@ bool DoDownload(CommandLine &CmdL) return false; APT::CacheSetHelper helper(c0out); - APT::VersionList verset = APT::VersionList::FromCommandLine(Cache, - CmdL.FileList + 1, APT::VersionList::CANDIDATE, helper); + APT::VersionSet verset = APT::VersionSet::FromCommandLine(Cache, + CmdL.FileList + 1, APT::VersionSet::CANDIDATE, helper); if (verset.empty() == true) return false; @@ -565,7 +650,7 @@ bool DoDownload(CommandLine &CmdL) std::string const cwd = SafeGetCWD(); _config->Set("Dir::Cache::Archives", cwd); int i = 0; - for (APT::VersionList::const_iterator Ver = verset.begin(); + for (APT::VersionSet::const_iterator Ver = verset.begin(); Ver != verset.end(); ++Ver, ++i) { pkgAcquire::Item *I = new pkgAcqArchive(&Fetcher, SrcList, &Recs, *Ver, storefile[i]); @@ -593,14 +678,17 @@ bool DoDownload(CommandLine &CmdL) // copy files in local sources to the current directory for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I) - if ((*I)->Local == true && (*I)->Status == pkgAcquire::Item::StatDone) + { + std::string const filename = cwd + flNotDir((*I)->DestFile); + if ((*I)->Local == true && + filename != (*I)->DestFile && + (*I)->Status == pkgAcquire::Item::StatDone) { - std::string const filename = cwd + flNotDir((*I)->DestFile); std::ifstream src((*I)->DestFile.c_str(), std::ios::binary); std::ofstream dst(filename.c_str(), std::ios::binary); dst << src.rdbuf(); } - + } return Failed == false; } /*}}}*/ @@ -741,13 +829,10 @@ bool DoSource(CommandLine &CmdL) queued.insert(Last->Index().ArchiveURI(I->Path)); // check if we have a file with that md5 sum already localy - if(!I->MD5Hash.empty() && FileExists(flNotDir(I->Path))) + if(!I->Hash.empty() && FileExists(flNotDir(I->Path))) { - FileFd Fd(flNotDir(I->Path), FileFd::ReadOnly); - MD5Summation sum; - sum.AddFD(Fd.Fd(), Fd.Size()); - Fd.Close(); - if((string)sum.Result() == I->MD5Hash) + HashString hash_string = HashString(I->Hash); + if(hash_string.VerifyFile(flNotDir(I->Path))) { ioprintf(c1out,_("Skipping already downloaded file '%s'\n"), flNotDir(I->Path).c_str()); @@ -756,7 +841,7 @@ bool DoSource(CommandLine &CmdL) } new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path), - I->MD5Hash,I->Size, + I->Hash,I->Size, Last->Index().SourceInfo(*Last,*I),Src); } } @@ -1451,14 +1536,12 @@ bool DoChangelog(CommandLine &CmdL) bool const downOnly = _config->FindB("APT::Get::Download-Only", false); char tmpname[100]; - char* tmpdir = NULL; + const char* tmpdir = NULL; if (downOnly == false) { - const char* const tmpDir = getenv("TMPDIR"); - if (tmpDir != NULL && *tmpDir != '\0') - snprintf(tmpname, sizeof(tmpname), "%s/apt-changelog-XXXXXX", tmpDir); - else - strncpy(tmpname, "/tmp/apt-changelog-XXXXXX", sizeof(tmpname)); + std::string systemTemp = GetTempDir(); + snprintf(tmpname, sizeof(tmpname), "%s/apt-changelog-XXXXXX", + systemTemp.c_str()); tmpdir = mkdtemp(tmpname); if (tmpdir == NULL) return _error->Errno("mkdtemp", "mkdtemp failed"); @@ -1594,14 +1677,6 @@ void SigWinch(int) if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5) ScreenWidth = ws.ws_col - 1; #endif -} - /*}}}*/ -bool DoUpgrade(CommandLine &CmdL) /*{{{*/ -{ - if (_config->FindB("APT::Get::Upgrade-Allow-New", false) == true) - return DoUpgradeWithAllowNewPackages(CmdL); - else - return DoUpgradeNoNewPackages(CmdL); } /*}}}*/ int main(int argc,const char *argv[]) /*{{{*/ @@ -1658,10 +1733,6 @@ int main(int argc,const char *argv[]) /*{{{*/ // see if we are in simulate mode CheckSimulateMode(CmdL); - // Deal with stdout not being a tty - if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) - _config->Set("quiet","1"); - // Setup the output streams InitOutput();