summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--apt-pkg/algorithms.cc51
-rw-r--r--apt-pkg/algorithms.h4
-rw-r--r--apt-pkg/cachefilter.cc11
-rw-r--r--apt-pkg/cachefilter.h35
-rw-r--r--apt-pkg/cacheset.cc64
-rw-r--r--apt-pkg/cacheset.h13
-rw-r--r--apt-pkg/contrib/cmndline.cc48
-rw-r--r--apt-pkg/contrib/cmndline.h6
-rw-r--r--apt-pkg/contrib/strutl.cc12
-rw-r--r--apt-pkg/contrib/strutl.h4
-rw-r--r--apt-private/acqprogress.cc309
-rw-r--r--apt-private/acqprogress.h38
-rw-r--r--apt-private/makefile28
-rw-r--r--apt-private/private-cachefile.cc109
-rw-r--r--apt-private/private-cachefile.h51
-rw-r--r--apt-private/private-cacheset.cc63
-rw-r--r--apt-private/private-cacheset.h265
-rw-r--r--apt-private/private-cmndline.cc268
-rw-r--r--apt-private/private-cmndline.h10
-rw-r--r--apt-private/private-install.cc852
-rw-r--r--apt-private/private-install.h181
-rw-r--r--apt-private/private-list.cc158
-rw-r--r--apt-private/private-list.h9
-rw-r--r--apt-private/private-main.cc26
-rw-r--r--apt-private/private-main.h9
-rw-r--r--apt-private/private-moo.cc193
-rw-r--r--apt-private/private-moo.h12
-rw-r--r--apt-private/private-output.cc753
-rw-r--r--apt-private/private-output.h49
-rw-r--r--apt-private/private-search.cc99
-rw-r--r--apt-private/private-search.h9
-rw-r--r--apt-private/private-show.cc122
-rw-r--r--apt-private/private-show.h12
-rw-r--r--apt-private/private-update.cc93
-rw-r--r--apt-private/private-update.h8
-rw-r--r--apt-private/private-upgrade.cc47
-rw-r--r--apt-private/private-upgrade.h11
-rw-r--r--cmdline/apt-cache.cc116
-rw-r--r--cmdline/apt-cdrom.cc30
-rw-r--r--cmdline/apt-config.cc23
-rw-r--r--cmdline/apt-get.cc1988
-rw-r--r--cmdline/apt-mark.cc21
-rw-r--r--cmdline/apt.cc158
-rw-r--r--cmdline/makefile19
45 files changed, 4281 insertions, 2107 deletions
diff --git a/Makefile b/Makefile
index 47fc23656..fb843983c 100644
--- a/Makefile
+++ b/Makefile
@@ -13,6 +13,7 @@ default: startup all
all headers library clean veryclean binary program doc manpages debiandoc test update-po startup dirs:
$(MAKE) -C apt-pkg $@
$(MAKE) -C apt-inst $@
+ $(MAKE) -C apt-private $@
$(MAKE) -C methods $@
$(MAKE) -C cmdline $@
$(MAKE) -C ftparchive $@
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index 85799a11b..69d4acd83 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -459,6 +459,49 @@ bool pkgAllUpgrade(pkgDepCache &Cache)
return Fix.ResolveByKeep();
}
/*}}}*/
+// AllUpgradeNoDelete - Upgrade without removing packages /*{{{*/
+// ---------------------------------------------------------------------
+/* Right now the system must be consistent before this can be called.
+ * Upgrade as much as possible without deleting anything (useful for
+ * stable systems)
+ */
+bool pkgAllUpgradeNoDelete(pkgDepCache &Cache)
+{
+ pkgDepCache::ActionGroup group(Cache);
+
+ pkgProblemResolver Fix(&Cache);
+
+ if (Cache.BrokenCount() != 0)
+ return false;
+
+ // provide the initial set of stuff we want to upgrade by marking
+ // all upgradable packages for upgrade
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ {
+ if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
+ {
+ if (_config->FindB("APT::Ignore-Hold",false) == false)
+ if (I->SelectedState == pkgCache::State::Hold)
+ continue;
+
+ Cache.MarkInstall(I, false, 0, false);
+ }
+ }
+
+ // then let auto-install loose
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if (Cache[I].Install())
+ Cache.MarkInstall(I, true, 0, false);
+
+ // ... but it may remove stuff, we we need to clean up afterwards again
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if (Cache[I].Delete() == true)
+ Cache.MarkKeep(I, false, false);
+
+ // resolve remaining issues via keep
+ return Fix.ResolveByKeep();
+}
+ /*}}}*/
// MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
// ---------------------------------------------------------------------
/* This simply goes over the entire set of packages and tries to keep
@@ -550,14 +593,12 @@ void pkgProblemResolver::MakeScores()
unsigned long Size = Cache.Head().PackageCount;
memset(Scores,0,sizeof(*Scores)*Size);
- // Maps to pkgCache::State::VerPriority
- // which is "Important Required Standard Optional Extra"
- // (yes, that is confusing, the order of pkgCache::State::VerPriority
- // needs to be adjusted but that requires a ABI break)
+ // maps to pkgCache::State::VerPriority:
+ // Required Important Standard Optional Extra
int PrioMap[] = {
0,
- _config->FindI("pkgProblemResolver::Scores::Important",2),
_config->FindI("pkgProblemResolver::Scores::Required",3),
+ _config->FindI("pkgProblemResolver::Scores::Important",2),
_config->FindI("pkgProblemResolver::Scores::Standard",1),
_config->FindI("pkgProblemResolver::Scores::Optional",-1),
_config->FindI("pkgProblemResolver::Scores::Extra",-2)
diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h
index 7f58c8eed..a499db8ba 100644
--- a/apt-pkg/algorithms.h
+++ b/apt-pkg/algorithms.h
@@ -143,7 +143,11 @@ class pkgProblemResolver /*{{{*/
bool pkgDistUpgrade(pkgDepCache &Cache);
bool pkgApplyStatus(pkgDepCache &Cache);
bool pkgFixBroken(pkgDepCache &Cache);
+
bool pkgAllUpgrade(pkgDepCache &Cache);
+
+bool pkgAllUpgradeNoDelete(pkgDepCache &Cache);
+
bool pkgMinimizeUpgrade(pkgDepCache &Cache);
void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List);
diff --git a/apt-pkg/cachefilter.cc b/apt-pkg/cachefilter.cc
index 64cde41d1..57b9af159 100644
--- a/apt-pkg/cachefilter.cc
+++ b/apt-pkg/cachefilter.cc
@@ -55,6 +55,17 @@ PackageNameMatchesRegEx::~PackageNameMatchesRegEx() { /*{{{*/
}
/*}}}*/
+// Fnmatch support /*{{{*/
+//----------------------------------------------------------------------
+bool PackageNameMatchesFnmatch::operator() (pkgCache::PkgIterator const &Pkg) {/*{{{*/
+ return fnmatch(Pattern.c_str(), Pkg.Name(), FNM_CASEFOLD) == 0;
+}
+ /*}}}*/
+bool PackageNameMatchesFnmatch::operator() (pkgCache::GrpIterator const &Grp) {/*{{{*/
+ return fnmatch(Pattern.c_str(), Grp.Name(), FNM_CASEFOLD) == 0;
+}
+ /*}}}*/
+
// CompleteArch to <kernel>-<cpu> tuple /*{{{*/
//----------------------------------------------------------------------
/* The complete architecture, consisting of <kernel>-<cpu>. */
diff --git a/apt-pkg/cachefilter.h b/apt-pkg/cachefilter.h
index 25cd43f47..f55d5c7f7 100644
--- a/apt-pkg/cachefilter.h
+++ b/apt-pkg/cachefilter.h
@@ -14,18 +14,41 @@
/*}}}*/
namespace APT {
namespace CacheFilter {
+
+class PackageMatcher {
+ public:
+ virtual bool operator() (pkgCache::PkgIterator const &Pkg) { return false; };
+ virtual bool operator() (pkgCache::GrpIterator const &Grp) { return false; };
+ virtual bool operator() (pkgCache::VerIterator const &Ver) { return false; };
+
+ virtual ~PackageMatcher() {};
+};
+
// PackageNameMatchesRegEx /*{{{*/
-class PackageNameMatchesRegEx {
+class PackageNameMatchesRegEx : public PackageMatcher {
/** \brief dpointer placeholder (for later in case we need it) */
void *d;
regex_t* pattern;
public:
PackageNameMatchesRegEx(std::string const &Pattern);
- bool operator() (pkgCache::PkgIterator const &Pkg);
- bool operator() (pkgCache::GrpIterator const &Grp);
+ virtual bool operator() (pkgCache::PkgIterator const &Pkg);
+ virtual bool operator() (pkgCache::GrpIterator const &Grp);
~PackageNameMatchesRegEx();
};
/*}}}*/
+// PackageNameMatchesFnmatch /*{{{*/
+ class PackageNameMatchesFnmatch : public PackageMatcher{
+ /** \brief dpointer placeholder (for later in case we need it) */
+ void *d;
+ const std::string Pattern;
+public:
+ PackageNameMatchesFnmatch(std::string const &Pattern)
+ : Pattern(Pattern) {};
+ virtual bool operator() (pkgCache::PkgIterator const &Pkg);
+ virtual bool operator() (pkgCache::GrpIterator const &Grp);
+ ~PackageNameMatchesFnmatch() {};
+};
+ /*}}}*/
// PackageArchitectureMatchesSpecification /*{{{*/
/** \class PackageArchitectureMatchesSpecification
\brief matching against architecture specification strings
@@ -35,7 +58,7 @@ public:
debian-policy ยง11.1 "Architecture specification strings".
Examples: i386, mipsel, linux-any, any-amd64, any */
-class PackageArchitectureMatchesSpecification {
+class PackageArchitectureMatchesSpecification : public PackageMatcher {
std::string literal;
std::string complete;
bool isPattern;
@@ -51,8 +74,8 @@ public:
*/
PackageArchitectureMatchesSpecification(std::string const &pattern, bool const isPattern = true);
bool operator() (char const * const &arch);
- bool operator() (pkgCache::PkgIterator const &Pkg);
- bool operator() (pkgCache::VerIterator const &Ver);
+ virtual bool operator() (pkgCache::PkgIterator const &Pkg);
+ virtual bool operator() (pkgCache::VerIterator const &Ver);
~PackageArchitectureMatchesSpecification();
};
/*}}}*/
diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc
index 1fea4f94a..0147f7e86 100644
--- a/apt-pkg/cacheset.cc
+++ b/apt-pkg/cacheset.cc
@@ -155,6 +155,69 @@ bool PackageContainerInterface::FromRegEx(PackageContainerInterface * const pci,
return true;
}
/*}}}*/
+// FromFnmatch - Returns the package defined by this fnmatch /*{{{*/
+bool
+PackageContainerInterface::FromFnmatch(PackageContainerInterface * const pci,
+ pkgCacheFile &Cache,
+ std::string pattern,
+ CacheSetHelper &helper)
+{
+ static const char * const isfnmatch = ".?*[]!";
+ if (pattern.find_first_of(isfnmatch) == std::string::npos)
+ return false;
+
+ bool const wasEmpty = pci->empty();
+ if (wasEmpty == true)
+ pci->setConstructor(FNMATCH);
+
+ size_t archfound = pattern.find_last_of(':');
+ std::string arch = "native";
+ if (archfound != std::string::npos) {
+ arch = pattern.substr(archfound+1);
+ if (arch.find_first_of(isfnmatch) == std::string::npos)
+ pattern.erase(archfound);
+ else
+ arch = "native";
+ }
+
+ if (unlikely(Cache.GetPkgCache() == 0))
+ return false;
+
+ APT::CacheFilter::PackageNameMatchesFnmatch filter(pattern);
+
+ bool found = false;
+ for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) {
+ if (filter(Grp) == false)
+ continue;
+ pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
+ if (Pkg.end() == true) {
+ if (archfound == std::string::npos) {
+ std::vector<std::string> archs = APT::Configuration::getArchitectures();
+ for (std::vector<std::string>::const_iterator a = archs.begin();
+ a != archs.end() && Pkg.end() != true; ++a)
+ Pkg = Grp.FindPkg(*a);
+ }
+ if (Pkg.end() == true)
+ continue;
+ }
+
+ pci->insert(Pkg);
+ helper.showRegExSelection(Pkg, pattern);
+ found = true;
+ }
+
+ if (found == false) {
+ helper.canNotFindRegEx(pci, Cache, pattern);
+ pci->setConstructor(UNKNOWN);
+ return false;
+ }
+
+ if (wasEmpty == false && pci->getConstructor() != UNKNOWN)
+ pci->setConstructor(UNKNOWN);
+
+ return true;
+}
+ /*}}}*/
// FromName - Returns the package defined by this string /*{{{*/
pkgCache::PkgIterator PackageContainerInterface::FromName(pkgCacheFile &Cache,
std::string const &str, CacheSetHelper &helper) {
@@ -239,6 +302,7 @@ bool PackageContainerInterface::FromString(PackageContainerInterface * const pci
if (FromGroup(pci, Cache, str, helper) == false &&
FromTask(pci, Cache, str, helper) == false &&
+ FromFnmatch(pci, Cache, str, helper) == false &&
FromRegEx(pci, Cache, str, helper) == false)
{
helper.canNotFindPackage(pci, Cache, str);
diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h
index d7328d705..29103aad9 100644
--- a/apt-pkg/cacheset.h
+++ b/apt-pkg/cacheset.h
@@ -131,13 +131,14 @@ public:
virtual bool empty() const = 0;
virtual void clear() = 0;
- enum Constructor { UNKNOWN, REGEX, TASK };
+ enum Constructor { UNKNOWN, REGEX, TASK, FNMATCH };
virtual void setConstructor(Constructor const &con) = 0;
virtual Constructor getConstructor() const = 0;
static bool FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static bool FromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
+ static bool FromFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static bool FromGroup(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static bool FromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
static bool FromCommandLine(PackageContainerInterface * const pci, pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper);
@@ -259,6 +260,16 @@ public: /*{{{*/
return FromRegEx(Cache, pattern, helper);
}
+ static PackageContainer FromFnmatch(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
+ PackageContainer cont(FNMATCH);
+ PackageContainerInterface::FromFnmatch(&cont, Cache, pattern, helper);
+ return cont;
+ }
+ static PackageContainer FromFnMatch(pkgCacheFile &Cache, std::string const &pattern) {
+ CacheSetHelper helper;
+ return FromFnmatch(Cache, pattern, helper);
+ }
+
/** \brief returns a package specified by a string
\param Cache the package is in
diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc
index 75d02cad4..8cef80368 100644
--- a/apt-pkg/contrib/cmndline.cc
+++ b/apt-pkg/contrib/cmndline.cc
@@ -38,6 +38,42 @@ CommandLine::~CommandLine()
delete [] FileList;
}
/*}}}*/
+// CommandLine::GetCommand - return the first non-option word /*{{{*/
+char const * CommandLine::GetCommand(Dispatch const * const Map,
+ unsigned int const argc, char const * const * const argv)
+{
+ // if there is a -- on the line there must be the word we search for around it
+ // as -- marks the end of the options, just not sure if the command can be
+ // considered an option or not, so accept both
+ for (size_t i = 1; i < argc; ++i)
+ {
+ if (strcmp(argv[i], "--") != 0)
+ continue;
+ ++i;
+ if (i < argc)
+ for (size_t j = 0; Map[j].Match != NULL; ++j)
+ if (strcmp(argv[i], Map[j].Match) == 0)
+ return Map[j].Match;
+ i -= 2;
+ if (i != 0)
+ for (size_t j = 0; Map[j].Match != NULL; ++j)
+ if (strcmp(argv[i], Map[j].Match) == 0)
+ return Map[j].Match;
+ return NULL;
+ }
+ // no --, so search for the first word matching a command
+ // FIXME: How like is it that an option parameter will be also a valid Match ?
+ for (size_t i = 1; i < argc; ++i)
+ {
+ if (*(argv[i]) == '-')
+ continue;
+ for (size_t j = 0; Map[j].Match != NULL; ++j)
+ if (strcmp(argv[i], Map[j].Match) == 0)
+ return Map[j].Match;
+ }
+ return NULL;
+}
+ /*}}}*/
// CommandLine::Parse - Main action member /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -390,3 +426,15 @@ void CommandLine::SaveInConfig(unsigned int const &argc, char const * const * co
_config->Set("CommandLine::AsString", cmdline);
}
/*}}}*/
+CommandLine::Args CommandLine::MakeArgs(char ShortOpt, char const *LongOpt, char const *ConfName, unsigned long Flags)/*{{{*/
+{
+ /* In theory, this should be a constructor for CommandLine::Args instead,
+ but this breaks compatibility as gcc thinks this is a c++11 initializer_list */
+ CommandLine::Args arg;
+ arg.ShortOpt = ShortOpt;
+ arg.LongOpt = LongOpt;
+ arg.ConfName = ConfName;
+ arg.Flags = Flags;
+ return arg;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/cmndline.h b/apt-pkg/contrib/cmndline.h
index 9f505fd41..180276633 100644
--- a/apt-pkg/contrib/cmndline.h
+++ b/apt-pkg/contrib/cmndline.h
@@ -83,6 +83,12 @@ class CommandLine
unsigned int FileSize() const;
bool DispatchArg(Dispatch *List,bool NoMatch = true);
+ static char const * GetCommand(Dispatch const * const Map,
+ unsigned int const argc, char const * const * const argv);
+
+ static CommandLine::Args MakeArgs(char ShortOpt, char const *LongOpt,
+ char const *ConfName, unsigned long Flags);
+
CommandLine(Args *AList,Configuration *Conf);
~CommandLine();
};
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index df02c3499..d06637155 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/apt-pkg/contrib/strutl.cc
@@ -1291,6 +1291,18 @@ bool CheckDomainList(const string &Host,const string &List)
return false;
}
/*}}}*/
+// strv_length - Return the length of a NULL-terminated string array /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+size_t strv_length(const char **str_array)
+{
+ size_t i;
+ for (i=0; str_array[i] != NULL; i++)
+ /* nothing */
+ ;
+ return i;
+}
+
// DeEscapeString - unescape (\0XX and \xXX) from a string /*{{{*/
// ---------------------------------------------------------------------
/* */
diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h
index e92f91dc0..530896141 100644
--- a/apt-pkg/contrib/strutl.h
+++ b/apt-pkg/contrib/strutl.h
@@ -108,6 +108,10 @@ inline int stringcasecmp(std::string::const_iterator A,std::string::const_iterat
APT_MKSTRCMP2(stringcmp,stringcmp);
APT_MKSTRCMP2(stringcasecmp,stringcasecmp);
+// Return the length of a NULL-terminated string array
+size_t strv_length(const char **str_array);
+
+
inline const char *DeNull(const char *s) {return (s == 0?"(null)":s);};
class URI
diff --git a/apt-private/acqprogress.cc b/apt-private/acqprogress.cc
new file mode 100644
index 000000000..af2d0f461
--- /dev/null
+++ b/apt-private/acqprogress.cc
@@ -0,0 +1,309 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: acqprogress.cc,v 1.24 2003/04/27 01:56:48 doogie Exp $
+/* ######################################################################
+
+ Acquire Progress - Command line progress meter
+
+ ##################################################################### */
+ /*}}}*/
+// Include files /*{{{*/
+#include<config.h>
+
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/acquire-worker.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/error.h>
+
+#include <stdio.h>
+#include <signal.h>
+#include <iostream>
+#include <unistd.h>
+
+#include "acqprogress.h"
+#include <apti18n.h>
+ /*}}}*/
+
+using namespace std;
+
+// AcqTextStatus::AcqTextStatus - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+AcqTextStatus::AcqTextStatus(unsigned int &ScreenWidth,unsigned int Quiet) :
+ ScreenWidth(ScreenWidth), ID(0), Quiet(Quiet)
+{
+ BlankLine[0] = 0;
+}
+ /*}}}*/
+// AcqTextStatus::Start - Downloading has started /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void AcqTextStatus::Start()
+{
+ pkgAcquireStatus::Start();
+ BlankLine[0] = 0;
+ ID = 1;
+};
+ /*}}}*/
+// AcqTextStatus::IMSHit - Called when an item got a HIT response /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void AcqTextStatus::IMSHit(pkgAcquire::ItemDesc &Itm)
+{
+ if (Quiet > 1)
+ return;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r';
+
+ cout << _("Hit ") << Itm.Description;
+ if (Itm.Owner->FileSize != 0)
+ cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
+ cout << endl;
+ Update = true;
+};
+ /*}}}*/
+// AcqTextStatus::Fetch - An item has started to download /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out the short description and the expected size */
+void AcqTextStatus::Fetch(pkgAcquire::ItemDesc &Itm)
+{
+ Update = true;
+ if (Itm.Owner->Complete == true)
+ return;
+
+ Itm.Owner->ID = ID++;
+
+ if (Quiet > 1)
+ return;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r';
+
+ cout << _("Get:") << Itm.Owner->ID << ' ' << Itm.Description;
+ if (Itm.Owner->FileSize != 0)
+ cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
+ cout << endl;
+};
+ /*}}}*/
+// AcqTextStatus::Done - Completed a download /*{{{*/
+// ---------------------------------------------------------------------
+/* We don't display anything... */
+void AcqTextStatus::Done(pkgAcquire::ItemDesc &Itm)
+{
+ Update = true;
+};
+ /*}}}*/
+// AcqTextStatus::Fail - Called when an item fails to download /*{{{*/
+// ---------------------------------------------------------------------
+/* We print out the error text */
+void AcqTextStatus::Fail(pkgAcquire::ItemDesc &Itm)
+{
+ if (Quiet > 1)
+ return;
+
+ // Ignore certain kinds of transient failures (bad code)
+ if (Itm.Owner->Status == pkgAcquire::Item::StatIdle)
+ return;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r';
+
+ if (Itm.Owner->Status == pkgAcquire::Item::StatDone)
+ {
+ cout << _("Ign ") << Itm.Description << endl;
+ }
+ else
+ {
+ cout << _("Err ") << Itm.Description << endl;
+ cout << " " << Itm.Owner->ErrorText << endl;
+ }
+
+ Update = true;
+};
+ /*}}}*/
+// AcqTextStatus::Stop - Finished downloading /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out the bytes downloaded and the overall average line
+ speed */
+void AcqTextStatus::Stop()
+{
+ pkgAcquireStatus::Stop();
+ if (Quiet > 1)
+ return;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r' << flush;
+
+ if (FetchedBytes != 0 && _error->PendingError() == false)
+ ioprintf(cout,_("Fetched %sB in %s (%sB/s)\n"),
+ SizeToStr(FetchedBytes).c_str(),
+ TimeToStr(ElapsedTime).c_str(),
+ SizeToStr(CurrentCPS).c_str());
+}
+ /*}}}*/
+// AcqTextStatus::Pulse - Regular event pulse /*{{{*/
+// ---------------------------------------------------------------------
+/* This draws the current progress. Each line has an overall percent
+ meter and a per active item status meter along with an overall
+ bandwidth and ETA indicator. */
+bool AcqTextStatus::Pulse(pkgAcquire *Owner)
+{
+ pkgAcquireStatus::Pulse(Owner);
+
+ if (Quiet > 0)
+ return true;
+
+ enum {Long = 0,Medium,Short} Mode = Medium;
+
+ char Buffer[sizeof(BlankLine)];
+ char *End = Buffer + sizeof(Buffer);
+ char *S = Buffer;
+ if (ScreenWidth >= sizeof(Buffer))
+ ScreenWidth = sizeof(Buffer)-1;
+
+ // Put in the percent done
+ sprintf(S,"%.0f%%",((CurrentBytes + CurrentItems)*100.0)/(TotalBytes+TotalItems));
+
+ bool Shown = false;
+ for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0;
+ I = Owner->WorkerStep(I))
+ {
+ S += strlen(S);
+
+ // There is no item running
+ if (I->CurrentItem == 0)
+ {
+ if (I->Status.empty() == false)
+ {
+ snprintf(S,End-S," [%s]",I->Status.c_str());
+ Shown = true;
+ }
+
+ continue;
+ }
+
+ Shown = true;
+
+ // Add in the short description
+ if (I->CurrentItem->Owner->ID != 0)
+ snprintf(S,End-S," [%lu %s",I->CurrentItem->Owner->ID,
+ I->CurrentItem->ShortDesc.c_str());
+ else
+ snprintf(S,End-S," [%s",I->CurrentItem->ShortDesc.c_str());
+ S += strlen(S);
+
+ // Show the short mode string
+ if (I->CurrentItem->Owner->Mode != 0)
+ {
+ snprintf(S,End-S," %s",I->CurrentItem->Owner->Mode);
+ S += strlen(S);
+ }
+
+ // Add the current progress
+ if (Mode == Long)
+ snprintf(S,End-S," %llu",I->CurrentSize);
+ else
+ {
+ if (Mode == Medium || I->TotalSize == 0)
+ snprintf(S,End-S," %sB",SizeToStr(I->CurrentSize).c_str());
+ }
+ S += strlen(S);
+
+ // Add the total size and percent
+ if (I->TotalSize > 0 && I->CurrentItem->Owner->Complete == false)
+ {
+ if (Mode == Short)
+ snprintf(S,End-S," %.0f%%",
+ (I->CurrentSize*100.0)/I->TotalSize);
+ else
+ snprintf(S,End-S,"/%sB %.0f%%",SizeToStr(I->TotalSize).c_str(),
+ (I->CurrentSize*100.0)/I->TotalSize);
+ }
+ S += strlen(S);
+ snprintf(S,End-S,"]");
+ }
+
+ // Show something..
+ if (Shown == false)
+ snprintf(S,End-S,_(" [Working]"));
+
+ /* Put in the ETA and cps meter, block off signals to prevent strangeness
+ during resizing */
+ sigset_t Sigs,OldSigs;
+ sigemptyset(&Sigs);
+ sigaddset(&Sigs,SIGWINCH);
+ sigprocmask(SIG_BLOCK,&Sigs,&OldSigs);
+
+ if (CurrentCPS != 0)
+ {
+ char Tmp[300];
+ unsigned long long ETA = (TotalBytes - CurrentBytes)/CurrentCPS;
+ sprintf(Tmp," %sB/s %s",SizeToStr(CurrentCPS).c_str(),TimeToStr(ETA).c_str());
+ unsigned int Len = strlen(Buffer);
+ unsigned int LenT = strlen(Tmp);
+ if (Len + LenT < ScreenWidth)
+ {
+ memset(Buffer + Len,' ',ScreenWidth - Len);
+ strcpy(Buffer + ScreenWidth - LenT,Tmp);
+ }
+ }
+ Buffer[ScreenWidth] = 0;
+ BlankLine[ScreenWidth] = 0;
+ sigprocmask(SIG_SETMASK,&OldSigs,0);
+
+ // Draw the current status
+ if (_config->FindB("Apt::Color", false) == true)
+ cout << _config->Find("APT::Color::Yellow");
+ if (strlen(Buffer) == strlen(BlankLine))
+ cout << '\r' << Buffer << flush;
+ else
+ cout << '\r' << BlankLine << '\r' << Buffer << flush;
+ if (_config->FindB("Apt::Color", false) == true)
+ cout << _config->Find("APT::Color::Neutral");
+
+ memset(BlankLine,' ',strlen(Buffer));
+ BlankLine[strlen(Buffer)] = 0;
+
+ Update = false;
+
+ return true;
+}
+ /*}}}*/
+// AcqTextStatus::MediaChange - Media need to be swapped /*{{{*/
+// ---------------------------------------------------------------------
+/* Prompt for a media swap */
+bool AcqTextStatus::MediaChange(string Media,string Drive)
+{
+ // If we do not output on a terminal and one of the options to avoid user
+ // interaction is given, we assume that no user is present who could react
+ // on your media change request
+ if (isatty(STDOUT_FILENO) != 1 && Quiet >= 2 &&
+ (_config->FindB("APT::Get::Assume-Yes",false) == true ||
+ _config->FindB("APT::Get::Force-Yes",false) == true ||
+ _config->FindB("APT::Get::Trivial-Only",false) == true))
+
+ return false;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r';
+ ioprintf(cout,_("Media change: please insert the disc labeled\n"
+ " '%s'\n"
+ "in the drive '%s' and press enter\n"),
+ Media.c_str(),Drive.c_str());
+
+ char C = 0;
+ bool bStatus = true;
+ while (C != '\n' && C != '\r')
+ {
+ int len = read(STDIN_FILENO,&C,1);
+ if(C == 'c' || len <= 0)
+ bStatus = false;
+ }
+
+ if(bStatus)
+ Update = true;
+ return bStatus;
+}
+ /*}}}*/
diff --git a/apt-private/acqprogress.h b/apt-private/acqprogress.h
new file mode 100644
index 000000000..e47bfb72d
--- /dev/null
+++ b/apt-private/acqprogress.h
@@ -0,0 +1,38 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* ######################################################################
+
+ Acquire Progress - Command line progress meter
+
+ ##################################################################### */
+ /*}}}*/
+#ifndef ACQPROGRESS_H
+#define ACQPROGRESS_H
+
+#include <apt-pkg/acquire.h>
+
+#include <string>
+
+class AcqTextStatus : public pkgAcquireStatus
+{
+ unsigned int &ScreenWidth;
+ char BlankLine[1024];
+ unsigned long ID;
+ unsigned long Quiet;
+
+ public:
+
+ virtual bool MediaChange(std::string Media,std::string Drive);
+ virtual void IMSHit(pkgAcquire::ItemDesc &Itm);
+ virtual void Fetch(pkgAcquire::ItemDesc &Itm);
+ virtual void Done(pkgAcquire::ItemDesc &Itm);
+ virtual void Fail(pkgAcquire::ItemDesc &Itm);
+ virtual void Start();
+ virtual void Stop();
+
+ bool Pulse(pkgAcquire *Owner);
+
+ AcqTextStatus(unsigned int &ScreenWidth,unsigned int Quiet);
+};
+
+#endif
diff --git a/apt-private/makefile b/apt-private/makefile
new file mode 100644
index 000000000..8feb1ce6c
--- /dev/null
+++ b/apt-private/makefile
@@ -0,0 +1,28 @@
+# -*- make -*-
+BASE=..
+SUBDIR=apt-private
+
+# Header location
+HEADER_TARGETDIRS = apt-private
+
+# Bring in the default rules
+include ../buildlib/defaults.mak
+
+# The library name and version (indirectly used from init.h)
+include ../buildlib/libversion.mak
+
+# The library name
+LIBRARY=apt-private
+MAJOR=0.0
+MINOR=0
+SLIBS=$(PTHREADLIB) -lapt-pkg
+
+PRIVATES=list install output cachefile cacheset update upgrade cmndline moo search show main
+SOURCE += $(foreach private, $(PRIVATES), private-$(private).cc)
+HEADERS += $(foreach private, $(PRIVATES), private-$(private).h)
+
+SOURCE+= acqprogress.cc
+HEADERS+= acqprogress.h private-cacheset.h
+
+HEADERS := $(addprefix apt-private/,$(HEADERS))
+include $(LIBRARY_H)
diff --git a/apt-private/private-cachefile.cc b/apt-private/private-cachefile.cc
new file mode 100644
index 000000000..25f65ef09
--- /dev/null
+++ b/apt-private/private-cachefile.cc
@@ -0,0 +1,109 @@
+// Include files /*{{{*/
+#include<config.h>
+
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/error.h>
+
+#include <cstdlib>
+
+#include "private-output.h"
+#include "private-cachefile.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+using namespace std;
+
+// CacheFile::NameComp - QSort compare by name /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgCache *CacheFile::SortCache = 0;
+int CacheFile::NameComp(const void *a,const void *b)
+{
+ if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0)
+ return *(pkgCache::Package **)a - *(pkgCache::Package **)b;
+
+ const pkgCache::Package &A = **(pkgCache::Package **)a;
+ const pkgCache::Package &B = **(pkgCache::Package **)b;
+
+ return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name);
+}
+ /*}}}*/
+// CacheFile::Sort - Sort by name /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void CacheFile::Sort()
+{
+ delete [] List;
+ List = new pkgCache::Package *[Cache->Head().PackageCount];
+ memset(List,0,sizeof(*List)*Cache->Head().PackageCount);
+ pkgCache::PkgIterator I = Cache->PkgBegin();
+ for (;I.end() != true; ++I)
+ List[I->ID] = I;
+
+ SortCache = *this;
+ qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp);
+}
+ /*}}}*/
+// CacheFile::CheckDeps - Open the cache file /*{{{*/
+// ---------------------------------------------------------------------
+/* This routine generates the caches and then opens the dependency cache
+ and verifies that the system is OK. */
+bool CacheFile::CheckDeps(bool AllowBroken)
+{
+ bool FixBroken = _config->FindB("APT::Get::Fix-Broken",false);
+
+ if (_error->PendingError() == true)
+ return false;
+
+ // Check that the system is OK
+ if (DCache->DelCount() != 0 || DCache->InstCount() != 0)
+ return _error->Error("Internal error, non-zero counts");
+
+ // Apply corrections for half-installed packages
+ if (pkgApplyStatus(*DCache) == false)
+ return false;
+
+ if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true)
+ {
+ FixBroken = true;
+ if ((DCache->PolicyBrokenCount() > 0))
+ {
+ // upgrade all policy-broken packages with ForceImportantDeps=True
+ for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); ++I)
+ if ((*DCache)[I].NowPolicyBroken() == true)
+ DCache->MarkInstall(I,true,0, false, true);
+ }
+ }
+
+ // Nothing is broken
+ if (DCache->BrokenCount() == 0 || AllowBroken == true)
+ return true;
+
+ // Attempt to fix broken things
+ if (FixBroken == true)
+ {
+ c1out << _("Correcting dependencies...") << flush;
+ if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
+ {
+ c1out << _(" failed.") << endl;
+ ShowBroken(c1out,*this,true);
+
+ return _error->Error(_("Unable to correct dependencies"));
+ }
+ if (pkgMinimizeUpgrade(*DCache) == false)
+ return _error->Error(_("Unable to minimize the upgrade set"));
+
+ c1out << _(" Done") << endl;
+ }
+ else
+ {
+ c1out << _("You might want to run 'apt-get -f install' to correct these.") << endl;
+ ShowBroken(c1out,*this,true);
+
+ return _error->Error(_("Unmet dependencies. Try using -f."));
+ }
+
+ return true;
+}
+ /*}}}*/
diff --git a/apt-private/private-cachefile.h b/apt-private/private-cachefile.h
new file mode 100644
index 000000000..f24d93020
--- /dev/null
+++ b/apt-private/private-cachefile.h
@@ -0,0 +1,51 @@
+#ifndef APT_PRIVATE_CACHEFILE_H
+#define APT_PRIVATE_CACHEFILE_H
+
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/progress.h>
+
+
+// class CacheFile - Cover class for some dependency cache functions /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+class CacheFile : public pkgCacheFile
+{
+ static pkgCache *SortCache;
+ static int NameComp(const void *a,const void *b);
+
+ public:
+ pkgCache::Package **List;
+
+ void Sort();
+ bool CheckDeps(bool AllowBroken = false);
+ bool BuildCaches(bool WithLock = true)
+ {
+ OpTextProgress Prog(*_config);
+ if (pkgCacheFile::BuildCaches(&Prog,WithLock) == false)
+ return false;
+ return true;
+ }
+ bool Open(bool WithLock = true)
+ {
+ OpTextProgress Prog(*_config);
+ if (pkgCacheFile::Open(&Prog,WithLock) == false)
+ return false;
+ Sort();
+
+ return true;
+ };
+ bool OpenForInstall()
+ {
+ if (_config->FindB("APT::Get::Print-URIs") == true)
+ return Open(false);
+ else
+ return Open(true);
+ }
+ CacheFile() : List(0) {};
+ ~CacheFile() {
+ delete[] List;
+ }
+};
+ /*}}}*/
+
+#endif
diff --git a/apt-private/private-cacheset.cc b/apt-private/private-cacheset.cc
new file mode 100644
index 000000000..6fb224010
--- /dev/null
+++ b/apt-private/private-cacheset.cc
@@ -0,0 +1,63 @@
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/strutl.h>
+
+#include "private-cacheset.h"
+
+bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
+ LocalitySortedVersionSet &output_set,
+ OpProgress &progress)
+{
+ Matcher null_matcher = Matcher();
+ return GetLocalitySortedVersionSet(CacheFile, output_set,
+ null_matcher, progress);
+}
+
+bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
+ LocalitySortedVersionSet &output_set,
+ Matcher &matcher,
+ OpProgress &progress)
+{
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ pkgDepCache *DepCache = CacheFile.GetDepCache();
+
+ int Done=0;
+ progress.SubProgress(Cache->Head().PackageCount, _("Sorting"));
+ for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
+ {
+ if (Done%500 == 0)
+ progress.Progress(Done);
+ Done++;
+
+ if ((matcher)(P) == false)
+ continue;
+
+ // exclude virtual pkgs
+ if (P.VersionList() == 0)
+ continue;
+ pkgDepCache::StateCache &state = (*DepCache)[P];
+ if (_config->FindB("APT::Cmd::Installed") == true)
+ {
+ if (P.CurrentVer() != NULL)
+ {
+ output_set.insert(P.CurrentVer());
+ }
+ }
+ else if (_config->FindB("APT::Cmd::Upgradable") == true)
+ {
+ if(P.CurrentVer() && state.Upgradable())
+ {
+ pkgPolicy *policy = CacheFile.GetPolicy();
+ output_set.insert(policy->GetCandidateVer(P));
+ }
+ }
+ else
+ {
+ pkgPolicy *policy = CacheFile.GetPolicy();
+ output_set.insert(policy->GetCandidateVer(P));
+ }
+ }
+ progress.Done();
+ return true;
+}
diff --git a/apt-private/private-cacheset.h b/apt-private/private-cacheset.h
new file mode 100644
index 000000000..15b531e9d
--- /dev/null
+++ b/apt-private/private-cacheset.h
@@ -0,0 +1,265 @@
+#ifndef APT_PRIVATE_CACHESET_H
+#define APT_PRIVATE_CACHESET_H
+
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/sptr.h>
+
+#include <algorithm>
+#include <vector>
+
+#include "private-output.h"
+
+#include <apti18n.h>
+
+struct VersionSortDescriptionLocality
+{
+ bool operator () (const pkgCache::VerIterator &v_lhs,
+ const pkgCache::VerIterator &v_rhs)
+ {
+ pkgCache::DescFile *A = v_lhs.TranslatedDescription().FileList();
+ pkgCache::DescFile *B = v_rhs.TranslatedDescription().FileList();
+ if (A == 0 && B == 0)
+ return false;
+
+ if (A == 0)
+ return true;
+
+ if (B == 0)
+ return false;
+
+ if (A->File == B->File)
+ return A->Offset < B->Offset;
+
+ return A->File < B->File;
+ }
+};
+
+// sorted by locality which makes iterating much faster
+typedef APT::VersionContainer<
+ std::set<pkgCache::VerIterator,
+ VersionSortDescriptionLocality> > LocalitySortedVersionSet;
+
+class Matcher {
+public:
+ virtual bool operator () (const pkgCache::PkgIterator &P) {
+ return true;};
+};
+
+// FIXME: add default argument for OpProgress (or overloaded function)
+bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
+ LocalitySortedVersionSet &output_set,
+ Matcher &matcher,
+ OpProgress &progress);
+bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
+ LocalitySortedVersionSet &output_set,
+ OpProgress &progress);
+
+
+// CacheSetHelper saving virtual packages /*{{{*/
+class CacheSetHelperVirtuals: public APT::CacheSetHelper {
+public:
+ APT::PackageSet virtualPkgs;
+
+ virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ virtualPkgs.insert(Pkg);
+ return CacheSetHelper::canNotFindCandidateVer(Cache, Pkg);
+ }
+
+ virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ virtualPkgs.insert(Pkg);
+ return CacheSetHelper::canNotFindNewestVer(Cache, Pkg);
+ }
+
+ virtual void canNotFindAllVer(APT::VersionContainerInterface * vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ virtualPkgs.insert(Pkg);
+ CacheSetHelper::canNotFindAllVer(vci, Cache, Pkg);
+ }
+
+ CacheSetHelperVirtuals(bool const ShowErrors = true, GlobalError::MsgType const &ErrorType = GlobalError::NOTICE) : CacheSetHelper(ShowErrors, ErrorType) {}
+};
+ /*}}}*/
+
+// CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/
+class CacheSetHelperAPTGet : public APT::CacheSetHelper {
+ /** \brief stream message should be printed to */
+ std::ostream &out;
+ /** \brief were things like Task or RegEx used to select packages? */
+ bool explicitlyNamed;
+
+ APT::PackageSet virtualPkgs;
+
+public:
+ std::list<std::pair<pkgCache::VerIterator, std::string> > selectedByRelease;
+
+ CacheSetHelperAPTGet(std::ostream &out) : APT::CacheSetHelper(true), out(out) {
+ explicitlyNamed = true;
+ }
+
+ virtual void showTaskSelection(pkgCache::PkgIterator const &Pkg, std::string const &pattern) {
+ ioprintf(out, _("Note, selecting '%s' for task '%s'\n"),
+ Pkg.FullName(true).c_str(), pattern.c_str());
+ explicitlyNamed = false;
+ }
+ virtual void showRegExSelection(pkgCache::PkgIterator const &Pkg, std::string const &pattern) {
+ ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"),
+ Pkg.FullName(true).c_str(), pattern.c_str());
+ explicitlyNamed = false;
+ }
+ virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
+ std::string const &ver, bool const verIsRel) {
+ if (ver == Ver.VerStr())
+ return;
+ selectedByRelease.push_back(make_pair(Ver, ver));
+ }
+
+ bool showVirtualPackageErrors(pkgCacheFile &Cache) {
+ if (virtualPkgs.empty() == true)
+ return true;
+ for (APT::PackageSet::const_iterator Pkg = virtualPkgs.begin();
+ Pkg != virtualPkgs.end(); ++Pkg) {
+ if (Pkg->ProvidesList != 0) {
+ ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
+ Pkg.FullName(true).c_str());
+
+ pkgCache::PrvIterator I = Pkg.ProvidesList();
+ unsigned short provider = 0;
+ for (; I.end() == false; ++I) {
+ pkgCache::PkgIterator Pkg = I.OwnerPkg();
+
+ if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) {
+ c1out << " " << Pkg.FullName(true) << " " << I.OwnerVer().VerStr();
+ if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
+ c1out << _(" [Installed]");
+ c1out << std::endl;
+ ++provider;
+ }
+ }
+ // if we found no candidate which provide this package, show non-candidates
+ if (provider == 0)
+ for (I = Pkg.ProvidesList(); I.end() == false; ++I)
+ c1out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr()
+ << _(" [Not candidate version]") << std::endl;
+ else
+ out << _("You should explicitly select one to install.") << std::endl;
+ } else {
+ ioprintf(c1out,
+ _("Package %s is not available, but is referred to by another package.\n"
+ "This may mean that the package is missing, has been obsoleted, or\n"
+ "is only available from another source\n"),Pkg.FullName(true).c_str());
+
+ std::string List;
+ std::string VersionsList;
+ SPtrArray<bool> Seen = new bool[Cache.GetPkgCache()->Head().PackageCount];
+ memset(Seen,0,Cache.GetPkgCache()->Head().PackageCount*sizeof(*Seen));
+ for (pkgCache::DepIterator Dep = Pkg.RevDependsList();
+ Dep.end() == false; ++Dep) {
+ if (Dep->Type != pkgCache::Dep::Replaces)
+ continue;
+ if (Seen[Dep.ParentPkg()->ID] == true)
+ continue;
+ Seen[Dep.ParentPkg()->ID] = true;
+ List += Dep.ParentPkg().FullName(true) + " ";
+ //VersionsList += std::string(Dep.ParentPkg().CurVersion) + "\n"; ???
+ }
+ ShowList(c1out,_("However the following packages replace it:"),List,VersionsList);
+ }
+ c1out << std::endl;
+ }
+ return false;
+ }
+
+ virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDIDATE);
+ if (verset.empty() == false)
+ return *(verset.begin());
+ else if (ShowError == true) {
+ _error->Error(_("Package '%s' has no installation candidate"),Pkg.FullName(true).c_str());
+ virtualPkgs.insert(Pkg);
+ }
+ return pkgCache::VerIterator(Cache, 0);
+ }
+
+ virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ if (Pkg->ProvidesList != 0)
+ {
+ APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST);
+ if (verset.empty() == false)
+ return *(verset.begin());
+ if (ShowError == true)
+ ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str());
+ }
+ else
+ {
+ pkgCache::GrpIterator Grp = Pkg.Group();
+ pkgCache::PkgIterator P = Grp.PackageList();
+ for (; P.end() != true; P = Grp.NextPkg(P))
+ {
+ if (P == Pkg)
+ continue;
+ if (P->CurrentVer != 0) {
+ // TRANSLATORS: Note, this is not an interactive question
+ ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
+ Pkg.FullName(true).c_str(), P.FullName(true).c_str());
+ break;
+ }
+ }
+ if (P.end() == true)
+ ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str());
+ }
+ return pkgCache::VerIterator(Cache, 0);
+ }
+
+ APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg,
+ APT::VersionSet::Version const &select) {
+ /* This is a pure virtual package and there is a single available
+ candidate providing it. */
+ if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0)
+ return APT::VersionSet();
+
+ pkgCache::PkgIterator Prov;
+ bool found_one = false;
+ for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) {
+ pkgCache::VerIterator const PVer = P.OwnerVer();
+ pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
+
+ /* Ignore versions that are not a candidate. */
+ if (Cache[PPkg].CandidateVer != PVer)
+ continue;
+
+ if (found_one == false) {
+ Prov = PPkg;
+ found_one = true;
+ } else if (PPkg != Prov) {
+ // same group, so it's a foreign package
+ if (PPkg->Group == Prov->Group) {
+ // do we already have the requested arch?
+ if (strcmp(Pkg.Arch(), Prov.Arch()) == 0 ||
+ strcmp(Prov.Arch(), "all") == 0 ||
+ unlikely(strcmp(PPkg.Arch(), Prov.Arch()) == 0)) // packages have only on candidate, but just to be sure
+ continue;
+ // see which architecture we prefer more and switch to it
+ std::vector<std::string> archs = APT::Configuration::getArchitectures();
+ if (std::find(archs.begin(), archs.end(), PPkg.Arch()) < std::find(archs.begin(), archs.end(), Prov.Arch()))
+ Prov = PPkg;
+ continue;
+ }
+ found_one = false; // we found at least two
+ break;
+ }
+ }
+
+ if (found_one == true) {
+ ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"),
+ Prov.FullName(true).c_str(), Pkg.FullName(true).c_str());
+ return APT::VersionSet::FromPackage(Cache, Prov, select, *this);
+ }
+ return APT::VersionSet();
+ }
+
+ inline bool allPkgNamedExplicitly() const { return explicitlyNamed; }
+
+};
+ /*}}}*/
+
+#endif
diff --git a/apt-private/private-cmndline.cc b/apt-private/private-cmndline.cc
new file mode 100644
index 000000000..aceb865d5
--- /dev/null
+++ b/apt-private/private-cmndline.cc
@@ -0,0 +1,268 @@
+// Include Files /*{{{*/
+#include <config.h>
+
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/configuration.h>
+
+#include <vector>
+
+#include <stdarg.h>
+#include <string.h>
+
+#include "private-cmndline.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+bool strcmp_match_in_list(char const * const Cmd, ...) /*{{{*/
+{
+ va_list args;
+ bool found = false;
+ va_start(args, Cmd);
+ char const * Match = NULL;
+ while ((Match = va_arg(args, char const *)) != NULL)
+ {
+ if (strcmp(Cmd, Match) != 0)
+ continue;
+ found = true;
+ break;
+ }
+ va_end(args);
+ return found;
+}
+ /*}}}*/
+#define addArg(w,x,y,z) Args.push_back(CommandLine::MakeArgs(w,x,y,z))
+#define CmdMatches(...) strcmp_match_in_list(Cmd, __VA_ARGS__, NULL)
+bool addArgumentsAPTCache(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
+{
+ if (CmdMatches("depends", "rdepends", "xvcg", "dotty"))
+ {
+ addArg('i', "important", "APT::Cache::Important", 0);
+ addArg(0, "installed", "APT::Cache::Installed", 0);
+ addArg(0, "pre-depends", "APT::Cache::ShowPre-Depends", 0);
+ addArg(0, "depends", "APT::Cache::ShowDepends", 0);
+ addArg(0, "recommends", "APT::Cache::ShowRecommends", 0);
+ addArg(0, "suggests", "APT::Cache::ShowSuggests", 0);
+ addArg(0, "replaces", "APT::Cache::ShowReplaces", 0);
+ addArg(0, "breaks", "APT::Cache::ShowBreaks", 0);
+ addArg(0, "conflicts", "APT::Cache::ShowConflicts", 0);
+ addArg(0, "enhances", "APT::Cache::ShowEnhances", 0);
+ addArg(0, "recurse", "APT::Cache::RecurseDepends", 0);
+ }
+ else if (CmdMatches("search"))
+ {
+ addArg('n', "names-only", "APT::Cache::NamesOnly", 0);
+ addArg('f', "full", "APT::Cache::ShowFull", 0);
+ }
+ else if (CmdMatches("show"))
+ {
+ addArg('a', "all-versions", "APT::Cache::AllVersions", 0);
+ }
+ else if (CmdMatches("pkgnames"))
+ {
+ addArg(0, "all-names", "APT::Cache::AllNames", 0);
+ }
+ else if (CmdMatches("gencaches", "showsrc", "showpkg", "stats", "dump",
+ "dumpavail", "unmet", "showauto", "policy", "madison"))
+ ;
+ else
+ return false;
+
+ // FIXME: move to the correct command(s)
+ addArg('g', "generate", "APT::Cache::Generate", 0);
+ addArg('t', "target-release", "APT::Default-Release", CommandLine::HasArg);
+ addArg('t', "default-release", "APT::Default-Release", CommandLine::HasArg);
+
+ addArg('p', "pkg-cache", "Dir::Cache::pkgcache", CommandLine::HasArg);
+ addArg('s', "src-cache", "Dir::Cache::srcpkgcache", CommandLine::HasArg);
+ return true;
+}
+ /*}}}*/
+bool addArgumentsAPTCDROM(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
+{
+ if (CmdMatches("add", "ident") == false)
+ return false;
+
+ // FIXME: move to the correct command(s)
+ addArg(0, "auto-detect", "Acquire::cdrom::AutoDetect", CommandLine::Boolean);
+ addArg('d', "cdrom", "Acquire::cdrom::mount", CommandLine::HasArg);
+ addArg('r', "rename", "APT::CDROM::Rename", 0);
+ addArg('m', "no-mount", "APT::CDROM::NoMount", 0);
+ addArg('f', "fast", "APT::CDROM::Fast", 0);
+ addArg('n', "just-print", "APT::CDROM::NoAct", 0);
+ addArg('n', "recon", "APT::CDROM::NoAct", 0);
+ addArg('n', "no-act", "APT::CDROM::NoAct", 0);
+ addArg('a', "thorough", "APT::CDROM::Thorough", 0);
+ return true;
+}
+ /*}}}*/
+bool addArgumentsAPTConfig(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
+{
+ if (CmdMatches("dump"))
+ {
+ addArg(0,"empty","APT::Config::Dump::EmptyValue",CommandLine::Boolean);
+ addArg(0,"format","APT::Config::Dump::Format",CommandLine::HasArg);
+ }
+ else if (CmdMatches("shell"))
+ ;
+ else
+ return false;
+
+ return true;
+}
+ /*}}}*/
+bool addArgumentsAPTGet(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
+{
+ if (CmdMatches("install", "remove", "purge", "upgrade", "dist-upgrade",
+ "deselect-upgrade", "autoremove"))
+ {
+ addArg(0, "dpkg-progress", "DpkgPM::Progress", 0);
+ addArg('f', "fix-broken", "APT::Get::Fix-Broken", 0);
+ addArg(0, "purge", "APT::Get::Purge", 0);
+ addArg('V',"verbose-versions","APT::Get::Show-Versions",0);
+ addArg(0, "auto-remove", "APT::Get::AutomaticRemove", 0);
+ addArg(0, "reinstall", "APT::Get::ReInstall", 0);
+ addArg(0, "solver", "APT::Solver", CommandLine::HasArg);
+ if (CmdMatches("upgrade"))
+ {
+ addArg(0, "allow-new", "APT::Get::UpgradeAllowNew", 0);
+ }
+ }
+ else if (CmdMatches("update"))
+ {
+ addArg(0, "list-cleanup", "APT::Get::List-Cleanup", 0);
+ }
+ else if (CmdMatches("source"))
+ {
+ addArg('b', "compile", "APT::Get::Compile", 0);
+ addArg('b', "build", "APT::Get::Compile", 0);
+ addArg(0, "diff-only", "APT::Get::Diff-Only", 0);
+ addArg(0, "debian-only", "APT::Get::Diff-Only", 0);
+ addArg(0, "tar-only", "APT::Get::Tar-Only", 0);
+ addArg(0, "dsc-only", "APT::Get::Dsc-Only", 0);
+ }
+ else if (CmdMatches("build-dep"))
+ {
+ addArg('a', "host-architecture", "APT::Get::Host-Architecture", CommandLine::HasArg);
+ addArg(0, "solver", "APT::Solver", CommandLine::HasArg);
+ }
+ else if (CmdMatches("clean", "autoclean", "check", "download", "changelog") ||
+ CmdMatches("markauto", "unmarkauto")) // deprecated commands
+ ;
+ else if (CmdMatches("moo"))
+ addArg(0, "color", "APT::Moo::Color", 0);
+
+ if (CmdMatches("install", "remove", "purge", "upgrade", "dist-upgrade",
+ "deselect-upgrade", "autoremove", "clean", "autoclean", "check",
+ "build-dep"))
+ {
+ addArg('s', "simulate", "APT::Get::Simulate", 0);
+ addArg('s', "just-print", "APT::Get::Simulate", 0);
+ addArg('s', "recon", "APT::Get::Simulate", 0);
+ addArg('s', "dry-run", "APT::Get::Simulate", 0);
+ addArg('s', "no-act", "APT::Get::Simulate", 0);
+ }
+
+ // FIXME: move to the correct command(s)
+ addArg('d',"download-only","APT::Get::Download-Only",0);
+ addArg('y',"yes","APT::Get::Assume-Yes",0);
+ addArg('y',"assume-yes","APT::Get::Assume-Yes",0);
+ addArg(0,"assume-no","APT::Get::Assume-No",0);
+ addArg('u',"show-upgraded","APT::Get::Show-Upgraded",0);
+ addArg('m',"ignore-missing","APT::Get::Fix-Missing",0);
+ addArg('t',"target-release","APT::Default-Release",CommandLine::HasArg);
+ addArg('t',"default-release","APT::Default-Release",CommandLine::HasArg);
+ addArg(0,"download","APT::Get::Download",0);
+ addArg(0,"fix-missing","APT::Get::Fix-Missing",0);
+ addArg(0,"ignore-hold","APT::Ignore-Hold",0);
+ addArg(0,"upgrade","APT::Get::upgrade",0);
+ addArg(0,"only-upgrade","APT::Get::Only-Upgrade",0);
+ addArg(0,"force-yes","APT::Get::force-yes",0);
+ addArg(0,"print-uris","APT::Get::Print-URIs",0);
+ addArg(0,"trivial-only","APT::Get::Trivial-Only",0);
+ addArg(0,"remove","APT::Get::Remove",0);
+ addArg(0,"only-source","APT::Get::Only-Source",0);
+ addArg(0,"arch-only","APT::Get::Arch-Only",0);
+ addArg(0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0);
+ addArg(0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean);
+ addArg(0,"install-suggests","APT::Install-Suggests",CommandLine::Boolean);
+ addArg(0,"fix-policy","APT::Get::Fix-Policy-Broken",0);
+
+ return true;
+}
+ /*}}}*/
+bool addArgumentsAPTMark(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
+{
+ if (CmdMatches("auto", "manual", "hold", "unhold", "showauto",
+ "showmanual", "showhold", "showholds", "install",
+ "markauto", "unmarkauto"))
+ ;
+ else
+ return false;
+
+ addArg('v',"verbose","APT::MarkAuto::Verbose",0);
+ addArg('s',"simulate","APT::Mark::Simulate",0);
+ addArg('s',"just-print","APT::Mark::Simulate",0);
+ addArg('s',"recon","APT::Mark::Simulate",0);
+ addArg('s',"dry-run","APT::Mark::Simulate",0);
+ addArg('s',"no-act","APT::Mark::Simulate",0);
+ addArg('f',"file","Dir::State::extended_states",CommandLine::HasArg);
+
+ return true;
+}
+ /*}}}*/
+bool addArgumentsAPT(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
+{
+ if (CmdMatches("list"))
+ {
+ addArg(0,"installed","APT::Cmd::Installed",0);
+ addArg(0,"upgradable","APT::Cmd::Upgradable",0);
+ addArg('a', "all-versions", "APT::Cmd::AllVersions", 0);
+ }
+ else if (addArgumentsAPTGet(Args, Cmd) || addArgumentsAPTCache(Args, Cmd))
+ {
+ // we have no (supported) command-name overlaps so far, so we call
+ // specifics in order until we find one which adds arguments
+ }
+ else
+ return false;
+
+ return true;
+}
+ /*}}}*/
+std::vector<CommandLine::Args> getCommandArgs(char const * const Program, char const * const Cmd)/*{{{*/
+{
+ std::vector<CommandLine::Args> Args;
+ Args.reserve(50);
+ if (Program == NULL || Cmd == NULL)
+ ; // FIXME: Invalid command supplied
+ else if (strcmp(Cmd, "help") == 0)
+ ; // no options for help so no need to implement it in each
+ else if (strcmp(Program, "apt-get") == 0)
+ addArgumentsAPTGet(Args, Cmd);
+ else if (strcmp(Program, "apt-cache") == 0)
+ addArgumentsAPTCache(Args, Cmd);
+ else if (strcmp(Program, "apt-cdrom") == 0)
+ addArgumentsAPTCDROM(Args, Cmd);
+ else if (strcmp(Program, "apt-config") == 0)
+ addArgumentsAPTConfig(Args, Cmd);
+ else if (strcmp(Program, "apt-mark") == 0)
+ addArgumentsAPTMark(Args, Cmd);
+ else if (strcmp(Program, "apt") == 0)
+ addArgumentsAPT(Args, Cmd);
+
+ // options without a command
+ addArg('h', "help", "help", 0);
+ addArg('v', "version", "version", 0);
+ // general options
+ addArg('q', "quiet", "quiet", CommandLine::IntLevel);
+ addArg('q', "silent", "quiet", CommandLine::IntLevel);
+ addArg('c', "config-file", 0, CommandLine::ConfigFile);
+ addArg('o', "option", 0, CommandLine::ArbItem);
+ addArg(0, NULL, NULL, 0);
+
+ return Args;
+}
+ /*}}}*/
+#undef CmdMatches
+#undef addArg
diff --git a/apt-private/private-cmndline.h b/apt-private/private-cmndline.h
new file mode 100644
index 000000000..76045ffe7
--- /dev/null
+++ b/apt-private/private-cmndline.h
@@ -0,0 +1,10 @@
+#ifndef APT_PRIVATE_CMNDLINE_H
+#define APT_PRIVATE_CMNDLINE_H
+
+#include <apt-pkg/cmndline.h>
+
+#include <vector>
+
+std::vector<CommandLine::Args> getCommandArgs(char const * const Program, char const * const Cmd);
+
+#endif
diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc
new file mode 100644
index 000000000..d5052fcc0
--- /dev/null
+++ b/apt-private/private-install.cc
@@ -0,0 +1,852 @@
+// Include Files /*{{{*/
+#include <config.h>
+
+#include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/clean.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/md5.h>
+#include <apt-pkg/versionmatch.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/indexfile.h>
+
+#include <set>
+#include <locale.h>
+#include <langinfo.h>
+#include <fstream>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <regex.h>
+#include <sys/wait.h>
+#include <sstream>
+
+#include "private-install.h"
+#include "private-cachefile.h"
+#include "private-output.h"
+#include "private-cacheset.h"
+#include "acqprogress.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+// CheckAuth - check if each download comes form a trusted source /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+static bool CheckAuth(pkgAcquire& Fetcher)
+{
+ std::string UntrustedList;
+ for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I)
+ {
+ if (!(*I)->IsTrusted())
+ {
+ UntrustedList += std::string((*I)->ShortDesc()) + " ";
+ }
+ }
+
+ if (UntrustedList == "")
+ {
+ return true;
+ }
+
+ ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,"");
+
+ if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true)
+ {
+ c2out << _("Authentication warning overridden.\n");
+ return true;
+ }
+
+ if (_config->FindI("quiet",0) < 2
+ && _config->FindB("APT::Get::Assume-Yes",false) == false)
+ {
+ c2out << _("Install these packages without verification?") << std::flush;
+ if (!YnPrompt(false))
+ return _error->Error(_("Some packages could not be authenticated"));
+
+ return true;
+ }
+ else if (_config->FindB("APT::Get::Force-Yes",false) == true)
+ {
+ return true;
+ }
+
+ return _error->Error(_("There are problems and -y was used without --force-yes"));
+}
+ /*}}}*/
+
+
+// InstallPackages - Actually download and install the packages /*{{{*/
+// ---------------------------------------------------------------------
+/* This displays the informative messages describing what is going to
+ happen and then calls the download routines */
+bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
+{
+ if (_config->FindB("APT::Get::Purge",false) == true)
+ {
+ pkgCache::PkgIterator I = Cache->PkgBegin();
+ for (; I.end() == false; ++I)
+ {
+ if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
+ Cache->MarkDelete(I,true);
+ }
+ }
+
+ bool Fail = false;
+ bool Essential = false;
+
+ // Show all the various warning indicators
+ ShowDel(c1out,Cache);
+ ShowNew(c1out,Cache);
+ if (ShwKept == true)
+ ShowKept(c1out,Cache);
+ Fail |= !ShowHold(c1out,Cache);
+ if (_config->FindB("APT::Get::Show-Upgraded",true) == true)
+ ShowUpgraded(c1out,Cache);
+ Fail |= !ShowDowngraded(c1out,Cache);
+ if (_config->FindB("APT::Get::Download-Only",false) == false)
+ Essential = !ShowEssential(c1out,Cache);
+ Fail |= Essential;
+ Stats(c1out,Cache);
+
+ // Sanity check
+ if (Cache->BrokenCount() != 0)
+ {
+ ShowBroken(c1out,Cache,false);
+ return _error->Error(_("Internal error, InstallPackages was called with broken packages!"));
+ }
+
+ if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
+ Cache->BadCount() == 0)
+ return true;
+
+ // No remove flag
+ if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
+ return _error->Error(_("Packages need to be removed but remove is disabled."));
+
+ // Run the simulator ..
+ if (_config->FindB("APT::Get::Simulate") == true)
+ {
+ pkgSimulate PM(Cache);
+ int status_fd = _config->FindI("APT::Status-Fd",-1);
+ pkgPackageManager::OrderResult Res = PM.DoInstall(status_fd);
+ if (Res == pkgPackageManager::Failed)
+ return false;
+ if (Res != pkgPackageManager::Completed)
+ return _error->Error(_("Internal error, Ordering didn't finish"));
+ return true;
+ }
+
+ // Create the text record parser
+ pkgRecords Recs(Cache);
+ if (_error->PendingError() == true)
+ return false;
+
+ // Create the download object
+ pkgAcquire Fetcher;
+ AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
+ if (_config->FindB("APT::Get::Print-URIs", false) == true)
+ {
+ // force a hashsum for compatibility reasons
+ _config->CndSet("Acquire::ForceHash", "md5sum");
+ }
+ else if (Fetcher.Setup(&Stat, _config->FindDir("Dir::Cache::Archives")) == false)
+ return false;
+
+ // Read the source list
+ if (Cache.BuildSourceList() == false)
+ return false;
+ pkgSourceList *List = Cache.GetSourceList();
+
+ // Create the package manager and prepare to download
+ SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
+ if (PM->GetArchives(&Fetcher,List,&Recs) == false ||
+ _error->PendingError() == true)
+ return false;
+
+ // Display statistics
+ unsigned long long FetchBytes = Fetcher.FetchNeeded();
+ unsigned long long FetchPBytes = Fetcher.PartialPresent();
+ unsigned long long DebBytes = Fetcher.TotalNeeded();
+ if (DebBytes != Cache->DebSize())
+ {
+ c0out << DebBytes << ',' << Cache->DebSize() << std::endl;
+ c0out << _("How odd.. The sizes didn't match, email apt@packages.debian.org") << std::endl;
+ }
+
+ // Number of bytes
+ if (DebBytes != FetchBytes)
+ //TRANSLATOR: The required space between number and unit is already included
+ // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
+ ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
+ SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
+ else if (DebBytes != 0)
+ //TRANSLATOR: The required space between number and unit is already included
+ // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
+ ioprintf(c1out,_("Need to get %sB of archives.\n"),
+ SizeToStr(DebBytes).c_str());
+
+ // Size delta
+ if (Cache->UsrSize() >= 0)
+ //TRANSLATOR: The required space between number and unit is already included
+ // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
+ ioprintf(c1out,_("After this operation, %sB of additional disk space will be used.\n"),
+ SizeToStr(Cache->UsrSize()).c_str());
+ else
+ //TRANSLATOR: The required space between number and unit is already included
+ // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
+ ioprintf(c1out,_("After this operation, %sB disk space will be freed.\n"),
+ SizeToStr(-1*Cache->UsrSize()).c_str());
+
+ if (_error->PendingError() == true)
+ return false;
+
+ /* Check for enough free space, but only if we are actually going to
+ download */
+ if (_config->FindB("APT::Get::Print-URIs") == false &&
+ _config->FindB("APT::Get::Download",true) == true)
+ {
+ struct statvfs Buf;
+ std::string OutputDir = _config->FindDir("Dir::Cache::Archives");
+ 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());
+ }
+ }
+
+ // Fail safe check
+ if (_config->FindI("quiet",0) >= 2 ||
+ _config->FindB("APT::Get::Assume-Yes",false) == true)
+ {
+ if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
+ return _error->Error(_("There are problems and -y was used without --force-yes"));
+ }
+
+ if (Essential == true && Safety == true)
+ {
+ if (_config->FindB("APT::Get::Trivial-Only",false) == true)
+ return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
+
+ // TRANSLATOR: This string needs to be typed by the user as a confirmation, so be
+ // careful with hard to type or special characters (like non-breaking spaces)
+ const char *Prompt = _("Yes, do as I say!");
+ ioprintf(c2out,
+ _("You are about to do something potentially harmful.\n"
+ "To continue type in the phrase '%s'\n"
+ " ?] "),Prompt);
+ c2out << std::flush;
+ if (AnalPrompt(Prompt) == false)
+ {
+ c2out << _("Abort.") << std::endl;
+ exit(1);
+ }
+ }
+ else
+ {
+ // Prompt to continue
+ if (Ask == true || Fail == true)
+ {
+ if (_config->FindB("APT::Get::Trivial-Only",false) == true)
+ return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
+
+ if (_config->FindI("quiet",0) < 2 &&
+ _config->FindB("APT::Get::Assume-Yes",false) == false)
+ {
+ c2out << _("Do you want to continue?") << std::flush;
+ if (YnPrompt() == false)
+ {
+ c2out << _("Abort.") << std::endl;
+ exit(1);
+ }
+ }
+ }
+ }
+
+ // Just print out the uris an 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)
+ c1out << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
+ I->Owner->FileSize << ' ' << I->Owner->HashSum() << std::endl;
+ return true;
+ }
+
+ if (!CheckAuth(Fetcher))
+ return false;
+
+ /* Unlock the dpkg lock if we are not going to be doing an install
+ after. */
+ if (_config->FindB("APT::Get::Download-Only",false) == true)
+ _system->UnLock();
+
+ // Run it
+ while (1)
+ {
+ bool Transient = false;
+ if (_config->FindB("APT::Get::Download",true) == false)
+ {
+ for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
+ {
+ if ((*I)->Local == true)
+ {
+ ++I;
+ continue;
+ }
+
+ // Close the item and check if it was found in cache
+ (*I)->Finished();
+ if ((*I)->Complete == false)
+ Transient = true;
+
+ // Clear it out of the fetch list
+ delete *I;
+ I = Fetcher.ItemsBegin();
+ }
+ }
+
+ if (Fetcher.Run() == pkgAcquire::Failed)
+ return false;
+
+ // Print out errors
+ bool Failed = false;
+ for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I)
+ {
+ if ((*I)->Status == pkgAcquire::Item::StatDone &&
+ (*I)->Complete == true)
+ continue;
+
+ if ((*I)->Status == pkgAcquire::Item::StatIdle)
+ {
+ Transient = true;
+ // Failed = true;
+ continue;
+ }
+
+ fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
+ (*I)->ErrorText.c_str());
+ Failed = true;
+ }
+
+ /* If we are in no download mode and missing files and there were
+ 'failures' then the user must specify -m. Furthermore, there
+ is no such thing as a transient error in no-download mode! */
+ if (Transient == true &&
+ _config->FindB("APT::Get::Download",true) == false)
+ {
+ Transient = false;
+ Failed = true;
+ }
+
+ if (_config->FindB("APT::Get::Download-Only",false) == true)
+ {
+ if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
+ return _error->Error(_("Some files failed to download"));
+ c1out << _("Download complete and in download only mode") << std::endl;
+ return true;
+ }
+
+ if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
+ {
+ return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
+ }
+
+ if (Transient == true && Failed == true)
+ return _error->Error(_("--fix-missing and media swapping is not currently supported"));
+
+ // Try to deal with missing package files
+ if (Failed == true && PM->FixMissing() == false)
+ {
+ c2out << _("Unable to correct missing packages.") << std::endl;
+ return _error->Error(_("Aborting install."));
+ }
+
+ _system->UnLock();
+ int status_fd = _config->FindI("APT::Status-Fd",-1);
+ pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd);
+ if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
+ return false;
+ if (Res == pkgPackageManager::Completed)
+ break;
+
+ // Reload the fetcher object and loop again for media swapping
+ Fetcher.Shutdown();
+ if (PM->GetArchives(&Fetcher,List,&Recs) == false)
+ return false;
+
+ _system->Lock();
+ }
+
+ std::set<std::string> const disappearedPkgs = PM->GetDisappearedPackages();
+ if (disappearedPkgs.empty() == true)
+ return true;
+
+ std::string disappear;
+ for (std::set<std::string>::const_iterator d = disappearedPkgs.begin();
+ d != disappearedPkgs.end(); ++d)
+ disappear.append(*d).append(" ");
+
+ ShowList(c1out, P_("The following package disappeared from your system as\n"
+ "all files have been overwritten by other packages:",
+ "The following packages disappeared from your system as\n"
+ "all files have been overwritten by other packages:", disappearedPkgs.size()), disappear, "");
+ c0out << _("Note: This is done automatically and on purpose by dpkg.") << std::endl;
+
+ return true;
+}
+ /*}}}*/
+
+
+// DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
+// ---------------------------------------------------------------------
+/* Remove unused automatic packages */
+bool DoAutomaticRemove(CacheFile &Cache)
+{
+ bool Debug = _config->FindI("Debug::pkgAutoRemove",false);
+ bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
+ bool hideAutoRemove = _config->FindB("APT::Get::HideAutoRemove");
+
+ pkgDepCache::ActionGroup group(*Cache);
+ if(Debug)
+ std::cout << "DoAutomaticRemove()" << std::endl;
+
+ if (doAutoRemove == true &&
+ _config->FindB("APT::Get::Remove",true) == false)
+ {
+ c1out << _("We are not supposed to delete stuff, can't start "
+ "AutoRemover") << std::endl;
+ return false;
+ }
+
+ bool purgePkgs = _config->FindB("APT::Get::Purge", false);
+ bool smallList = (hideAutoRemove == false &&
+ strcasecmp(_config->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
+
+ unsigned long autoRemoveCount = 0;
+ APT::PackageSet tooMuch;
+ APT::PackageList autoRemoveList;
+ // look over the cache to see what can be removed
+ for (unsigned J = 0; J < Cache->Head().PackageCount; ++J)
+ {
+ pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
+ if (Cache[Pkg].Garbage)
+ {
+ if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
+ if(Debug)
+ std::cout << "We could delete %s" << Pkg.FullName(true).c_str() << std::endl;
+
+ if (doAutoRemove)
+ {
+ if(Pkg.CurrentVer() != 0 &&
+ Pkg->CurrentState != pkgCache::State::ConfigFiles)
+ Cache->MarkDelete(Pkg, purgePkgs, 0, false);
+ else
+ Cache->MarkKeep(Pkg, false, false);
+ }
+ else
+ {
+ if (hideAutoRemove == false && Cache[Pkg].Delete() == false)
+ autoRemoveList.insert(Pkg);
+ // 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)
+ {
+ if (Pkg.CandVersion() != 0)
+ tooMuch.insert(Pkg);
+ Cache->MarkDelete(Pkg, false, 0, false);
+ }
+ // only show stuff in the list that is not yet marked for removal
+ else if(hideAutoRemove == false && Cache[Pkg].Delete() == false)
+ ++autoRemoveCount;
+ }
+ }
+ }
+
+ // 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 || Cache->PolicyBrokenCount() != 0))
+ {
+ bool Changed;
+ do {
+ Changed = false;
+ for (APT::PackageSet::const_iterator Pkg = tooMuch.begin();
+ Pkg != tooMuch.end() && Changed == false; ++Pkg)
+ {
+ APT::PackageSet too;
+ too.insert(*Pkg);
+ for (pkgCache::PrvIterator Prv = Cache[Pkg].CandidateVerIter(Cache).ProvidesList();
+ Prv.end() == false; ++Prv)
+ too.insert(Prv.ParentPkg());
+ for (APT::PackageSet::const_iterator P = too.begin();
+ P != too.end() && Changed == false; ++P) {
+ for (pkgCache::DepIterator R = P.RevDependsList();
+ R.end() == false; ++R)
+ {
+ if (R.IsNegative() == true ||
+ Cache->IsImportantDep(R) == false)
+ continue;
+ pkgCache::PkgIterator N = R.ParentPkg();
+ if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
+ continue;
+ if (Debug == true)
+ std::clog << "Save " << Pkg << " as another installed garbage package depends on it" << std::endl;
+ Cache->MarkInstall(Pkg, false, 0, false);
+ if (hideAutoRemove == false)
+ ++autoRemoveCount;
+ tooMuch.erase(Pkg);
+ Changed = true;
+ break;
+ }
+ }
+ }
+ } while (Changed == true);
+ }
+
+ std::string autoremovelist, autoremoveversions;
+ if (smallList == false && autoRemoveCount != 0)
+ {
+ for (APT::PackageList::const_iterator Pkg = autoRemoveList.begin(); Pkg != autoRemoveList.end(); ++Pkg)
+ {
+ if (Cache[Pkg].Garbage == false)
+ continue;
+ autoremovelist += Pkg.FullName(true) + " ";
+ autoremoveversions += std::string(Cache[Pkg].CandVersion) + "\n";
+ }
+ }
+
+ // Now see if we had destroyed anything (if we had done anything)
+ if (Cache->BrokenCount() != 0)
+ {
+ c1out << _("Hmm, seems like the AutoRemover destroyed something which really\n"
+ "shouldn't happen. Please file a bug report against apt.") << std::endl;
+ c1out << std::endl;
+ c1out << _("The following information may help to resolve the situation:") << std::endl;
+ c1out << std::endl;
+ ShowBroken(c1out,Cache,false);
+
+ return _error->Error(_("Internal Error, AutoRemover broke stuff"));
+ }
+
+ // if we don't remove them, we should show them!
+ if (doAutoRemove == false && (autoremovelist.empty() == false || autoRemoveCount != 0))
+ {
+ if (smallList == false)
+ ShowList(c1out, P_("The following package was automatically installed and is no longer required:",
+ "The following packages were automatically installed and are no longer required:",
+ autoRemoveCount), autoremovelist, autoremoveversions);
+ else
+ ioprintf(c1out, P_("%lu package was automatically installed and is no longer required.\n",
+ "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount), autoRemoveCount);
+ c1out << P_("Use 'apt-get autoremove' to remove it.", "Use 'apt-get autoremove' to remove them.", autoRemoveCount) << std::endl;
+ }
+ return true;
+}
+ /*}}}*/
+
+
+
+
+// DoInstall - Install packages from the command line /*{{{*/
+// ---------------------------------------------------------------------
+/* Install named packages */
+bool DoInstall(CommandLine &CmdL)
+{
+ CacheFile Cache;
+ if (Cache.OpenForInstall() == false ||
+ Cache.CheckDeps(CmdL.FileSize() != 1) == false)
+ return false;
+
+ // Enter the special broken fixing mode if the user specified arguments
+ bool BrokenFix = false;
+ if (Cache->BrokenCount() != 0)
+ BrokenFix = true;
+
+ 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;
+
+ unsigned short fallback = MOD_INSTALL;
+ if (strcasecmp(CmdL.FileList[0],"remove") == 0)
+ fallback = MOD_REMOVE;
+ else if (strcasecmp(CmdL.FileList[0], "purge") == 0)
+ {
+ _config->Set("APT::Get::Purge", true);
+ fallback = MOD_REMOVE;
+ }
+ else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0)
+ {
+ _config->Set("APT::Get::AutomaticRemove", "true");
+ fallback = MOD_REMOVE;
+ }
+
+ std::list<APT::VersionSet::Modifier> mods;
+ mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+",
+ APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDIDATE));
+ mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-",
+ APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST));
+ CacheSetHelperAPTGet helper(c0out);
+ std::map<unsigned short, APT::VersionSet> verset = APT::VersionSet::GroupedFromCommandLine(Cache,
+ CmdL.FileList + 1, mods, fallback, helper);
+
+ if (_error->PendingError() == true)
+ {
+ helper.showVirtualPackageErrors(Cache);
+ if (Fix != NULL)
+ delete Fix;
+ return false;
+ }
+
+
+ TryToInstall InstallAction(Cache, Fix, BrokenFix);
+ TryToRemove RemoveAction(Cache, Fix);
+
+ // new scope for the ActionGroup
+ {
+ pkgDepCache::ActionGroup group(Cache);
+ unsigned short const order[] = { MOD_REMOVE, MOD_INSTALL, 0 };
+
+ for (unsigned short i = 0; order[i] != 0; ++i)
+ {
+ 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();
+ }
+ }
+
+ 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
+ packages */
+ if (BrokenFix == true && Cache->BrokenCount() != 0)
+ {
+ c1out << _("You might want to run 'apt-get -f install' to correct these:") << std::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)."));
+ }
+
+ if (Fix != NULL)
+ {
+ // Call the scored problem resolver
+ Fix->Resolve(true);
+ delete Fix;
+ }
+
+ // Now we check the state of the packages,
+ if (Cache->BrokenCount() != 0)
+ {
+ c1out <<
+ _("Some packages could not be installed. This may mean that you have\n"
+ "requested an impossible situation or if you are using the unstable\n"
+ "distribution that some required packages have not yet been created\n"
+ "or been moved out of Incoming.") << std::endl;
+ /*
+ if (Packages == 1)
+ {
+ c1out << std::endl;
+ c1out <<
+ _("Since you only requested a single operation it is extremely likely that\n"
+ "the package is simply not installable and a bug report against\n"
+ "that package should be filed.") << std::endl;
+ }
+ */
+
+ c1out << _("The following information may help to resolve the situation:") << std::endl;
+ c1out << std::endl;
+ ShowBroken(c1out,Cache,false);
+ if (_error->PendingError() == true)
+ return false;
+ else
+ return _error->Error(_("Broken packages"));
+ }
+ }
+ if (!DoAutomaticRemove(Cache))
+ return false;
+
+ /* Print out a list of packages that are going to be installed extra
+ to what the user asked */
+ if (Cache->InstCount() != verset[MOD_INSTALL].size())
+ {
+ std::string List;
+ std::string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if ((*Cache)[I].Install() == false)
+ continue;
+ pkgCache::VerIterator Cand = Cache[I].CandidateVerIter(Cache);
+
+ if (verset[MOD_INSTALL].find(Cand) != verset[MOD_INSTALL].end())
+ continue;
+
+ List += I.FullName(true) + " ";
+ VersionsList += std::string(Cache[I].CandVersion) + "\n";
+ }
+
+ ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList);
+ }
+
+ /* Print out a list of suggested and recommended packages */
+ {
+ std::string SuggestsList, RecommendsList;
+ std::string SuggestsVersions, RecommendsVersions;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
+
+ /* Just look at the ones we want to install */
+ if ((*Cache)[Pkg].Install() == false)
+ continue;
+
+ // get the recommends/suggests for the candidate ver
+ pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
+ for (pkgCache::DepIterator D = CV.DependsList(); D.end() == false; )
+ {
+ pkgCache::DepIterator Start;
+ pkgCache::DepIterator End;
+ D.GlobOr(Start,End); // advances D
+
+ // FIXME: we really should display a or-group as a or-group to the user
+ // the problem is that ShowList is incapable of doing this
+ std::string RecommendsOrList,RecommendsOrVersions;
+ std::string SuggestsOrList,SuggestsOrVersions;
+ bool foundInstalledInOrGroup = false;
+ for(;;)
+ {
+ /* Skip if package is installed already, or is about to be */
+ std::string target = Start.TargetPkg().FullName(true) + " ";
+ pkgCache::PkgIterator const TarPkg = Start.TargetPkg();
+ if (TarPkg->SelectedState == pkgCache::State::Install ||
+ TarPkg->SelectedState == pkgCache::State::Hold ||
+ Cache[Start.TargetPkg()].Install())
+ {
+ foundInstalledInOrGroup=true;
+ break;
+ }
+
+ /* Skip if we already saw it */
+ if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1)
+ {
+ foundInstalledInOrGroup=true;
+ break;
+ }
+
+ // this is a dep on a virtual pkg, check if any package that provides it
+ // should be installed
+ if(Start.TargetPkg().ProvidesList() != 0)
+ {
+ pkgCache::PrvIterator I = Start.TargetPkg().ProvidesList();
+ for (; I.end() == false; ++I)
+ {
+ pkgCache::PkgIterator Pkg = I.OwnerPkg();
+ if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer() &&
+ Pkg.CurrentVer() != 0)
+ foundInstalledInOrGroup=true;
+ }
+ }
+
+ if (Start->Type == pkgCache::Dep::Suggests)
+ {
+ SuggestsOrList += target;
+ SuggestsOrVersions += std::string(Cache[Start.TargetPkg()].CandVersion) + "\n";
+ }
+
+ if (Start->Type == pkgCache::Dep::Recommends)
+ {
+ RecommendsOrList += target;
+ RecommendsOrVersions += std::string(Cache[Start.TargetPkg()].CandVersion) + "\n";
+ }
+
+ if (Start >= End)
+ break;
+ ++Start;
+ }
+
+ if(foundInstalledInOrGroup == false)
+ {
+ RecommendsList += RecommendsOrList;
+ RecommendsVersions += RecommendsOrVersions;
+ SuggestsList += SuggestsOrList;
+ SuggestsVersions += SuggestsOrVersions;
+ }
+
+ }
+ }
+
+ ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions);
+ ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions);
+
+ }
+
+ // if nothing changed in the cache, but only the automark information
+ // we write the StateFile here, otherwise it will be written in
+ // cache.commit()
+ if (InstallAction.AutoMarkChanged > 0 &&
+ Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
+ Cache->BadCount() == 0 &&
+ _config->FindB("APT::Get::Simulate",false) == false)
+ Cache->writeStateFile(NULL);
+
+ // See if we need to prompt
+ // FIXME: check if really the packages in the set are going to be installed
+ if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0)
+ return InstallPackages(Cache,false,false);
+
+ return InstallPackages(Cache,false);
+}
+ /*}}}*/
diff --git a/apt-private/private-install.h b/apt-private/private-install.h
new file mode 100644
index 000000000..fcf4cbced
--- /dev/null
+++ b/apt-private/private-install.h
@@ -0,0 +1,181 @@
+#ifndef APT_PRIVATE_INSTALL_H
+#define APT_PRIVATE_INSTALL_H
+
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+
+#include "private-cachefile.h"
+#include "private-output.h"
+
+#include <apti18n.h>
+
+#define RAMFS_MAGIC 0x858458f6
+
+bool DoInstall(CommandLine &Cmd);
+
+
+bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
+ bool Safety = true);
+
+
+// TryToInstall - Mark a package for installation /*{{{*/
+struct TryToInstall {
+ pkgCacheFile* Cache;
+ pkgProblemResolver* Fix;
+ bool FixBroken;
+ unsigned long AutoMarkChanged;
+ APT::PackageSet doAutoInstallLater;
+
+ TryToInstall(pkgCacheFile &Cache, pkgProblemResolver *PM, bool const FixBroken) : Cache(&Cache), Fix(PM),
+ FixBroken(FixBroken), AutoMarkChanged(0) {};
+
+ void operator() (pkgCache::VerIterator const &Ver) {
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
+
+ Cache->GetDepCache()->SetCandidateVersion(Ver);
+ pkgDepCache::StateCache &State = (*Cache)[Pkg];
+
+ // Handle the no-upgrade case
+ if (_config->FindB("APT::Get::upgrade",true) == false && Pkg->CurrentVer != 0)
+ ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
+ Pkg.FullName(true).c_str());
+ // Ignore request for install if package would be new
+ else if (_config->FindB("APT::Get::Only-Upgrade", false) == true && Pkg->CurrentVer == 0)
+ ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
+ Pkg.FullName(true).c_str());
+ else {
+ if (Fix != NULL) {
+ Fix->Clear(Pkg);
+ Fix->Protect(Pkg);
+ }
+ Cache->GetDepCache()->MarkInstall(Pkg,false);
+
+ if (State.Install() == false) {
+ if (_config->FindB("APT::Get::ReInstall",false) == true) {
+ if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
+ ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
+ Pkg.FullName(true).c_str());
+ else
+ Cache->GetDepCache()->SetReInstall(Pkg, true);
+ } else
+ ioprintf(c1out,_("%s is already the newest version.\n"),
+ Pkg.FullName(true).c_str());
+ }
+
+ // Install it with autoinstalling enabled (if we not respect the minial
+ // required deps or the policy)
+ if (FixBroken == false)
+ doAutoInstallLater.insert(Pkg);
+ }
+
+ // see if we need to fix the auto-mark flag
+ // e.g. apt-get install foo
+ // where foo is marked automatic
+ if (State.Install() == false &&
+ (State.Flags & pkgCache::Flag::Auto) &&
+ _config->FindB("APT::Get::ReInstall",false) == false &&
+ _config->FindB("APT::Get::Only-Upgrade",false) == false &&
+ _config->FindB("APT::Get::Download-Only",false) == false)
+ {
+ ioprintf(c1out,_("%s set to manually installed.\n"),
+ Pkg.FullName(true).c_str());
+ Cache->GetDepCache()->MarkAuto(Pkg,false);
+ AutoMarkChanged++;
+ }
+ }
+
+ bool propergateReleaseCandiateSwitching(std::list<std::pair<pkgCache::VerIterator, std::string> > start, std::ostream &out)
+ {
+ for (std::list<std::pair<pkgCache::VerIterator, std::string> >::const_iterator s = start.begin();
+ s != start.end(); ++s)
+ Cache->GetDepCache()->SetCandidateVersion(s->first);
+
+ bool Success = true;
+ std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > Changed;
+ for (std::list<std::pair<pkgCache::VerIterator, std::string> >::const_iterator s = start.begin();
+ s != start.end(); ++s)
+ {
+ Changed.push_back(std::make_pair(s->first, pkgCache::VerIterator(*Cache)));
+ // We continue here even if it failed to enhance the ShowBroken output
+ Success &= Cache->GetDepCache()->SetCandidateRelease(s->first, s->second, Changed);
+ }
+ for (std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::const_iterator c = Changed.begin();
+ c != Changed.end(); ++c)
+ {
+ if (c->second.end() == true)
+ ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"),
+ c->first.VerStr(), c->first.RelStr().c_str(), c->first.ParentPkg().FullName(true).c_str());
+ else if (c->first.ParentPkg()->Group != c->second.ParentPkg()->Group)
+ {
+ pkgCache::VerIterator V = (*Cache)[c->first.ParentPkg()].CandidateVerIter(*Cache);
+ ioprintf(out, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V.VerStr(),
+ V.RelStr().c_str(), V.ParentPkg().FullName(true).c_str(), c->second.ParentPkg().FullName(true).c_str());
+ }
+ }
+ return Success;
+ }
+
+ void doAutoInstall() {
+ for (APT::PackageSet::const_iterator P = doAutoInstallLater.begin();
+ P != doAutoInstallLater.end(); ++P) {
+ pkgDepCache::StateCache &State = (*Cache)[P];
+ if (State.InstBroken() == false && State.InstPolicyBroken() == false)
+ continue;
+ Cache->GetDepCache()->MarkInstall(P, true);
+ }
+ doAutoInstallLater.clear();
+ }
+};
+ /*}}}*/
+// TryToRemove - Mark a package for removal /*{{{*/
+struct TryToRemove {
+ pkgCacheFile* Cache;
+ pkgProblemResolver* Fix;
+ bool PurgePkgs;
+
+ 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();
+
+ 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))
+ {
+ pkgCache::GrpIterator Grp = Pkg.Group();
+ pkgCache::PkgIterator P = Grp.PackageList();
+ for (; P.end() != true; P = Grp.NextPkg(P))
+ {
+ if (P == Pkg)
+ continue;
+ if (P->CurrentVer != 0 || (PurgePkgs == true && P->CurrentState != pkgCache::State::NotInstalled))
+ {
+ // TRANSLATORS: Note, this is not an interactive question
+ ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
+ Pkg.FullName(true).c_str(), P.FullName(true).c_str());
+ break;
+ }
+ }
+ if (P.end() == true)
+ 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);
+ }
+};
+ /*}}}*/
+
+
+#endif
diff --git a/apt-private/private-list.cc b/apt-private/private-list.cc
new file mode 100644
index 000000000..ac72ce51a
--- /dev/null
+++ b/apt-private/private-list.cc
@@ -0,0 +1,158 @@
+// Include Files /*{{{*/
+#include <config.h>
+
+#include <apt-pkg/error.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cachefilter.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/policy.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/indexfile.h>
+#include <apt-pkg/metaindex.h>
+
+#include <sstream>
+#include <vector>
+#include <utility>
+#include <cassert>
+#include <locale.h>
+#include <iostream>
+#include <unistd.h>
+#include <errno.h>
+#include <regex.h>
+#include <stdio.h>
+#include <algorithm>
+
+#include "private-cmndline.h"
+#include "private-list.h"
+#include "private-output.h"
+#include "private-cacheset.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+struct PackageSortAlphabetic
+{
+ bool operator () (const pkgCache::PkgIterator &p_lhs,
+ const pkgCache::PkgIterator &p_rhs)
+ {
+ const std::string &l_name = p_lhs.FullName(true);
+ const std::string &r_name = p_rhs.FullName(true);
+ return (l_name < r_name);
+ }
+};
+
+class PackageNameMatcher : public Matcher
+{
+ public:
+ PackageNameMatcher(const char **patterns)
+ {
+ for(int i=0; patterns[i] != NULL; i++)
+ {
+ std::string pattern = patterns[i];
+ APT::CacheFilter::PackageMatcher *cachefilter = NULL;
+ if(_config->FindB("APT::Cmd::UseRegexp", false) == true)
+ cachefilter = new APT::CacheFilter::PackageNameMatchesRegEx(pattern);
+ else
+ cachefilter = new APT::CacheFilter::PackageNameMatchesFnmatch(pattern);
+ filters.push_back(cachefilter);
+ }
+ }
+ virtual ~PackageNameMatcher()
+ {
+ for(J=filters.begin(); J != filters.end(); J++)
+ delete *J;
+ }
+ virtual bool operator () (const pkgCache::PkgIterator &P)
+ {
+ for(J=filters.begin(); J != filters.end(); J++)
+ {
+ APT::CacheFilter::PackageMatcher *cachefilter = *J;
+ if((*cachefilter)(P))
+ return true;
+ }
+ return false;
+ }
+
+private:
+ std::vector<APT::CacheFilter::PackageMatcher*> filters;
+ std::vector<APT::CacheFilter::PackageMatcher*>::const_iterator J;
+};
+
+
+void ListAllVersions(pkgCacheFile &CacheFile, pkgRecords &records,
+ pkgCache::PkgIterator P,
+ std::ostream &outs)
+{
+ for (pkgCache::VerIterator Ver = P.VersionList();
+ Ver.end() == false; Ver++)
+ ListSingleVersion(CacheFile, records, Ver, outs);
+}
+
+// list - list package based on criteria /*{{{*/
+// ---------------------------------------------------------------------
+bool List(CommandLine &Cmd)
+{
+ pkgCacheFile CacheFile;
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ pkgRecords records(CacheFile);
+
+ if (unlikely(Cache == NULL))
+ return false;
+
+ const char **patterns;
+ const char *all_pattern[] = { "*", NULL};
+
+ if (strv_length(Cmd.FileList + 1) == 0)
+ {
+ patterns = all_pattern;
+ } else {
+ patterns = Cmd.FileList + 1;
+ }
+
+ std::map<std::string, std::string> output_map;
+ std::map<std::string, std::string>::const_iterator K;
+
+ PackageNameMatcher matcher(patterns);
+ LocalitySortedVersionSet bag;
+ OpTextProgress progress;
+ progress.OverallProgress(0,
+ Cache->Head().PackageCount,
+ Cache->Head().PackageCount,
+ _("Listing"));
+ GetLocalitySortedVersionSet(CacheFile, bag, matcher, progress);
+ for (LocalitySortedVersionSet::iterator V = bag.begin(); V != bag.end(); V++)
+ {
+ std::stringstream outs;
+ if(_config->FindB("APT::Cmd::AllVersions", false) == true)
+ {
+ ListAllVersions(CacheFile, records, V.ParentPkg(), outs);
+ output_map.insert(std::make_pair<std::string, std::string>(
+ V.ParentPkg().Name(), outs.str()));
+ } else {
+ ListSingleVersion(CacheFile, records, V, outs);
+ output_map.insert(std::make_pair<std::string, std::string>(
+ V.ParentPkg().Name(), outs.str()));
+ }
+ }
+
+ // FIXME: SORT! and make sorting flexible (alphabetic, by pkg status)
+ // output the sorted map
+ for (K = output_map.begin(); K != output_map.end(); K++)
+ std::cout << (*K).second << std::endl;
+
+
+ return true;
+}
+
diff --git a/apt-private/private-list.h b/apt-private/private-list.h
new file mode 100644
index 000000000..6f5aad27a
--- /dev/null
+++ b/apt-private/private-list.h
@@ -0,0 +1,9 @@
+#ifndef APT_PRIVATE_LIST_H
+#define APT_PRIVATE_LIST_H
+
+#include <apt-pkg/cmndline.h>
+
+bool List(CommandLine &Cmd);
+
+
+#endif
diff --git a/apt-private/private-main.cc b/apt-private/private-main.cc
new file mode 100644
index 000000000..1fdf3f0be
--- /dev/null
+++ b/apt-private/private-main.cc
@@ -0,0 +1,26 @@
+
+#include<unistd.h>
+#include<cstring>
+
+#include <apt-pkg/configuration.h>
+#include "private-main.h"
+
+#include <apti18n.h>
+
+void CheckSimulateMode(CommandLine &CmdL)
+{
+ // simulate user-friendly if apt-get has no root privileges
+ 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)
+ std::cout << _("NOTE: This is only a simulation!\n"
+ " apt-get needs root privileges for real execution.\n"
+ " Keep also in mind that locking is deactivated,\n"
+ " so don't depend on the relevance to the real current situation!"
+ ) << std::endl;
+ _config->Set("Debug::NoLocking",true);
+ }
+}
diff --git a/apt-private/private-main.h b/apt-private/private-main.h
new file mode 100644
index 000000000..f9a95c4ec
--- /dev/null
+++ b/apt-private/private-main.h
@@ -0,0 +1,9 @@
+#ifndef APT_PRIVATE_MAIN_H
+#define APT_PRIVATE_MAIN_H
+
+#include <apt-pkg/cmndline.h>
+
+void CheckSimulateMode(CommandLine &CmdL);
+
+
+#endif
diff --git a/apt-private/private-moo.cc b/apt-private/private-moo.cc
new file mode 100644
index 000000000..9b5b94654
--- /dev/null
+++ b/apt-private/private-moo.cc
@@ -0,0 +1,193 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* ######################################################################
+
+ Here be cows โ€“ but: Never ask, never tell
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include<config.h>
+
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+
+#include <strings.h>
+#include <sstream>
+
+#include "private-moo.h"
+#include "private-output.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+std::string getMooLine() { /*{{{*/
+ time_t const timenow = time(NULL);
+ struct tm special;
+ localtime_r(&timenow, &special);
+ enum { NORMAL, PACKAGEMANAGER, APPRECIATION, AGITATION, AIRBORN } line;
+ if (special.tm_mon == 11 && special.tm_mday == 25)
+ line = PACKAGEMANAGER;
+ else if (special.tm_mon == 7 && special.tm_mday == 16)
+ line = APPRECIATION;
+ else if (special.tm_mon == 10 && special.tm_mday == 7)
+ line = AGITATION;
+ else if (special.tm_mon == 1 && special.tm_mday == 18)
+ line = AIRBORN;
+ else
+ line = NORMAL;
+
+ bool const quiet = _config->FindI("quiet") >= 2;
+ std::ostringstream out;
+ if (quiet == false)
+ out << "...\"";
+
+ switch(line)
+ {
+ case PACKAGEMANAGER: out << "Happy package management day!"; break;
+ case APPRECIATION: out << "Three moos for Debian!"; break;
+ case AGITATION: out << "Whoever needs milk, bows to the animal."; break;
+ case AIRBORN: out << "It's a Bird ... It's a Plane ... It's Super Cow!"; break;
+ default: out << "Have you mooed today?"; break;
+ }
+
+ if (quiet == true)
+ out << std::endl;
+ else
+ out << "\"..." << std::endl;
+
+ return out.str();
+}
+ /*}}}*/
+bool printMooLine() { /*{{{*/
+ std::cerr << getMooLine() << std::endl;
+ return true;
+}
+ /*}}}*/
+bool DoMoo1(CommandLine &CmdL) /*{{{*/
+{
+ // our trustworthy super cow since 2001
+ if (_config->FindI("quiet") >= 2)
+ return printMooLine();
+ std::string const moo = getMooLine();
+ size_t const depth = moo.length()/4;
+ c1out <<
+ OutputInDepth(depth, " ") << " (__) \n" <<
+ OutputInDepth(depth, " ") << " (oo) \n" <<
+ OutputInDepth(depth, " ") << " /------\\/ \n" <<
+ OutputInDepth(depth, " ") << " / | || \n" <<
+ OutputInDepth(depth, " ") << " * /\\---/\\ \n" <<
+ OutputInDepth(depth, " ") << " ~~ ~~ \n" <<
+ moo;
+ return true;
+}
+ /*}}}*/
+bool DoMoo2(CommandLine &CmdL) /*{{{*/
+{
+ // by Fernando Ribeiro in lp:56125
+ if (_config->FindI("quiet") >= 2)
+ return printMooLine();
+ std::string const moo = getMooLine();
+ size_t const depth = moo.length()/4;
+ if (_config->FindB("APT::Moo::Color", false) == false)
+ c1out <<
+ OutputInDepth(depth, " ") << " (__) \n" <<
+ OutputInDepth(depth, " ") << " _______~(..)~ \n" <<
+ OutputInDepth(depth, " ") << " ,----\\(oo) \n" <<
+ OutputInDepth(depth, " ") << " /|____|,' \n" <<
+ OutputInDepth(depth, " ") << " * /\"\\ /\\ \n" <<
+ OutputInDepth(depth, " ") << " ~ ~ ~ ~ \n" <<
+ moo;
+ else
+ {
+ c1out <<
+ OutputInDepth(depth, " ") << " \e[1;97m(\e[0;33m__\e[1;97m)\e[0m\n" <<
+ OutputInDepth(depth, " ") << " \e[31m_______\e[33m~(\e[1;34m..\e[0;33m)~\e[0m\n" <<
+ OutputInDepth(depth, " ") << " \e[33m,----\e[31m\\\e[33m(\e[1;4;35moo\e[0;33m)\e[0m\n" <<
+ OutputInDepth(depth, " ") << " \e[33m/|____|,'\e[0m\n" <<
+ OutputInDepth(depth, " ") << " \e[1;5;97m*\e[0;33m /\\ /\\\e[0m\n" <<
+ "\e[32m";
+ for (size_t i = moo.length()/2; i > 1; --i)
+ c1out << "wW";
+
+ c1out << "w\e[0m\n" << moo;
+ }
+
+ return true;
+}
+ /*}}}*/
+bool DoMoo3(CommandLine &CmdL) /*{{{*/
+{
+ // by Robert Millan in deb:134156
+ if (_config->FindI("quiet") >= 2)
+ return printMooLine();
+ std::string const moo = getMooLine();
+ size_t const depth = moo.length()/16;
+ c1out <<
+ OutputInDepth(depth, " ") << " \\_/ \n" <<
+ OutputInDepth(depth, " ") << " m00h (__) -(_)- \n" <<
+ OutputInDepth(depth, " ") << " \\ ~Oo~___ / \\\n" <<
+ OutputInDepth(depth, " ") << " (..) |\\ \n" <<
+ OutputInDepth(depth, "_") << "_________|_|_|__________" <<
+ OutputInDepth((moo.length() - (depth + 27)), "_") << "\n" << moo;
+ return true;
+}
+ /*}}}*/
+bool DoMooApril(CommandLine &CmdL) /*{{{*/
+{
+ // by Christopher Allan Webber and proposed by Paul Tagliamonte
+ // in a "Community outreach": https://lists.debian.org/debian-devel/2013/04/msg00045.html
+ if (_config->FindI("quiet") >= 2)
+ {
+ std::cerr << "Have you smashed some milk today?" << std::endl;
+ return true;
+ }
+ c1out <<
+ " _ _\n"
+ " (_\\___( \\,\n"
+ " )___ _ Have you smashed some milk today?\n"
+ " /( (_)-(_) /\n"
+ " ,---------' \\_\n"
+ " //( ',__,' \\ (' ')\n"
+ " // ) '----'\n"
+ " '' ; \\ .--. ,/\n"
+ " | )',_,'----( ;\n"
+ " ||| ''' '||\n";
+ return true;
+}
+ /*}}}*/
+bool DoMoo(CommandLine &CmdL) /*{{{*/
+{
+ time_t const timenow = time(NULL);
+ struct tm april;
+ localtime_r(&timenow, &april);
+ if (april.tm_mday == 1 && april.tm_mon == 3)
+ return DoMooApril(CmdL);
+
+ signed short SuperCow = 1;
+ if (CmdL.FileSize() != 0)
+ for (const char **Moo = CmdL.FileList + 1; *Moo != 0; Moo++)
+ if (strcasecmp(*Moo, "moo") == 0)
+ SuperCow++;
+
+ // time is random enough for our purpose
+ if (SuperCow > 3)
+ {
+ if (april.tm_sec == 1)
+ SuperCow = 1 + (timenow % 4);
+ else
+ SuperCow = 1 + (timenow % 3);
+ }
+
+ switch(SuperCow) {
+ case 1: return DoMoo1(CmdL);
+ case 2: return DoMoo2(CmdL);
+ case 3: return DoMoo3(CmdL);
+ case 4: return DoMooApril(CmdL);
+ default: return DoMoo1(CmdL);
+ }
+
+ return true;
+}
+ /*}}}*/
diff --git a/apt-private/private-moo.h b/apt-private/private-moo.h
new file mode 100644
index 000000000..7bfc5c1fc
--- /dev/null
+++ b/apt-private/private-moo.h
@@ -0,0 +1,12 @@
+#ifndef APT_PRIVATE_MOO_H
+#define APT_PRIVATE_MOO_H
+
+class CommandLine;
+
+bool DoMoo(CommandLine &CmdL);
+bool DoMoo1(CommandLine &CmdL);
+bool DoMoo2(CommandLine &CmdL);
+bool DoMoo3(CommandLine &CmdL);
+bool DoMooApril(CommandLine &CmdL);
+
+#endif
diff --git a/apt-private/private-output.cc b/apt-private/private-output.cc
new file mode 100644
index 000000000..659975476
--- /dev/null
+++ b/apt-private/private-output.cc
@@ -0,0 +1,753 @@
+// Include files /*{{{*/
+#include<config.h>
+
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/policy.h>
+
+#include <iomanip>
+#include <iostream>
+#include <locale.h>
+#include <langinfo.h>
+#include <unistd.h>
+
+#include "private-output.h"
+#include "private-cachefile.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+using namespace std;
+
+std::ostream c0out(0);
+std::ostream c1out(0);
+std::ostream c2out(0);
+std::ofstream devnull("/dev/null");
+unsigned int ScreenWidth = 80 - 1; /* - 1 for the cursor */
+
+
+bool InitOutput()
+{
+ 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());
+
+ if(!isatty(1))
+ {
+ _config->Set("APT::Color", "false");
+ _config->Set("APT::Color::Highlight", "");
+ _config->Set("APT::Color::Neutral", "");
+ } else {
+ // Colors
+ _config->CndSet("APT::Color::Highlight", "\x1B[32m");
+ _config->CndSet("APT::Color::Neutral", "\x1B[0m");
+
+ _config->CndSet("APT::Color::Red", "\x1B[31m");
+ _config->CndSet("APT::Color::Green", "\x1B[32m");
+ _config->CndSet("APT::Color::Yellow", "\x1B[33m");
+ _config->CndSet("APT::Color::Blue", "\x1B[34m");
+ _config->CndSet("APT::Color::Magenta", "\x1B[35m");
+ _config->CndSet("APT::Color::Cyan", "\x1B[36m");
+ _config->CndSet("APT::Color::White", "\x1B[37m");
+ }
+
+ return true;
+}
+
+std::string GetArchiveSuite(pkgCacheFile &CacheFile, pkgCache::VerIterator ver)
+{
+ std::string suite = "";
+ if (ver && ver.FileList() && ver.FileList())
+ {
+ pkgCache::VerFileIterator VF = ver.FileList();
+ for (; VF.end() == false ; ++VF)
+ {
+ // XXX: how to figure out the relevant suite? if its in multiple ones?
+ suite = suite + "," + VF.File().Archive();
+ //suite = VF.File().Archive();
+ }
+ suite = suite.erase(0, 1);
+ }
+ return suite;
+}
+
+std::string GetFlagsStr(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)
+{
+ pkgDepCache *DepCache = CacheFile.GetDepCache();
+ pkgDepCache::StateCache &state = (*DepCache)[P];
+
+ std::string flags_str;
+ if (state.NowBroken())
+ flags_str = "B";
+ if (P.CurrentVer() && state.Upgradable())
+ flags_str = "g";
+ else if (P.CurrentVer() != NULL)
+ flags_str = "i";
+ else
+ flags_str = "-";
+ return flags_str;
+}
+
+std::string GetCandidateVersion(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)
+{
+ pkgPolicy *policy = CacheFile.GetPolicy();
+ pkgCache::VerIterator cand = policy->GetCandidateVer(P);
+
+ return cand ? cand.VerStr() : "(none)";
+}
+
+std::string GetInstalledVersion(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)
+{
+ pkgCache::VerIterator inst = P.CurrentVer();
+
+ return inst ? inst.VerStr() : "(none)";
+}
+
+std::string GetVersion(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
+{
+ pkgCache::PkgIterator P = V.ParentPkg();
+ if (V == P.CurrentVer())
+ {
+ pkgDepCache *DepCache = CacheFile.GetDepCache();
+ pkgDepCache::StateCache &state = (*DepCache)[P];
+ std::string inst_str = DeNull(V.VerStr());
+ if (state.Upgradable())
+ return "**"+inst_str;
+ return inst_str;
+ }
+
+ if(V)
+ return DeNull(V.VerStr());
+ return "(none)";
+}
+
+std::string GetArchitecture(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)
+{
+ pkgPolicy *policy = CacheFile.GetPolicy();
+ pkgCache::VerIterator inst = P.CurrentVer();
+ pkgCache::VerIterator cand = policy->GetCandidateVer(P);
+
+ return inst ? inst.Arch() : cand.Arch();
+}
+
+std::string GetShortDescription(pkgCacheFile &CacheFile, pkgRecords &records, pkgCache::PkgIterator P)
+{
+ pkgPolicy *policy = CacheFile.GetPolicy();
+
+ pkgCache::VerIterator ver;
+ if (P.CurrentVer())
+ ver = P.CurrentVer();
+ else
+ ver = policy->GetCandidateVer(P);
+
+ std::string ShortDescription = "(none)";
+ if(ver)
+ {
+ pkgCache::DescIterator Desc = ver.TranslatedDescription();
+ pkgRecords::Parser & parser = records.Lookup(Desc.FileList());
+
+ ShortDescription = parser.ShortDesc();
+ }
+ return ShortDescription;
+}
+
+void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records,
+ pkgCache::VerIterator V, std::ostream &out)
+{
+ pkgCache::PkgIterator P = V.ParentPkg();
+
+ pkgDepCache *DepCache = CacheFile.GetDepCache();
+ pkgDepCache::StateCache &state = (*DepCache)[P];
+
+ std::string suite = GetArchiveSuite(CacheFile, V);
+ std::string name_str = P.Name();
+
+ if (_config->FindB("APT::Cmd::use-format", false))
+ {
+ std::string format = _config->Find("APT::Cmd::format", "${db::Status-Abbrev} ${Package} ${Version} ${Origin} ${Description}");
+ std::string output = format;
+
+ output = SubstVar(output, "${db::Status-Abbrev}", GetFlagsStr(CacheFile, P));
+ output = SubstVar(output, "${Package}", name_str);
+ output = SubstVar(output, "${installed:Version}", GetInstalledVersion(CacheFile, P));
+ output = SubstVar(output, "${candidate:Version}", GetCandidateVersion(CacheFile, P));
+ output = SubstVar(output, "${Version}", GetVersion(CacheFile, V));
+ output = SubstVar(output, "${Description}", GetShortDescription(CacheFile, records, P));
+ output = SubstVar(output, "${Origin}", GetArchiveSuite(CacheFile, V));
+ out << output << std::endl;
+ } else {
+ // raring/linux-kernel version [upradable: new-version]
+ // description
+ pkgPolicy *policy = CacheFile.GetPolicy();
+ out << std::setiosflags(std::ios::left)
+ << _config->Find("APT::Color::Highlight", "")
+ << name_str
+ << _config->Find("APT::Color::Neutral", "")
+ << "/" << suite
+ << " ";
+ if(P.CurrentVer() == V && state.Upgradable()) {
+ out << GetVersion(CacheFile, V)
+ << " "
+ << "[" << _("installed,upgradable to: ")
+ << GetCandidateVersion(CacheFile, P) << "]";
+ } else if (P.CurrentVer() == V) {
+ out << GetVersion(CacheFile, V)
+ << " ";
+ if(!V.Downloadable())
+ out << _("[installed,local]");
+ else
+ if(V.Automatic() && state.Garbage)
+ out << _("[installed,auto-removable]");
+ else if (state.Flags & pkgCache::Flag::Auto)
+ out << _("[installed,automatic]");
+ else
+ out << _("[installed]");
+ } else if (P.CurrentVer() &&
+ policy->GetCandidateVer(P) == V &&
+ state.Upgradable()) {
+ out << GetVersion(CacheFile, V)
+ << " "
+ << _("[upgradable from: ")
+ << GetInstalledVersion(CacheFile, P) << "]";
+ } else {
+ if (V.ParentPkg()->CurrentState == pkgCache::State::ConfigFiles)
+ out << GetVersion(CacheFile, V)
+ << " "
+ << _("[residual-config]");
+ else
+ out << GetVersion(CacheFile, V);
+ }
+ out << " " << GetArchitecture(CacheFile, P) << " ";
+ out << std::endl
+ << " " << GetShortDescription(CacheFile, records, P)
+ << std::endl;
+ }
+}
+
+
+// ShowList - Show a list /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out a string of space separated words with a title and
+ a two space indent line wraped to the current screen width. */
+bool ShowList(ostream &out,string Title,string List,string VersionsList)
+{
+ if (List.empty() == true)
+ return true;
+ // trim trailing space
+ int NonSpace = List.find_last_not_of(' ');
+ if (NonSpace != -1)
+ {
+ List = List.erase(NonSpace + 1);
+ if (List.empty() == true)
+ return true;
+ }
+
+ // Acount for the leading space
+ int ScreenWidth = ::ScreenWidth - 3;
+
+ out << Title << endl;
+ string::size_type Start = 0;
+ string::size_type VersionsStart = 0;
+ while (Start < List.size())
+ {
+ if(_config->FindB("APT::Get::Show-Versions",false) == true &&
+ VersionsList.size() > 0) {
+ string::size_type End;
+ string::size_type VersionsEnd;
+
+ End = List.find(' ',Start);
+ VersionsEnd = VersionsList.find('\n', VersionsStart);
+
+ out << " " << string(List,Start,End - Start) << " (" <<
+ string(VersionsList,VersionsStart,VersionsEnd - VersionsStart) <<
+ ")" << endl;
+
+ if (End == string::npos || End < Start)
+ End = Start + ScreenWidth;
+
+ Start = End + 1;
+ VersionsStart = VersionsEnd + 1;
+ } else {
+ string::size_type End;
+
+ if (Start + ScreenWidth >= List.size())
+ End = List.size();
+ else
+ End = List.rfind(' ',Start+ScreenWidth);
+
+ if (End == string::npos || End < Start)
+ End = Start + ScreenWidth;
+ out << " " << string(List,Start,End - Start) << endl;
+ Start = End + 1;
+ }
+ }
+
+ return false;
+}
+ /*}}}*/
+// ShowBroken - Debugging aide /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out the names of all the packages that are broken along
+ with the name of each each broken dependency and a quite version
+ description.
+
+ The output looks like:
+ The following packages have unmet dependencies:
+ exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed
+ Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
+ Depends: libsasl7 but it is not going to be installed
+ */
+void ShowBroken(ostream &out,CacheFile &Cache,bool Now)
+{
+ if (Cache->BrokenCount() == 0)
+ return;
+
+ out << _("The following packages have unmet dependencies:") << endl;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+
+ if (Now == true)
+ {
+ if (Cache[I].NowBroken() == false)
+ continue;
+ }
+ else
+ {
+ if (Cache[I].InstBroken() == false)
+ continue;
+ }
+
+ // Print out each package and the failed dependencies
+ out << " " << I.FullName(true) << " :";
+ unsigned const Indent = I.FullName(true).size() + 3;
+ bool First = true;
+ pkgCache::VerIterator Ver;
+
+ if (Now == true)
+ Ver = I.CurrentVer();
+ else
+ Ver = Cache[I].InstVerIter(Cache);
+
+ if (Ver.end() == true)
+ {
+ out << endl;
+ continue;
+ }
+
+ for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
+ {
+ // Compute a single dependency element (glob or)
+ pkgCache::DepIterator Start;
+ pkgCache::DepIterator End;
+ D.GlobOr(Start,End); // advances D
+
+ if (Cache->IsImportantDep(End) == false)
+ continue;
+
+ if (Now == true)
+ {
+ if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
+ continue;
+ }
+ else
+ {
+ if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
+ continue;
+ }
+
+ bool FirstOr = true;
+ while (1)
+ {
+ if (First == false)
+ for (unsigned J = 0; J != Indent; J++)
+ out << ' ';
+ First = false;
+
+ if (FirstOr == false)
+ {
+ for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
+ out << ' ';
+ }
+ else
+ out << ' ' << End.DepType() << ": ";
+ FirstOr = false;
+
+ out << Start.TargetPkg().FullName(true);
+
+ // Show a quick summary of the version requirements
+ if (Start.TargetVer() != 0)
+ out << " (" << Start.CompType() << " " << Start.TargetVer() << ")";
+
+ /* Show a summary of the target package if possible. In the case
+ of virtual packages we show nothing */
+ pkgCache::PkgIterator Targ = Start.TargetPkg();
+ if (Targ->ProvidesList == 0)
+ {
+ out << ' ';
+ pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
+ if (Now == true)
+ Ver = Targ.CurrentVer();
+
+ if (Ver.end() == false)
+ {
+ if (Now == true)
+ ioprintf(out,_("but %s is installed"),Ver.VerStr());
+ else
+ ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
+ }
+ else
+ {
+ if (Cache[Targ].CandidateVerIter(Cache).end() == true)
+ {
+ if (Targ->ProvidesList == 0)
+ out << _("but it is not installable");
+ else
+ out << _("but it is a virtual package");
+ }
+ else
+ out << (Now?_("but it is not installed"):_("but it is not going to be installed"));
+ }
+ }
+
+ if (Start != End)
+ out << _(" or");
+ out << endl;
+
+ if (Start == End)
+ break;
+ ++Start;
+ }
+ }
+ }
+}
+ /*}}}*/
+// ShowNew - Show packages to newly install /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void ShowNew(ostream &out,CacheFile &Cache)
+{
+ /* Print out a list of packages that are going to be installed extra
+ to what the user asked */
+ string List;
+ string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if (Cache[I].NewInstall() == true) {
+ List += I.FullName(true) + " ";
+ VersionsList += string(Cache[I].CandVersion) + "\n";
+ }
+ }
+
+ ShowList(out,_("The following NEW packages will be installed:"),List,VersionsList);
+}
+ /*}}}*/
+// ShowDel - Show packages to delete /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void ShowDel(ostream &out,CacheFile &Cache)
+{
+ /* Print out a list of packages that are going to be removed extra
+ to what the user asked */
+ string List;
+ string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if (Cache[I].Delete() == true)
+ {
+ if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
+ List += I.FullName(true) + "* ";
+ else
+ List += I.FullName(true) + " ";
+
+ VersionsList += string(Cache[I].CandVersion)+ "\n";
+ }
+ }
+
+ ShowList(out,_("The following packages will be REMOVED:"),List,VersionsList);
+}
+ /*}}}*/
+// ShowKept - Show kept packages /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void ShowKept(ostream &out,CacheFile &Cache)
+{
+ string List;
+ string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+
+ // Not interesting
+ if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false ||
+ I->CurrentVer == 0 || Cache[I].Delete() == true)
+ continue;
+
+ List += I.FullName(true) + " ";
+ VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
+ }
+ ShowList(out,_("The following packages have been kept back:"),List,VersionsList);
+}
+ /*}}}*/
+// ShowUpgraded - Show upgraded packages /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void ShowUpgraded(ostream &out,CacheFile &Cache)
+{
+ string List;
+ string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+
+ // Not interesting
+ if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
+ continue;
+
+ List += I.FullName(true) + " ";
+ VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
+ }
+ ShowList(out,_("The following packages will be upgraded:"),List,VersionsList);
+}
+ /*}}}*/
+// ShowDowngraded - Show downgraded packages /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowDowngraded(ostream &out,CacheFile &Cache)
+{
+ string List;
+ string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+
+ // Not interesting
+ if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
+ continue;
+
+ List += I.FullName(true) + " ";
+ VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
+ }
+ return ShowList(out,_("The following packages will be DOWNGRADED:"),List,VersionsList);
+}
+ /*}}}*/
+// ShowHold - Show held but changed packages /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowHold(ostream &out,CacheFile &Cache)
+{
+ string List;
+ string VersionsList;
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
+ I->SelectedState == pkgCache::State::Hold) {
+ List += I.FullName(true) + " ";
+ VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
+ }
+ }
+
+ return ShowList(out,_("The following held packages will be changed:"),List,VersionsList);
+}
+ /*}}}*/
+// ShowEssential - Show an essential package warning /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out a warning message that is not to be ignored. It shows
+ all essential packages and their dependents that are to be removed.
+ It is insanely risky to remove the dependents of an essential package! */
+bool ShowEssential(ostream &out,CacheFile &Cache)
+{
+ string List;
+ string VersionsList;
+ bool *Added = new bool[Cache->Head().PackageCount];
+ for (unsigned int I = 0; I != Cache->Head().PackageCount; I++)
+ Added[I] = false;
+
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
+ (I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
+ continue;
+
+ // The essential package is being removed
+ if (Cache[I].Delete() == true)
+ {
+ if (Added[I->ID] == false)
+ {
+ Added[I->ID] = true;
+ List += I.FullName(true) + " ";
+ //VersionsList += string(Cache[I].CurVersion) + "\n"; ???
+ }
+ }
+ else
+ continue;
+
+ if (I->CurrentVer == 0)
+ continue;
+
+ // Print out any essential package depenendents that are to be removed
+ for (pkgCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; ++D)
+ {
+ // Skip everything but depends
+ if (D->Type != pkgCache::Dep::PreDepends &&
+ D->Type != pkgCache::Dep::Depends)
+ continue;
+
+ pkgCache::PkgIterator P = D.SmartTargetPkg();
+ if (Cache[P].Delete() == true)
+ {
+ if (Added[P->ID] == true)
+ continue;
+ Added[P->ID] = true;
+
+ char S[300];
+ snprintf(S,sizeof(S),_("%s (due to %s) "),P.FullName(true).c_str(),I.FullName(true).c_str());
+ List += S;
+ //VersionsList += "\n"; ???
+ }
+ }
+ }
+
+ delete [] Added;
+ return ShowList(out,_("WARNING: The following essential packages will be removed.\n"
+ "This should NOT be done unless you know exactly what you are doing!"),List,VersionsList);
+}
+
+ /*}}}*/
+// Stats - Show some statistics /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void Stats(ostream &out,pkgDepCache &Dep)
+{
+ unsigned long Upgrade = 0;
+ unsigned long Downgrade = 0;
+ unsigned long Install = 0;
+ unsigned long ReInstall = 0;
+ for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; ++I)
+ {
+ if (Dep[I].NewInstall() == true)
+ Install++;
+ else
+ {
+ if (Dep[I].Upgrade() == true)
+ Upgrade++;
+ else
+ if (Dep[I].Downgrade() == true)
+ Downgrade++;
+ }
+
+ if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
+ ReInstall++;
+ }
+
+ ioprintf(out,_("%lu upgraded, %lu newly installed, "),
+ Upgrade,Install);
+
+ if (ReInstall != 0)
+ ioprintf(out,_("%lu reinstalled, "),ReInstall);
+ if (Downgrade != 0)
+ ioprintf(out,_("%lu downgraded, "),Downgrade);
+
+ ioprintf(out,_("%lu to remove and %lu not upgraded.\n"),
+ Dep.DelCount(),Dep.KeepCount());
+
+ if (Dep.BadCount() != 0)
+ ioprintf(out,_("%lu not fully installed or removed.\n"),
+ Dep.BadCount());
+}
+ /*}}}*/
+// YnPrompt - Yes No Prompt. /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns true on a Yes.*/
+bool YnPrompt(bool Default)
+{
+ /* nl_langinfo does not support LANGUAGE setting, so we unset it here
+ to have the help-message (hopefully) match the expected characters */
+ char * language = getenv("LANGUAGE");
+ if (language != NULL)
+ language = strdup(language);
+ if (language != NULL)
+ unsetenv("LANGUAGE");
+
+ if (Default == true)
+ // TRANSLATOR: Yes/No question help-text: defaulting to Y[es]
+ // e.g. "Do you want to continue? [Y/n] "
+ // The user has to answer with an input matching the
+ // YESEXPR/NOEXPR defined in your l10n.
+ c2out << " " << _("[Y/n]") << " " << std::flush;
+ else
+ // TRANSLATOR: Yes/No question help-text: defaulting to N[o]
+ // e.g. "Should this file be removed? [y/N] "
+ // The user has to answer with an input matching the
+ // YESEXPR/NOEXPR defined in your l10n.
+ c2out << " " << _("[y/N]") << " " << std::flush;
+
+ if (language != NULL)
+ {
+ setenv("LANGUAGE", language, 0);
+ free(language);
+ }
+
+ if (_config->FindB("APT::Get::Assume-Yes",false) == true)
+ {
+ // TRANSLATOR: "Yes" answer printed for a yes/no question if --assume-yes is set
+ c1out << _("Y") << std::endl;
+ return true;
+ }
+ else if (_config->FindB("APT::Get::Assume-No",false) == true)
+ {
+ // TRANSLATOR: "No" answer printed for a yes/no question if --assume-no is set
+ c1out << _("N") << std::endl;
+ return false;
+ }
+
+ char response[1024] = "";
+ std::cin.getline(response, sizeof(response));
+
+ if (!std::cin)
+ return false;
+
+ if (strlen(response) == 0)
+ return Default;
+
+ regex_t Pattern;
+ int Res;
+
+ Res = regcomp(&Pattern, nl_langinfo(YESEXPR),
+ REG_EXTENDED|REG_ICASE|REG_NOSUB);
+
+ if (Res != 0) {
+ char Error[300];
+ regerror(Res,&Pattern,Error,sizeof(Error));
+ return _error->Error(_("Regex compilation error - %s"),Error);
+ }
+
+ Res = regexec(&Pattern, response, 0, NULL, 0);
+ if (Res == 0)
+ return true;
+ return false;
+}
+ /*}}}*/
+// AnalPrompt - Annoying Yes No Prompt. /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns true on a Yes.*/
+bool AnalPrompt(const char *Text)
+{
+ char Buf[1024];
+ std::cin.getline(Buf,sizeof(Buf));
+ if (strcmp(Buf,Text) == 0)
+ return true;
+ return false;
+}
+ /*}}}*/
diff --git a/apt-private/private-output.h b/apt-private/private-output.h
new file mode 100644
index 000000000..9283e39ab
--- /dev/null
+++ b/apt-private/private-output.h
@@ -0,0 +1,49 @@
+#ifndef APT_PRIVATE_OUTPUT_H
+#define APT_PRIVATE_OUTPUT_H
+
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include "private-cachefile.h"
+
+// forward declaration
+class pkgCacheFile;
+class CacheFile;
+class pkgCache;
+class pkgDepCache;
+class pkgRecords;
+
+
+extern std::ostream c0out;
+extern std::ostream c1out;
+extern std::ostream c2out;
+extern std::ofstream devnull;
+extern unsigned int ScreenWidth;
+
+bool InitOutput();
+void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records,
+ pkgCache::VerIterator V, std::ostream &out);
+
+
+
+bool ShowList(std::ostream &out, std::string Title, std::string List,
+ std::string VersionsList);
+void ShowBroken(std::ostream &out,CacheFile &Cache,bool Now);
+void ShowNew(std::ostream &out,CacheFile &Cache);
+void ShowDel(std::ostream &out,CacheFile &Cache);
+void ShowKept(std::ostream &out,CacheFile &Cache);
+void ShowUpgraded(std::ostream &out,CacheFile &Cache);
+bool ShowDowngraded(std::ostream &out,CacheFile &Cache);
+bool ShowHold(std::ostream &out,CacheFile &Cache);
+
+bool ShowEssential(std::ostream &out,CacheFile &Cache);
+
+void Stats(std::ostream &out, pkgDepCache &Dep);
+
+// prompting
+bool YnPrompt(bool Default=true);
+bool AnalPrompt(const char *Text);
+
+#endif
diff --git a/apt-private/private-search.cc b/apt-private/private-search.cc
new file mode 100644
index 000000000..6881f482f
--- /dev/null
+++ b/apt-private/private-search.cc
@@ -0,0 +1,99 @@
+#include <apt-pkg/error.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cachefilter.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/policy.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/indexfile.h>
+#include <apt-pkg/metaindex.h>
+
+#include <sstream>
+#include <utility>
+#include <cassert>
+#include <locale.h>
+#include <iostream>
+#include <unistd.h>
+#include <errno.h>
+#include <regex.h>
+#include <stdio.h>
+#include <iomanip>
+#include <algorithm>
+#include <map>
+
+#include "private-search.h"
+#include "private-cacheset.h"
+
+
+bool FullTextSearch(CommandLine &CmdL)
+{
+ pkgCacheFile CacheFile;
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ pkgDepCache::Policy *Plcy = CacheFile.GetPolicy();
+ pkgRecords records(CacheFile);
+ if (unlikely(Cache == NULL || Plcy == NULL))
+ return false;
+
+ const char **patterns;
+ patterns = CmdL.FileList + 1;
+
+ std::map<std::string, std::string> output_map;
+ std::map<std::string, std::string>::const_iterator K;
+
+ LocalitySortedVersionSet bag;
+ OpTextProgress progress;
+ progress.OverallProgress(0, 100, 50, _("Sorting"));
+ GetLocalitySortedVersionSet(CacheFile, bag, progress);
+ LocalitySortedVersionSet::iterator V = bag.begin();
+
+ progress.OverallProgress(50, 100, 50, _("Full Text Search"));
+ progress.SubProgress(bag.size());
+ int Done = 0;
+ for ( ;V != bag.end(); V++)
+ {
+ if (Done%500 == 0)
+ progress.Progress(Done);
+ Done++;
+
+ int i;
+ pkgCache::DescIterator Desc = V.TranslatedDescription();
+ pkgRecords::Parser &parser = records.Lookup(Desc.FileList());
+
+ bool all_found = true;
+ for(i=0; patterns[i] != NULL; i++)
+ {
+ // FIXME: use regexp instead of simple find()
+ const char *pattern = patterns[i];
+ all_found &= (
+ strstr(V.ParentPkg().Name(), pattern) != NULL ||
+ parser.ShortDesc().find(pattern) != std::string::npos ||
+ parser.LongDesc().find(pattern) != std::string::npos);
+ }
+ if (all_found)
+ {
+ std::stringstream outs;
+ ListSingleVersion(CacheFile, records, V, outs);
+ output_map.insert(std::make_pair<std::string, std::string>(
+ V.ParentPkg().Name(), outs.str()));
+ }
+ }
+ progress.Done();
+
+ // FIXME: SORT! and make sorting flexible (alphabetic, by pkg status)
+ // output the sorted map
+ for (K = output_map.begin(); K != output_map.end(); K++)
+ std::cout << (*K).second << std::endl;
+
+ return true;
+}
diff --git a/apt-private/private-search.h b/apt-private/private-search.h
new file mode 100644
index 000000000..17faffebc
--- /dev/null
+++ b/apt-private/private-search.h
@@ -0,0 +1,9 @@
+#ifndef APT_PRIVATE_SEARCH_H
+#define APT_PRIVATE_SEARCH_H
+
+#include <apt-pkg/cmndline.h>
+
+bool FullTextSearch(CommandLine &CmdL);
+
+
+#endif
diff --git a/apt-private/private-show.cc b/apt-private/private-show.cc
new file mode 100644
index 000000000..e26a2b30a
--- /dev/null
+++ b/apt-private/private-show.cc
@@ -0,0 +1,122 @@
+#include <apt-pkg/error.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cachefilter.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/policy.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/indexfile.h>
+#include <apt-pkg/metaindex.h>
+
+#include <apti18n.h>
+
+#include "private-output.h"
+#include "private-cacheset.h"
+
+namespace APT {
+ namespace Cmd {
+
+// DisplayRecord - Displays the complete record for the package /*{{{*/
+// ---------------------------------------------------------------------
+bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V,
+ ostream &out)
+{
+ pkgCache *Cache = CacheFile.GetPkgCache();
+ if (unlikely(Cache == NULL))
+ return false;
+
+ // Find an appropriate file
+ pkgCache::VerFileIterator Vf = V.FileList();
+ for (; Vf.end() == false; ++Vf)
+ if ((Vf.File()->Flags & pkgCache::Flag::NotSource) == 0)
+ break;
+ if (Vf.end() == true)
+ Vf = V.FileList();
+
+ // Check and load the package list file
+ pkgCache::PkgFileIterator I = Vf.File();
+ if (I.IsOk() == false)
+ return _error->Error(_("Package file %s is out of sync."),I.FileName());
+
+ // Read the record
+ FileFd PkgF;
+ if (PkgF.Open(I.FileName(), FileFd::ReadOnly, FileFd::Extension) == false)
+ return false;
+ pkgTagSection Tags;
+ pkgTagFile TagF(&PkgF);
+
+ TFRewriteData RW[] = {
+ {"Conffiles",0},
+ {"Description",0},
+ {"Description-md5",0},
+ {}
+ };
+ const char *Zero = 0;
+ if (TagF.Jump(Tags, V.FileList()->Offset) == false ||
+ TFRewrite(stdout,Tags,&Zero,RW) == false)
+ {
+ _error->Error("Internal Error, Unable to parse a package record");
+ return false;
+ }
+
+ // write the description
+ pkgRecords Recs(*Cache);
+ pkgCache::DescIterator Desc = V.TranslatedDescription();
+ if (Desc.end() == false)
+ {
+ pkgRecords::Parser &P = Recs.Lookup(Desc.FileList());
+ if (strcmp(Desc.LanguageCode(),"") != 0)
+ out << "Description-lang: " << Desc.LanguageCode() << std::endl;
+ out << "Description" << P.LongDesc();
+ }
+
+ // write a final newline (after the description)
+ out << std::endl << std::endl;
+
+ return true;
+}
+ /*}}}*/
+
+bool ShowPackage(CommandLine &CmdL)
+{
+ pkgCacheFile CacheFile;
+ CacheSetHelperVirtuals helper(true, GlobalError::NOTICE);
+ APT::VersionList::Version const select = APT::VersionList::CANDIDATE;
+ APT::VersionList const verset = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, select, helper);
+ for (APT::VersionList::const_iterator Ver = verset.begin(); Ver != verset.end(); ++Ver)
+ if (DisplayRecord(CacheFile, Ver, c1out) == false)
+ return false;
+
+ for (APT::PackageSet::const_iterator Pkg = helper.virtualPkgs.begin();
+ Pkg != helper.virtualPkgs.end(); ++Pkg)
+ {
+ c1out << "Package: " << Pkg.FullName(true) << std::endl;
+ c1out << "State: " << _("not a real pacakge (virtual)") << std::endl;
+ // FIXME: show providers, see private-cacheset.h
+ // CacheSetHelperAPTGet::showVirtualPackageErrors()
+ }
+
+ if (verset.empty() == true)
+ {
+ if (helper.virtualPkgs.empty() == true)
+ return _error->Error(_("No packages found"));
+ else
+ _error->Notice(_("No packages found"));
+ }
+
+ return true;
+}
+ /*}}}*/
+} // namespace Cmd
+} // namespace APT
diff --git a/apt-private/private-show.h b/apt-private/private-show.h
new file mode 100644
index 000000000..b428c7af0
--- /dev/null
+++ b/apt-private/private-show.h
@@ -0,0 +1,12 @@
+#ifndef APT_PRIVATE_SHOW_H
+#define APT_PRIVATE_SHOW_H
+
+#include <apt-pkg/cmndline.h>
+
+namespace APT {
+ namespace Cmd {
+
+ bool ShowPackage(CommandLine &CmdL);
+ }
+}
+#endif
diff --git a/apt-private/private-update.cc b/apt-private/private-update.cc
new file mode 100644
index 000000000..61259748d
--- /dev/null
+++ b/apt-private/private-update.cc
@@ -0,0 +1,93 @@
+// Include files /*{{{*/
+#include<config.h>
+
+#include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/clean.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/md5.h>
+#include <apt-pkg/versionmatch.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/indexfile.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "private-cachefile.h"
+#include "private-output.h"
+#include "acqprogress.h"
+
+#include <apti18n.h>
+ /*}}}*/
+
+// DoUpdate - Update the package lists /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DoUpdate(CommandLine &CmdL)
+{
+ if (CmdL.FileSize() != 1)
+ return _error->Error(_("The update command takes no arguments"));
+
+ CacheFile Cache;
+
+ // Get the source list
+ if (Cache.BuildSourceList() == false)
+ return false;
+ pkgSourceList *List = Cache.GetSourceList();
+
+ // Create the progress
+ AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
+
+ // Just print out the uris an exit if the --print-uris flag was used
+ if (_config->FindB("APT::Get::Print-URIs") == true)
+ {
+ // force a hashsum for compatibility reasons
+ _config->CndSet("Acquire::ForceHash", "md5sum");
+
+ // get a fetcher
+ pkgAcquire Fetcher;
+ if (Fetcher.Setup(&Stat) == false)
+ return false;
+
+ // Populate it with the source selection and get all Indexes
+ // (GetAll=true)
+ if (List->GetIndexes(&Fetcher,true) == false)
+ return false;
+
+ pkgAcquire::UriIterator I = Fetcher.UriBegin();
+ for (; I != Fetcher.UriEnd(); ++I)
+ c1out << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
+ I->Owner->FileSize << ' ' << I->Owner->HashSum() << std::endl;
+ return true;
+ }
+
+ // do the work
+ if (_config->FindB("APT::Get::Download",true) == true)
+ ListUpdate(Stat, *List);
+
+ // Rebuild the cache.
+ if (_config->FindB("pkgCacheFile::Generate", true) == true)
+ {
+ pkgCacheFile::RemoveCaches();
+ if (Cache.BuildCaches() == false)
+ return false;
+ }
+
+ return true;
+}
+ /*}}}*/
diff --git a/apt-private/private-update.h b/apt-private/private-update.h
new file mode 100644
index 000000000..d3d0b7af9
--- /dev/null
+++ b/apt-private/private-update.h
@@ -0,0 +1,8 @@
+#ifndef APT_PRIVATE_UPDATE_H
+#define APT_PRIVATE_UPDATE_H
+
+class CommandLine;
+
+bool DoUpdate(CommandLine &CmdL);
+
+#endif
diff --git a/apt-private/private-upgrade.cc b/apt-private/private-upgrade.cc
new file mode 100644
index 000000000..85b5a492a
--- /dev/null
+++ b/apt-private/private-upgrade.cc
@@ -0,0 +1,47 @@
+
+#include <apt-pkg/algorithms.h>
+
+#include "private-install.h"
+#include "private-cachefile.h"
+#include "private-upgrade.h"
+#include "private-output.h"
+
+
+// DoUpgradeNoNewPackages - Upgrade all packages /*{{{*/
+// ---------------------------------------------------------------------
+/* Upgrade all packages without installing new packages or erasing old
+ packages */
+bool DoUpgradeNoNewPackages(CommandLine &CmdL)
+{
+ CacheFile Cache;
+ if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
+ return false;
+
+ // Do the upgrade
+ if (pkgAllUpgrade(Cache) == false)
+ {
+ ShowBroken(c1out,Cache,false);
+ return _error->Error(_("Internal error, AllUpgrade broke stuff"));
+ }
+
+ return InstallPackages(Cache,true);
+}
+ /*}}}*/
+
+// DoSafeUpgrade - Upgrade all packages with install but not remove /*{{{*/
+bool DoUpgradeWithAllowNewPackages(CommandLine &CmdL)
+{
+ CacheFile Cache;
+ if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
+ return false;
+
+ // Do the upgrade
+ if (pkgAllUpgradeNoDelete(Cache) == false)
+ {
+ ShowBroken(c1out,Cache,false);
+ return _error->Error(_("Internal error, AllUpgrade broke stuff"));
+ }
+
+ return InstallPackages(Cache,true);
+}
+ /*}}}*/
diff --git a/apt-private/private-upgrade.h b/apt-private/private-upgrade.h
new file mode 100644
index 000000000..6ede6f96c
--- /dev/null
+++ b/apt-private/private-upgrade.h
@@ -0,0 +1,11 @@
+#ifndef APTPRIVATE_PRIVATE_UPGRADE_H
+#define APTPRIVATE_PRIVATE_UPGRADE_H
+
+#include <apt-pkg/cmndline.h>
+
+
+bool DoUpgradeNoNewPackages(CommandLine &CmdL);
+bool DoUpgradeWithAllowNewPackages(CommandLine &CmdL);
+
+
+#endif
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc
index e847de875..b8892d23d 100644
--- a/cmdline/apt-cache.cc
+++ b/cmdline/apt-cache.cc
@@ -35,6 +35,11 @@
#include <apt-pkg/indexfile.h>
#include <apt-pkg/metaindex.h>
+#include <apt-private/private-list.h>
+#include <apt-private/private-cmndline.h>
+#include <apt-private/private-show.h>
+#include <apt-private/private-cacheset.h>
+
#include <cassert>
#include <locale.h>
#include <iostream>
@@ -50,29 +55,6 @@
using namespace std;
-// CacheSetHelper saving virtual packages /*{{{*/
-class CacheSetHelperVirtuals: public APT::CacheSetHelper {
-public:
- APT::PackageSet virtualPkgs;
-
- virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
- virtualPkgs.insert(Pkg);
- return CacheSetHelper::canNotFindCandidateVer(Cache, Pkg);
- }
-
- virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
- virtualPkgs.insert(Pkg);
- return CacheSetHelper::canNotFindNewestVer(Cache, Pkg);
- }
-
- virtual void canNotFindAllVer(APT::VersionContainerInterface * vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
- virtualPkgs.insert(Pkg);
- CacheSetHelper::canNotFindAllVer(vci, Cache, Pkg);
- }
-
- CacheSetHelperVirtuals(bool const ShowErrors = true, GlobalError::MsgType const &ErrorType = GlobalError::NOTICE) : CacheSetHelper(ShowErrors, ErrorType) {}
-};
- /*}}}*/
// LocalitySort - Sort a version list by package file locality /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -396,42 +378,42 @@ bool Dump(CommandLine &Cmd)
if (unlikely(Cache == NULL))
return false;
- cout << "Using Versioning System: " << Cache->VS->Label << endl;
+ std::cout << "Using Versioning System: " << Cache->VS->Label << std::endl;
for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
{
- cout << "Package: " << P.FullName(true) << endl;
+ std::cout << "Package: " << P.FullName(true) << std::endl;
for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V)
{
- cout << " Version: " << V.VerStr() << endl;
- cout << " File: " << V.FileList().File().FileName() << endl;
+ std::cout << " Version: " << V.VerStr() << std::endl;
+ std::cout << " File: " << V.FileList().File().FileName() << std::endl;
for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ++D)
- cout << " Depends: " << D.TargetPkg().FullName(true) << ' ' <<
- DeNull(D.TargetVer()) << endl;
+ std::cout << " Depends: " << D.TargetPkg().FullName(true) << ' ' <<
+ DeNull(D.TargetVer()) << std::endl;
for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; ++D)
{
- cout << " Description Language: " << D.LanguageCode() << endl
- << " File: " << D.FileList().File().FileName() << endl
- << " MD5: " << D.md5() << endl;
+ std::cout << " Description Language: " << D.LanguageCode() << std::endl
+ << " File: " << D.FileList().File().FileName() << std::endl
+ << " MD5: " << D.md5() << std::endl;
}
}
}
for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F.end() == false; ++F)
{
- cout << "File: " << F.FileName() << endl;
- cout << " Type: " << F.IndexType() << endl;
- cout << " Size: " << F->Size << endl;
- cout << " ID: " << F->ID << endl;
- cout << " Flags: " << F->Flags << endl;
- cout << " Time: " << TimeRFC1123(F->mtime) << endl;
- cout << " Archive: " << DeNull(F.Archive()) << endl;
- cout << " Component: " << DeNull(F.Component()) << endl;
- cout << " Version: " << DeNull(F.Version()) << endl;
- cout << " Origin: " << DeNull(F.Origin()) << endl;
- cout << " Site: " << DeNull(F.Site()) << endl;
- cout << " Label: " << DeNull(F.Label()) << endl;
- cout << " Architecture: " << DeNull(F.Architecture()) << endl;
+ std::cout << "File: " << F.FileName() << std::endl;
+ std::cout << " Type: " << F.IndexType() << std::endl;
+ std::cout << " Size: " << F->Size << std::endl;
+ std::cout << " ID: " << F->ID << std::endl;
+ std::cout << " Flags: " << F->Flags << std::endl;
+ std::cout << " Time: " << TimeRFC1123(F->mtime) << std::endl;
+ std::cout << " Archive: " << DeNull(F.Archive()) << std::endl;
+ std::cout << " Component: " << DeNull(F.Component()) << std::endl;
+ std::cout << " Version: " << DeNull(F.Version()) << std::endl;
+ std::cout << " Origin: " << DeNull(F.Origin()) << std::endl;
+ std::cout << " Site: " << DeNull(F.Site()) << std::endl;
+ std::cout << " Label: " << DeNull(F.Label()) << std::endl;
+ std::cout << " Architecture: " << DeNull(F.Architecture()) << std::endl;
}
return true;
@@ -627,8 +609,7 @@ bool ShowDepends(CommandLine &CmdL, bool const RevDepends)
case pkgCache::Dep::Depends: if (!ShowDepends) continue; break;
case pkgCache::Dep::Recommends: if (!ShowRecommends) continue; break;
case pkgCache::Dep::Suggests: if (!ShowSuggests) continue; break;
- case pkgCache::Dep::Replaces: if (!ShowReplaces) continue; break;
- case pkgCache::Dep::Conflicts: if (!ShowConflicts) continue; break;
+ case pkgCache::Dep::Replaces: if (!ShowReplaces) continue; break; case pkgCache::Dep::Conflicts: if (!ShowConflicts) continue; break;
case pkgCache::Dep::DpkgBreaks: if (!ShowBreaks) continue; break;
case pkgCache::Dep::Enhances: if (!ShowEnhances) continue; break;
}
@@ -1238,7 +1219,6 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
return true;
}
/*}}}*/
-
struct ExDescFile
{
pkgCache::DescFile *Df;
@@ -1795,38 +1775,10 @@ bool ShowHelp(CommandLine &Cmd)
/*}}}*/
int main(int argc,const char *argv[]) /*{{{*/
{
- CommandLine::Args Args[] = {
- {'h',"help","help",0},
- {'v',"version","version",0},
- {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg},
- {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg},
- {'q',"quiet","quiet",CommandLine::IntLevel},
- {'i',"important","APT::Cache::Important",0},
- {'f',"full","APT::Cache::ShowFull",0},
- {'g',"generate","APT::Cache::Generate",0},
- {'a',"all-versions","APT::Cache::AllVersions",0},
- {'n',"names-only","APT::Cache::NamesOnly",0},
- {0,"all-names","APT::Cache::AllNames",0},
- {0,"recurse","APT::Cache::RecurseDepends",0},
- {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
- {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
- {'c',"config-file",0,CommandLine::ConfigFile},
- {'o',"option",0,CommandLine::ArbItem},
- {0,"installed","APT::Cache::Installed",0},
- {0,"pre-depends","APT::Cache::ShowPre-Depends",0},
- {0,"depends","APT::Cache::ShowDepends",0},
- {0,"recommends","APT::Cache::ShowRecommends",0},
- {0,"suggests","APT::Cache::ShowSuggests",0},
- {0,"replaces","APT::Cache::ShowReplaces",0},
- {0,"breaks","APT::Cache::ShowBreaks",0},
- {0,"conflicts","APT::Cache::ShowConflicts",0},
- {0,"enhances","APT::Cache::ShowEnhances",0},
- {0,0,0,0}};
- CommandLine::Dispatch CmdsA[] = {{"help",&ShowHelp},
+ CommandLine::Dispatch Cmds[] = {{"help",&ShowHelp},
{"gencaches",&GenCaches},
{"showsrc",&ShowSrcPackage},
- {0,0}};
- CommandLine::Dispatch CmdsB[] = {{"showpkg",&DumpPackage},
+ {"showpkg",&DumpPackage},
{"stats",&Stats},
{"dump",&Dump},
{"dumpavail",&DumpAvail},
@@ -1843,12 +1795,14 @@ int main(int argc,const char *argv[]) /*{{{*/
{"madison",&Madison},
{0,0}};
+ std::vector<CommandLine::Args> Args = getCommandArgs("apt-cache", CommandLine::GetCommand(Cmds, argc, argv));
+
// Set up gettext support
setlocale(LC_ALL,"");
textdomain(PACKAGE);
// Parse the command line and initialize the package library
- CommandLine CmdL(Args,_config);
+ CommandLine CmdL(Args.data(),_config);
if (pkgInitConfig(*_config) == false ||
CmdL.Parse(argc,argv) == false ||
pkgInitSystem(*_config,_system) == false)
@@ -1872,8 +1826,8 @@ int main(int argc,const char *argv[]) /*{{{*/
if (_config->Exists("APT::Cache::Generate") == true)
_config->Set("pkgCacheFile::Generate", _config->FindB("APT::Cache::Generate", true));
- if (CmdL.DispatchArg(CmdsA,false) == false && _error->PendingError() == false)
- CmdL.DispatchArg(CmdsB);
+ // Match the operation
+ CmdL.DispatchArg(Cmds);
// Print any errors or warnings found during parsing
bool const Errors = _error->PendingError();
diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc
index a95970782..17a60ddcb 100644
--- a/cmdline/apt-cdrom.cc
+++ b/cmdline/apt-cdrom.cc
@@ -37,6 +37,8 @@
#include <unistd.h>
#include <stdio.h>
+#include <apt-private/private-cmndline.h>
+
#include <apti18n.h>
/*}}}*/
static const char *W_NO_CDROM_FOUND = \
@@ -203,12 +205,12 @@ bool DoIdent(CommandLine &)
// ShowHelp - Show the help screen /*{{{*/
// ---------------------------------------------------------------------
/* */
-int ShowHelp()
+bool ShowHelp(CommandLine &)
{
ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION,
COMMON_ARCH,__DATE__,__TIME__);
if (_config->FindB("version") == true)
- return 0;
+ return true;
cout <<
"Usage: apt-cdrom [options] command\n"
@@ -232,37 +234,25 @@ int ShowHelp()
" -c=? Read this configuration file\n"
" -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
"See fstab(5)\n";
- return 0;
+ return true;
}
/*}}}*/
int main(int argc,const char *argv[]) /*{{{*/
{
- CommandLine::Args Args[] = {
- {'h',"help","help",0},
- { 0,"auto-detect","Acquire::cdrom::AutoDetect", CommandLine::Boolean},
- {'v',"version","version",0},
- {'d',"cdrom","Acquire::cdrom::mount",CommandLine::HasArg},
- {'r',"rename","APT::CDROM::Rename",0},
- {'m',"no-mount","APT::CDROM::NoMount",0},
- {'f',"fast","APT::CDROM::Fast",0},
- {'n',"just-print","APT::CDROM::NoAct",0},
- {'n',"recon","APT::CDROM::NoAct",0},
- {'n',"no-act","APT::CDROM::NoAct",0},
- {'a',"thorough","APT::CDROM::Thorough",0},
- {'c',"config-file",0,CommandLine::ConfigFile},
- {'o',"option",0,CommandLine::ArbItem},
- {0,0,0,0}};
CommandLine::Dispatch Cmds[] = {
{"add",&DoAdd},
{"ident",&DoIdent},
+ {"help",&ShowHelp},
{0,0}};
+ std::vector<CommandLine::Args> Args = getCommandArgs("apt-cdrom", CommandLine::GetCommand(Cmds, argc, argv));
+
// Set up gettext support
setlocale(LC_ALL,"");
textdomain(PACKAGE);
// Parse the command line and initialize the package library
- CommandLine CmdL(Args,_config);
+ CommandLine CmdL(Args.data(),_config);
if (pkgInitConfig(*_config) == false ||
CmdL.Parse(argc,argv) == false ||
pkgInitSystem(*_config,_system) == false)
@@ -274,7 +264,7 @@ int main(int argc,const char *argv[]) /*{{{*/
// See if the help should be shown
if (_config->FindB("help") == true || _config->FindB("version") == true ||
CmdL.FileSize() == 0)
- return ShowHelp();
+ return ShowHelp(CmdL);
// Deal with stdout not being a tty
if (isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
diff --git a/cmdline/apt-config.cc b/cmdline/apt-config.cc
index 397ce32df..3481eaf5f 100644
--- a/cmdline/apt-config.cc
+++ b/cmdline/apt-config.cc
@@ -31,6 +31,8 @@
#include <string>
#include <vector>
+#include <apt-private/private-cmndline.h>
+
#include <apti18n.h>
/*}}}*/
using namespace std;
@@ -76,12 +78,12 @@ bool DoDump(CommandLine &CmdL)
// ShowHelp - Show the help screen /*{{{*/
// ---------------------------------------------------------------------
/* */
-int ShowHelp()
+bool ShowHelp(CommandLine &CmdL)
{
ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION,
COMMON_ARCH,__DATE__,__TIME__);
if (_config->FindB("version") == true)
- return 0;
+ return true;
cout <<
_("Usage: apt-config [options] command\n"
@@ -96,29 +98,24 @@ int ShowHelp()
" -h This help text.\n"
" -c=? Read this configuration file\n"
" -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n");
- return 0;
+ return true;
}
/*}}}*/
int main(int argc,const char *argv[]) /*{{{*/
{
- CommandLine::Args Args[] = {
- {'h',"help","help",0},
- {'v',"version","version",0},
- {'c',"config-file",0,CommandLine::ConfigFile},
- {'o',"option",0,CommandLine::ArbItem},
- {0,"empty","APT::Config::Dump::EmptyValue",CommandLine::Boolean},
- {0,"format","APT::Config::Dump::Format",CommandLine::HasArg},
- {0,0,0,0}};
CommandLine::Dispatch Cmds[] = {{"shell",&DoShell},
{"dump",&DoDump},
+ {"help",&ShowHelp},
{0,0}};
+ std::vector<CommandLine::Args> Args = getCommandArgs("apt-cdrom", CommandLine::GetCommand(Cmds, argc, argv));
+
// Set up gettext support
setlocale(LC_ALL,"");
textdomain(PACKAGE);
// Parse the command line and initialize the package library
- CommandLine CmdL(Args,_config);
+ CommandLine CmdL(Args.data(),_config);
if (pkgInitConfig(*_config) == false ||
CmdL.Parse(argc,argv) == false ||
pkgInitSystem(*_config,_system) == false)
@@ -130,7 +127,7 @@ int main(int argc,const char *argv[]) /*{{{*/
// See if the help should be shown
if (_config->FindB("help") == true ||
CmdL.FileSize() == 0)
- return ShowHelp();
+ return ShowHelp(CmdL);
std::vector<std::string> const langs = APT::Configuration::getLanguages(true);
_config->Clear("Acquire::Languages");
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index 4b7691d93..06dbbce5b 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -50,7 +50,16 @@
#include <apt-pkg/pkgrecords.h>
#include <apt-pkg/indexfile.h>
-#include "acqprogress.h"
+
+#include <apt-private/private-install.h>
+#include <apt-private/private-upgrade.h>
+#include <apt-private/private-output.h>
+#include <apt-private/private-cacheset.h>
+#include <apt-private/private-update.h>
+#include <apt-private/private-cmndline.h>
+#include <apt-private/private-moo.h>
+
+#include <apt-private/acqprogress.h>
#include <set>
#include <locale.h>
@@ -69,1391 +78,17 @@
#include <sys/wait.h>
#include <sstream>
+#include <apt-private/private-output.h>
+#include <apt-private/private-main.h>
+
#include <apti18n.h>
/*}}}*/
-#define RAMFS_MAGIC 0x858458f6
using namespace std;
-ostream c0out(0);
-ostream c1out(0);
-ostream c2out(0);
-ofstream devnull("/dev/null");
-unsigned int ScreenWidth = 80 - 1; /* - 1 for the cursor */
-
-// class CacheFile - Cover class for some dependency cache functions /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-class CacheFile : public pkgCacheFile
-{
- static pkgCache *SortCache;
- static int NameComp(const void *a,const void *b);
-
- public:
- pkgCache::Package **List;
-
- void Sort();
- bool CheckDeps(bool AllowBroken = false);
- bool BuildCaches(bool WithLock = true)
- {
- OpTextProgress Prog(*_config);
- if (pkgCacheFile::BuildCaches(&Prog,WithLock) == false)
- return false;
- return true;
- }
- bool Open(bool WithLock = true)
- {
- OpTextProgress Prog(*_config);
- if (pkgCacheFile::Open(&Prog,WithLock) == false)
- return false;
- Sort();
-
- return true;
- };
- bool OpenForInstall()
- {
- if (_config->FindB("APT::Get::Print-URIs") == true)
- return Open(false);
- else
- return Open(true);
- }
- CacheFile() : List(0) {};
- ~CacheFile() {
- delete[] List;
- }
-};
- /*}}}*/
-
-// YnPrompt - Yes No Prompt. /*{{{*/
-// ---------------------------------------------------------------------
-/* Returns true on a Yes.*/
-bool YnPrompt(bool Default=true)
-{
- /* nl_langinfo does not support LANGUAGE setting, so we unset it here
- to have the help-message (hopefully) match the expected characters */
- char * language = getenv("LANGUAGE");
- if (language != NULL)
- language = strdup(language);
- if (language != NULL)
- unsetenv("LANGUAGE");
-
- if (Default == true)
- // TRANSLATOR: Yes/No question help-text: defaulting to Y[es]
- // e.g. "Do you want to continue? [Y/n] "
- // The user has to answer with an input matching the
- // YESEXPR/NOEXPR defined in your l10n.
- c2out << " " << _("[Y/n]") << " " << std::flush;
- else
- // TRANSLATOR: Yes/No question help-text: defaulting to N[o]
- // e.g. "Should this file be removed? [y/N] "
- // The user has to answer with an input matching the
- // YESEXPR/NOEXPR defined in your l10n.
- c2out << " " << _("[y/N]") << " " << std::flush;
-
- if (language != NULL)
- {
- setenv("LANGUAGE", language, 0);
- free(language);
- }
-
- if (_config->FindB("APT::Get::Assume-Yes",false) == true)
- {
- // TRANSLATOR: "Yes" answer printed for a yes/no question if --assume-yes is set
- c1out << _("Y") << endl;
- return true;
- }
- else if (_config->FindB("APT::Get::Assume-No",false) == true)
- {
- // TRANSLATOR: "No" answer printed for a yes/no question if --assume-no is set
- c1out << _("N") << endl;
- return false;
- }
-
- char response[1024] = "";
- cin.getline(response, sizeof(response));
-
- if (!cin)
- return false;
-
- if (strlen(response) == 0)
- return Default;
-
- regex_t Pattern;
- int Res;
-
- Res = regcomp(&Pattern, nl_langinfo(YESEXPR),
- REG_EXTENDED|REG_ICASE|REG_NOSUB);
-
- if (Res != 0) {
- char Error[300];
- regerror(Res,&Pattern,Error,sizeof(Error));
- return _error->Error(_("Regex compilation error - %s"),Error);
- }
-
- Res = regexec(&Pattern, response, 0, NULL, 0);
- if (Res == 0)
- return true;
- return false;
-}
- /*}}}*/
-// AnalPrompt - Annoying Yes No Prompt. /*{{{*/
-// ---------------------------------------------------------------------
-/* Returns true on a Yes.*/
-bool AnalPrompt(const char *Text)
-{
- char Buf[1024];
- cin.getline(Buf,sizeof(Buf));
- if (strcmp(Buf,Text) == 0)
- return true;
- return false;
-}
- /*}}}*/
-// ShowList - Show a list /*{{{*/
-// ---------------------------------------------------------------------
-/* This prints out a string of space separated words with a title and
- a two space indent line wraped to the current screen width. */
-bool ShowList(ostream &out,string Title,string List,string VersionsList)
-{
- if (List.empty() == true)
- return true;
- // trim trailing space
- int NonSpace = List.find_last_not_of(' ');
- if (NonSpace != -1)
- {
- List = List.erase(NonSpace + 1);
- if (List.empty() == true)
- return true;
- }
-
- // Acount for the leading space
- int ScreenWidth = ::ScreenWidth - 3;
-
- out << Title << endl;
- string::size_type Start = 0;
- string::size_type VersionsStart = 0;
- while (Start < List.size())
- {
- if(_config->FindB("APT::Get::Show-Versions",false) == true &&
- VersionsList.size() > 0) {
- string::size_type End;
- string::size_type VersionsEnd;
-
- End = List.find(' ',Start);
- VersionsEnd = VersionsList.find('\n', VersionsStart);
-
- out << " " << string(List,Start,End - Start) << " (" <<
- string(VersionsList,VersionsStart,VersionsEnd - VersionsStart) <<
- ")" << endl;
-
- if (End == string::npos || End < Start)
- End = Start + ScreenWidth;
-
- Start = End + 1;
- VersionsStart = VersionsEnd + 1;
- } else {
- string::size_type End;
-
- if (Start + ScreenWidth >= List.size())
- End = List.size();
- else
- End = List.rfind(' ',Start+ScreenWidth);
-
- if (End == string::npos || End < Start)
- End = Start + ScreenWidth;
- out << " " << string(List,Start,End - Start) << endl;
- Start = End + 1;
- }
- }
-
- return false;
-}
- /*}}}*/
-// ShowBroken - Debugging aide /*{{{*/
-// ---------------------------------------------------------------------
-/* This prints out the names of all the packages that are broken along
- with the name of each each broken dependency and a quite version
- description.
-
- The output looks like:
- The following packages have unmet dependencies:
- exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed
- Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
- Depends: libsasl7 but it is not going to be installed
- */
-void ShowBroken(ostream &out,CacheFile &Cache,bool Now)
-{
- if (Cache->BrokenCount() == 0)
- return;
-
- out << _("The following packages have unmet dependencies:") << endl;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
-
- if (Now == true)
- {
- if (Cache[I].NowBroken() == false)
- continue;
- }
- else
- {
- if (Cache[I].InstBroken() == false)
- continue;
- }
-
- // Print out each package and the failed dependencies
- out << " " << I.FullName(true) << " :";
- unsigned const Indent = I.FullName(true).size() + 3;
- bool First = true;
- pkgCache::VerIterator Ver;
-
- if (Now == true)
- Ver = I.CurrentVer();
- else
- Ver = Cache[I].InstVerIter(Cache);
-
- if (Ver.end() == true)
- {
- out << endl;
- continue;
- }
-
- for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
- {
- // Compute a single dependency element (glob or)
- pkgCache::DepIterator Start;
- pkgCache::DepIterator End;
- D.GlobOr(Start,End); // advances D
-
- if (Cache->IsImportantDep(End) == false)
- continue;
-
- if (Now == true)
- {
- if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
- continue;
- }
- else
- {
- if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
- continue;
- }
-
- bool FirstOr = true;
- while (1)
- {
- if (First == false)
- for (unsigned J = 0; J != Indent; J++)
- out << ' ';
- First = false;
-
- if (FirstOr == false)
- {
- for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
- out << ' ';
- }
- else
- out << ' ' << End.DepType() << ": ";
- FirstOr = false;
-
- out << Start.TargetPkg().FullName(true);
-
- // Show a quick summary of the version requirements
- if (Start.TargetVer() != 0)
- out << " (" << Start.CompType() << " " << Start.TargetVer() << ")";
-
- /* Show a summary of the target package if possible. In the case
- of virtual packages we show nothing */
- pkgCache::PkgIterator Targ = Start.TargetPkg();
- if (Targ->ProvidesList == 0)
- {
- out << ' ';
- pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
- if (Now == true)
- Ver = Targ.CurrentVer();
-
- if (Ver.end() == false)
- {
- if (Now == true)
- ioprintf(out,_("but %s is installed"),Ver.VerStr());
- else
- ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
- }
- else
- {
- if (Cache[Targ].CandidateVerIter(Cache).end() == true)
- {
- if (Targ->ProvidesList == 0)
- out << _("but it is not installable");
- else
- out << _("but it is a virtual package");
- }
- else
- out << (Now?_("but it is not installed"):_("but it is not going to be installed"));
- }
- }
-
- if (Start != End)
- out << _(" or");
- out << endl;
-
- if (Start == End)
- break;
- ++Start;
- }
- }
- }
-}
- /*}}}*/
-// ShowNew - Show packages to newly install /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void ShowNew(ostream &out,CacheFile &Cache)
-{
- /* Print out a list of packages that are going to be installed extra
- to what the user asked */
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if (Cache[I].NewInstall() == true) {
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CandVersion) + "\n";
- }
- }
-
- ShowList(out,_("The following NEW packages will be installed:"),List,VersionsList);
-}
- /*}}}*/
-// ShowDel - Show packages to delete /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void ShowDel(ostream &out,CacheFile &Cache)
-{
- /* Print out a list of packages that are going to be removed extra
- to what the user asked */
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if (Cache[I].Delete() == true)
- {
- if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
- List += I.FullName(true) + "* ";
- else
- List += I.FullName(true) + " ";
-
- VersionsList += string(Cache[I].CandVersion)+ "\n";
- }
- }
-
- ShowList(out,_("The following packages will be REMOVED:"),List,VersionsList);
-}
- /*}}}*/
-// ShowKept - Show kept packages /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void ShowKept(ostream &out,CacheFile &Cache)
-{
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
-
- // Not interesting
- if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false ||
- I->CurrentVer == 0 || Cache[I].Delete() == true)
- continue;
-
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
- }
- ShowList(out,_("The following packages have been kept back:"),List,VersionsList);
-}
- /*}}}*/
-// ShowUpgraded - Show upgraded packages /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void ShowUpgraded(ostream &out,CacheFile &Cache)
-{
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
-
- // Not interesting
- if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
- continue;
-
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
- }
- ShowList(out,_("The following packages will be upgraded:"),List,VersionsList);
-}
- /*}}}*/
-// ShowDowngraded - Show downgraded packages /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool ShowDowngraded(ostream &out,CacheFile &Cache)
-{
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
-
- // Not interesting
- if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
- continue;
-
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
- }
- return ShowList(out,_("The following packages will be DOWNGRADED:"),List,VersionsList);
-}
- /*}}}*/
-// ShowHold - Show held but changed packages /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool ShowHold(ostream &out,CacheFile &Cache)
-{
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
- I->SelectedState == pkgCache::State::Hold) {
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
- }
- }
-
- return ShowList(out,_("The following held packages will be changed:"),List,VersionsList);
-}
- /*}}}*/
-// ShowEssential - Show an essential package warning /*{{{*/
-// ---------------------------------------------------------------------
-/* This prints out a warning message that is not to be ignored. It shows
- all essential packages and their dependents that are to be removed.
- It is insanely risky to remove the dependents of an essential package! */
-bool ShowEssential(ostream &out,CacheFile &Cache)
-{
- string List;
- string VersionsList;
- bool *Added = new bool[Cache->Head().PackageCount];
- for (unsigned int I = 0; I != Cache->Head().PackageCount; I++)
- Added[I] = false;
-
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
- (I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
- continue;
-
- // The essential package is being removed
- if (Cache[I].Delete() == true)
- {
- if (Added[I->ID] == false)
- {
- Added[I->ID] = true;
- List += I.FullName(true) + " ";
- //VersionsList += string(Cache[I].CurVersion) + "\n"; ???
- }
- }
- else
- continue;
-
- if (I->CurrentVer == 0)
- continue;
-
- // Print out any essential package depenendents that are to be removed
- for (pkgCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; ++D)
- {
- // Skip everything but depends
- if (D->Type != pkgCache::Dep::PreDepends &&
- D->Type != pkgCache::Dep::Depends)
- continue;
-
- pkgCache::PkgIterator P = D.SmartTargetPkg();
- if (Cache[P].Delete() == true)
- {
- if (Added[P->ID] == true)
- continue;
- Added[P->ID] = true;
-
- char S[300];
- snprintf(S,sizeof(S),_("%s (due to %s) "),P.FullName(true).c_str(),I.FullName(true).c_str());
- List += S;
- //VersionsList += "\n"; ???
- }
- }
- }
-
- delete [] Added;
- return ShowList(out,_("WARNING: The following essential packages will be removed.\n"
- "This should NOT be done unless you know exactly what you are doing!"),List,VersionsList);
-}
-
- /*}}}*/
-// Stats - Show some statistics /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void Stats(ostream &out,pkgDepCache &Dep)
-{
- unsigned long Upgrade = 0;
- unsigned long Downgrade = 0;
- unsigned long Install = 0;
- unsigned long ReInstall = 0;
- for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; ++I)
- {
- if (Dep[I].NewInstall() == true)
- Install++;
- else
- {
- if (Dep[I].Upgrade() == true)
- Upgrade++;
- else
- if (Dep[I].Downgrade() == true)
- Downgrade++;
- }
-
- if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
- ReInstall++;
- }
-
- ioprintf(out,_("%lu upgraded, %lu newly installed, "),
- Upgrade,Install);
-
- if (ReInstall != 0)
- ioprintf(out,_("%lu reinstalled, "),ReInstall);
- if (Downgrade != 0)
- ioprintf(out,_("%lu downgraded, "),Downgrade);
-
- ioprintf(out,_("%lu to remove and %lu not upgraded.\n"),
- Dep.DelCount(),Dep.KeepCount());
-
- if (Dep.BadCount() != 0)
- ioprintf(out,_("%lu not fully installed or removed.\n"),
- Dep.BadCount());
-}
- /*}}}*/
-// CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/
-class CacheSetHelperAPTGet : public APT::CacheSetHelper {
- /** \brief stream message should be printed to */
- std::ostream &out;
- /** \brief were things like Task or RegEx used to select packages? */
- bool explicitlyNamed;
-
- APT::PackageSet virtualPkgs;
-
-public:
- std::list<std::pair<pkgCache::VerIterator, std::string> > selectedByRelease;
-
- CacheSetHelperAPTGet(std::ostream &out) : APT::CacheSetHelper(true), out(out) {
- explicitlyNamed = true;
- }
-
- virtual void showTaskSelection(pkgCache::PkgIterator const &Pkg, string const &pattern) {
- ioprintf(out, _("Note, selecting '%s' for task '%s'\n"),
- Pkg.FullName(true).c_str(), pattern.c_str());
- explicitlyNamed = false;
- }
- virtual void showRegExSelection(pkgCache::PkgIterator const &Pkg, string const &pattern) {
- ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"),
- Pkg.FullName(true).c_str(), pattern.c_str());
- explicitlyNamed = false;
- }
- virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
- string const &ver, bool const verIsRel) {
- if (ver == Ver.VerStr())
- return;
- selectedByRelease.push_back(make_pair(Ver, ver));
- }
-
- bool showVirtualPackageErrors(pkgCacheFile &Cache) {
- if (virtualPkgs.empty() == true)
- return true;
- for (APT::PackageSet::const_iterator Pkg = virtualPkgs.begin();
- Pkg != virtualPkgs.end(); ++Pkg) {
- if (Pkg->ProvidesList != 0) {
- ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
- Pkg.FullName(true).c_str());
-
- pkgCache::PrvIterator I = Pkg.ProvidesList();
- unsigned short provider = 0;
- for (; I.end() == false; ++I) {
- pkgCache::PkgIterator Pkg = I.OwnerPkg();
-
- if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) {
- c1out << " " << Pkg.FullName(true) << " " << I.OwnerVer().VerStr();
- if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
- c1out << _(" [Installed]");
- c1out << endl;
- ++provider;
- }
- }
- // if we found no candidate which provide this package, show non-candidates
- if (provider == 0)
- for (I = Pkg.ProvidesList(); I.end() == false; ++I)
- c1out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr()
- << _(" [Not candidate version]") << endl;
- else
- out << _("You should explicitly select one to install.") << endl;
- } else {
- ioprintf(c1out,
- _("Package %s is not available, but is referred to by another package.\n"
- "This may mean that the package is missing, has been obsoleted, or\n"
- "is only available from another source\n"),Pkg.FullName(true).c_str());
-
- string List;
- string VersionsList;
- SPtrArray<bool> Seen = new bool[Cache.GetPkgCache()->Head().PackageCount];
- memset(Seen,0,Cache.GetPkgCache()->Head().PackageCount*sizeof(*Seen));
- for (pkgCache::DepIterator Dep = Pkg.RevDependsList();
- Dep.end() == false; ++Dep) {
- if (Dep->Type != pkgCache::Dep::Replaces)
- continue;
- if (Seen[Dep.ParentPkg()->ID] == true)
- continue;
- Seen[Dep.ParentPkg()->ID] = true;
- List += Dep.ParentPkg().FullName(true) + " ";
- //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ???
- }
- ShowList(c1out,_("However the following packages replace it:"),List,VersionsList);
- }
- c1out << std::endl;
- }
- return false;
- }
-
- virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
- APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDIDATE);
- if (verset.empty() == false)
- return *(verset.begin());
- else if (ShowError == true) {
- _error->Error(_("Package '%s' has no installation candidate"),Pkg.FullName(true).c_str());
- virtualPkgs.insert(Pkg);
- }
- return pkgCache::VerIterator(Cache, 0);
- }
-
- virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
- if (Pkg->ProvidesList != 0)
- {
- APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST);
- if (verset.empty() == false)
- return *(verset.begin());
- if (ShowError == true)
- ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str());
- }
- else
- {
- pkgCache::GrpIterator Grp = Pkg.Group();
- pkgCache::PkgIterator P = Grp.PackageList();
- for (; P.end() != true; P = Grp.NextPkg(P))
- {
- if (P == Pkg)
- continue;
- if (P->CurrentVer != 0) {
- // TRANSLATORS: Note, this is not an interactive question
- ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
- Pkg.FullName(true).c_str(), P.FullName(true).c_str());
- break;
- }
- }
- if (P.end() == true)
- ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str());
- }
- return pkgCache::VerIterator(Cache, 0);
- }
-
- APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg,
- APT::VersionSet::Version const &select) {
- /* This is a pure virtual package and there is a single available
- candidate providing it. */
- if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0)
- return APT::VersionSet();
-
- pkgCache::PkgIterator Prov;
- bool found_one = false;
- for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) {
- pkgCache::VerIterator const PVer = P.OwnerVer();
- pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
-
- /* Ignore versions that are not a candidate. */
- if (Cache[PPkg].CandidateVer != PVer)
- continue;
-
- if (found_one == false) {
- Prov = PPkg;
- found_one = true;
- } else if (PPkg != Prov) {
- // same group, so it's a foreign package
- if (PPkg->Group == Prov->Group) {
- // do we already have the requested arch?
- if (strcmp(Pkg.Arch(), Prov.Arch()) == 0 ||
- strcmp(Prov.Arch(), "all") == 0 ||
- unlikely(strcmp(PPkg.Arch(), Prov.Arch()) == 0)) // packages have only on candidate, but just to be sure
- continue;
- // see which architecture we prefer more and switch to it
- std::vector<std::string> archs = APT::Configuration::getArchitectures();
- if (std::find(archs.begin(), archs.end(), PPkg.Arch()) < std::find(archs.begin(), archs.end(), Prov.Arch()))
- Prov = PPkg;
- continue;
- }
- found_one = false; // we found at least two
- break;
- }
- }
-
- if (found_one == true) {
- ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"),
- Prov.FullName(true).c_str(), Pkg.FullName(true).c_str());
- return APT::VersionSet::FromPackage(Cache, Prov, select, *this);
- }
- return APT::VersionSet();
- }
-
- inline bool allPkgNamedExplicitly() const { return explicitlyNamed; }
-
-};
- /*}}}*/
-// TryToInstall - Mark a package for installation /*{{{*/
-struct TryToInstall {
- pkgCacheFile* Cache;
- pkgProblemResolver* Fix;
- bool FixBroken;
- unsigned long AutoMarkChanged;
- APT::PackageSet doAutoInstallLater;
-
- TryToInstall(pkgCacheFile &Cache, pkgProblemResolver *PM, bool const FixBroken) : Cache(&Cache), Fix(PM),
- FixBroken(FixBroken), AutoMarkChanged(0) {};
-
- void operator() (pkgCache::VerIterator const &Ver) {
- pkgCache::PkgIterator Pkg = Ver.ParentPkg();
-
- Cache->GetDepCache()->SetCandidateVersion(Ver);
- pkgDepCache::StateCache &State = (*Cache)[Pkg];
-
- // Handle the no-upgrade case
- if (_config->FindB("APT::Get::upgrade",true) == false && Pkg->CurrentVer != 0)
- ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
- Pkg.FullName(true).c_str());
- // Ignore request for install if package would be new
- else if (_config->FindB("APT::Get::Only-Upgrade", false) == true && Pkg->CurrentVer == 0)
- ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
- Pkg.FullName(true).c_str());
- else {
- if (Fix != NULL) {
- Fix->Clear(Pkg);
- Fix->Protect(Pkg);
- }
- Cache->GetDepCache()->MarkInstall(Pkg,false);
-
- if (State.Install() == false) {
- if (_config->FindB("APT::Get::ReInstall",false) == true) {
- if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
- ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
- Pkg.FullName(true).c_str());
- else
- Cache->GetDepCache()->SetReInstall(Pkg, true);
- } else
- ioprintf(c1out,_("%s is already the newest version.\n"),
- Pkg.FullName(true).c_str());
- }
-
- // Install it with autoinstalling enabled (if we not respect the minial
- // required deps or the policy)
- if (FixBroken == false)
- doAutoInstallLater.insert(Pkg);
- }
-
- // see if we need to fix the auto-mark flag
- // e.g. apt-get install foo
- // where foo is marked automatic
- if (State.Install() == false &&
- (State.Flags & pkgCache::Flag::Auto) &&
- _config->FindB("APT::Get::ReInstall",false) == false &&
- _config->FindB("APT::Get::Only-Upgrade",false) == false &&
- _config->FindB("APT::Get::Download-Only",false) == false)
- {
- ioprintf(c1out,_("%s set to manually installed.\n"),
- Pkg.FullName(true).c_str());
- Cache->GetDepCache()->MarkAuto(Pkg,false);
- AutoMarkChanged++;
- }
- }
-
- bool propergateReleaseCandiateSwitching(std::list<std::pair<pkgCache::VerIterator, std::string> > start, std::ostream &out)
- {
- for (std::list<std::pair<pkgCache::VerIterator, std::string> >::const_iterator s = start.begin();
- s != start.end(); ++s)
- Cache->GetDepCache()->SetCandidateVersion(s->first);
-
- bool Success = true;
- std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > Changed;
- for (std::list<std::pair<pkgCache::VerIterator, std::string> >::const_iterator s = start.begin();
- s != start.end(); ++s)
- {
- Changed.push_back(std::make_pair(s->first, pkgCache::VerIterator(*Cache)));
- // We continue here even if it failed to enhance the ShowBroken output
- Success &= Cache->GetDepCache()->SetCandidateRelease(s->first, s->second, Changed);
- }
- for (std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::const_iterator c = Changed.begin();
- c != Changed.end(); ++c)
- {
- if (c->second.end() == true)
- ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"),
- c->first.VerStr(), c->first.RelStr().c_str(), c->first.ParentPkg().FullName(true).c_str());
- else if (c->first.ParentPkg()->Group != c->second.ParentPkg()->Group)
- {
- pkgCache::VerIterator V = (*Cache)[c->first.ParentPkg()].CandidateVerIter(*Cache);
- ioprintf(out, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V.VerStr(),
- V.RelStr().c_str(), V.ParentPkg().FullName(true).c_str(), c->second.ParentPkg().FullName(true).c_str());
- }
- }
- return Success;
- }
-
- void doAutoInstall() {
- for (APT::PackageSet::const_iterator P = doAutoInstallLater.begin();
- P != doAutoInstallLater.end(); ++P) {
- pkgDepCache::StateCache &State = (*Cache)[P];
- if (State.InstBroken() == false && State.InstPolicyBroken() == false)
- continue;
- Cache->GetDepCache()->MarkInstall(P, true);
- }
- doAutoInstallLater.clear();
- }
-};
- /*}}}*/
-// TryToRemove - Mark a package for removal /*{{{*/
-struct TryToRemove {
- pkgCacheFile* Cache;
- pkgProblemResolver* Fix;
- bool PurgePkgs;
-
- 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();
-
- 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))
- {
- pkgCache::GrpIterator Grp = Pkg.Group();
- pkgCache::PkgIterator P = Grp.PackageList();
- for (; P.end() != true; P = Grp.NextPkg(P))
- {
- if (P == Pkg)
- continue;
- if (P->CurrentVer != 0 || (PurgePkgs == true && P->CurrentState != pkgCache::State::NotInstalled))
- {
- // TRANSLATORS: Note, this is not an interactive question
- ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
- Pkg.FullName(true).c_str(), P.FullName(true).c_str());
- break;
- }
- }
- if (P.end() == true)
- 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);
- }
-};
- /*}}}*/
-// CacheFile::NameComp - QSort compare by name /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-pkgCache *CacheFile::SortCache = 0;
-int CacheFile::NameComp(const void *a,const void *b)
-{
- if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0)
- return *(pkgCache::Package **)a - *(pkgCache::Package **)b;
-
- const pkgCache::Package &A = **(pkgCache::Package **)a;
- const pkgCache::Package &B = **(pkgCache::Package **)b;
-
- return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name);
-}
- /*}}}*/
-// CacheFile::Sort - Sort by name /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void CacheFile::Sort()
-{
- delete [] List;
- List = new pkgCache::Package *[Cache->Head().PackageCount];
- memset(List,0,sizeof(*List)*Cache->Head().PackageCount);
- pkgCache::PkgIterator I = Cache->PkgBegin();
- for (;I.end() != true; ++I)
- List[I->ID] = I;
-
- SortCache = *this;
- qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp);
-}
- /*}}}*/
-// CacheFile::CheckDeps - Open the cache file /*{{{*/
-// ---------------------------------------------------------------------
-/* This routine generates the caches and then opens the dependency cache
- and verifies that the system is OK. */
-bool CacheFile::CheckDeps(bool AllowBroken)
-{
- bool FixBroken = _config->FindB("APT::Get::Fix-Broken",false);
-
- if (_error->PendingError() == true)
- return false;
-
- // Check that the system is OK
- if (DCache->DelCount() != 0 || DCache->InstCount() != 0)
- return _error->Error("Internal error, non-zero counts");
-
- // Apply corrections for half-installed packages
- if (pkgApplyStatus(*DCache) == false)
- return false;
-
- if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true)
- {
- FixBroken = true;
- if ((DCache->PolicyBrokenCount() > 0))
- {
- // upgrade all policy-broken packages with ForceImportantDeps=True
- for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); ++I)
- if ((*DCache)[I].NowPolicyBroken() == true)
- DCache->MarkInstall(I,true,0, false, true);
- }
- }
-
- // Nothing is broken
- if (DCache->BrokenCount() == 0 || AllowBroken == true)
- return true;
-
- // Attempt to fix broken things
- if (FixBroken == true)
- {
- c1out << _("Correcting dependencies...") << flush;
- if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
- {
- c1out << _(" failed.") << endl;
- ShowBroken(c1out,*this,true);
-
- return _error->Error(_("Unable to correct dependencies"));
- }
- if (pkgMinimizeUpgrade(*DCache) == false)
- return _error->Error(_("Unable to minimize the upgrade set"));
-
- c1out << _(" Done") << endl;
- }
- else
- {
- c1out << _("You might want to run 'apt-get -f install' to correct these.") << endl;
- ShowBroken(c1out,*this,true);
-
- return _error->Error(_("Unmet dependencies. Try using -f."));
- }
-
- return true;
-}
- /*}}}*/
-// CheckAuth - check if each download comes form a trusted source /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-static bool CheckAuth(pkgAcquire& Fetcher)
-{
- string UntrustedList;
- for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I)
- {
- if (!(*I)->IsTrusted())
- {
- UntrustedList += string((*I)->ShortDesc()) + " ";
- }
- }
-
- if (UntrustedList == "")
- {
- return true;
- }
-
- ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,"");
-
- if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true)
- {
- c2out << _("Authentication warning overridden.\n");
- return true;
- }
-
- if (_config->FindI("quiet",0) < 2
- && _config->FindB("APT::Get::Assume-Yes",false) == false)
- {
- c2out << _("Install these packages without verification?") << flush;
- if (!YnPrompt(false))
- return _error->Error(_("Some packages could not be authenticated"));
-
- return true;
- }
- else if (_config->FindB("APT::Get::Force-Yes",false) == true)
- {
- return true;
- }
-
- return _error->Error(_("There are problems and -y was used without --force-yes"));
-}
- /*}}}*/
-// InstallPackages - Actually download and install the packages /*{{{*/
-// ---------------------------------------------------------------------
-/* This displays the informative messages describing what is going to
- happen and then calls the download routines */
-bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
- bool Safety = true)
-{
- if (_config->FindB("APT::Get::Purge",false) == true)
- {
- pkgCache::PkgIterator I = Cache->PkgBegin();
- for (; I.end() == false; ++I)
- {
- if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
- Cache->MarkDelete(I,true);
- }
- }
-
- bool Fail = false;
- bool Essential = false;
-
- // Show all the various warning indicators
- ShowDel(c1out,Cache);
- ShowNew(c1out,Cache);
- if (ShwKept == true)
- ShowKept(c1out,Cache);
- Fail |= !ShowHold(c1out,Cache);
- if (_config->FindB("APT::Get::Show-Upgraded",true) == true)
- ShowUpgraded(c1out,Cache);
- Fail |= !ShowDowngraded(c1out,Cache);
- if (_config->FindB("APT::Get::Download-Only",false) == false)
- Essential = !ShowEssential(c1out,Cache);
- Fail |= Essential;
- Stats(c1out,Cache);
-
- // Sanity check
- if (Cache->BrokenCount() != 0)
- {
- ShowBroken(c1out,Cache,false);
- return _error->Error(_("Internal error, InstallPackages was called with broken packages!"));
- }
-
- if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
- Cache->BadCount() == 0)
- return true;
-
- // No remove flag
- if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
- return _error->Error(_("Packages need to be removed but remove is disabled."));
-
- // Run the simulator ..
- if (_config->FindB("APT::Get::Simulate") == true)
- {
- pkgSimulate PM(Cache);
- int status_fd = _config->FindI("APT::Status-Fd",-1);
- pkgPackageManager::OrderResult Res = PM.DoInstall(status_fd);
- if (Res == pkgPackageManager::Failed)
- return false;
- if (Res != pkgPackageManager::Completed)
- return _error->Error(_("Internal error, Ordering didn't finish"));
- return true;
- }
-
- // Create the text record parser
- pkgRecords Recs(Cache);
- if (_error->PendingError() == true)
- return false;
-
- // Create the download object
- pkgAcquire Fetcher;
- AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
- if (_config->FindB("APT::Get::Print-URIs", false) == true)
- {
- // force a hashsum for compatibility reasons
- _config->CndSet("Acquire::ForceHash", "md5sum");
- }
- else if (Fetcher.Setup(&Stat, _config->FindDir("Dir::Cache::Archives")) == false)
- return false;
- // Read the source list
- if (Cache.BuildSourceList() == false)
- return false;
- pkgSourceList *List = Cache.GetSourceList();
-
- // Create the package manager and prepare to download
- SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
- if (PM->GetArchives(&Fetcher,List,&Recs) == false ||
- _error->PendingError() == true)
- return false;
- // Display statistics
- unsigned long long FetchBytes = Fetcher.FetchNeeded();
- unsigned long long FetchPBytes = Fetcher.PartialPresent();
- unsigned long long DebBytes = Fetcher.TotalNeeded();
- if (DebBytes != Cache->DebSize())
- {
- c0out << DebBytes << ',' << Cache->DebSize() << endl;
- c0out << _("How odd.. The sizes didn't match, email apt@packages.debian.org") << endl;
- }
-
- // Number of bytes
- if (DebBytes != FetchBytes)
- //TRANSLATOR: The required space between number and unit is already included
- // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
- ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
- SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
- else if (DebBytes != 0)
- //TRANSLATOR: The required space between number and unit is already included
- // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
- ioprintf(c1out,_("Need to get %sB of archives.\n"),
- SizeToStr(DebBytes).c_str());
-
- // Size delta
- if (Cache->UsrSize() >= 0)
- //TRANSLATOR: The required space between number and unit is already included
- // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
- ioprintf(c1out,_("After this operation, %sB of additional disk space will be used.\n"),
- SizeToStr(Cache->UsrSize()).c_str());
- else
- //TRANSLATOR: The required space between number and unit is already included
- // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
- ioprintf(c1out,_("After this operation, %sB disk space will be freed.\n"),
- SizeToStr(-1*Cache->UsrSize()).c_str());
-
- if (_error->PendingError() == true)
- return false;
-
- /* Check for enough free space, but only if we are actually going to
- download */
- if (_config->FindB("APT::Get::Print-URIs") == false &&
- _config->FindB("APT::Get::Download",true) == true)
- {
- struct statvfs Buf;
- string OutputDir = _config->FindDir("Dir::Cache::Archives");
- 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());
- }
- }
-
- // Fail safe check
- if (_config->FindI("quiet",0) >= 2 ||
- _config->FindB("APT::Get::Assume-Yes",false) == true)
- {
- if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
- return _error->Error(_("There are problems and -y was used without --force-yes"));
- }
-
- if (Essential == true && Safety == true)
- {
- if (_config->FindB("APT::Get::Trivial-Only",false) == true)
- return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
-
- // TRANSLATOR: This string needs to be typed by the user as a confirmation, so be
- // careful with hard to type or special characters (like non-breaking spaces)
- const char *Prompt = _("Yes, do as I say!");
- ioprintf(c2out,
- _("You are about to do something potentially harmful.\n"
- "To continue type in the phrase '%s'\n"
- " ?] "),Prompt);
- c2out << flush;
- if (AnalPrompt(Prompt) == false)
- {
- c2out << _("Abort.") << endl;
- exit(1);
- }
- }
- else
- {
- // Prompt to continue
- if (Ask == true || Fail == true)
- {
- if (_config->FindB("APT::Get::Trivial-Only",false) == true)
- return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
-
- if (_config->FindI("quiet",0) < 2 &&
- _config->FindB("APT::Get::Assume-Yes",false) == false)
- {
- c2out << _("Do you want to continue?") << flush;
-
- if (YnPrompt() == false)
- {
- c2out << _("Abort.") << endl;
- exit(1);
- }
- }
- }
- }
-
- // Just print out the uris an 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;
- }
-
- if (!CheckAuth(Fetcher))
- return false;
-
- /* Unlock the dpkg lock if we are not going to be doing an install
- after. */
- if (_config->FindB("APT::Get::Download-Only",false) == true)
- _system->UnLock();
-
- // Run it
- while (1)
- {
- bool Transient = false;
- if (_config->FindB("APT::Get::Download",true) == false)
- {
- for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
- {
- if ((*I)->Local == true)
- {
- ++I;
- continue;
- }
-
- // Close the item and check if it was found in cache
- (*I)->Finished();
- if ((*I)->Complete == false)
- Transient = true;
-
- // Clear it out of the fetch list
- delete *I;
- I = Fetcher.ItemsBegin();
- }
- }
-
- if (Fetcher.Run() == pkgAcquire::Failed)
- return false;
-
- // Print out errors
- bool Failed = false;
- for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I)
- {
- if ((*I)->Status == pkgAcquire::Item::StatDone &&
- (*I)->Complete == true)
- continue;
-
- if ((*I)->Status == pkgAcquire::Item::StatIdle)
- {
- Transient = true;
- // Failed = true;
- continue;
- }
-
- fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
- (*I)->ErrorText.c_str());
- Failed = true;
- }
-
- /* If we are in no download mode and missing files and there were
- 'failures' then the user must specify -m. Furthermore, there
- is no such thing as a transient error in no-download mode! */
- if (Transient == true &&
- _config->FindB("APT::Get::Download",true) == false)
- {
- Transient = false;
- Failed = true;
- }
-
- if (_config->FindB("APT::Get::Download-Only",false) == true)
- {
- if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
- return _error->Error(_("Some files failed to download"));
- c1out << _("Download complete and in download only mode") << endl;
- return true;
- }
-
- if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
- {
- return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
- }
-
- if (Transient == true && Failed == true)
- return _error->Error(_("--fix-missing and media swapping is not currently supported"));
-
- // Try to deal with missing package files
- if (Failed == true && PM->FixMissing() == false)
- {
- cerr << _("Unable to correct missing packages.") << endl;
- return _error->Error(_("Aborting install."));
- }
-
- _system->UnLock();
- int status_fd = _config->FindI("APT::Status-Fd",-1);
- pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd);
- if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
- return false;
- if (Res == pkgPackageManager::Completed)
- break;
-
- // Reload the fetcher object and loop again for media swapping
- Fetcher.Shutdown();
- if (PM->GetArchives(&Fetcher,List,&Recs) == false)
- return false;
-
- _system->Lock();
- }
-
- std::set<std::string> const disappearedPkgs = PM->GetDisappearedPackages();
- if (disappearedPkgs.empty() == true)
- return true;
-
- string disappear;
- for (std::set<std::string>::const_iterator d = disappearedPkgs.begin();
- d != disappearedPkgs.end(); ++d)
- disappear.append(*d).append(" ");
-
- ShowList(c1out, P_("The following package disappeared from your system as\n"
- "all files have been overwritten by other packages:",
- "The following packages disappeared from your system as\n"
- "all files have been overwritten by other packages:", disappearedPkgs.size()), disappear, "");
- c0out << _("Note: This is done automatically and on purpose by dpkg.") << std::endl;
-
- return true;
-}
- /*}}}*/
// TryToInstallBuildDep - Try to install a single package /*{{{*/
// ---------------------------------------------------------------------
/* This used to be inlined in DoInstall, but with the advent of regex package
@@ -1667,497 +302,6 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
return Last;
}
/*}}}*/
-// DoUpdate - Update the package lists /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool DoUpdate(CommandLine &CmdL)
-{
- if (CmdL.FileSize() != 1)
- return _error->Error(_("The update command takes no arguments"));
-
- CacheFile Cache;
-
- // Get the source list
- if (Cache.BuildSourceList() == false)
- return false;
- pkgSourceList *List = Cache.GetSourceList();
-
- // Create the progress
- AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
-
- // Just print out the uris an exit if the --print-uris flag was used
- if (_config->FindB("APT::Get::Print-URIs") == true)
- {
- // force a hashsum for compatibility reasons
- _config->CndSet("Acquire::ForceHash", "md5sum");
-
- // get a fetcher
- pkgAcquire Fetcher;
- if (Fetcher.Setup(&Stat) == false)
- return false;
-
- // Populate it with the source selection and get all Indexes
- // (GetAll=true)
- if (List->GetIndexes(&Fetcher,true) == false)
- return false;
-
- 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;
- }
-
- // do the work
- if (_config->FindB("APT::Get::Download",true) == true)
- ListUpdate(Stat, *List);
-
- // Rebuild the cache.
- if (_config->FindB("pkgCacheFile::Generate", true) == true)
- {
- pkgCacheFile::RemoveCaches();
- if (Cache.BuildCaches() == false)
- return false;
- }
-
- return true;
-}
- /*}}}*/
-// DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
-// ---------------------------------------------------------------------
-/* Remove unused automatic packages */
-bool DoAutomaticRemove(CacheFile &Cache)
-{
- bool Debug = _config->FindI("Debug::pkgAutoRemove",false);
- bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
- bool hideAutoRemove = _config->FindB("APT::Get::HideAutoRemove");
-
- pkgDepCache::ActionGroup group(*Cache);
- if(Debug)
- std::cout << "DoAutomaticRemove()" << std::endl;
-
- if (doAutoRemove == true &&
- _config->FindB("APT::Get::Remove",true) == false)
- {
- c1out << _("We are not supposed to delete stuff, can't start "
- "AutoRemover") << std::endl;
- return false;
- }
-
- bool purgePkgs = _config->FindB("APT::Get::Purge", false);
- bool smallList = (hideAutoRemove == false &&
- strcasecmp(_config->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
-
- unsigned long autoRemoveCount = 0;
- APT::PackageSet tooMuch;
- APT::PackageList autoRemoveList;
- // look over the cache to see what can be removed
- for (unsigned J = 0; J < Cache->Head().PackageCount; ++J)
- {
- pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
- if (Cache[Pkg].Garbage)
- {
- if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
- if(Debug)
- std::cout << "We could delete %s" << Pkg.FullName(true).c_str() << std::endl;
-
- if (doAutoRemove)
- {
- if(Pkg.CurrentVer() != 0 &&
- Pkg->CurrentState != pkgCache::State::ConfigFiles)
- Cache->MarkDelete(Pkg, purgePkgs, 0, false);
- else
- Cache->MarkKeep(Pkg, false, false);
- }
- else
- {
- if (hideAutoRemove == false && Cache[Pkg].Delete() == false)
- autoRemoveList.insert(Pkg);
- // 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)
- {
- if (Pkg.CandVersion() != 0)
- tooMuch.insert(Pkg);
- Cache->MarkDelete(Pkg, false, 0, false);
- }
- // only show stuff in the list that is not yet marked for removal
- else if(hideAutoRemove == false && Cache[Pkg].Delete() == false)
- ++autoRemoveCount;
- }
- }
- }
-
- // 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 || Cache->PolicyBrokenCount() != 0))
- {
- bool Changed;
- do {
- Changed = false;
- for (APT::PackageSet::const_iterator Pkg = tooMuch.begin();
- Pkg != tooMuch.end() && Changed == false; ++Pkg)
- {
- APT::PackageSet too;
- too.insert(*Pkg);
- for (pkgCache::PrvIterator Prv = Cache[Pkg].CandidateVerIter(Cache).ProvidesList();
- Prv.end() == false; ++Prv)
- too.insert(Prv.ParentPkg());
- for (APT::PackageSet::const_iterator P = too.begin();
- P != too.end() && Changed == false; ++P) {
- for (pkgCache::DepIterator R = P.RevDependsList();
- R.end() == false; ++R)
- {
- if (R.IsNegative() == true ||
- Cache->IsImportantDep(R) == false)
- continue;
- pkgCache::PkgIterator N = R.ParentPkg();
- if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
- continue;
- if (Debug == true)
- std::clog << "Save " << Pkg << " as another installed garbage package depends on it" << std::endl;
- Cache->MarkInstall(Pkg, false, 0, false);
- if (hideAutoRemove == false)
- ++autoRemoveCount;
- tooMuch.erase(Pkg);
- Changed = true;
- break;
- }
- }
- }
- } while (Changed == true);
- }
-
- std::string autoremovelist, autoremoveversions;
- if (smallList == false && autoRemoveCount != 0)
- {
- for (APT::PackageList::const_iterator Pkg = autoRemoveList.begin(); Pkg != autoRemoveList.end(); ++Pkg)
- {
- if (Cache[Pkg].Garbage == false)
- continue;
- autoremovelist += Pkg.FullName(true) + " ";
- autoremoveversions += string(Cache[Pkg].CandVersion) + "\n";
- }
- }
-
- // Now see if we had destroyed anything (if we had done anything)
- if (Cache->BrokenCount() != 0)
- {
- c1out << _("Hmm, seems like the AutoRemover destroyed something which really\n"
- "shouldn't happen. Please file a bug report against apt.") << endl;
- c1out << endl;
- c1out << _("The following information may help to resolve the situation:") << endl;
- c1out << endl;
- ShowBroken(c1out,Cache,false);
-
- return _error->Error(_("Internal Error, AutoRemover broke stuff"));
- }
-
- // if we don't remove them, we should show them!
- if (doAutoRemove == false && (autoremovelist.empty() == false || autoRemoveCount != 0))
- {
- if (smallList == false)
- ShowList(c1out, P_("The following package was automatically installed and is no longer required:",
- "The following packages were automatically installed and are no longer required:",
- autoRemoveCount), autoremovelist, autoremoveversions);
- else
- ioprintf(c1out, P_("%lu package was automatically installed and is no longer required.\n",
- "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount), autoRemoveCount);
- c1out << P_("Use 'apt-get autoremove' to remove it.", "Use 'apt-get autoremove' to remove them.", autoRemoveCount) << std::endl;
- }
- return true;
-}
- /*}}}*/
-// DoUpgrade - Upgrade all packages /*{{{*/
-// ---------------------------------------------------------------------
-/* Upgrade all packages without installing new packages or erasing old
- packages */
-bool DoUpgrade(CommandLine &CmdL)
-{
- CacheFile Cache;
- if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
- return false;
-
- // Do the upgrade
- if (pkgAllUpgrade(Cache) == false)
- {
- ShowBroken(c1out,Cache,false);
- return _error->Error(_("Internal error, AllUpgrade broke stuff"));
- }
-
- return InstallPackages(Cache,true);
-}
- /*}}}*/
-// DoInstall - Install packages from the command line /*{{{*/
-// ---------------------------------------------------------------------
-/* Install named packages */
-bool DoInstall(CommandLine &CmdL)
-{
- CacheFile Cache;
- if (Cache.OpenForInstall() == false ||
- Cache.CheckDeps(CmdL.FileSize() != 1) == false)
- return false;
-
- // Enter the special broken fixing mode if the user specified arguments
- bool BrokenFix = false;
- if (Cache->BrokenCount() != 0)
- BrokenFix = true;
-
- 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;
-
- unsigned short fallback = MOD_INSTALL;
- if (strcasecmp(CmdL.FileList[0],"remove") == 0)
- fallback = MOD_REMOVE;
- else if (strcasecmp(CmdL.FileList[0], "purge") == 0)
- {
- _config->Set("APT::Get::Purge", true);
- fallback = MOD_REMOVE;
- }
- else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0)
- {
- _config->Set("APT::Get::AutomaticRemove", "true");
- fallback = MOD_REMOVE;
- }
-
- std::list<APT::VersionSet::Modifier> mods;
- mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+",
- APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDIDATE));
- mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-",
- APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST));
- CacheSetHelperAPTGet helper(c0out);
- std::map<unsigned short, APT::VersionSet> verset = APT::VersionSet::GroupedFromCommandLine(Cache,
- CmdL.FileList + 1, mods, fallback, helper);
-
- if (_error->PendingError() == true)
- {
- helper.showVirtualPackageErrors(Cache);
- if (Fix != NULL)
- delete Fix;
- return false;
- }
-
-
- TryToInstall InstallAction(Cache, Fix, BrokenFix);
- TryToRemove RemoveAction(Cache, Fix);
-
- // new scope for the ActionGroup
- {
- pkgDepCache::ActionGroup group(Cache);
- unsigned short const order[] = { MOD_REMOVE, MOD_INSTALL, 0 };
-
- for (unsigned short i = 0; order[i] != 0; ++i)
- {
- 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();
- }
- }
-
- 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
- packages */
- if (BrokenFix == true && Cache->BrokenCount() != 0)
- {
- 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)."));
- }
-
- if (Fix != NULL)
- {
- // Call the scored problem resolver
- Fix->Resolve(true);
- delete Fix;
- }
-
- // Now we check the state of the packages,
- if (Cache->BrokenCount() != 0)
- {
- c1out <<
- _("Some packages could not be installed. This may mean that you have\n"
- "requested an impossible situation or if you are using the unstable\n"
- "distribution that some required packages have not yet been created\n"
- "or been moved out of Incoming.") << endl;
- /*
- if (Packages == 1)
- {
- c1out << endl;
- c1out <<
- _("Since you only requested a single operation it is extremely likely that\n"
- "the package is simply not installable and a bug report against\n"
- "that package should be filed.") << endl;
- }
- */
-
- c1out << _("The following information may help to resolve the situation:") << endl;
- c1out << endl;
- ShowBroken(c1out,Cache,false);
- if (_error->PendingError() == true)
- return false;
- else
- return _error->Error(_("Broken packages"));
- }
- }
- if (!DoAutomaticRemove(Cache))
- return false;
-
- /* Print out a list of packages that are going to be installed extra
- to what the user asked */
- if (Cache->InstCount() != verset[MOD_INSTALL].size())
- {
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if ((*Cache)[I].Install() == false)
- continue;
- pkgCache::VerIterator Cand = Cache[I].CandidateVerIter(Cache);
-
- if (verset[MOD_INSTALL].find(Cand) != verset[MOD_INSTALL].end())
- continue;
-
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CandVersion) + "\n";
- }
-
- ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList);
- }
-
- /* Print out a list of suggested and recommended packages */
- {
- string SuggestsList, RecommendsList;
- string SuggestsVersions, RecommendsVersions;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
-
- /* Just look at the ones we want to install */
- if ((*Cache)[Pkg].Install() == false)
- continue;
-
- // get the recommends/suggests for the candidate ver
- pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
- for (pkgCache::DepIterator D = CV.DependsList(); D.end() == false; )
- {
- pkgCache::DepIterator Start;
- pkgCache::DepIterator End;
- D.GlobOr(Start,End); // advances D
-
- // FIXME: we really should display a or-group as a or-group to the user
- // the problem is that ShowList is incapable of doing this
- string RecommendsOrList,RecommendsOrVersions;
- string SuggestsOrList,SuggestsOrVersions;
- bool foundInstalledInOrGroup = false;
- for(;;)
- {
- /* Skip if package is installed already, or is about to be */
- string target = Start.TargetPkg().FullName(true) + " ";
- pkgCache::PkgIterator const TarPkg = Start.TargetPkg();
- if (TarPkg->SelectedState == pkgCache::State::Install ||
- TarPkg->SelectedState == pkgCache::State::Hold ||
- Cache[Start.TargetPkg()].Install())
- {
- foundInstalledInOrGroup=true;
- break;
- }
-
- /* Skip if we already saw it */
- if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1)
- {
- foundInstalledInOrGroup=true;
- break;
- }
-
- // this is a dep on a virtual pkg, check if any package that provides it
- // should be installed
- if(Start.TargetPkg().ProvidesList() != 0)
- {
- pkgCache::PrvIterator I = Start.TargetPkg().ProvidesList();
- for (; I.end() == false; ++I)
- {
- pkgCache::PkgIterator Pkg = I.OwnerPkg();
- if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer() &&
- Pkg.CurrentVer() != 0)
- foundInstalledInOrGroup=true;
- }
- }
-
- if (Start->Type == pkgCache::Dep::Suggests)
- {
- SuggestsOrList += target;
- SuggestsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
- }
-
- if (Start->Type == pkgCache::Dep::Recommends)
- {
- RecommendsOrList += target;
- RecommendsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
- }
-
- if (Start >= End)
- break;
- ++Start;
- }
-
- if(foundInstalledInOrGroup == false)
- {
- RecommendsList += RecommendsOrList;
- RecommendsVersions += RecommendsOrVersions;
- SuggestsList += SuggestsOrList;
- SuggestsVersions += SuggestsOrVersions;
- }
-
- }
- }
-
- ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions);
- ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions);
-
- }
-
- // if nothing changed in the cache, but only the automark information
- // we write the StateFile here, otherwise it will be written in
- // cache.commit()
- if (InstallAction.AutoMarkChanged > 0 &&
- Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
- Cache->BadCount() == 0 &&
- _config->FindB("APT::Get::Simulate",false) == false)
- Cache->writeStateFile(NULL);
-
- // See if we need to prompt
- // FIXME: check if really the packages in the set are going to be installed
- if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0)
- return InstallPackages(Cache,false,false);
-
- return InstallPackages(Cache,false);
-}
- /*}}}*/
/* mark packages as automatically/manually installed. {{{*/
bool DoMarkAuto(CommandLine &CmdL)
{
@@ -2585,7 +729,7 @@ bool DoSource(CommandLine &CmdL)
if(queued.find(Last->Index().ArchiveURI(I->Path)) != queued.end())
continue;
queued.insert(Last->Index().ArchiveURI(I->Path));
-
+
// check if we have a file with that md5 sum already localy
if(!I->MD5Hash.empty() && FileExists(flNotDir(I->Path)))
{
@@ -3367,23 +1511,6 @@ bool DoChangelog(CommandLine &CmdL)
return true;
}
/*}}}*/
-// DoMoo - Never Ask, Never Tell /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool DoMoo(CommandLine &CmdL)
-{
- cout <<
- " (__) \n"
- " (oo) \n"
- " /------\\/ \n"
- " / | || \n"
- " * /\\---/\\ \n"
- " ~~ ~~ \n"
- "....\"Have you mooed today?\"...\n";
-
- return true;
-}
- /*}}}*/
// ShowHelp - Show a help screen /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -3494,58 +1621,17 @@ void SigWinch(int)
#endif
}
/*}}}*/
+
+bool DoUpgrade(CommandLine &CmdL)
+{
+ if (_config->FindB("APT::Get::UpgradeAllowNew", false) == true)
+ return DoUpgradeWithAllowNewPackages(CmdL);
+ else
+ return DoUpgradeNoNewPackages(CmdL);
+}
+
int main(int argc,const char *argv[]) /*{{{*/
{
- CommandLine::Args Args[] = {
- {'h',"help","help",0},
- {'v',"version","version",0},
- {'V',"verbose-versions","APT::Get::Show-Versions",0},
- {'q',"quiet","quiet",CommandLine::IntLevel},
- {'q',"silent","quiet",CommandLine::IntLevel},
- {'d',"download-only","APT::Get::Download-Only",0},
- {'b',"compile","APT::Get::Compile",0},
- {'b',"build","APT::Get::Compile",0},
- {'s',"simulate","APT::Get::Simulate",0},
- {'s',"just-print","APT::Get::Simulate",0},
- {'s',"recon","APT::Get::Simulate",0},
- {'s',"dry-run","APT::Get::Simulate",0},
- {'s',"no-act","APT::Get::Simulate",0},
- {'y',"yes","APT::Get::Assume-Yes",0},
- {'y',"assume-yes","APT::Get::Assume-Yes",0},
- {0,"assume-no","APT::Get::Assume-No",0},
- {'f',"fix-broken","APT::Get::Fix-Broken",0},
- {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
- {'m',"ignore-missing","APT::Get::Fix-Missing",0},
- {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
- {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
- {'a',"host-architecture","APT::Get::Host-Architecture",CommandLine::HasArg},
- {0,"download","APT::Get::Download",0},
- {0,"fix-missing","APT::Get::Fix-Missing",0},
- {0,"ignore-hold","APT::Ignore-Hold",0},
- {0,"upgrade","APT::Get::upgrade",0},
- {0,"only-upgrade","APT::Get::Only-Upgrade",0},
- {0,"force-yes","APT::Get::force-yes",0},
- {0,"print-uris","APT::Get::Print-URIs",0},
- {0,"diff-only","APT::Get::Diff-Only",0},
- {0,"debian-only","APT::Get::Diff-Only",0},
- {0,"tar-only","APT::Get::Tar-Only",0},
- {0,"dsc-only","APT::Get::Dsc-Only",0},
- {0,"purge","APT::Get::Purge",0},
- {0,"list-cleanup","APT::Get::List-Cleanup",0},
- {0,"reinstall","APT::Get::ReInstall",0},
- {0,"trivial-only","APT::Get::Trivial-Only",0},
- {0,"remove","APT::Get::Remove",0},
- {0,"only-source","APT::Get::Only-Source",0},
- {0,"arch-only","APT::Get::Arch-Only",0},
- {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}};
CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
{"upgrade",&DoUpgrade},
{"install",&DoInstall},
@@ -3567,12 +1653,14 @@ int main(int argc,const char *argv[]) /*{{{*/
{"help",&ShowHelp},
{0,0}};
+ std::vector<CommandLine::Args> Args = getCommandArgs("apt-get", CommandLine::GetCommand(Cmds, argc, argv));
+
// Set up gettext support
setlocale(LC_ALL,"");
textdomain(PACKAGE);
// Parse the command line and initialize the package library
- CommandLine CmdL(Args,_config);
+ CommandLine CmdL(Args.data(),_config);
if (pkgInitConfig(*_config) == false ||
CmdL.Parse(argc,argv) == false ||
pkgInitSystem(*_config,_system) == false)
@@ -3593,33 +1681,15 @@ int main(int argc,const char *argv[]) /*{{{*/
return 0;
}
- // simulate user-friendly if apt-get has no root privileges
- 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"
- " apt-get needs root privileges for real execution.\n"
- " Keep also in mind that locking is deactivated,\n"
- " so don't depend on the relevance to the real current situation!"
- ) << std::endl;
- _config->Set("Debug::NoLocking",true);
- }
+ // see if we are in simulate mode
+ CheckSimulateMode(CmdL);
// Deal with stdout not being a tty
if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
_config->Set("quiet","1");
// Setup the output streams
- 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());
+ InitOutput();
// Setup the signals
signal(SIGPIPE,SIG_IGN);
diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc
index 4c0fc2893..eb3410be1 100644
--- a/cmdline/apt-mark.cc
+++ b/cmdline/apt-mark.cc
@@ -24,6 +24,8 @@
#include <sys/wait.h>
#include <fcntl.h>
+#include <apt-private/private-cmndline.h>
+
#include <apti18n.h>
/*}}}*/
using namespace std;
@@ -400,21 +402,6 @@ bool ShowHelp(CommandLine &CmdL)
/*}}}*/
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},
@@ -432,12 +419,14 @@ int main(int argc,const char *argv[]) /*{{{*/
{"unmarkauto", &DoMarkAuto},
{0,0}};
+ std::vector<CommandLine::Args> Args = getCommandArgs("apt-mark", CommandLine::GetCommand(Cmds, argc, argv));
+
// Set up gettext support
setlocale(LC_ALL,"");
textdomain(PACKAGE);
// Parse the command line and initialize the package library
- CommandLine CmdL(Args,_config);
+ CommandLine CmdL(Args.data(),_config);
if (pkgInitConfig(*_config) == false ||
CmdL.Parse(argc,argv) == false ||
pkgInitSystem(*_config,_system) == false)
diff --git a/cmdline/apt.cc b/cmdline/apt.cc
new file mode 100644
index 000000000..e30967ec2
--- /dev/null
+++ b/cmdline/apt.cc
@@ -0,0 +1,158 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* ######################################################################
+
+ apt - CLI UI for apt
+
+ Returns 100 on failure, 0 on success.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include<config.h>
+
+#include <cassert>
+#include <locale.h>
+#include <iostream>
+#include <unistd.h>
+#include <errno.h>
+#include <regex.h>
+#include <stdio.h>
+#include <iomanip>
+#include <algorithm>
+
+
+#include <apt-pkg/error.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/progress.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/policy.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/indexfile.h>
+#include <apt-pkg/metaindex.h>
+
+#include <apti18n.h>
+
+#include <apt-private/private-list.h>
+#include <apt-private/private-search.h>
+#include <apt-private/private-install.h>
+#include <apt-private/private-output.h>
+#include <apt-private/private-update.h>
+#include <apt-private/private-cmndline.h>
+#include <apt-private/private-moo.h>
+#include <apt-private/private-upgrade.h>
+#include <apt-private/private-show.h>
+#include <apt-private/private-main.h>
+ /*}}}*/
+
+bool ShowHelp(CommandLine &CmdL)
+{
+ ioprintf(c1out,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION,
+ COMMON_ARCH,__DATE__,__TIME__);
+
+ // FIXME: generate from CommandLine
+ c1out <<
+ _("Usage: apt [options] command\n"
+ "\n"
+ "CLI for apt.\n"
+ "Commands: \n"
+ " list - list packages based on package names\n"
+ " search - search in package descriptions\n"
+ " show - show package details\n"
+ "\n"
+ " update - update list of available packages\n"
+ " install - install packages\n"
+ " upgrade - upgrade the systems packages\n"
+ );
+
+ return true;
+}
+
+int main(int argc, const char *argv[]) /*{{{*/
+{
+ CommandLine::Dispatch Cmds[] = {{"list",&List},
+ {"search", &FullTextSearch},
+ {"show", &APT::Cmd::ShowPackage},
+ // needs root
+ {"install",&DoInstall},
+ {"remove", &DoInstall},
+ {"update",&DoUpdate},
+ {"upgrade",&DoUpgradeWithAllowNewPackages},
+ // helper
+ {"moo",&DoMoo},
+ {"help",&ShowHelp},
+ {0,0}};
+
+ std::vector<CommandLine::Args> Args = getCommandArgs("apt", CommandLine::GetCommand(Cmds, argc, argv));
+
+ if(!isatty(1))
+ {
+ std::cerr << std::endl
+ << "WARNING WARNING "
+ << argv[0]
+ << " is *NOT* intended for scripts "
+ << "use at your own peril^Wrisk"
+ << std::endl
+ << std::endl;
+ }
+
+ InitOutput();
+
+ // Set up gettext support
+ setlocale(LC_ALL,"");
+ textdomain(PACKAGE);
+
+ if(pkgInitConfig(*_config) == false)
+ {
+ _error->DumpErrors();
+ return 100;
+ }
+
+ // FIXME: move into a new libprivate/private-install.cc:Install()
+ _config->Set("DPkgPM::Progress", "1");
+ _config->Set("Apt::Color", "1");
+
+ // Parse the command line and initialize the package library
+ CommandLine CmdL(Args.data(), _config);
+ if (CmdL.Parse(argc, argv) == false ||
+ pkgInitSystem(*_config, _system) == false)
+ {
+ _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;
+ }
+
+ // see if we are in simulate mode
+ CheckSimulateMode(CmdL);
+
+ // parse args
+ 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 460a71240..e77ad5669 100644
--- a/cmdline/makefile
+++ b/cmdline/makefile
@@ -5,30 +5,37 @@ SUBDIR=cmdline
# Bring in the default rules
include ../buildlib/defaults.mak
+# The apt program
+PROGRAM=apt
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
+LIB_MAKES = apt-pkg/makefile
+SOURCE = apt.cc
+include $(PROGRAM_H)
+
# The apt-cache program
PROGRAM=apt-cache
-SLIBS = -lapt-pkg $(INTLLIBS)
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
SOURCE = apt-cache.cc
include $(PROGRAM_H)
# The apt-get program
PROGRAM=apt-get
-SLIBS = -lapt-pkg $(INTLLIBS)
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
-SOURCE = apt-get.cc acqprogress.cc
+SOURCE = apt-get.cc
include $(PROGRAM_H)
# The apt-config program
PROGRAM=apt-config
-SLIBS = -lapt-pkg $(INTLLIBS)
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
SOURCE = apt-config.cc
include $(PROGRAM_H)
# The apt-cdrom program
PROGRAM=apt-cdrom
-SLIBS = -lapt-pkg $(INTLLIBS)
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
SOURCE = apt-cdrom.cc
include $(PROGRAM_H)
@@ -41,7 +48,7 @@ include $(COPY_H)
# The apt-mark program
PROGRAM=apt-mark
-SLIBS = -lapt-pkg $(INTLLIBS)
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
SOURCE = apt-mark.cc
include $(PROGRAM_H)