summaryrefslogtreecommitdiff
path: root/cmdline
diff options
context:
space:
mode:
Diffstat (limited to 'cmdline')
-rw-r--r--cmdline/apt-cache.cc93
-rw-r--r--cmdline/apt-config.cc13
-rw-r--r--cmdline/apt-dump-solver.cc50
-rw-r--r--cmdline/apt-get.cc266
-rw-r--r--cmdline/apt-internal-solver.cc190
-rwxr-xr-xcmdline/apt-key17
-rwxr-xr-xcmdline/apt-mark101
-rw-r--r--cmdline/apt-mark.cc373
-rw-r--r--cmdline/makefile23
9 files changed, 864 insertions, 262 deletions
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc
index 45ea50433..232bb93ec 100644
--- a/cmdline/apt-cache.cc
+++ b/cmdline/apt-cache.cc
@@ -121,9 +121,7 @@ bool ShowUnMet(pkgCache::VerIterator const &V, bool const &Important)
continue;
// Skip conflicts and replaces
- if (End->Type == pkgCache::Dep::DpkgBreaks ||
- End->Type == pkgCache::Dep::Replaces ||
- End->Type == pkgCache::Dep::Conflicts)
+ if (End.IsNegative() == true)
continue;
// Verify the or group
@@ -848,10 +846,7 @@ bool XVcg(CommandLine &CmdL)
{
/* If a conflicts does not meet anything in the database
then show the relation but do not recurse */
- if (Hit == false &&
- (D->Type == pkgCache::Dep::Conflicts ||
- D->Type == pkgCache::Dep::DpkgBreaks ||
- D->Type == pkgCache::Dep::Obsoletes))
+ if (Hit == false && D.IsNegative() == true)
{
if (Show[D.TargetPkg()->ID] == None &&
Show[D.TargetPkg()->ID] != ToShow)
@@ -1060,9 +1055,7 @@ bool Dotty(CommandLine &CmdL)
{
/* If a conflicts does not meet anything in the database
then show the relation but do not recurse */
- if (Hit == false &&
- (D->Type == pkgCache::Dep::Conflicts ||
- D->Type == pkgCache::Dep::Obsoletes))
+ if (Hit == false && D.IsNegative() == true)
{
if (Show[D.TargetPkg()->ID] == None &&
Show[D.TargetPkg()->ID] != ToShow)
@@ -1082,6 +1075,7 @@ bool Dotty(CommandLine &CmdL)
{
case pkgCache::Dep::Conflicts:
case pkgCache::Dep::Obsoletes:
+ case pkgCache::Dep::DpkgBreaks:
printf("[color=springgreen];\n");
break;
@@ -1115,61 +1109,12 @@ bool Dotty(CommandLine &CmdL)
}
printf("}\n");
+ delete[] Show;
+ delete[] Flags;
+ delete[] ShapeMap;
return true;
}
/*}}}*/
-// DoAdd - Perform an adding operation /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool DoAdd(CommandLine &CmdL)
-{
- return _error->Error("Unimplemented");
-#if 0
- // Make sure there is at least one argument
- if (CmdL.FileSize() <= 1)
- return _error->Error("You must give at least one file name");
-
- // Open the cache
- FileFd CacheF(_config->FindFile("Dir::Cache::pkgcache"),FileFd::WriteAny);
- if (_error->PendingError() == true)
- return false;
-
- DynamicMMap Map(CacheF,MMap::Public);
- if (_error->PendingError() == true)
- return false;
-
- OpTextProgress Progress(*_config);
- pkgCacheGenerator Gen(Map,Progress);
- if (_error->PendingError() == true)
- return false;
-
- unsigned long Length = CmdL.FileSize() - 1;
- for (const char **I = CmdL.FileList + 1; *I != 0; I++)
- {
- Progress.OverallProgress(I - CmdL.FileList,Length,1,"Generating cache");
- Progress.SubProgress(Length);
-
- // Do the merge
- FileFd TagF(*I,FileFd::ReadOnly);
- debListParser Parser(TagF);
- if (_error->PendingError() == true)
- return _error->Error("Problem opening %s",*I);
-
- if (Gen.SelectFile(*I,"") == false)
- return _error->Error("Problem with SelectFile");
-
- if (Gen.MergeList(Parser) == false)
- return _error->Error("Problem with MergeList");
- }
-
- Progress.Done();
- GCache = &Gen.GetCache();
- Stats(CmdL);
-
- return true;
-#endif
-}
- /*}}}*/
// DisplayRecord - Displays the complete record for the package /*{{{*/
// ---------------------------------------------------------------------
/* This displays the package record from the proper package index file.
@@ -1383,9 +1328,8 @@ bool Search(CommandLine &CmdL)
return _error->Error("Write to stdout failed");
return true;
}
-
-
-/* show automatically installed packages (sorted) */
+ /*}}}*/
+/* ShowAuto - show automatically installed packages (sorted) {{{*/
bool ShowAuto(CommandLine &CmdL)
{
pkgCacheFile CacheFile;
@@ -1406,6 +1350,7 @@ bool ShowAuto(CommandLine &CmdL)
for (vector<string>::iterator I = packages.begin(); I != packages.end(); I++)
cout << *I << "\n";
+ _error->Notice(_("This command is deprecated. Please use 'apt-mark showauto' instead."));
return true;
}
/*}}}*/
@@ -1571,7 +1516,6 @@ bool Policy(CommandLine &CmdL)
return true;
}
- string const myArch = _config->Find("APT::Architecture");
char const * const msgInstalled = _(" Installed: ");
char const * const msgCandidate = _(" Candidate: ");
short const InstalledLessCandidate =
@@ -1584,14 +1528,8 @@ bool Policy(CommandLine &CmdL)
// Print out detailed information for each package
APT::CacheSetHelper helper(true, GlobalError::NOTICE);
APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1, helper);
- for (APT::PackageSet::const_iterator I = pkgset.begin(); I != pkgset.end(); ++I)
+ for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
{
- pkgCache::PkgIterator Pkg = I.Group().FindPkg("any");
-
- for (; Pkg.end() != true; Pkg = I.Group().NextPkg(Pkg)) {
- if (strcmp(Pkg.Arch(),"all") == 0)
- continue;
-
cout << Pkg.FullName(true) << ":" << endl;
// Installed version
@@ -1640,7 +1578,6 @@ bool Policy(CommandLine &CmdL)
Indx->Describe(true).c_str());
}
}
- }
}
return true;
@@ -1743,15 +1680,13 @@ bool ShowHelp(CommandLine &Cmd)
cout <<
_("Usage: apt-cache [options] command\n"
- " apt-cache [options] add file1 [file2 ...]\n"
" apt-cache [options] showpkg pkg1 [pkg2 ...]\n"
" apt-cache [options] showsrc pkg1 [pkg2 ...]\n"
"\n"
- "apt-cache is a low-level tool used to manipulate APT's binary\n"
- "cache files, and query information from them\n"
+ "apt-cache is a low-level tool used to query information\n"
+ "from APT's binary cache files\n"
"\n"
"Commands:\n"
- " add - Add a package file to the source cache\n"
" gencaches - Build both the package and source cache\n"
" showpkg - Show some general information for a single package\n"
" showsrc - Show source records\n"
@@ -1761,7 +1696,6 @@ bool ShowHelp(CommandLine &Cmd)
" unmet - Show unmet dependencies\n"
" search - Search the package list for a regex pattern\n"
" show - Show a readable record for the package\n"
- " showauto - Display a list of automatically installed packages\n"
" depends - Show raw dependency information for a package\n"
" rdepends - Show reverse dependency information for a package\n"
" pkgnames - List the names of all packages in the system\n"
@@ -1811,7 +1745,6 @@ int main(int argc,const char *argv[]) /*{{{*/
{0,"enhances","APT::Cache::ShowEnhances",0},
{0,0,0,0}};
CommandLine::Dispatch CmdsA[] = {{"help",&ShowHelp},
- {"add",&DoAdd},
{"gencaches",&GenCaches},
{"showsrc",&ShowSrcPackage},
{0,0}};
diff --git a/cmdline/apt-config.cc b/cmdline/apt-config.cc
index 9919a9c94..589ee7ada 100644
--- a/cmdline/apt-config.cc
+++ b/cmdline/apt-config.cc
@@ -20,6 +20,8 @@
#include <apt-pkg/error.h>
#include <apt-pkg/init.h>
#include <apt-pkg/strutl.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/aptconfiguration.h>
#include <config.h>
#include <apti18n.h>
@@ -27,6 +29,7 @@
#include <locale.h>
#include <iostream>
#include <string>
+#include <vector>
/*}}}*/
using namespace std;
@@ -119,6 +122,16 @@ int main(int argc,const char *argv[]) /*{{{*/
CmdL.FileSize() == 0)
return ShowHelp();
+ std::vector<std::string> const langs = APT::Configuration::getLanguages(true);
+ _config->Clear("Acquire::Languages");
+ for (std::vector<std::string>::const_iterator l = langs.begin(); l != langs.end(); ++l)
+ _config->Set("Acquire::Languages::", *l);
+
+ std::vector<std::string> const archs = APT::Configuration::getArchitectures();
+ _config->Clear("APT::Architectures");
+ for (std::vector<std::string>::const_iterator a = archs.begin(); a != archs.end(); ++a)
+ _config->Set("APT::Architectures::", *a);
+
// Match the operation
CmdL.DispatchArg(Cmds);
diff --git a/cmdline/apt-dump-solver.cc b/cmdline/apt-dump-solver.cc
new file mode 100644
index 000000000..dab0cc6fd
--- /dev/null
+++ b/cmdline/apt-dump-solver.cc
@@ -0,0 +1,50 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* #####################################################################
+
+ dummy solver to get quickly a scenario file out of APT
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <apt-pkg/edsp.h>
+
+#include <config.h>
+
+#include <cstdio>
+ /*}}}*/
+
+// ShowHelp - Show a help screen /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowHelp() {
+
+ std::cout <<
+ PACKAGE " " VERSION " for " COMMON_ARCH " compiled on " __DATE__ " " __TIME__ << std::endl <<
+ "Usage: apt-dump-resolver\n"
+ "\n"
+ "apt-dump-resolver is a dummy solver who just dumps its input to the\n"
+ "file /tmp/dump.edsp and exists with a proper EDSP error.\n"
+ "\n"
+ " This dump has lost Super Cow Powers.\n";
+ return true;
+}
+ /*}}}*/
+int main(int argc,const char *argv[]) /*{{{*/
+{
+ if (argc > 1 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1],"-h") == 0 ||
+ strcmp(argv[1],"-v") == 0 || strcmp(argv[1],"--version") == 0)) {
+ ShowHelp();
+ return 0;
+ }
+
+ FILE* input = fdopen(STDIN_FILENO, "r");
+ FILE* output = fopen("/tmp/dump.edsp", "w");
+ char buffer[400];
+ while (fgets(buffer, sizeof(buffer), input) != NULL)
+ fputs(buffer, output);
+ fclose(output);
+ fclose(input);
+
+ EDSP::WriteError("ERR_JUST_DUMPING", "I am too dumb, i can just dump!\nPlease use one of my friends instead!", stdout);
+}
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index 61efa5601..66ebd30b8 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -382,8 +382,6 @@ void ShowNew(ostream &out,CacheFile &Cache)
{
pkgCache::PkgIterator I(Cache,Cache.List[J]);
if (Cache[I].NewInstall() == true) {
- if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
- continue;
List += I.FullName(true) + " ";
VersionsList += string(Cache[I].CandVersion) + "\n";
}
@@ -406,8 +404,6 @@ void ShowDel(ostream &out,CacheFile &Cache)
pkgCache::PkgIterator I(Cache,Cache.List[J]);
if (Cache[I].Delete() == true)
{
- if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
- continue;
if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
List += I.FullName(true) + "* ";
else
@@ -456,8 +452,6 @@ void ShowUpgraded(ostream &out,CacheFile &Cache)
// Not interesting
if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
continue;
- if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
- continue;
List += I.FullName(true) + " ";
VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
@@ -479,8 +473,6 @@ bool ShowDowngraded(ostream &out,CacheFile &Cache)
// Not interesting
if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
continue;
- if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
- continue;
List += I.FullName(true) + " ";
VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
@@ -584,9 +576,6 @@ void Stats(ostream &out,pkgDepCache &Dep)
unsigned long ReInstall = 0;
for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++)
{
- if (pkgCache::VerIterator(Dep, Dep[I].CandidateVer).Pseudo() == true)
- continue;
-
if (Dep[I].NewInstall() == true)
Install++;
else
@@ -775,7 +764,7 @@ struct TryToInstall {
unsigned long AutoMarkChanged;
APT::PackageSet doAutoInstallLater;
- TryToInstall(pkgCacheFile &Cache, pkgProblemResolver &PM, bool const &FixBroken) : Cache(&Cache), Fix(&PM),
+ TryToInstall(pkgCacheFile &Cache, pkgProblemResolver *PM, bool const &FixBroken) : Cache(&Cache), Fix(PM),
FixBroken(FixBroken), AutoMarkChanged(0) {};
void operator() (pkgCache::VerIterator const &Ver) {
@@ -793,8 +782,10 @@ struct TryToInstall {
ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
Pkg.FullName(true).c_str());
else {
- Fix->Clear(Pkg);
- Fix->Protect(Pkg);
+ if (Fix != NULL) {
+ Fix->Clear(Pkg);
+ Fix->Protect(Pkg);
+ }
Cache->GetDepCache()->MarkInstall(Pkg,false);
if (State.Install() == false) {
@@ -882,20 +873,27 @@ struct TryToRemove {
bool PurgePkgs;
unsigned long AutoMarkChanged;
- TryToRemove(pkgCacheFile &Cache, pkgProblemResolver &PM) : Cache(&Cache), Fix(&PM),
+ TryToRemove(pkgCacheFile &Cache, pkgProblemResolver *PM) : Cache(&Cache), Fix(PM),
PurgePkgs(_config->FindB("APT::Get::Purge", false)) {};
void operator() (pkgCache::VerIterator const &Ver)
{
pkgCache::PkgIterator Pkg = Ver.ParentPkg();
- Fix->Clear(Pkg);
- Fix->Protect(Pkg);
- Fix->Remove(Pkg);
+ if (Fix != NULL)
+ {
+ Fix->Clear(Pkg);
+ Fix->Protect(Pkg);
+ Fix->Remove(Pkg);
+ }
if ((Pkg->CurrentVer == 0 && PurgePkgs == false) ||
(PurgePkgs == true && Pkg->CurrentState == pkgCache::State::NotInstalled))
+ {
ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.FullName(true).c_str());
+ // MarkInstall refuses to install packages on hold
+ Pkg->SelectedState = pkgCache::State::Hold;
+ }
else
Cache->GetDepCache()->MarkDelete(Pkg, PurgePkgs);
}
@@ -1392,10 +1390,10 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache,
if (Remove == true)
{
- TryToRemove RemoveAction(Cache, Fix);
+ TryToRemove RemoveAction(Cache, &Fix);
RemoveAction(Pkg.VersionList());
} else if (Cache[Pkg].CandidateVer != 0) {
- TryToInstall InstallAction(Cache, Fix, BrokenFix);
+ TryToInstall InstallAction(Cache, &Fix, BrokenFix);
InstallAction(Cache[Pkg].CandidateVerIter(Cache));
InstallAction.doAutoInstall();
} else
@@ -1655,6 +1653,7 @@ bool DoAutomaticRemove(CacheFile &Cache)
string autoremovelist, autoremoveversions;
unsigned long autoRemoveCount = 0;
+ APT::PackageSet tooMuch;
// look over the cache to see what can be removed
for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg)
{
@@ -1677,7 +1676,10 @@ bool DoAutomaticRemove(CacheFile &Cache)
// if the package is a new install and already garbage we don't need to
// install it in the first place, so nuke it instead of show it
if (Cache[Pkg].Install() == true && Pkg.CurrentVer() == 0)
+ {
Cache->MarkDelete(Pkg, false);
+ tooMuch.insert(Pkg);
+ }
// only show stuff in the list that is not yet marked for removal
else if(hideAutoRemove == false && Cache[Pkg].Delete() == false)
{
@@ -1693,6 +1695,45 @@ bool DoAutomaticRemove(CacheFile &Cache)
}
}
+ // we could have removed a new dependency of a garbage package,
+ // so check if a reverse depends is broken and if so install it again.
+ if (tooMuch.empty() == false && Cache->BrokenCount() != 0)
+ {
+ bool Changed;
+ do {
+ Changed = false;
+ for (APT::PackageSet::const_iterator P = tooMuch.begin();
+ P != tooMuch.end() && Changed == false; ++P)
+ {
+ for (pkgCache::DepIterator R = P.RevDependsList();
+ R.end() == false; ++R)
+ {
+ if (R->Type != pkgCache::Dep::Depends &&
+ R->Type != pkgCache::Dep::PreDepends)
+ continue;
+ pkgCache::PkgIterator N = R.ParentPkg();
+ if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
+ continue;
+ if (Debug == true)
+ std::clog << "Save " << P << " as another installed garbage package depends on it" << std::endl;
+ Cache->MarkInstall(P, false);
+ if(hideAutoRemove == false)
+ {
+ ++autoRemoveCount;
+ if (smallList == false)
+ {
+ autoremovelist += P.FullName(true) + " ";
+ autoremoveversions += string(Cache[P].CandVersion) + "\n";
+ }
+ }
+ tooMuch.erase(P);
+ Changed = true;
+ break;
+ }
+ }
+ } while (Changed == true);
+ }
+
// Now see if we had destroyed anything (if we had done anything)
if (Cache->BrokenCount() != 0)
{
@@ -1755,8 +1796,10 @@ bool DoInstall(CommandLine &CmdL)
bool BrokenFix = false;
if (Cache->BrokenCount() != 0)
BrokenFix = true;
-
- pkgProblemResolver Fix(Cache);
+
+ pkgProblemResolver* Fix = NULL;
+ if (_config->FindB("APT::Get::CallResolver", true) == true)
+ Fix = new pkgProblemResolver(Cache);
static const unsigned short MOD_REMOVE = 1;
static const unsigned short MOD_INSTALL = 2;
@@ -1787,17 +1830,12 @@ bool DoInstall(CommandLine &CmdL)
if (_error->PendingError() == true)
{
helper.showVirtualPackageErrors(Cache);
+ if (Fix != NULL)
+ delete Fix;
return false;
}
- unsigned short order[] = { 0, 0, 0 };
- if (fallback == MOD_INSTALL) {
- order[0] = MOD_INSTALL;
- order[1] = MOD_REMOVE;
- } else {
- order[0] = MOD_REMOVE;
- order[1] = MOD_INSTALL;
- }
+ unsigned short const order[] = { MOD_REMOVE, MOD_INSTALL, 0 };
TryToInstall InstallAction(Cache, Fix, BrokenFix);
TryToRemove RemoveAction(Cache, Fix);
@@ -1808,17 +1846,29 @@ bool DoInstall(CommandLine &CmdL)
for (unsigned short i = 0; order[i] != 0; ++i)
{
- if (order[i] == MOD_INSTALL) {
+ if (order[i] == MOD_INSTALL)
InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction);
+ else if (order[i] == MOD_REMOVE)
+ RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction);
+ }
+
+ if (Fix != NULL && _config->FindB("APT::Get::AutoSolving", true) == true)
+ {
+ for (unsigned short i = 0; order[i] != 0; ++i)
+ {
+ if (order[i] != MOD_INSTALL)
+ continue;
InstallAction.propergateReleaseCandiateSwitching(helper.selectedByRelease, c0out);
InstallAction.doAutoInstall();
}
- else if (order[i] == MOD_REMOVE)
- RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction);
}
if (_error->PendingError() == true)
+ {
+ if (Fix != NULL)
+ delete Fix;
return false;
+ }
/* If we are in the Broken fixing mode we do not attempt to fix the
problems. This is if the user invoked install without -f and gave
@@ -1827,14 +1877,18 @@ bool DoInstall(CommandLine &CmdL)
{
c1out << _("You might want to run 'apt-get -f install' to correct these:") << endl;
ShowBroken(c1out,Cache,false);
-
+ if (Fix != NULL)
+ delete Fix;
return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
}
-
- // Call the scored problem resolver
- Fix.InstallProtect();
- if (Fix.Resolve(true) == false)
- _error->Discard();
+
+ if (Fix != NULL)
+ {
+ // Call the scored problem resolver
+ Fix->InstallProtect();
+ Fix->Resolve(true);
+ delete Fix;
+ }
// Now we check the state of the packages,
if (Cache->BrokenCount() != 0)
@@ -1858,8 +1912,11 @@ bool DoInstall(CommandLine &CmdL)
c1out << _("The following information may help to resolve the situation:") << endl;
c1out << endl;
ShowBroken(c1out,Cache,false);
- return _error->Error(_("Broken packages"));
- }
+ if (_error->PendingError() == true)
+ return false;
+ else
+ return _error->Error(_("Broken packages"));
+ }
}
if (!DoAutomaticRemove(Cache))
return false;
@@ -1876,8 +1933,6 @@ bool DoInstall(CommandLine &CmdL)
if ((*Cache)[I].Install() == false)
continue;
pkgCache::VerIterator Cand = Cache[I].CandidateVerIter(Cache);
- if (Cand.Pseudo() == true)
- continue;
if (verset[MOD_INSTALL].find(Cand) != verset[MOD_INSTALL].end())
continue;
@@ -1997,8 +2052,8 @@ bool DoInstall(CommandLine &CmdL)
return InstallPackages(Cache,false);
}
-
-/* mark packages as automatically/manually installed. */
+ /*}}}*/
+/* mark packages as automatically/manually installed. {{{*/
bool DoMarkAuto(CommandLine &CmdL)
{
bool Action = true;
@@ -2033,6 +2088,9 @@ bool DoMarkAuto(CommandLine &CmdL)
AutoMarkChanged++;
}
}
+
+ _error->Notice(_("This command is deprecated. Please use 'apt-mark auto' and 'apt-mark manual' instead."));
+
if (AutoMarkChanged && ! _config->FindB("APT::Get::Simulate",false))
return Cache->writeStateFile(NULL);
return false;
@@ -2211,13 +2269,15 @@ bool DoDownload(CommandLine &CmdL)
APT::CacheSetHelper helper(c0out);
APT::VersionSet verset = APT::VersionSet::FromCommandLine(Cache,
CmdL.FileList + 1, APT::VersionSet::CANDIDATE, helper);
- pkgAcquire Fetcher;
- AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0));
- Fetcher.Setup(&Stat);
if (verset.empty() == true)
return false;
+ pkgAcquire Fetcher;
+ AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0));
+ if (_config->FindB("APT::Get::Print-URIs") == true)
+ Fetcher.Setup(&Stat);
+
pkgRecords Recs(Cache);
pkgSourceList *SrcList = Cache.GetSourceList();
for (APT::VersionSet::const_iterator Ver = verset.begin();
@@ -2250,9 +2310,18 @@ bool DoDownload(CommandLine &CmdL)
// get the file
new pkgAcqFile(&Fetcher, uri, hash.toStr(), (*Ver)->Size, descr, Pkg.Name(), ".");
}
- bool result = (Fetcher.Run() == pkgAcquire::Continue);
- return result;
+ // Just print out the uris and exit if the --print-uris flag was used
+ if (_config->FindB("APT::Get::Print-URIs") == true)
+ {
+ pkgAcquire::UriIterator I = Fetcher.UriBegin();
+ for (; I != Fetcher.UriEnd(); I++)
+ cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
+ I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
+ return true;
+ }
+
+ return (Fetcher.Run() == pkgAcquire::Continue);
}
/*}}}*/
// DoCheck - Perform the check operation /*{{{*/
@@ -2324,8 +2393,10 @@ bool DoSource(CommandLine &CmdL)
string Src;
pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
- if (Last == 0)
+ if (Last == 0) {
+ delete[] Dsc;
return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
+ }
string srec = Last->AsStr();
string::size_type pos = srec.find("\nVcs-");
@@ -2356,8 +2427,10 @@ bool DoSource(CommandLine &CmdL)
// Back track
vector<pkgSrcRecords::File> Lst;
- if (Last->Files(Lst) == false)
+ if (Last->Files(Lst) == false) {
+ delete[] Dsc;
return false;
+ }
// Load them into the fetcher
for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
@@ -2418,6 +2491,7 @@ 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());
@@ -2431,10 +2505,12 @@ bool DoSource(CommandLine &CmdL)
#if HAVE_STRUCT_STATFS_F_TYPE
|| unsigned(Stat.f_type) != RAMFS_MAGIC
#endif
- )
+ ) {
+ delete[] Dsc;
return _error->Error(_("You don't have enough free space in %s"),
OutputDir.c_str());
- }
+ }
+ }
// Number of bytes
if (DebBytes != FetchBytes)
@@ -2469,7 +2545,10 @@ bool DoSource(CommandLine &CmdL)
// Run it
if (Fetcher.Run() == pkgAcquire::Failed)
+ {
+ delete[] Dsc;
return false;
+ }
// Print error messages
bool Failed = false;
@@ -2484,8 +2563,11 @@ bool DoSource(CommandLine &CmdL)
Failed = true;
}
if (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;
@@ -2576,6 +2658,9 @@ bool DoSource(CommandLine &CmdL)
bool DoBuildDep(CommandLine &CmdL)
{
CacheFile Cache;
+
+ _config->Set("APT::Install-Recommends", false);
+
if (Cache.Open(true) == false)
return false;
@@ -2881,6 +2966,7 @@ bool GuessThirdPartyChangelogUri(CacheFile &Cache,
// now strip away the filename and add srcpkg_srcver.changelog
return true;
}
+ /*}}}*/
// DownloadChangelog - Download the changelog /*{{{*/
// ---------------------------------------------------------------------
bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher,
@@ -2905,13 +2991,19 @@ bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher,
"http://packages.debian.org/changelogs");
path = GetChangelogPath(CacheFile, Pkg, Ver);
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;
+ }
+
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);
- // try downloading it, if that fails, they third-party-changelogs location
- // FIXME: res is "Continue" even if I get a 404?!?
- int res = Fetcher.Run();
+ // 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;
@@ -2919,7 +3011,7 @@ bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher,
{
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);
- res = Fetcher.Run();
+ Fetcher.Run();
}
}
@@ -2959,30 +3051,53 @@ bool DoChangelog(CommandLine &CmdL)
APT::CacheSetHelper helper(c0out);
APT::VersionSet verset = APT::VersionSet::FromCommandLine(Cache,
CmdL.FileList + 1, APT::VersionSet::CANDIDATE, helper);
+ if (verset.empty() == true)
+ return false;
pkgAcquire Fetcher;
+
+ if (_config->FindB("APT::Get::Print-URIs", false) == true)
+ for (APT::VersionSet::const_iterator Ver = verset.begin();
+ Ver != verset.end(); ++Ver)
+ return DownloadChangelog(Cache, Fetcher, Ver, "");
+
AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0));
Fetcher.Setup(&Stat);
- if (verset.empty() == true)
- return false;
- char *tmpdir = mkdtemp(strdup("/tmp/apt-changelog-XXXXXX"));
- if (tmpdir == NULL) {
- return _error->Errno("mkdtemp", "mkdtemp failed");
+ bool const downOnly = _config->FindB("APT::Get::Download-Only", false);
+
+ char tmpname[100];
+ 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));
+ tmpdir = mkdtemp(tmpname);
+ if (tmpdir == NULL)
+ return _error->Errno("mkdtemp", "mkdtemp failed");
}
-
+
for (APT::VersionSet::const_iterator Ver = verset.begin();
Ver != verset.end();
++Ver)
{
- string changelogfile = string(tmpdir) + "changelog";
- if (DownloadChangelog(Cache, Fetcher, Ver, changelogfile))
+ string changelogfile;
+ if (downOnly == false)
+ changelogfile.append(tmpname).append("changelog");
+ else
+ changelogfile.append(Ver.ParentPkg().Name()).append(".changelog");
+ if (DownloadChangelog(Cache, Fetcher, Ver, changelogfile) && downOnly == false)
+ {
DisplayFileInPager(changelogfile);
- // cleanup temp file
- unlink(changelogfile.c_str());
+ // cleanup temp file
+ unlink(changelogfile.c_str());
+ }
}
// clenaup tmp dir
- rmdir(tmpdir);
- free(tmpdir);
+ if (tmpdir != NULL)
+ rmdir(tmpdir);
return true;
}
/*}}}*/
@@ -3076,8 +3191,6 @@ bool ShowHelp(CommandLine &CmdL)
" clean - Erase downloaded archive files\n"
" autoclean - Erase old downloaded archive files\n"
" check - Verify that there are no broken dependencies\n"
- " markauto - Mark the given packages as automatically installed\n"
- " unmarkauto - Mark the given packages as manually installed\n"
" changelog - Download and display the changelog for the given package\n"
" download - Download the binary package into the current directory\n"
"\n"
@@ -3159,7 +3272,9 @@ int main(int argc,const char *argv[]) /*{{{*/
{0,"auto-remove","APT::Get::AutomaticRemove",0},
{0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0},
{0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean},
+ {0,"install-suggests","APT::Install-Suggests",CommandLine::Boolean},
{0,"fix-policy","APT::Get::Fix-Policy-Broken",0},
+ {0,"solver","APT::Solver",CommandLine::HasArg},
{'c',"config-file",0,CommandLine::ConfigFile},
{'o',"option",0,CommandLine::ArbItem},
{0,0,0,0}};
@@ -3211,7 +3326,10 @@ int main(int argc,const char *argv[]) /*{{{*/
}
// simulate user-friendly if apt-get has no root privileges
- if (getuid() != 0 && _config->FindB("APT::Get::Simulate") == true)
+ if (getuid() != 0 && _config->FindB("APT::Get::Simulate") == true &&
+ (CmdL.FileSize() == 0 ||
+ (strcmp(CmdL.FileList[0], "source") != 0 && strcmp(CmdL.FileList[0], "download") != 0 &&
+ strcmp(CmdL.FileList[0], "changelog") != 0)))
{
if (_config->FindB("APT::Get::Show-User-Simulation-Note",true) == true)
cout << _("NOTE: This is only a simulation!\n"
diff --git a/cmdline/apt-internal-solver.cc b/cmdline/apt-internal-solver.cc
new file mode 100644
index 000000000..ef6c688fe
--- /dev/null
+++ b/cmdline/apt-internal-solver.cc
@@ -0,0 +1,190 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* #####################################################################
+
+ cover around the internal solver to be able to run it like an external
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <apt-pkg/error.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/edsp.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/fileutl.h>
+
+#include <config.h>
+#include <apti18n.h>
+
+#include <unistd.h>
+#include <cstdio>
+ /*}}}*/
+
+// ShowHelp - Show a help screen /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowHelp(CommandLine &CmdL) {
+ ioprintf(std::cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
+ COMMON_ARCH,__DATE__,__TIME__);
+
+ std::cout <<
+ _("Usage: apt-internal-resolver\n"
+ "\n"
+ "apt-internal-resolver is an interface to use the current internal\n"
+ "like an external resolver for the APT family for debugging or alike\n"
+ "\n"
+ "Options:\n"
+ " -h This help text.\n"
+ " -q Loggable output - no progress indicator\n"
+ " -c=? Read this configuration file\n"
+ " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
+ "apt.conf(5) manual pages for more information and options.\n"
+ " This APT has Super Cow Powers.\n");
+ return true;
+}
+ /*}}}*/
+int main(int argc,const char *argv[]) /*{{{*/
+{
+ CommandLine::Args Args[] = {
+ {'h',"help","help",0},
+ {'v',"version","version",0},
+ {'q',"quiet","quiet",CommandLine::IntLevel},
+ {'q',"silent","quiet",CommandLine::IntLevel},
+ {'c',"config-file",0,CommandLine::ConfigFile},
+ {'o',"option",0,CommandLine::ArbItem},
+ {0,0,0,0}};
+
+ CommandLine CmdL(Args,_config);
+ if (pkgInitConfig(*_config) == false ||
+ CmdL.Parse(argc,argv) == false) {
+ _error->DumpErrors();
+ return 2;
+ }
+
+ // See if the help should be shown
+ if (_config->FindB("help") == true ||
+ _config->FindB("version") == true) {
+ ShowHelp(CmdL);
+ return 1;
+ }
+
+ if (CmdL.FileList[0] != 0 && strcmp(CmdL.FileList[0], "scenario") == 0)
+ {
+ if (pkgInitSystem(*_config,_system) == false) {
+ std::cerr << "System could not be initialized!" << std::endl;
+ return 1;
+ }
+ pkgCacheFile CacheFile;
+ CacheFile.Open(NULL, false);
+ APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1);
+ FILE* output = stdout;
+ if (pkgset.empty() == true)
+ EDSP::WriteScenario(CacheFile, output);
+ else
+ EDSP::WriteLimitedScenario(CacheFile, output, pkgset);
+ fclose(output);
+ _error->DumpErrors(std::cerr);
+ return 0;
+ }
+
+ // Deal with stdout not being a tty
+ if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
+ _config->Set("quiet","1");
+
+ if (_config->FindI("quiet", 0) < 1)
+ _config->Set("Debug::EDSP::WriteSolution", true);
+
+ _config->Set("APT::Solver", "internal");
+ _config->Set("edsp::scenario", "stdin");
+ int input = STDIN_FILENO;
+ FILE* output = stdout;
+ SetNonBlock(input, false);
+
+ EDSP::WriteProgress(0, "Start up solver…", output);
+
+ if (pkgInitSystem(*_config,_system) == false) {
+ std::cerr << "System could not be initialized!" << std::endl;
+ return 1;
+ }
+
+ EDSP::WriteProgress(1, "Read request…", output);
+
+ if (WaitFd(input, false, 5) == false)
+ std::cerr << "WAIT timed out in the resolver" << std::endl;
+
+ std::list<std::string> install, remove;
+ bool upgrade, distUpgrade, autoRemove;
+ if (EDSP::ReadRequest(input, install, remove, upgrade, distUpgrade, autoRemove) == false) {
+ std::cerr << "Parsing the request failed!" << std::endl;
+ return 2;
+ }
+
+ EDSP::WriteProgress(5, "Read scenario…", output);
+
+ pkgCacheFile CacheFile;
+ CacheFile.Open(NULL, false);
+
+ EDSP::WriteProgress(50, "Apply request on scenario…", output);
+
+ if (EDSP::ApplyRequest(install, remove, CacheFile) == false) {
+ std::cerr << "Failed to apply request to depcache!" << std::endl;
+ return 3;
+ }
+
+ pkgProblemResolver Fix(CacheFile);
+ for (std::list<std::string>::const_iterator i = remove.begin();
+ i != remove.end(); ++i) {
+ pkgCache::PkgIterator P = CacheFile->FindPkg(*i);
+ Fix.Clear(P);
+ Fix.Protect(P);
+ Fix.Remove(P);
+ }
+
+ for (std::list<std::string>::const_iterator i = install.begin();
+ i != install.end(); ++i) {
+ pkgCache::PkgIterator P = CacheFile->FindPkg(*i);
+ Fix.Clear(P);
+ Fix.Protect(P);
+ }
+
+ for (std::list<std::string>::const_iterator i = install.begin();
+ i != install.end(); ++i)
+ CacheFile->MarkInstall(CacheFile->FindPkg(*i), true);
+
+ EDSP::WriteProgress(60, "Call problemresolver on current scenario…", output);
+
+ if (upgrade == true) {
+ if (pkgAllUpgrade(CacheFile) == false) {
+ EDSP::WriteError("ERR_UNSOLVABLE_UPGRADE", "An upgrade error occured", output);
+ return 0;
+ }
+ } else if (distUpgrade == true) {
+ if (pkgDistUpgrade(CacheFile) == false) {
+ EDSP::WriteError("ERR_UNSOLVABLE_DIST_UPGRADE", "An dist-upgrade error occured", output);
+ return 0;
+ }
+ } else if (Fix.Resolve() == false) {
+ EDSP::WriteError("ERR_UNSOLVABLE", "An error occured", output);
+ return 0;
+ }
+
+ EDSP::WriteProgress(95, "Write solution…", output);
+
+ if (EDSP::WriteSolution(CacheFile, output) == false) {
+ std::cerr << "Failed to output the solution!" << std::endl;
+ return 4;
+ }
+
+ EDSP::WriteProgress(100, "Done", output);
+
+ bool const Errors = _error->PendingError();
+ if (_config->FindI("quiet",0) > 0)
+ _error->DumpErrors(std::cerr);
+ else
+ _error->DumpErrors(std::cerr, GlobalError::DEBUG);
+ return Errors == true ? 100 : 0;
+}
+ /*}}}*/
diff --git a/cmdline/apt-key b/cmdline/apt-key
index c1e01a776..843163f82 100755
--- a/cmdline/apt-key
+++ b/cmdline/apt-key
@@ -7,7 +7,7 @@ unset GREP_OPTIONS
# implodes if there isn't one available
GPG_CMD='gpg --ignore-time-conflict --no-options --no-default-keyring --secret-keyring /etc/apt/secring.gpg'
-if ! id -u > /dev/null; then
+if [ "$(id -u)" -eq 0 ]; then
GPG_CMD="$GPG_CMD --trustdb-name /etc/apt/trustdb.gpg"
fi
@@ -21,6 +21,13 @@ ARCHIVE_KEYRING_URI=""
ARCHIVE_KEYRING=/usr/share/keyrings/debian-archive-keyring.gpg
REMOVED_KEYS=/usr/share/keyrings/debian-archive-removed-keys.gpg
+requires_root() {
+ if [ "$(id -u)" -ne 0 ]; then
+ echo >&1 "ERROR: This command can only be used by root."
+ exit 1
+ fi
+}
+
add_keys_with_verify_against_master_keyring() {
ADD_KEYRING=$1
MASTER=$2
@@ -59,13 +66,14 @@ add_keys_with_verify_against_master_keyring() {
# (otherwise it does not make sense from a security POV)
net_update() {
if [ -z "$ARCHIVE_KEYRING_URI" ]; then
- echo "ERROR: no location for the archive-keyring given"
+ echo >&2 "ERROR: Your distribution is not supported in net-update as no uri for the archive-keyring is set"
exit 1
fi
+ requires_root
# in theory we would need to depend on wget for this, but this feature
# isn't useable in debian anyway as we have no keyring uri nor a master key
if ! which wget >/dev/null 2>&1; then
- echo "ERROR: an installed wget is required for a network-based update"
+ echo >&2 "ERROR: an installed wget is required for a network-based update"
exit 1
fi
if [ ! -d /var/lib/apt/keyrings ]; then
@@ -93,6 +101,7 @@ update() {
echo >&2 "Is the debian-archive-keyring package installed?"
exit 1
fi
+ requires_root
# add new keys from the package;
@@ -184,10 +193,12 @@ fi
case "$command" in
add)
+ requires_root
$GPG --quiet --batch --import "$1"
echo "OK"
;;
del|rm|remove)
+ requires_root
$GPG --quiet --batch --delete-key --yes "$1"
echo "OK"
;;
diff --git a/cmdline/apt-mark b/cmdline/apt-mark
deleted file mode 100755
index c64d4356c..000000000
--- a/cmdline/apt-mark
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/python
-
-from optparse import OptionParser
-
-import sys
-import os.path
-
-try:
- import apt_pkg
-except ImportError:
- print >> sys.stderr, "Error importing apt_pkg, is python-apt installed?"
- sys.exit(1)
-
-actions = { "markauto" : 1,
- "unmarkauto": 0
- }
-
-def show_automatic(filename):
- if not os.path.exists(STATE_FILE):
- return
- auto = set()
- tagfile = apt_pkg.TagFile(open(STATE_FILE))
- for section in tagfile:
- pkgname = section.get("Package")
- autoInst = section.get("Auto-Installed")
- if int(autoInst):
- auto.add(pkgname)
- print "\n".join(sorted(auto))
-
-
-def mark_unmark_automatic(filename, action, pkgs):
- " mark or unmark automatic flag"
- # open the statefile
- if os.path.exists(STATE_FILE):
- try:
- tagfile = apt_pkg.TagFile(open(STATE_FILE))
- outfile = open(STATE_FILE+".tmp","w")
- except IOError, msg:
- print "%s, are you root?" % (msg)
- sys.exit(1)
- for section in tagfile:
- pkgname = section.get("Package")
- autoInst = section.get("Auto-Installed")
- if pkgname in pkgs:
- if options.verbose:
- print "changing %s to %s" % (pkgname,action)
- newsec = apt_pkg.rewrite_section(section,
- [],
- [ ("Auto-Installed",str(action)) ])
- pkgs.remove(pkgname)
- outfile.write(newsec+"\n")
- else:
- outfile.write(str(section)+"\n")
- if action == 1:
- for pkgname in pkgs:
- if options.verbose:
- print "changing %s to %s" % (pkgname,action)
- outfile.write("Package: %s\nAuto-Installed: %d\n\n" % (pkgname, action))
- # all done, rename the tmpfile
- os.chmod(outfile.name, 0644)
- os.rename(outfile.name, STATE_FILE)
- os.chmod(STATE_FILE, 0644)
-
-
-if __name__ == "__main__":
- apt_pkg.init()
-
- # option parsing
- parser = OptionParser()
- parser.usage = "%prog [options] {markauto|unmarkauto} packages..."
- parser.epilog = "apt-mark is deprecated, use apt-get markauto/unmarkauto."
- parser.add_option("-f", "--file", action="store", type="string",
- dest="filename",
- help="read/write a different file")
- parser.add_option("-v", "--verbose",
- action="store_true", dest="verbose", default=False,
- help="print verbose status messages to stdout")
- (options, args) = parser.parse_args()
-
- if not args:
- parser.print_help()
- sys.exit(1)
-
- # get the state-file
- if not options.filename:
- STATE_FILE = apt_pkg.config.find_dir("Dir::State") + "extended_states"
- else:
- STATE_FILE=options.filename
-
- if len(args) == 0:
- parser.error("first argument must be 'markauto', 'unmarkauto' or 'showauto'")
-
- if args[0] == "showauto":
- show_automatic(STATE_FILE)
- else:
- # get pkgs to change
- if args[0] not in actions.keys():
- parser.error("first argument must be 'markauto', 'unmarkauto' or 'showauto'")
- pkgs = args[1:]
- action = actions[args[0]]
- mark_unmark_automatic(STATE_FILE, action, pkgs)
diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc
new file mode 100644
index 000000000..b2c664979
--- /dev/null
+++ b/cmdline/apt-mark.cc
@@ -0,0 +1,373 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* #####################################################################
+ apt-mark - show and change auto-installed bit information
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/strutl.h>
+
+#include <config.h>
+#include <apti18n.h>
+
+#include <algorithm>
+ /*}}}*/
+using namespace std;
+
+ostream c0out(0);
+ostream c1out(0);
+ostream c2out(0);
+ofstream devnull("/dev/null");
+/* DoAuto - mark packages as automatically/manually installed {{{*/
+bool DoAuto(CommandLine &CmdL)
+{
+ pkgCacheFile CacheFile;
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ pkgDepCache *DepCache = CacheFile.GetDepCache();
+ if (unlikely(Cache == NULL || DepCache == NULL))
+ return false;
+
+ APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1);
+ if (pkgset.empty() == true)
+ return _error->Error(_("No packages found"));
+
+ bool MarkAuto = strcasecmp(CmdL.FileList[0],"auto") == 0;
+ int AutoMarkChanged = 0;
+
+ for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+ {
+ if (Pkg->CurrentVer == 0)
+ {
+ ioprintf(c1out,_("%s can not be marked as it is not installed.\n"), Pkg.FullName(true).c_str());
+ continue;
+ }
+ else if ((((*DepCache)[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) == MarkAuto)
+ {
+ if (MarkAuto == false)
+ ioprintf(c1out,_("%s was already set to manually installed.\n"), Pkg.FullName(true).c_str());
+ else
+ ioprintf(c1out,_("%s was already set to automatically installed.\n"), Pkg.FullName(true).c_str());
+ continue;
+ }
+
+ if (MarkAuto == false)
+ ioprintf(c1out,_("%s set to manually installed.\n"), Pkg.FullName(true).c_str());
+ else
+ ioprintf(c1out,_("%s set to automatically installed.\n"), Pkg.FullName(true).c_str());
+
+ DepCache->MarkAuto(Pkg, MarkAuto);
+ ++AutoMarkChanged;
+ }
+ if (AutoMarkChanged > 0 && _config->FindB("APT::Mark::Simulate", false) == false)
+ return DepCache->writeStateFile(NULL);
+ return true;
+}
+ /*}}}*/
+/* DoMarkAuto - mark packages as automatically/manually installed {{{*/
+/* Does the same as DoAuto but tries to do it exactly the same why as
+ the python implementation did it so it can be a drop-in replacement */
+bool DoMarkAuto(CommandLine &CmdL)
+{
+ pkgCacheFile CacheFile;
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ pkgDepCache *DepCache = CacheFile.GetDepCache();
+ if (unlikely(Cache == NULL || DepCache == NULL))
+ return false;
+
+ APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1);
+ if (pkgset.empty() == true)
+ return _error->Error(_("No packages found"));
+
+ bool const MarkAuto = strcasecmp(CmdL.FileList[0],"markauto") == 0;
+ bool const Verbose = _config->FindB("APT::MarkAuto::Verbose", false);
+ int AutoMarkChanged = 0;
+
+ for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+ {
+ if (Pkg->CurrentVer == 0 ||
+ (((*DepCache)[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) == MarkAuto)
+ continue;
+
+ if (Verbose == true)
+ ioprintf(c1out, "changing %s to %d\n", Pkg.Name(), (MarkAuto == false) ? 0 : 1);
+
+ DepCache->MarkAuto(Pkg, MarkAuto);
+ ++AutoMarkChanged;
+ }
+ if (AutoMarkChanged > 0 && _config->FindB("APT::Mark::Simulate", false) == false)
+ return DepCache->writeStateFile(NULL);
+
+ _error->Notice(_("This command is deprecated. Please use 'apt-mark auto' and 'apt-mark manual' instead."));
+
+ return true;
+}
+ /*}}}*/
+/* ShowAuto - show automatically installed packages (sorted) {{{*/
+bool ShowAuto(CommandLine &CmdL)
+{
+ pkgCacheFile CacheFile;
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ pkgDepCache *DepCache = CacheFile.GetDepCache();
+ if (unlikely(Cache == NULL || DepCache == NULL))
+ return false;
+
+ std::vector<string> packages;
+
+ bool const ShowAuto = strcasecmp(CmdL.FileList[0],"showauto") == 0;
+
+ if (CmdL.FileList[1] == 0)
+ {
+ packages.reserve(Cache->HeaderP->PackageCount / 3);
+ for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
+ if (P->CurrentVer != 0 &&
+ (((*DepCache)[P].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) == ShowAuto)
+ packages.push_back(P.FullName(true));
+ }
+ else
+ {
+ APT::CacheSetHelper helper(false); // do not show errors
+ APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1, helper);
+ packages.reserve(pkgset.size());
+ for (APT::PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P)
+ if (P->CurrentVer != 0 &&
+ (((*DepCache)[P].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) == ShowAuto)
+ packages.push_back(P.FullName(true));
+ }
+
+ std::sort(packages.begin(), packages.end());
+
+ for (vector<string>::const_iterator I = packages.begin(); I != packages.end(); ++I)
+ std::cout << *I << std::endl;
+
+ return true;
+}
+ /*}}}*/
+/* DoHold - mark packages as hold by dpkg {{{*/
+bool DoHold(CommandLine &CmdL)
+{
+ pkgCacheFile CacheFile;
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ if (unlikely(Cache == NULL))
+ return false;
+
+ APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1);
+ if (pkgset.empty() == true)
+ return _error->Error(_("No packages found"));
+
+ bool const MarkHold = strcasecmp(CmdL.FileList[0],"hold") == 0;
+
+ for (APT::PackageSet::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+ {
+ if ((Pkg->SelectedState == pkgCache::State::Hold) == MarkHold)
+ {
+ if (MarkHold == true)
+ ioprintf(c1out,_("%s was already set on hold.\n"), Pkg.FullName(true).c_str());
+ else
+ ioprintf(c1out,_("%s was already not hold.\n"), Pkg.FullName(true).c_str());
+ pkgset.erase(Pkg);
+ continue;
+ }
+ }
+
+ if (pkgset.empty() == true)
+ return true;
+
+ if (_config->FindB("APT::Mark::Simulate", false) == true)
+ {
+ for (APT::PackageSet::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+ {
+ if (MarkHold == false)
+ ioprintf(c1out,_("%s set on hold.\n"), Pkg.FullName(true).c_str());
+ else
+ ioprintf(c1out,_("Canceled hold on %s.\n"), Pkg.FullName(true).c_str());
+ }
+ return true;
+ }
+
+ string dpkgcall = _config->Find("Dir::Bin::dpkg", "dpkg");
+ std::vector<string> const dpkgoptions = _config->FindVector("DPkg::options");
+ for (std::vector<string>::const_iterator o = dpkgoptions.begin();
+ o != dpkgoptions.end(); ++o)
+ dpkgcall.append(" ").append(*o);
+ dpkgcall.append(" --set-selections");
+ FILE *dpkg = popen(dpkgcall.c_str(), "w");
+ if (dpkg == NULL)
+ return _error->Errno("DoHold", "fdopen on dpkg stdin failed");
+
+ for (APT::PackageSet::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+ {
+ if (MarkHold == true)
+ {
+ fprintf(dpkg, "%s hold\n", Pkg.FullName(true).c_str());
+ ioprintf(c1out,_("%s set on hold.\n"), Pkg.FullName(true).c_str());
+ }
+ else
+ {
+ fprintf(dpkg, "%s install\n", Pkg.FullName(true).c_str());
+ ioprintf(c1out,_("Canceled hold on %s.\n"), Pkg.FullName(true).c_str());
+ }
+ }
+
+ int const status = pclose(dpkg);
+ if (status == -1)
+ return _error->Errno("DoHold", "dpkg execution failed in the end");
+ if (WIFEXITED(status) == false || WEXITSTATUS(status) != 0)
+ return _error->Error(_("Executing dpkg failed. Are you root?"));
+ return true;
+}
+ /*}}}*/
+/* ShowHold - show packages set on hold in dpkg status {{{*/
+bool ShowHold(CommandLine &CmdL)
+{
+ pkgCacheFile CacheFile;
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ if (unlikely(Cache == NULL))
+ return false;
+
+ std::vector<string> packages;
+
+ if (CmdL.FileList[1] == 0)
+ {
+ packages.reserve(50); // how many holds are realistic? I hope just a few…
+ for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
+ if (P->SelectedState == pkgCache::State::Hold)
+ packages.push_back(P.FullName(true));
+ }
+ else
+ {
+ APT::CacheSetHelper helper(false); // do not show errors
+ APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1, helper);
+ packages.reserve(pkgset.size());
+ for (APT::PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P)
+ if (P->SelectedState == pkgCache::State::Hold)
+ packages.push_back(P.FullName(true));
+ }
+
+ std::sort(packages.begin(), packages.end());
+
+ for (vector<string>::const_iterator I = packages.begin(); I != packages.end(); ++I)
+ std::cout << *I << std::endl;
+
+ return true;
+}
+ /*}}}*/
+// ShowHelp - Show a help screen /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowHelp(CommandLine &CmdL)
+{
+ ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
+ COMMON_ARCH,__DATE__,__TIME__);
+
+ cout <<
+ _("Usage: apt-mark [options] {auto|manual} pkg1 [pkg2 ...]\n"
+ "\n"
+ "apt-mark is a simple command line interface for marking packages\n"
+ "as manual or automatical installed. It can also list marks.\n"
+ "\n"
+ "Commands:\n"
+ " auto - Mark the given packages as automatically installed\n"
+ " manual - Mark the given packages as manually installed\n"
+ "\n"
+ "Options:\n"
+ " -h This help text.\n"
+ " -q Loggable output - no progress indicator\n"
+ " -qq No output except for errors\n"
+ " -s No-act. Just prints what would be done.\n"
+ " -f read/write auto/manual marking in the given file\n"
+ " -c=? Read this configuration file\n"
+ " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
+ "See the apt-mark(8) and apt.conf(5) manual pages for more information.")
+ << std::endl;
+ return true;
+}
+ /*}}}*/
+int main(int argc,const char *argv[]) /*{{{*/
+{
+ CommandLine::Args Args[] = {
+ {'h',"help","help",0},
+ {0,"version","version",0},
+ {'q',"quiet","quiet",CommandLine::IntLevel},
+ {'q',"silent","quiet",CommandLine::IntLevel},
+ {'v',"verbose","APT::MarkAuto::Verbose",0},
+ {'s',"simulate","APT::Mark::Simulate",0},
+ {'s',"just-print","APT::Mark::Simulate",0},
+ {'s',"recon","APT::Mark::Simulate",0},
+ {'s',"dry-run","APT::Mark::Simulate",0},
+ {'s',"no-act","APT::Mark::Simulate",0},
+ {'f',"file","Dir::State::extended_states",CommandLine::HasArg},
+ {'c',"config-file",0,CommandLine::ConfigFile},
+ {'o',"option",0,CommandLine::ArbItem},
+ {0,0,0,0}};
+ CommandLine::Dispatch Cmds[] = {{"help",&ShowHelp},
+ {"auto",&DoAuto},
+ {"manual",&DoAuto},
+ {"hold",&DoHold},
+ {"unhold",&DoHold},
+ {"showauto",&ShowAuto},
+ {"showmanual",&ShowAuto},
+ {"showhold",&ShowHold},
+ // be nice and forgive the typo
+ {"showholds",&ShowHold},
+ // be nice and forgive it as it is technical right
+ {"install",&DoHold},
+ // obsolete commands for compatibility
+ {"markauto", &DoMarkAuto},
+ {"unmarkauto", &DoMarkAuto},
+ {0,0}};
+
+ // Set up gettext support
+ setlocale(LC_ALL,"");
+ textdomain(PACKAGE);
+
+ // Parse the command line and initialize the package library
+ CommandLine CmdL(Args,_config);
+ if (pkgInitConfig(*_config) == false ||
+ CmdL.Parse(argc,argv) == false ||
+ pkgInitSystem(*_config,_system) == false)
+ {
+ if (_config->FindB("version") == true)
+ ShowHelp(CmdL);
+ _error->DumpErrors();
+ return 100;
+ }
+
+ // See if the help should be shown
+ if (_config->FindB("help") == true ||
+ _config->FindB("version") == true ||
+ CmdL.FileSize() == 0)
+ {
+ ShowHelp(CmdL);
+ return 0;
+ }
+
+ // Deal with stdout not being a tty
+ if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
+ _config->Set("quiet","1");
+
+ // Setup the output streams
+ c0out.rdbuf(cout.rdbuf());
+ c1out.rdbuf(cout.rdbuf());
+ c2out.rdbuf(cout.rdbuf());
+ if (_config->FindI("quiet",0) > 0)
+ c0out.rdbuf(devnull.rdbuf());
+ if (_config->FindI("quiet",0) > 1)
+ c1out.rdbuf(devnull.rdbuf());
+
+ // Match the operation
+ CmdL.DispatchArg(Cmds);
+
+ // 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;
+}
+ /*}}}*/
diff --git a/cmdline/makefile b/cmdline/makefile
index 917ccc96a..6d988a8f5 100644
--- a/cmdline/makefile
+++ b/cmdline/makefile
@@ -54,13 +54,28 @@ TARGET=program
include $(COPY_H)
# The apt-mark program
-SOURCE=apt-mark
-TO=$(BIN)
-TARGET=program
-include $(COPY_H)
+PROGRAM=apt-mark
+SLIBS = -lapt-pkg $(INTLLIBS)
+LIB_MAKES = apt-pkg/makefile
+SOURCE = apt-mark.cc
+include $(PROGRAM_H)
# The apt-report-mirror-failure program
#SOURCE=apt-report-mirror-failure
#TO=$(BIN)
#TARGET=program
#include $(COPY_H)
+
+# The internal solver acting as an external
+PROGRAM=apt-internal-solver
+SLIBS = -lapt-pkg $(INTLLIBS)
+LIB_MAKES = apt-pkg/makefile
+SOURCE = apt-internal-solver.cc
+include $(PROGRAM_H)
+
+# The internal solver acting as an external
+PROGRAM=apt-dump-solver
+SLIBS = -lapt-pkg $(INTLLIBS)
+LIB_MAKES = apt-pkg/makefile
+SOURCE = apt-dump-solver.cc
+include $(PROGRAM_H)