X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/da029b0aaebdc64a3a9f6b7012213539421c934b..87ecd6a2d719aeaeedd99dd500b467e966376f1c:/cmdline/apt-get.cc diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index bd866bc8c..e176a3350 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -78,8 +78,6 @@ #include #include #include -#include -#include #include #include #include @@ -195,7 +193,7 @@ static std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, // FindSrc - Find a source record /*{{{*/ // --------------------------------------------------------------------- /* */ -static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, +static pkgSrcRecords::Parser *FindSrc(const char *Name, pkgSrcRecords &SrcRecs,string &Src, CacheFile &CacheFile) { @@ -303,16 +301,10 @@ static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, (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(); - // no SourcePkg name, so it is the "binary" name - if (Src.empty() == true) - Src = TmpSrc; + Src = Ver.SourcePkgName(); // the Version we have is possibly fuzzy or includes binUploads, - // so we use the Version of the SourcePkg (empty if same as package) - VerTag = Parse.SourceVer(); - if (VerTag.empty() == true) - VerTag = Ver.VerStr(); + // so we use the Version of the SourcePkg + VerTag = Ver.SourceVerStr(); break; } } @@ -343,10 +335,10 @@ static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgCache::VerIterator Ver = Cache->GetCandidateVer(Pkg); if (Ver.end() == false) { - pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); - Src = Parse.SourcePkg(); - if (VerTag.empty() == true) - VerTag = Parse.SourceVer(); + if (strcmp(Ver.SourcePkgName(),Ver.ParentPkg().Name()) != 0) + Src = Ver.SourcePkgName(); + if (VerTag.empty() == true && strcmp(Ver.SourceVerStr(),Ver.VerStr()) != 0) + VerTag = Ver.SourceVerStr(); } } } @@ -540,7 +532,7 @@ static bool DoDSelectUpgrade(CommandLine &) } // Now upgrade everything - if (pkgAllUpgrade(Cache) == false) + if (APT::Upgrade::Upgrade(Cache, APT::Upgrade::FORBID_REMOVE_PACKAGES | APT::Upgrade::FORBID_INSTALL_NEW_PACKAGES) == false) { ShowBroken(c1out,Cache,false); return _error->Error(_("Internal error, problem resolver broke stuff")); @@ -555,30 +547,44 @@ static bool DoDSelectUpgrade(CommandLine &) static bool DoClean(CommandLine &) { std::string const archivedir = _config->FindDir("Dir::Cache::archives"); - std::string const pkgcache = _config->FindFile("Dir::cache::pkgcache"); - std::string const srcpkgcache = _config->FindFile("Dir::cache::srcpkgcache"); + std::string const listsdir = _config->FindDir("Dir::state::lists"); if (_config->FindB("APT::Get::Simulate") == true) { + std::string const pkgcache = _config->FindFile("Dir::cache::pkgcache"); + std::string const srcpkgcache = _config->FindFile("Dir::cache::srcpkgcache"); cout << "Del " << archivedir << "* " << archivedir << "partial/*"<< endl + << "Del " << listsdir << "partial/*" << endl << "Del " << pkgcache << " " << srcpkgcache << endl; return true; } - + + bool const NoLocking = _config->FindB("Debug::NoLocking",false); // Lock the archive directory FileFd Lock; - if (_config->FindB("Debug::NoLocking",false) == false) + if (NoLocking == false) { int lock_fd = GetLock(archivedir + "lock"); if (lock_fd < 0) - return _error->Error(_("Unable to lock the download directory")); + return _error->Error(_("Unable to lock directory %s"), archivedir.c_str()); Lock.Fd(lock_fd); } - + pkgAcquire Fetcher; Fetcher.Clean(archivedir); Fetcher.Clean(archivedir + "partial/"); + if (NoLocking == false) + { + Lock.Close(); + int lock_fd = GetLock(listsdir + "lock"); + if (lock_fd < 0) + return _error->Error(_("Unable to lock directory %s"), listsdir.c_str()); + Lock.Fd(lock_fd); + } + + Fetcher.Clean(listsdir + "partial/"); + pkgCacheFile::RemoveCaches(); return true; @@ -632,15 +638,13 @@ static bool DoDownload(CommandLine &CmdL) APT::CacheSetHelper helper(c0out); APT::VersionSet verset = APT::VersionSet::FromCommandLine(Cache, - CmdL.FileList + 1, APT::VersionSet::CANDIDATE, helper); + CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper); if (verset.empty() == true) return false; AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet", 0)); - pkgAcquire Fetcher; - if (Fetcher.Setup(&Stat) == false) - return false; + pkgAcquire Fetcher(&Stat); pkgRecords Recs(Cache); pkgSourceList *SrcList = Cache.GetSourceList(); @@ -665,11 +669,14 @@ static bool DoDownload(CommandLine &CmdL) { pkgAcquire::UriIterator I = Fetcher.UriBegin(); for (; I != Fetcher.UriEnd(); ++I) - cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << + cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl; return true; } + // Disable drop-privs if "_apt" can not write to the target dir + CheckDropPrivsMustBeDisabled(Fetcher); + if (_error->PendingError() == true || CheckAuth(Fetcher, false) == false) return false; @@ -731,15 +738,13 @@ static bool DoSource(CommandLine &CmdL) pkgSourceList *List = Cache.GetSourceList(); // Create the text record parsers - pkgRecords Recs(Cache); pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; // Create the download object - AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); - pkgAcquire Fetcher; - Fetcher.SetLog(&Stat); + AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); + pkgAcquire Fetcher(&Stat); SPtrArray Dsc = new DscFile[CmdL.FileSize()]; @@ -760,7 +765,7 @@ static bool DoSource(CommandLine &CmdL) for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; - pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); + pkgSrcRecords::Parser *Last = FindSrc(*I,SrcRecs,Src,Cache); if (Last == 0) { return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); @@ -854,38 +859,14 @@ static bool DoSource(CommandLine &CmdL) } } - // check authentication status of the source as well - if (UntrustedList != "" && !AuthPrompt(UntrustedList, false)) - return false; - // Display statistics unsigned long long FetchBytes = Fetcher.FetchNeeded(); unsigned long long FetchPBytes = Fetcher.PartialPresent(); unsigned long long DebBytes = Fetcher.TotalNeeded(); - // Check for enough free space - struct statvfs Buf; - string OutputDir = "."; - if (statvfs(OutputDir.c_str(),&Buf) != 0) { - if (errno == EOVERFLOW) - return _error->WarningE("statvfs",_("Couldn't determine free space in %s"), - OutputDir.c_str()); - else - return _error->Errno("statvfs",_("Couldn't determine free space in %s"), - OutputDir.c_str()); - } else if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize) - { - struct statfs Stat; - if (statfs(OutputDir.c_str(),&Stat) != 0 -#if HAVE_STRUCT_STATFS_F_TYPE - || unsigned(Stat.f_type) != RAMFS_MAGIC -#endif - ) { - return _error->Error(_("You don't have enough free space in %s"), - OutputDir.c_str()); - } - } - + if (CheckFreeSpaceBeforeDownload(".", (FetchBytes - FetchPBytes)) == false) + return false; + // Number of bytes if (DebBytes != FetchBytes) //TRANSLATOR: The required space between number and unit is already included @@ -904,7 +885,7 @@ static bool DoSource(CommandLine &CmdL) ioprintf(cout,_("Fetch source %s\n"),Dsc[I].Package.c_str()); return true; } - + // Just print out the uris an exit if the --print-uris flag was used if (_config->FindB("APT::Get::Print-URIs") == true) { @@ -915,6 +896,13 @@ static bool DoSource(CommandLine &CmdL) return true; } + // Disable drop-privs if "_apt" can not write to the target dir + CheckDropPrivsMustBeDisabled(Fetcher); + + // check authentication status of the source as well + if (UntrustedList != "" && !AuthPrompt(UntrustedList, false)) + return false; + // Run it bool Failed = false; if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true) @@ -955,18 +943,19 @@ static bool DoSource(CommandLine &CmdL) else { // Call dpkg-source - char S[500]; - snprintf(S,sizeof(S),"%s -x %s", + std::string const sourceopts = _config->Find("DPkg::Source-Options", "-x"); + std::string S; + strprintf(S, "%s %s %s", _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(), - Dsc[I].Dsc.c_str()); - if (system(S) != 0) + sourceopts.c_str(), Dsc[I].Dsc.c_str()); + if (system(S.c_str()) != 0) { - fprintf(stderr,_("Unpack command '%s' failed.\n"),S); - fprintf(stderr,_("Check if the 'dpkg-dev' package is installed.\n")); + fprintf(stderr, _("Unpack command '%s' failed.\n"), S.c_str()); + fprintf(stderr, _("Check if the 'dpkg-dev' package is installed.\n")); _exit(1); - } + } } - + // Try to compile it with dpkg-buildpackage if (_config->FindB("APT::Get::Compile",false) == true) { @@ -982,20 +971,20 @@ static bool DoSource(CommandLine &CmdL) buildopts.append(_config->Find("DPkg::Build-Options","-b -uc")); // Call dpkg-buildpackage - char S[500]; - snprintf(S,sizeof(S),"cd %s && %s %s", + std::string S; + strprintf(S, "cd %s && %s %s", Dir.c_str(), _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(), buildopts.c_str()); - - if (system(S) != 0) + + if (system(S.c_str()) != 0) { - fprintf(stderr,_("Build command '%s' failed.\n"),S); + fprintf(stderr, _("Build command '%s' failed.\n"), S.c_str()); _exit(1); - } - } + } + } } - + _exit(0); } @@ -1036,17 +1025,10 @@ static bool DoBuildDep(CommandLine &CmdL) pkgSourceList *List = Cache.GetSourceList(); // Create the text record parsers - pkgRecords Recs(Cache); pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; - // Create the download object - AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); - pkgAcquire Fetcher; - if (Fetcher.Setup(&Stat) == false) - return false; - bool StripMultiArch; string hostArch = _config->Find("APT::Get::Host-Architecture"); if (hostArch.empty() == false) @@ -1065,9 +1047,12 @@ static bool DoBuildDep(CommandLine &CmdL) string Src; pkgSrcRecords::Parser *Last = 0; - // a unpacked debian source tree - if (DirectoryExists(*I)) + // an unpacked debian source tree + using APT::String::Startswith; + if ((Startswith(*I, "./") || Startswith(*I, "/")) && + DirectoryExists(*I)) { + ioprintf(c1out, _("Note, using directory '%s' to get the build dependencies\n"), *I); // FIXME: how can we make this more elegant? std::string TypeName = "debian/control File Source Index"; pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str()); @@ -1077,6 +1062,8 @@ static bool DoBuildDep(CommandLine &CmdL) // if its a local file (e.g. .dsc) use this else if (FileExists(*I)) { + ioprintf(c1out, _("Note, using file '%s' to get the build dependencies\n"), *I); + // see if we can get a parser for this pkgIndexFile type string TypeName = flExtension(*I) + " File Source Index"; pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str()); @@ -1084,7 +1071,7 @@ static bool DoBuildDep(CommandLine &CmdL) Last = Type->CreateSrcPkgParser(*I); } else { // normal case, search the cache for the source file - Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); + Last = FindSrc(*I,SrcRecs,Src,Cache); } if (Last == 0) @@ -1435,21 +1422,15 @@ static bool DoBuildDep(CommandLine &CmdL) * pool/ next to the deb itself) * Example return: "pool/main/a/apt/apt_0.8.8ubuntu3" */ -static string GetChangelogPath(CacheFile &Cache, - pkgCache::PkgIterator Pkg, +static string GetChangelogPath(CacheFile &Cache, pkgCache::VerIterator Ver) { - string path; - pkgRecords Recs(Cache); pkgRecords::Parser &rec=Recs.Lookup(Ver.FileList()); - string srcpkg = rec.SourcePkg().empty() ? Pkg.Name() : rec.SourcePkg(); - string ver = Ver.VerStr(); - // if there is a source version it always wins - if (rec.SourceVer() != "") - ver = rec.SourceVer(); - path = flNotFile(rec.FileName()); - path += srcpkg + "_" + StripEpoch(ver); + string path = flNotFile(rec.FileName()); + path.append(Ver.SourcePkgName()); + path.append("_"); + path.append(StripEpoch(Ver.SourceVerStr())); return path; } /*}}}*/ @@ -1463,7 +1444,6 @@ static string GetChangelogPath(CacheFile &Cache, * http://packages.medibuntu.org/pool/non-free/m/mplayer/mplayer_1.0~rc4~try1.dsfg1-1ubuntu1+medibuntu1.changelog */ static bool GuessThirdPartyChangelogUri(CacheFile &Cache, - pkgCache::PkgIterator Pkg, pkgCache::VerIterator Ver, string &out_uri) { @@ -1478,7 +1458,7 @@ static bool GuessThirdPartyChangelogUri(CacheFile &Cache, return false; // get archive uri for the binary deb - string path_without_dot_changelog = GetChangelogPath(Cache, Pkg, Ver); + string path_without_dot_changelog = GetChangelogPath(Cache, Ver); out_uri = index->ArchiveURI(path_without_dot_changelog + ".changelog"); // now strip away the filename and add srcpkg_srcver.changelog @@ -1496,36 +1476,34 @@ static bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, * GuessThirdPartyChangelogUri for details how) */ { - string path; - string descr; - string server; - string changelog_uri; - - // data structures we need - pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - // make the server root configurable - server = _config->Find("Apt::Changelogs::Server", + string const server = _config->Find("Apt::Changelogs::Server", "http://packages.debian.org/changelogs"); - path = GetChangelogPath(CacheFile, Pkg, Ver); + string const path = GetChangelogPath(CacheFile, Ver); + string changelog_uri; strprintf(changelog_uri, "%s/%s/changelog", server.c_str(), path.c_str()); if (_config->FindB("APT::Get::Print-URIs", false) == true) { std::cout << '\'' << changelog_uri << '\'' << std::endl; return true; } + pkgCache::PkgIterator const Pkg = Ver.ParentPkg(); + string descr; strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), changelog_uri.c_str()); // queue it new pkgAcqFile(&Fetcher, changelog_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); + // Disable drop-privs if "_apt" can not write to the target dir + CheckDropPrivsMustBeDisabled(Fetcher); + // try downloading it, if that fails, try third-party-changelogs location // FIXME: Fetcher.Run() is "Continue" even if I get a 404?!? Fetcher.Run(); if (!FileExists(targetfile)) { string third_party_uri; - if (GuessThirdPartyChangelogUri(CacheFile, Pkg, Ver, third_party_uri)) + if (GuessThirdPartyChangelogUri(CacheFile, Ver, third_party_uri)) { strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), third_party_uri.c_str()); new pkgAcqFile(&Fetcher, third_party_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); @@ -1550,7 +1528,7 @@ static bool DoChangelog(CommandLine &CmdL) APT::CacheSetHelper helper(c0out); APT::VersionList verset = APT::VersionList::FromCommandLine(Cache, - CmdL.FileList + 1, APT::VersionList::CANDIDATE, helper); + CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper); if (verset.empty() == true) return false; pkgAcquire Fetcher; @@ -1565,7 +1543,7 @@ static bool DoChangelog(CommandLine &CmdL) } AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); - Fetcher.Setup(&Stat); + Fetcher.SetLog(&Stat); bool const downOnly = _config->FindB("APT::Get::Download-Only", false); @@ -1587,7 +1565,7 @@ static bool DoChangelog(CommandLine &CmdL) { string changelogfile; if (downOnly == false) - changelogfile.append(tmpname).append("changelog"); + changelogfile.append(tmpname).append("/changelog"); else changelogfile.append(Ver.ParentPkg().Name()).append(".changelog"); if (DownloadChangelog(Cache, Fetcher, Ver, changelogfile) && downOnly == false)