X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/7014e1482942d00b66eb30061b0cf5d2a7b3ebf3..5803c1dcf0a6e590cfd98ca8ab11d5573652cb14:/cmdline/apt-get.cc diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 7e59f3d67..a58386eb0 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 @@ -27,66 +27,67 @@ // Include Files /*{{{*/ #include +#include +#include #include -#include +#include +#include +#include #include -#include +#include #include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include #include -#include -#include -#include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include +#include +#include +#include +#include #include #include -#include +#include +#include #include -#include #include -#include -#include +#include #include -#include - -#include - -#include -#include -#include - -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include #include - -#include -#include +#include +#include +#include +#include +#include +#include +#include #include /*}}}*/ @@ -97,7 +98,7 @@ using namespace std; // --------------------------------------------------------------------- /* This used to be inlined in DoInstall, but with the advent of regex package name matching it was split out.. */ -bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, +static bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, pkgProblemResolver &Fix,bool Remove,bool BrokenFix, bool AllowFail = true) { @@ -138,7 +139,7 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, // helper that can go wit hthe next ABI break #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) -std::string MetaIndexFileNameOnDisk(metaIndex *metaindex) +static std::string MetaIndexFileNameOnDisk(metaIndex *metaindex) { // FIXME: this cast is the horror, the horror debReleaseIndex *r = (debReleaseIndex*)metaindex; @@ -159,7 +160,7 @@ std::string MetaIndexFileNameOnDisk(metaIndex *metaindex) // GetReleaseForSourceRecord - Return Suite for the given srcrecord /*{{{*/ // --------------------------------------------------------------------- /* */ -std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, +static std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, pkgSrcRecords::Parser *Parse) { // try to find release @@ -194,22 +195,35 @@ std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, // FindSrc - Find a source record /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, +static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgSrcRecords &SrcRecs,string &Src, CacheFile &CacheFile) { - string VerTag; + 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] == '/') - RelTag = 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); } @@ -217,10 +231,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 || RelTag.empty() == false) + if(VerTag != "" || RelTag != "" || ArchTag != "") { bool fuzzy = false; // we have a default release, try to locate the pkg. we do it like @@ -240,6 +269,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 @@ -280,6 +320,20 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, break; } } + + 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 @@ -331,17 +385,15 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, const string Ver = Parse->Version(); // See if we need to look for a specific release tag - if (RelTag != "") + if (RelTag != "" && UserRequestedVerTag == "") { const string Rel = GetReleaseForSourceRecord(SrcList, Parse); if (Rel == RelTag) { - ioprintf(c1out, "Selectied version '%s' (%s) for %s\n", - Ver.c_str(), RelTag.c_str(), Src.c_str()); Last = Parse; Offset = Parse->Offset(); - break; + Version = Ver; } } @@ -362,9 +414,13 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, 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(_("Ignore unavailable version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str()); + _error->Error(_("Can not find version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str()); return 0; } @@ -375,7 +431,7 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, } /*}}}*/ /* mark packages as automatically/manually installed. {{{*/ -bool DoMarkAuto(CommandLine &CmdL) +static bool DoMarkAuto(CommandLine &CmdL) { bool Action = true; int AutoMarkChanged = 0; @@ -420,7 +476,7 @@ bool DoMarkAuto(CommandLine &CmdL) // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/ // --------------------------------------------------------------------- /* Follows dselect's selections */ -bool DoDSelectUpgrade(CommandLine &CmdL) +static bool DoDSelectUpgrade(CommandLine &) { CacheFile Cache; if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false) @@ -458,7 +514,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); @@ -496,7 +552,7 @@ bool DoDSelectUpgrade(CommandLine &CmdL) // DoClean - Remove download archives /*{{{*/ // --------------------------------------------------------------------- /* */ -bool DoClean(CommandLine &CmdL) +static bool DoClean(CommandLine &) { std::string const archivedir = _config->FindDir("Dir::Cache::archives"); std::string const pkgcache = _config->FindFile("Dir::cache::pkgcache"); @@ -544,7 +600,7 @@ class LogCleaner : public pkgArchiveCleaner }; }; -bool DoAutoClean(CommandLine &CmdL) +static bool DoAutoClean(CommandLine &) { // Lock the archive directory FileFd Lock; @@ -568,15 +624,15 @@ bool DoAutoClean(CommandLine &CmdL) /*}}}*/ // DoDownload - download a binary /*{{{*/ // --------------------------------------------------------------------- -bool DoDownload(CommandLine &CmdL) +static bool DoDownload(CommandLine &CmdL) { CacheFile Cache; if (Cache.ReadOnlyOpen() == false) 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; @@ -595,7 +651,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]); @@ -623,14 +679,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; } /*}}}*/ @@ -638,7 +697,7 @@ bool DoDownload(CommandLine &CmdL) // --------------------------------------------------------------------- /* Opening automatically checks the system, this command is mostly used for debugging */ -bool DoCheck(CommandLine &CmdL) +static bool DoCheck(CommandLine &) { CacheFile Cache; Cache.Open(); @@ -657,7 +716,7 @@ struct DscFile string Dsc; }; -bool DoSource(CommandLine &CmdL) +static bool DoSource(CommandLine &CmdL) { CacheFile Cache; if (Cache.Open(false) == false) @@ -682,7 +741,7 @@ bool DoSource(CommandLine &CmdL) pkgAcquire Fetcher; Fetcher.SetLog(&Stat); - DscFile *Dsc = new DscFile[CmdL.FileSize()]; + SPtrArray Dsc = new DscFile[CmdL.FileSize()]; // insert all downloaded uris into this set to avoid downloading them // twice @@ -697,15 +756,18 @@ bool DoSource(CommandLine &CmdL) // Load the requestd sources into the fetcher unsigned J = 0; + std::string UntrustedList; for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); if (Last == 0) { - delete[] Dsc; return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); } + + if (Last->Index().IsTrusted() == false) + UntrustedList += Src + " "; string srec = Last->AsStr(); string::size_type pos = srec.find("\nVcs-"); @@ -737,7 +799,6 @@ bool DoSource(CommandLine &CmdL) // Back track vector Lst; if (Last->Files(Lst) == false) { - delete[] Dsc; return false; } @@ -790,6 +851,10 @@ bool DoSource(CommandLine &CmdL) Last->Index().SourceInfo(*Last,*I),Src); } } + + // check authentication status of the source as well + if (UntrustedList != "" && !AuthPrompt(UntrustedList, false)) + return false; // Display statistics unsigned long long FetchBytes = Fetcher.FetchNeeded(); @@ -800,7 +865,6 @@ bool DoSource(CommandLine &CmdL) struct statvfs Buf; string OutputDir = "."; if (statvfs(OutputDir.c_str(),&Buf) != 0) { - delete[] Dsc; if (errno == EOVERFLOW) return _error->WarningE("statvfs",_("Couldn't determine free space in %s"), OutputDir.c_str()); @@ -815,7 +879,6 @@ bool DoSource(CommandLine &CmdL) || unsigned(Stat.f_type) != RAMFS_MAGIC #endif ) { - delete[] Dsc; return _error->Error(_("You don't have enough free space in %s"), OutputDir.c_str()); } @@ -837,7 +900,6 @@ bool DoSource(CommandLine &CmdL) { for (unsigned I = 0; I != J; I++) ioprintf(cout,_("Fetch source %s\n"),Dsc[I].Package.c_str()); - delete[] Dsc; return true; } @@ -848,7 +910,6 @@ bool DoSource(CommandLine &CmdL) for (; I != Fetcher.UriEnd(); ++I) cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl; - delete[] Dsc; return true; } @@ -856,14 +917,12 @@ bool DoSource(CommandLine &CmdL) bool Failed = false; if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true) { - delete[] Dsc; return _error->Error(_("Failed to fetch some archives.")); } if (_config->FindB("APT::Get::Download-only",false) == true) { c1out << _("Download complete and in download only mode") << endl; - delete[] Dsc; return true; } @@ -912,6 +971,12 @@ bool DoSource(CommandLine &CmdL) string buildopts = _config->Find("APT::Get::Host-Architecture"); if (buildopts.empty() == false) buildopts = "-a" + buildopts + " "; + + // get all active build profiles + std::string const profiles = APT::Configuration::getBuildProfilesString(); + if (profiles.empty() == false) + buildopts.append(" -P").append(profiles).append(" "); + buildopts.append(_config->Find("DPkg::Build-Options","-b -uc")); // Call dpkg-buildpackage @@ -931,7 +996,6 @@ bool DoSource(CommandLine &CmdL) _exit(0); } - delete[] Dsc; // Wait for the subprocess int Status = 0; @@ -952,7 +1016,7 @@ bool DoSource(CommandLine &CmdL) // --------------------------------------------------------------------- /* This function will look at the build depends list of the given source package and install the necessary packages to make it true, or fail. */ -bool DoBuildDep(CommandLine &CmdL) +static bool DoBuildDep(CommandLine &CmdL) { CacheFile Cache; @@ -1346,7 +1410,7 @@ bool DoBuildDep(CommandLine &CmdL) * pool/ next to the deb itself) * Example return: "pool/main/a/apt/apt_0.8.8ubuntu3" */ -string GetChangelogPath(CacheFile &Cache, +static string GetChangelogPath(CacheFile &Cache, pkgCache::PkgIterator Pkg, pkgCache::VerIterator Ver) { @@ -1373,7 +1437,7 @@ string GetChangelogPath(CacheFile &Cache, * apt-get changelog mplayer-doc: * http://packages.medibuntu.org/pool/non-free/m/mplayer/mplayer_1.0~rc4~try1.dsfg1-1ubuntu1+medibuntu1.changelog */ -bool GuessThirdPartyChangelogUri(CacheFile &Cache, +static bool GuessThirdPartyChangelogUri(CacheFile &Cache, pkgCache::PkgIterator Pkg, pkgCache::VerIterator Ver, string &out_uri) @@ -1398,7 +1462,7 @@ bool GuessThirdPartyChangelogUri(CacheFile &Cache, /*}}}*/ // DownloadChangelog - Download the changelog /*{{{*/ // --------------------------------------------------------------------- -bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, +static bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerIterator Ver, string targetfile) /* Download a changelog file for the given package version to * targetfile. This will first try the server from Apt::Changelogs::Server @@ -1453,7 +1517,7 @@ bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, /*}}}*/ // DoChangelog - Get changelog from the command line /*{{{*/ // --------------------------------------------------------------------- -bool DoChangelog(CommandLine &CmdL) +static bool DoChangelog(CommandLine &CmdL) { CacheFile Cache; if (Cache.ReadOnlyOpen() == false) @@ -1481,14 +1545,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"); @@ -1519,7 +1581,7 @@ bool DoChangelog(CommandLine &CmdL) // ShowHelp - Show a help screen /*{{{*/ // --------------------------------------------------------------------- /* */ -bool ShowHelp(CommandLine &CmdL) +static bool ShowHelp(CommandLine &) { ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, COMMON_ARCH,__DATE__,__TIME__); @@ -1612,28 +1674,6 @@ bool ShowHelp(CommandLine &CmdL) return true; } /*}}}*/ -// SigWinch - Window size change signal handler /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void SigWinch(int) -{ - // Riped from GNU ls -#ifdef TIOCGWINSZ - struct winsize ws; - - 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[]) /*{{{*/ { CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate}, @@ -1688,18 +1728,12 @@ 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"); + // Init the signals + InitSignals(); // Setup the output streams InitOutput(); - // Setup the signals - signal(SIGPIPE,SIG_IGN); - signal(SIGWINCH,SigWinch); - SigWinch(0); - // Match the operation CmdL.DispatchArg(Cmds);