X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/245dde96193702f7f51389d3583dee547f8ba366..6079b276a959086ff18302cab752b6d7cfe5ad9f:/cmdline/apt-get.cc?ds=sidebyside diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 184b51d23..69b12b2c7 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -56,6 +55,7 @@ #include #include #include +#include #include #include @@ -78,7 +78,6 @@ #include #include #include -#include #include #include #include @@ -137,11 +136,9 @@ static bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, return true; } /*}}}*/ -// GetReleaseForSourceRecord - Return Suite for the given srcrecord /*{{{*/ -// --------------------------------------------------------------------- -/* */ -static std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, - pkgSrcRecords::Parser *Parse) +// GetReleaseFileForSourceRecord - Return Suite for the given srcrecord /*{{{*/ +static pkgCache::RlsFileIterator GetReleaseFileForSourceRecord(CacheFile &CacheFile, + pkgSourceList *SrcList, pkgSrcRecords::Parser *Parse) { // try to find release const pkgIndexFile& CurrentIndexFile = Parse->Index(); @@ -154,28 +151,16 @@ static std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, IF != Indexes->end(); ++IF) { if (&CurrentIndexFile == (*IF)) - { - std::string const path = (*S)->LocalFileName(); - if (path != "") - { - indexRecords records; - records.Load(path); - return records.GetSuite(); - } - } + return (*S)->FindInCache(CacheFile, false); } } - return ""; + return pkgCache::RlsFileIterator(CacheFile); } /*}}}*/ // FindSrc - Find a source record /*{{{*/ // --------------------------------------------------------------------- /* */ -#if APT_PKG_ABI >= 413 static pkgSrcRecords::Parser *FindSrc(const char *Name, -#else -static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, -#endif pkgSrcRecords &SrcRecs,string &Src, CacheFile &CacheFile) { @@ -285,19 +270,8 @@ static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, { // the Version we have is possibly fuzzy or includes binUploads, // so we use the Version of the SourcePkg (empty if same as package) -#if APT_PKG_ABI >= 413 Src = Ver.SourcePkgName(); VerTag = Ver.SourceVerStr(); -#else - pkgRecords::Parser &Parse = Recs.Lookup(VF); - Src = Parse.SourcePkg(); - // no SourcePkg name, so it is the "binary" name - if (Src.empty() == true) - Src = TmpSrc; - VerTag = Parse.SourceVer(); - if (VerTag.empty() == true) - VerTag = Ver.VerStr(); -#endif break; } } @@ -328,17 +302,10 @@ static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgCache::VerIterator Ver = Cache->GetCandidateVer(Pkg); if (Ver.end() == false) { -#if APT_PKG_ABI >= 413 if (strcmp(Ver.SourcePkgName(),Ver.ParentPkg().Name()) != 0) Src = Ver.SourcePkgName(); if (VerTag.empty() == true && strcmp(Ver.SourceVerStr(),Ver.VerStr()) != 0) VerTag = Ver.SourceVerStr(); -#else - pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); - Src = Parse.SourcePkg(); - if (VerTag.empty() == true) - VerTag = Parse.SourceVer(); -#endif } } } @@ -379,13 +346,16 @@ static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, // See if we need to look for a specific release tag if (RelTag != "" && UserRequestedVerTag == "") { - const string Rel = GetReleaseForSourceRecord(SrcList, Parse); - - if (Rel == RelTag) + pkgCache::RlsFileIterator const Rls = GetReleaseFileForSourceRecord(CacheFile, SrcList, Parse); + if (Rls.end() == false) { - Last = Parse; - Offset = Parse->Offset(); - Version = Ver; + if ((Rls->Archive != 0 && RelTag == Rls.Archive()) || + (Rls->Codename != 0 && RelTag == Rls.Codename())) + { + Last = Parse; + Offset = Parse->Offset(); + Version = Ver; + } } } @@ -579,7 +549,7 @@ static bool DoClean(CommandLine &) class LogCleaner : public pkgArchiveCleaner { protected: - virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St) + virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St) APT_OVERRIDE { c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << endl; @@ -625,14 +595,12 @@ static bool DoDownload(CommandLine &CmdL) if (verset.empty() == true) return false; - AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0)); - pkgAcquire Fetcher(&Stat); - pkgRecords Recs(Cache); pkgSourceList *SrcList = Cache.GetSourceList(); // reuse the usual acquire methods for deb files, but don't drop them into // the usual directories - keep everything in the current directory + aptAcquireWithTextStatus Fetcher; std::vector storefile(verset.size()); std::string const cwd = SafeGetCWD(); _config->Set("Dir::Cache::Archives", cwd); @@ -658,9 +626,6 @@ static bool DoDownload(CommandLine &CmdL) 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; @@ -722,18 +687,11 @@ static bool DoSource(CommandLine &CmdL) pkgSourceList *List = Cache.GetSourceList(); // Create the text record parsers -#if APT_PKG_ABI < 413 - pkgRecords Recs(Cache); -#endif pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; - // Create the download object - AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0)); - pkgAcquire Fetcher(&Stat); - - SPtrArray Dsc = new DscFile[CmdL.FileSize()]; + std::unique_ptr Dsc(new DscFile[CmdL.FileSize()]); // insert all downloaded uris into this set to avoid downloading them // twice @@ -747,23 +705,20 @@ static bool DoSource(CommandLine &CmdL) bool const dscOnly = _config->FindB("APT::Get::Dsc-Only", false); // Load the requestd sources into the fetcher + aptAcquireWithTextStatus Fetcher; unsigned J = 0; - std::string UntrustedList; + std::vector UntrustedList; for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; -#if APT_PKG_ABI >= 413 pkgSrcRecords::Parser *Last = FindSrc(*I,SrcRecs,Src,Cache); -#else - pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); -#endif if (Last == 0) { return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); } if (Last->Index().IsTrusted() == false) - UntrustedList += Src + " "; - + UntrustedList.push_back(Src); + string srec = Last->AsStr(); string::size_type pos = srec.find("\nVcs-"); while (pos != string::npos) @@ -777,17 +732,22 @@ static bool DoSource(CommandLine &CmdL) } pos += vcs.length()+2; string::size_type epos = srec.find("\n", pos); - string uri = srec.substr(pos,epos-pos).c_str(); + string const uri = srec.substr(pos,epos-pos); ioprintf(c1out, _("NOTICE: '%s' packaging is maintained in " "the '%s' version control system at:\n" "%s\n"), Src.c_str(), vcs.c_str(), uri.c_str()); - if(vcs == "Bzr") - ioprintf(c1out,_("Please use:\n" - "bzr branch %s\n" - "to retrieve the latest (possibly unreleased) " - "updates to the package.\n"), - uri.c_str()); + std::string vcscmd; + if (vcs == "Bzr") + vcscmd = "bzr branch " + uri; + else if (vcs == "Git") + vcscmd = "git clone " + uri; + + if (vcscmd.empty() == false) + ioprintf(c1out,_("Please use:\n%s\n" + "to retrieve the latest (possibly unreleased) " + "updates to the package.\n"), + vcscmd.c_str()); break; } @@ -886,11 +846,8 @@ 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)) + if (UntrustedList.empty() == false && AuthPrompt(UntrustedList, false) == false) return false; // Run it @@ -978,19 +935,7 @@ static bool DoSource(CommandLine &CmdL) _exit(0); } - // Wait for the subprocess - int Status = 0; - while (waitpid(Process,&Status,0) != Process) - { - if (errno == EINTR) - continue; - return _error->Errno("waitpid","Couldn't wait for subprocess"); - } - - if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) - return _error->Error(_("Child process failed")); - - return true; + return ExecWait(Process, "dpkg-source"); } /*}}}*/ // DoBuildDep - Install/removes packages to satisfy build dependencies /*{{{*/ @@ -1002,8 +947,10 @@ static bool DoBuildDep(CommandLine &CmdL) CacheFile Cache; _config->Set("APT::Install-Recommends", false); + + bool WantLock = _config->FindB("APT::Get::Print-URIs", false) == false; - if (Cache.Open(true) == false) + if (Cache.Open(WantLock) == false) return false; if (CmdL.FileSize() <= 1) @@ -1015,9 +962,6 @@ static bool DoBuildDep(CommandLine &CmdL) pkgSourceList *List = Cache.GetSourceList(); // Create the text record parsers -#if APT_PKG_ABI < 413 - pkgRecords Recs(Cache); -#endif pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; @@ -1039,6 +983,7 @@ static bool DoBuildDep(CommandLine &CmdL) { string Src; pkgSrcRecords::Parser *Last = 0; + std::unique_ptr LastOwner; // an unpacked debian source tree using APT::String::Startswith; @@ -1047,10 +992,10 @@ static bool DoBuildDep(CommandLine &CmdL) { 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"; + std::string TypeName = "Debian control file"; pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str()); if(Type != NULL) - Last = Type->CreateSrcPkgParser(*I); + LastOwner.reset(Last = Type->CreateSrcPkgParser(*I)); } // if its a local file (e.g. .dsc) use this else if (FileExists(*I)) @@ -1058,17 +1003,13 @@ static bool DoBuildDep(CommandLine &CmdL) 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"; + string TypeName = "Debian " + flExtension(*I) + " file"; pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str()); if(Type != NULL) - Last = Type->CreateSrcPkgParser(*I); + LastOwner.reset(Last = Type->CreateSrcPkgParser(*I)); } else { // normal case, search the cache for the source file -#if APT_PKG_ABI >= 413 Last = FindSrc(*I,SrcRecs,Src,Cache); -#else - Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); -#endif } if (Last == 0) @@ -1213,12 +1154,12 @@ static bool DoBuildDep(CommandLine &CmdL) for (; Ver != verlist.end(); ++Ver) { forbidden.clear(); - if (Ver->MultiArch == pkgCache::Version::None || Ver->MultiArch == pkgCache::Version::All) + if (Ver->MultiArch == pkgCache::Version::No || Ver->MultiArch == pkgCache::Version::All) { if (colon == string::npos) Pkg = Ver.ParentPkg().Group().FindPkg(hostArch); else if (strcmp(D->Package.c_str() + colon, ":any") == 0) - forbidden = "Multi-Arch: none"; + forbidden = "Multi-Arch: no"; else if (strcmp(D->Package.c_str() + colon, ":native") == 0) Pkg = Ver.ParentPkg().Group().FindPkg("native"); } @@ -1422,13 +1363,11 @@ static bool DoChangelog(CommandLine &CmdL) CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper); if (verset.empty() == true) return false; - pkgAcquire Fetcher; - AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0)); - Fetcher.SetLog(&Stat); bool const downOnly = _config->FindB("APT::Get::Download-Only", false); bool const printOnly = _config->FindB("APT::Get::Print-URIs", false); + aptAcquireWithTextStatus Fetcher; for (APT::VersionList::const_iterator Ver = verset.begin(); Ver != verset.end(); ++Ver) @@ -1443,11 +1382,6 @@ static bool DoChangelog(CommandLine &CmdL) if (printOnly == false) { - // Disable drop-privs if "_apt" can not write to the target dir - CheckDropPrivsMustBeDisabled(Fetcher); - if (_error->PendingError() == true) - return false; - bool Failed = false; if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true) return false; @@ -1477,7 +1411,7 @@ static bool DoChangelog(CommandLine &CmdL) return true; } /*}}}*/ -// DoFiles - Lists all IndexTargets /*{{{*/ +// DoIndexTargets - Lists all IndexTargets /*{{{*/ static std::string format_key(std::string key) { // deb822 is case-insensitive, but the human eye prefers candy @@ -1493,7 +1427,7 @@ static std::string format_key(std::string key) } return key; } -static bool DoFiles(CommandLine &CmdL) +static bool DoIndexTargets(CommandLine &CmdL) { pkgCacheFile CacheFile; pkgSourceList *SrcList = CacheFile.GetSourceList(); @@ -1501,8 +1435,8 @@ static bool DoFiles(CommandLine &CmdL) if (SrcList == NULL) return false; - std::string const Format = _config->Find("APT::Get::Files::Format"); - bool const ReleaseInfo = _config->FindB("APT::Get::Files::ReleaseInfo", true); + std::string const Format = _config->Find("APT::Get::IndexTargets::Format"); + bool const ReleaseInfo = _config->FindB("APT::Get::IndexTargets::ReleaseInfo", true); bool Filtered = CmdL.FileSize() > 1; for (pkgSourceList::const_iterator S = SrcList->begin(); S != SrcList->end(); ++S) { @@ -1538,11 +1472,21 @@ static bool DoFiles(CommandLine &CmdL) << "Description: " << T->Description << "\n" << "URI: " << T->URI << "\n" << "Filename: " << filename << "\n" - << "Optional: " << (T->IsOptional ? "yes" : "no") << "\n"; + << "Optional: " << (T->IsOptional ? "yes" : "no") << "\n" + << "KeepCompressed: " << (T->KeepCompressed ? "yes" : "no") << "\n"; for (std::map::const_iterator O = AddOptions.begin(); O != AddOptions.end(); ++O) stanza << format_key(O->first) << ": " << O->second << "\n"; for (std::map::const_iterator O = T->Options.begin(); O != T->Options.end(); ++O) - stanza << format_key(O->first) << ": " << O->second << "\n"; + { + if (O->first == "PDIFFS") + stanza << "PDiffs: " << O->second << "\n"; + else if (O->first == "COMPRESSIONTYPES") + stanza << "CompressionTypes: " << O->second << "\n"; + else if (O->first == "DEFAULTENABLED") + stanza << "DefaultEnabled: " << O->second << "\n"; + else + stanza << format_key(O->first) << ": " << O->second << "\n"; + } stanza << "\n"; if (Filtered) @@ -1582,10 +1526,7 @@ static bool DoFiles(CommandLine &CmdL) return true; } /*}}}*/ -// ShowHelp - Show a help screen /*{{{*/ -// --------------------------------------------------------------------- -/* */ -static bool ShowHelp(CommandLine &) +bool ShowHelp(CommandLine &, aptDispatchWithHelp const * Cmds) /*{{{*/ { ioprintf(cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH); @@ -1630,34 +1571,26 @@ static bool ShowHelp(CommandLine &) return true; } - - cout << + + std::cout << _("Usage: apt-get [options] command\n" " apt-get [options] install|remove pkg1 [pkg2 ...]\n" " apt-get [options] source pkg1 [pkg2 ...]\n" "\n" "apt-get is a simple command line interface for downloading and\n" "installing packages. The most frequently used commands are update\n" - "and install.\n" - "\n" - "Commands:\n" - " update - Retrieve new lists of packages\n" - " upgrade - Perform an upgrade\n" - " install - Install new packages (pkg is libc6 not libc6.deb)\n" - " remove - Remove packages\n" - " autoremove - Remove automatically all unused packages\n" - " purge - Remove packages and config files\n" - " source - Download source archives\n" - " build-dep - Configure build-dependencies for source packages\n" - " dist-upgrade - Distribution upgrade, see apt-get(8)\n" - " dselect-upgrade - Follow dselect selections\n" - " clean - Erase downloaded archive files\n" - " autoclean - Erase old downloaded archive files\n" - " check - Verify that there are no broken dependencies\n" - " changelog - Download and display the changelog for the given package\n" - " download - Download the binary package into the current directory\n" - "\n" - "Options:\n" + "and install.\n") + << std::endl + << _("Commands:") << std::endl; + for (; Cmds->Handler != nullptr; ++Cmds) + { + if (Cmds->Help == nullptr) + continue; + std::cout << " " << Cmds->Match << " - " << Cmds->Help << std::endl; + } + + std::cout << std::endl << + _("Options:\n" " -h This help text.\n" " -q Loggable output - no progress indicator\n" " -qq No output except for errors\n" @@ -1677,58 +1610,48 @@ static bool ShowHelp(CommandLine &) return true; } /*}}}*/ +std::vector GetCommands() /*{{{*/ +{ + return { + {"update", &DoUpdate, _("Retrieve new lists of packages")}, + {"upgrade", &DoUpgrade, _("Perform an upgrade")}, + {"install", &DoInstall, _("Install new packages (pkg is libc6 not libc6.deb)")}, + {"remove", &DoInstall, _("Remove packages")}, + {"purge", &DoInstall, _("Remove packages and config files")}, + {"autoremove", &DoInstall, _("Remove automatically all unused packages")}, + {"auto-remove", &DoInstall, nullptr}, + {"markauto", &DoMarkAuto, nullptr}, + {"unmarkauto", &DoMarkAuto, nullptr}, + {"dist-upgrade", &DoDistUpgrade, _("Distribution upgrade, see apt-get(8)")}, + {"full-upgrade", &DoDistUpgrade, nullptr}, + {"dselect-upgrade", &DoDSelectUpgrade, _("Follow dselect selections")}, + {"build-dep", &DoBuildDep, _("Configure build-dependencies for source packages")}, + {"clean", &DoClean, _("Erase downloaded archive files")}, + {"autoclean", &DoAutoClean, _("Erase old downloaded archive files")}, + {"auto-clean", &DoAutoClean, nullptr}, + {"check", &DoCheck, _("Verify that there are no broken dependencies")}, + {"source", &DoSource, _("Download source archives")}, + {"download", &DoDownload, _("Download the binary package into the current directory")}, + {"changelog", &DoChangelog, _("Download and display the changelog for the given package")}, + {"indextargets", &DoIndexTargets, nullptr}, + {"moo", &DoMoo, nullptr}, + {nullptr, nullptr, nullptr} + }; +} + /*}}}*/ int main(int argc,const char *argv[]) /*{{{*/ { - CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate}, - {"upgrade",&DoUpgrade}, - {"install",&DoInstall}, - {"remove",&DoInstall}, - {"purge",&DoInstall}, - {"autoremove",&DoInstall}, - {"markauto",&DoMarkAuto}, - {"unmarkauto",&DoMarkAuto}, - {"dist-upgrade",&DoDistUpgrade}, - {"dselect-upgrade",&DoDSelectUpgrade}, - {"build-dep",&DoBuildDep}, - {"clean",&DoClean}, - {"autoclean",&DoAutoClean}, - {"check",&DoCheck}, - {"source",&DoSource}, - {"download",&DoDownload}, - {"changelog",&DoChangelog}, - {"files",&DoFiles}, - {"moo",&DoMoo}, - {"help",&ShowHelp}, - {0,0}}; - - std::vector Args = getCommandArgs("apt-get", CommandLine::GetCommand(Cmds, argc, argv)); - - // Set up gettext support - setlocale(LC_ALL,""); - textdomain(PACKAGE); + InitLocale(); // Parse the command line and initialize the package library CommandLine CmdL; - ParseCommandLine(CmdL, Cmds, Args.data(), &_config, &_system, argc, argv, ShowHelp); + auto const Cmds = ParseCommandLine(CmdL, APT_CMD::APT_GET, &_config, &_system, argc, argv); - // see if we are in simulate mode - CheckSimulateMode(CmdL); - - // Init the signals InitSignals(); - - // Setup the output streams InitOutput(); - // Match the operation - CmdL.DispatchArg(Cmds); + CheckIfSimulateMode(CmdL); - // Print any errors or warnings found during parsing - bool const Errors = _error->PendingError(); - if (_config->FindI("quiet",0) > 0) - _error->DumpErrors(); - else - _error->DumpErrors(GlobalError::DEBUG); - return Errors == true ? 100 : 0; + return DispatchCommandLine(CmdL, Cmds); } /*}}}*/