summaryrefslogtreecommitdiff
path: root/apt-private
diff options
context:
space:
mode:
Diffstat (limited to 'apt-private')
-rw-r--r--apt-private/acqprogress.cc218
-rw-r--r--apt-private/acqprogress.h8
-rw-r--r--apt-private/private-cachefile.cc4
-rw-r--r--apt-private/private-cachefile.h23
-rw-r--r--apt-private/private-cacheset.cc89
-rw-r--r--apt-private/private-cacheset.h37
-rw-r--r--apt-private/private-cmndline.cc47
-rw-r--r--apt-private/private-cmndline.h6
-rw-r--r--apt-private/private-download.cc99
-rw-r--r--apt-private/private-download.h12
-rw-r--r--apt-private/private-install.cc240
-rw-r--r--apt-private/private-install.h162
-rw-r--r--apt-private/private-list.cc53
-rw-r--r--apt-private/private-output.cc386
-rw-r--r--apt-private/private-output.h10
-rw-r--r--apt-private/private-search.cc82
-rw-r--r--apt-private/private-show.cc54
-rw-r--r--apt-private/private-update.cc38
-rw-r--r--apt-private/private-upgrade.cc16
-rw-r--r--apt-private/private-utils.cc58
-rw-r--r--apt-private/private-utils.h4
21 files changed, 967 insertions, 679 deletions
diff --git a/apt-private/acqprogress.cc b/apt-private/acqprogress.cc
index 0f5b53e50..0c606e48e 100644
--- a/apt-private/acqprogress.cc
+++ b/apt-private/acqprogress.cc
@@ -1,10 +1,9 @@
// -*- 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
-
+ Acquire Progress - Command line progress meter
+
##################################################################### */
/*}}}*/
// Include files /*{{{*/
@@ -23,20 +22,18 @@
#include <stdio.h>
#include <signal.h>
#include <iostream>
+#include <sstream>
#include <unistd.h>
#include <apti18n.h>
/*}}}*/
-using namespace std;
-
// AcqTextStatus::AcqTextStatus - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-AcqTextStatus::AcqTextStatus(unsigned int &ScreenWidth,unsigned int const Quiet) :
- pkgAcquireStatus(), ScreenWidth(ScreenWidth), ID(0), Quiet(Quiet)
+AcqTextStatus::AcqTextStatus(std::ostream &out, unsigned int &ScreenWidth,unsigned int const Quiet) :
+ pkgAcquireStatus(), out(out), ScreenWidth(ScreenWidth), LastLineLength(0), ID(0), Quiet(Quiet)
{
- BlankLine[0] = 0;
// testcases use it to disable pulses without disabling other user messages
if (Quiet == 0 && _config->FindB("quiet::NoUpdate", false) == true)
this->Quiet = 1;
@@ -48,7 +45,7 @@ AcqTextStatus::AcqTextStatus(unsigned int &ScreenWidth,unsigned int const Quiet)
void AcqTextStatus::Start()
{
pkgAcquireStatus::Start();
- BlankLine[0] = 0;
+ LastLineLength = 0;
ID = 1;
}
/*}}}*/
@@ -60,13 +57,10 @@ void AcqTextStatus::IMSHit(pkgAcquire::ItemDesc &Itm)
if (Quiet > 1)
return;
- if (Quiet <= 0)
- cout << '\r' << BlankLine << '\r';
+ clearLastLine();
- cout << _("Hit ") << Itm.Description;
- if (Itm.Owner->FileSize != 0)
- cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
- cout << endl;
+ out << _("Hit ") << Itm.Description;
+ out << std::endl;
Update = true;
}
/*}}}*/
@@ -84,13 +78,12 @@ void AcqTextStatus::Fetch(pkgAcquire::ItemDesc &Itm)
if (Quiet > 1)
return;
- if (Quiet <= 0)
- cout << '\r' << BlankLine << '\r';
+ clearLastLine();
- cout << _("Get:") << Itm.Owner->ID << ' ' << Itm.Description;
+ out << _("Get:") << Itm.Owner->ID << ' ' << Itm.Description;
if (Itm.Owner->FileSize != 0)
- cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
- cout << endl;
+ out << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
+ out << std::endl;
}
/*}}}*/
// AcqTextStatus::Done - Completed a download /*{{{*/
@@ -113,17 +106,19 @@ void AcqTextStatus::Fail(pkgAcquire::ItemDesc &Itm)
if (Itm.Owner->Status == pkgAcquire::Item::StatIdle)
return;
- if (Quiet <= 0)
- cout << '\r' << BlankLine << '\r';
+ clearLastLine();
if (Itm.Owner->Status == pkgAcquire::Item::StatDone)
{
- cout << _("Ign ") << Itm.Description << endl;
+ out << _("Ign ") << Itm.Description << std::endl;
+ if (Itm.Owner->ErrorText.empty() == false &&
+ _config->FindB("Acquire::Progress::Ignore::ShowErrorText", false) == true)
+ out << " " << Itm.Owner->ErrorText << std::endl;
}
else
{
- cout << _("Err ") << Itm.Description << endl;
- cout << " " << Itm.Owner->ErrorText << endl;
+ out << _("Err ") << Itm.Description << std::endl;
+ out << " " << Itm.Owner->ErrorText << std::endl;
}
Update = true;
@@ -139,11 +134,13 @@ void AcqTextStatus::Stop()
if (Quiet > 1)
return;
- if (Quiet <= 0)
- cout << '\r' << BlankLine << '\r' << flush;
+ clearLastLine();
+
+ if (_config->FindB("quiet::NoStatistic", false) == true)
+ return;
if (FetchedBytes != 0 && _error->PendingError() == false)
- ioprintf(cout,_("Fetched %sB in %s (%sB/s)\n"),
+ ioprintf(out,_("Fetched %sB in %s (%sB/s)\n"),
SizeToStr(FetchedBytes).c_str(),
TimeToStr(ElapsedTime).c_str(),
SizeToStr(CurrentCPS).c_str());
@@ -152,7 +149,7 @@ void AcqTextStatus::Stop()
// 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
+ meter and a per active item status meter along with an overall
bandwidth and ETA indicator. */
bool AcqTextStatus::Pulse(pkgAcquire *Owner)
{
@@ -163,77 +160,66 @@ bool AcqTextStatus::Pulse(pkgAcquire *Owner)
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))
+ std::string Line;
{
- S += strlen(S);
-
- // There is no item running
- if (I->CurrentItem == 0)
+ std::stringstream S;
+ for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0;
+ I = Owner->WorkerStep(I))
{
- if (I->Status.empty() == false)
+ // There is no item running
+ if (I->CurrentItem == 0)
{
- snprintf(S,End-S," [%s]",I->Status.c_str());
- Shown = true;
- }
-
- continue;
- }
+ if (I->Status.empty() == false)
+ S << " [" << I->Status << "]";
- Shown = true;
+ continue;
+ }
- // 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);
+ // Add in the short description
+ S << " [";
+ if (I->CurrentItem->Owner->ID != 0)
+ S << I->CurrentItem->Owner->ID << " ";
+ S << I->CurrentItem->ShortDesc;
- // 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);
+ // Show the short mode string
+ if (I->CurrentItem->Owner->ActiveSubprocess.empty() == false)
+ S << " " << I->CurrentItem->Owner->ActiveSubprocess;
- // 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);
+ // Add the current progress
+ if (Mode == Long)
+ S << " " << I->CurrentSize;
else
- snprintf(S,End-S,"/%sB %.0f%%",SizeToStr(I->TotalSize).c_str(),
+ {
+ if (Mode == Medium || I->TotalSize == 0)
+ S << " " << SizeToStr(I->CurrentSize) << "B";
+ }
+
+ // Add the total size and percent
+ if (I->TotalSize > 0 && I->CurrentItem->Owner->Complete == false)
+ {
+ if (Mode == Short)
+ ioprintf(S, " %.0f%%", (I->CurrentSize*100.0)/I->TotalSize);
+ else
+ ioprintf(S, "/%sB %.0f%%", SizeToStr(I->TotalSize).c_str(),
(I->CurrentSize*100.0)/I->TotalSize);
+ }
+ S << "]";
}
- S += strlen(S);
- snprintf(S,End-S,"]");
- }
- // Show something..
- if (Shown == false)
- snprintf(S,End-S,_(" [Working]"));
+ // Show at least something
+ Line = S.str();
+ S.clear();
+ if (Line.empty() == true)
+ Line = _(" [Working]");
+ }
+ // Put in the percent done
+ {
+ std::stringstream S;
+ ioprintf(S, "%.0f%%", Percent);
+ S << Line;
+ Line = S.str();
+ S.clear();
+ }
/* Put in the ETA and cps meter, block off signals to prevent strangeness
during resizing */
@@ -244,34 +230,33 @@ bool AcqTextStatus::Pulse(pkgAcquire *Owner)
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)
+ std::string Tmp = " " + SizeToStr(CurrentCPS) + "B/s " + TimeToStr(ETA);
+ size_t alignment = Line.length() + Tmp.length();
+ if (alignment < ScreenWidth)
{
- memset(Buffer + Len,' ',ScreenWidth - Len);
- strcpy(Buffer + ScreenWidth - LenT,Tmp);
+ alignment = ScreenWidth - alignment;
+ for (size_t i = 0; i < alignment; ++i)
+ Line.append(" ");
+ Line.append(Tmp);
}
}
- Buffer[ScreenWidth] = 0;
- BlankLine[ScreenWidth] = 0;
+ if (Line.length() > ScreenWidth)
+ Line.erase(ScreenWidth);
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;
+ out << _config->Find("APT::Color::Yellow");
+ if (LastLineLength > Line.length())
+ clearLastLine();
else
- cout << '\r' << BlankLine << '\r' << Buffer << flush;
+ out << '\r';
+ out << Line << std::flush;
if (_config->FindB("Apt::Color", false) == true)
- cout << _config->Find("APT::Color::Neutral") << flush;
-
- memset(BlankLine,' ',strlen(Buffer));
- BlankLine[strlen(Buffer)] = 0;
+ out << _config->Find("APT::Color::Neutral") << std::flush;
+ LastLineLength = Line.length();
Update = false;
return true;
@@ -280,7 +265,7 @@ bool AcqTextStatus::Pulse(pkgAcquire *Owner)
// AcqTextStatus::MediaChange - Media need to be swapped /*{{{*/
// ---------------------------------------------------------------------
/* Prompt for a media swap */
-bool AcqTextStatus::MediaChange(string Media,string Drive)
+bool AcqTextStatus::MediaChange(std::string Media, std::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
@@ -292,9 +277,8 @@ bool AcqTextStatus::MediaChange(string Media,string Drive)
return false;
- if (Quiet <= 0)
- cout << '\r' << BlankLine << '\r';
- ioprintf(cout,_("Media change: please insert the disc labeled\n"
+ clearLastLine();
+ ioprintf(out,_("Media change: please insert the disc labeled\n"
" '%s'\n"
"in the drive '%s' and press enter\n"),
Media.c_str(),Drive.c_str());
@@ -313,3 +297,17 @@ bool AcqTextStatus::MediaChange(string Media,string Drive)
return bStatus;
}
/*}}}*/
+void AcqTextStatus::clearLastLine() { /*{{{*/
+ if (Quiet > 0 || LastLineLength == 0)
+ return;
+
+ // do not try to clear more than the (now smaller) screen
+ if (LastLineLength > ScreenWidth)
+ LastLineLength = ScreenWidth;
+
+ out << '\r';
+ for (size_t i = 0; i < LastLineLength; ++i)
+ out << ' ';
+ out << '\r' << std::flush;
+}
+ /*}}}*/
diff --git a/apt-private/acqprogress.h b/apt-private/acqprogress.h
index 71a10d78a..7cf990c65 100644
--- a/apt-private/acqprogress.h
+++ b/apt-private/acqprogress.h
@@ -13,14 +13,18 @@
#include <apt-pkg/macros.h>
#include <string>
+#include <iostream>
class APT_PUBLIC AcqTextStatus : public pkgAcquireStatus
{
+ std::ostream &out;
unsigned int &ScreenWidth;
- char BlankLine[1024];
+ size_t LastLineLength;
unsigned long ID;
unsigned long Quiet;
+ void clearLastLine();
+
public:
virtual bool MediaChange(std::string Media,std::string Drive);
@@ -33,7 +37,7 @@ class APT_PUBLIC AcqTextStatus : public pkgAcquireStatus
bool Pulse(pkgAcquire *Owner);
- AcqTextStatus(unsigned int &ScreenWidth,unsigned int const Quiet);
+ AcqTextStatus(std::ostream &out, unsigned int &ScreenWidth,unsigned int const Quiet);
};
#endif
diff --git a/apt-private/private-cachefile.cc b/apt-private/private-cachefile.cc
index 5e955ac39..29e665245 100644
--- a/apt-private/private-cachefile.cc
+++ b/apt-private/private-cachefile.cc
@@ -32,8 +32,10 @@ int CacheFile::NameComp(const void *a,const void *b)
const pkgCache::Package &A = **(pkgCache::Package **)a;
const pkgCache::Package &B = **(pkgCache::Package **)b;
+ const pkgCache::Group * const GA = SortCache->GrpP + A.Group;
+ const pkgCache::Group * const GB = SortCache->GrpP + B.Group;
- return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name);
+ return strcmp(SortCache->StrP + GA->Name,SortCache->StrP + GB->Name);
}
/*}}}*/
// CacheFile::Sort - Sort by name /*{{{*/
diff --git a/apt-private/private-cachefile.h b/apt-private/private-cachefile.h
index dce7e0a3a..1fddabfbd 100644
--- a/apt-private/private-cachefile.h
+++ b/apt-private/private-cachefile.h
@@ -6,7 +6,20 @@
#include <apt-pkg/configuration.h>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/macros.h>
+#include <apt-pkg/sourcelist.h>
+#include <apti18n.h>
+// FIXME: we need to find a way to export this
+class APT_PUBLIC SourceList : public pkgSourceList
+{
+
+ public:
+ // Add custom metaIndex (e.g. local files)
+ void AddMetaIndex(metaIndex *mi) {
+ SrcList.push_back(mi);
+ }
+
+};
// class CacheFile - Cover class for some dependency cache functions /*{{{*/
// ---------------------------------------------------------------------
@@ -28,6 +41,16 @@ class APT_PUBLIC CacheFile : public pkgCacheFile
return false;
return true;
}
+ // FIXME: this can go once the "libapt-pkg" pkgSourceList has a way
+ // to add custom metaIndexes (or custom local files or so)
+ bool BuildSourceList(OpProgress */*Progress*/ = NULL) {
+ if (SrcList != NULL)
+ return true;
+ SrcList = new SourceList();
+ if (SrcList->ReadMainList() == false)
+ return _error->Error(_("The list of sources could not be read."));
+ return true;
+ }
bool Open(bool WithLock = true)
{
OpTextProgress Prog(*_config);
diff --git a/apt-private/private-cacheset.cc b/apt-private/private-cacheset.cc
index e37e7b227..cb68024db 100644
--- a/apt-private/private-cacheset.cc
+++ b/apt-private/private-cacheset.cc
@@ -14,74 +14,77 @@
#include <apti18n.h>
-bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
- LocalitySortedVersionSet &output_set,
- OpProgress &progress)
+bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
+ APT::VersionContainerInterface * const vci,
+ OpProgress * const progress)
{
Matcher null_matcher = Matcher();
- return GetLocalitySortedVersionSet(CacheFile, output_set,
+ return GetLocalitySortedVersionSet(CacheFile, vci,
null_matcher, progress);
}
-bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
- LocalitySortedVersionSet &output_set,
+bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
+ APT::VersionContainerInterface * const vci,
Matcher &matcher,
- OpProgress &progress)
+ OpProgress * const progress)
{
pkgCache *Cache = CacheFile.GetPkgCache();
pkgDepCache *DepCache = CacheFile.GetDepCache();
+ APT::CacheSetHelper helper(false);
int Done=0;
- progress.SubProgress(Cache->Head().PackageCount, _("Sorting"));
+ if (progress != NULL)
+ progress->SubProgress(Cache->Head().PackageCount, _("Sorting"));
+
+ bool const insertCurrentVer = _config->FindB("APT::Cmd::Installed", false);
+ bool const insertUpgradable = _config->FindB("APT::Cmd::Upgradable", false);
+ bool const insertManualInstalled = _config->FindB("APT::Cmd::Manual-Installed", false);
+
for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
{
- if (Done%500 == 0)
- progress.Progress(Done);
- Done++;
+ if (progress != NULL)
+ {
+ if (Done % 500 == 0)
+ progress->Progress(Done);
+ ++Done;
+ }
+
+ // exclude virtual pkgs
+ if (P->VersionList == 0)
+ continue;
if ((matcher)(P) == false)
- continue;
+ continue;
- // exclude virtual pkgs
- if (P.VersionList() == 0)
- continue;
pkgDepCache::StateCache &state = (*DepCache)[P];
- if (_config->FindB("APT::Cmd::Installed") == true)
+ if (insertCurrentVer == true)
{
- if (P.CurrentVer() != NULL)
- {
- output_set.insert(P.CurrentVer());
- }
+ if (P->CurrentVer != 0)
+ vci->FromPackage(vci, CacheFile, P, APT::CacheSetHelper::INSTALLED, helper);
}
- else if (_config->FindB("APT::Cmd::Upgradable") == true)
+ else if (insertUpgradable == true)
{
- if(P.CurrentVer() && state.Upgradable())
- {
- pkgPolicy *policy = CacheFile.GetPolicy();
- output_set.insert(policy->GetCandidateVer(P));
- }
+ if(P.CurrentVer() && state.Upgradable())
+ vci->FromPackage(vci, CacheFile, P, APT::CacheSetHelper::CANDIDATE, helper);
}
- else if (_config->FindB("APT::Cmd::Manual-Installed") == true)
+ else if (insertManualInstalled == true)
{
- if (P.CurrentVer() &&
- ((*DepCache)[P].Flags & pkgCache::Flag::Auto) == false)
- {
- pkgPolicy *policy = CacheFile.GetPolicy();
- output_set.insert(policy->GetCandidateVer(P));
- }
+ if (P.CurrentVer() &&
+ ((*DepCache)[P].Flags & pkgCache::Flag::Auto) == false)
+ vci->FromPackage(vci, CacheFile, P, APT::CacheSetHelper::CANDIDATE, helper);
}
- else
+ else
{
- pkgPolicy *policy = CacheFile.GetPolicy();
- if (policy->GetCandidateVer(P).IsGood())
- output_set.insert(policy->GetCandidateVer(P));
- else
- // no candidate, this may happen for packages in
- // dpkg "deinstall ok config-file" state - we pick the first ver
- // (which should be the only one)
- output_set.insert(P.VersionList());
+ if (vci->FromPackage(vci, CacheFile, P, APT::CacheSetHelper::CANDIDATE, helper) == false)
+ {
+ // no candidate, this may happen for packages in
+ // dpkg "deinstall ok config-file" state - we pick the first ver
+ // (which should be the only one)
+ vci->insert(P.VersionList());
+ }
}
}
- progress.Done();
+ if (progress != NULL)
+ progress->Done();
return true;
}
diff --git a/apt-private/private-cacheset.h b/apt-private/private-cacheset.h
index 854d16922..059c7637e 100644
--- a/apt-private/private-cacheset.h
+++ b/apt-private/private-cacheset.h
@@ -62,13 +62,13 @@ public:
};
// FIXME: add default argument for OpProgress (or overloaded function)
-bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
- LocalitySortedVersionSet &output_set,
+bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
+ APT::VersionContainerInterface * const vci,
Matcher &matcher,
- OpProgress &progress);
-bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
- LocalitySortedVersionSet &output_set,
- OpProgress &progress);
+ OpProgress * const progress);
+bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile,
+ APT::VersionContainerInterface * const vci,
+ OpProgress * const progress);
// CacheSetHelper saving virtual packages /*{{{*/
@@ -76,19 +76,16 @@ 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 canNotGetVersion(enum CacheSetHelper::VerSelector const select, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ if (select == NEWEST || select == CANDIDATE || select == ALL)
+ virtualPkgs.insert(Pkg);
+ return CacheSetHelper::canNotGetVersion(select, 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);
+ virtual void canNotFindVersion(enum CacheSetHelper::VerSelector const select, APT::VersionContainerInterface * vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ if (select == NEWEST || select == CANDIDATE || select == ALL)
+ virtualPkgs.insert(Pkg);
+ return CacheSetHelper::canNotFindVersion(select, vci, Cache, Pkg);
}
CacheSetHelperVirtuals(bool const ShowErrors = true, GlobalError::MsgType const &ErrorType = GlobalError::NOTICE) : CacheSetHelper(ShowErrors, ErrorType) {}
@@ -190,7 +187,7 @@ public:
}
virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
- APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDIDATE);
+ APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, CacheSetHelper::CANDIDATE);
if (verset.empty() == false)
return *(verset.begin());
else if (ShowError == true) {
@@ -203,7 +200,7 @@ public:
virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
if (Pkg->ProvidesList != 0)
{
- APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST);
+ APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, CacheSetHelper::NEWEST);
if (verset.empty() == false)
return *(verset.begin());
if (ShowError == true)
@@ -231,7 +228,7 @@ public:
}
APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg,
- APT::VersionSet::Version const &select) {
+ CacheSetHelper::VerSelector 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)
diff --git a/apt-private/private-cmndline.cc b/apt-private/private-cmndline.cc
index a21a9dc8c..41aab81f6 100644
--- a/apt-private/private-cmndline.cc
+++ b/apt-private/private-cmndline.cc
@@ -2,12 +2,17 @@
#include <config.h>
#include <apt-pkg/cmndline.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/error.h>
#include <apt-private/private-cmndline.h>
#include <vector>
#include <stdarg.h>
#include <string.h>
+#include <stdlib.h>
#include <apti18n.h>
/*}}}*/
@@ -70,6 +75,8 @@ static bool addArgumentsAPTCache(std::vector<CommandLine::Args> &Args, char cons
else
return false;
+ bool const found_something = Args.empty() == false;
+
// FIXME: move to the correct command(s)
addArg('g', "generate", "APT::Cache::Generate", 0);
addArg('t', "target-release", "APT::Default-Release", CommandLine::HasArg);
@@ -77,7 +84,8 @@ static bool addArgumentsAPTCache(std::vector<CommandLine::Args> &Args, char cons
addArg('p', "pkg-cache", "Dir::Cache::pkgcache", CommandLine::HasArg);
addArg('s', "src-cache", "Dir::Cache::srcpkgcache", CommandLine::HasArg);
- return true;
+
+ return found_something;
}
/*}}}*/
static bool addArgumentsAPTCDROM(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
@@ -162,8 +170,8 @@ static bool addArgumentsAPTGet(std::vector<CommandLine::Args> &Args, char const
addArg(0, "color", "APT::Moo::Color", 0);
if (CmdMatches("install", "remove", "purge", "upgrade", "dist-upgrade",
- "deselect-upgrade", "autoremove", "clean", "autoclean", "check",
- "build-dep", "full-upgrade"))
+ "dselect-upgrade", "autoremove", "clean", "autoclean", "check",
+ "build-dep", "full-upgrade", "source"))
{
addArg('s', "simulate", "APT::Get::Simulate", 0);
addArg('s', "just-print", "APT::Get::Simulate", 0);
@@ -172,6 +180,8 @@ static bool addArgumentsAPTGet(std::vector<CommandLine::Args> &Args, char const
addArg('s', "no-act", "APT::Get::Simulate", 0);
}
+ bool const found_something = Args.empty() == false;
+
// FIXME: move to the correct command(s)
addArg('d',"download-only","APT::Get::Download-Only",0);
addArg('y',"yes","APT::Get::Assume-Yes",0);
@@ -193,11 +203,12 @@ static bool addArgumentsAPTGet(std::vector<CommandLine::Args> &Args, char const
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,"allow-insecure-repositories","Acquire::AllowInsecureRepositories",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;
+ return found_something;
}
/*}}}*/
static bool addArgumentsAPTMark(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
@@ -281,3 +292,31 @@ std::vector<CommandLine::Args> getCommandArgs(char const * const Program, char c
/*}}}*/
#undef CmdMatches
#undef addArg
+void ParseCommandLine(CommandLine &CmdL, CommandLine::Dispatch * const Cmds, CommandLine::Args * const Args,/*{{{*/
+ Configuration * const * const Cnf, pkgSystem ** const Sys, int const argc, const char *argv[], bool(*ShowHelp)(CommandLine &CmdL))
+{
+ CmdL = CommandLine(Args,_config);
+ if ((Cnf != NULL && pkgInitConfig(**Cnf) == false) ||
+ CmdL.Parse(argc,argv) == false ||
+ (Sys != NULL && pkgInitSystem(*_config, *Sys) == false))
+ {
+ if (_config->FindB("version") == true)
+ ShowHelp(CmdL);
+
+ _error->DumpErrors();
+ exit(100);
+ }
+
+ // See if the help should be shown
+ if (_config->FindB("help") == true || _config->FindB("version") == true)
+ {
+ ShowHelp(CmdL);
+ exit(0);
+ }
+ if (Cmds != NULL && CmdL.FileSize() == 0)
+ {
+ ShowHelp(CmdL);
+ exit(1);
+ }
+}
+ /*}}}*/
diff --git a/apt-private/private-cmndline.h b/apt-private/private-cmndline.h
index d0af16782..7b468456b 100644
--- a/apt-private/private-cmndline.h
+++ b/apt-private/private-cmndline.h
@@ -6,6 +6,12 @@
#include <vector>
+class Configuration;
+class pkgSystem;
+
APT_PUBLIC std::vector<CommandLine::Args> getCommandArgs(char const * const Program, char const * const Cmd);
+APT_PUBLIC void ParseCommandLine(CommandLine &CmdL, CommandLine::Dispatch * const Cmds, CommandLine::Args * const Args,
+ Configuration * const * const Cnf, pkgSystem ** const Sys, int const argc, const char * argv[],
+ bool(*ShowHelp)(CommandLine &CmdL));
#endif
diff --git a/apt-private/private-download.cc b/apt-private/private-download.cc
index a095f0c67..37fae18e9 100644
--- a/apt-private/private-download.cc
+++ b/apt-private/private-download.cc
@@ -5,6 +5,7 @@
#include <apt-pkg/acquire-item.h>
#include <apt-pkg/configuration.h>
#include <apt-pkg/error.h>
+#include <apt-pkg/fileutl.h>
#include <apt-pkg/strutl.h>
#include <apt-private/private-output.h>
@@ -14,9 +15,66 @@
#include <string>
#include <vector>
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <fcntl.h>
+#include <sys/vfs.h>
+#include <sys/statvfs.h>
+#include <errno.h>
+
#include <apti18n.h>
/*}}}*/
+bool CheckDropPrivsMustBeDisabled(pkgAcquire &Fetcher) /*{{{*/
+{
+ // no need/possibility to drop privs
+ if(getuid() != 0)
+ return true;
+
+ // the user does not want to drop privs
+ std::string SandboxUser = _config->Find("APT::Sandbox::User");
+ if (SandboxUser.empty())
+ return true;
+
+ struct passwd const * const pw = getpwnam(SandboxUser.c_str());
+ if (pw == NULL)
+ return true;
+
+ if (seteuid(pw->pw_uid) != 0)
+ return _error->Errno("seteuid", "seteuid %u failed", pw->pw_uid);
+
+ bool res = true;
+ // check if we can write to destfile
+ for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin();
+ I != Fetcher.ItemsEnd() && res == true; ++I)
+ {
+ if ((*I)->DestFile.empty())
+ continue;
+ // we assume that an existing (partial) file means that we have sufficient rights
+ if (RealFileExists((*I)->DestFile))
+ continue;
+ int fd = open((*I)->DestFile.c_str(), O_CREAT | O_EXCL | O_RDWR, 0600);
+ if (fd < 0)
+ {
+ res = false;
+ std::string msg;
+ strprintf(msg, _("Can't drop privileges for downloading as file '%s' couldn't be accessed by user '%s'."),
+ (*I)->DestFile.c_str(), SandboxUser.c_str());
+ std::cerr << "W: " << msg << std::endl;
+ _config->Set("APT::Sandbox::User", "");
+ break;
+ }
+ unlink((*I)->DestFile.c_str());
+ close(fd);
+ }
+
+ if (seteuid(0) != 0)
+ return _error->Errno("seteuid", "seteuid %u failed", 0);
+
+ return res;
+}
+ /*}}}*/
// CheckAuth - check if each download comes form a trusted source /*{{{*/
bool CheckAuth(pkgAcquire& Fetcher, bool const PromptUser)
{
@@ -28,6 +86,11 @@ bool CheckAuth(pkgAcquire& Fetcher, bool const PromptUser)
if (UntrustedList == "")
return true;
+ return AuthPrompt(UntrustedList, PromptUser);
+}
+
+bool AuthPrompt(std::string const &UntrustedList, bool const PromptUser)
+{
ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,"");
if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true)
@@ -93,3 +156,39 @@ bool AcquireRun(pkgAcquire &Fetcher, int const PulseInterval, bool * const Failu
return true;
}
/*}}}*/
+bool CheckFreeSpaceBeforeDownload(std::string const &Dir, unsigned long long FetchBytes)/*{{{*/
+{
+ uint32_t const RAMFS_MAGIC = 0x858458f6;
+ /* Check for enough free space, but only if we are actually going to
+ download */
+ if (_config->FindB("APT::Get::Print-URIs", false) == true ||
+ _config->FindB("APT::Get::Download", true) == false)
+ return true;
+
+ struct statvfs Buf;
+ if (statvfs(Dir.c_str(),&Buf) != 0) {
+ if (errno == EOVERFLOW)
+ return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
+ Dir.c_str());
+ else
+ return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
+ Dir.c_str());
+ }
+ else
+ {
+ unsigned long long const FreeBlocks = _config->Find("APT::Sandbox::User").empty() ? Buf.f_bfree : Buf.f_bavail;
+ if (FreeBlocks < (FetchBytes / Buf.f_bsize))
+ {
+ struct statfs Stat;
+ if (statfs(Dir.c_str(),&Stat) != 0
+#if HAVE_STRUCT_STATFS_F_TYPE
+ || Stat.f_type != RAMFS_MAGIC
+#endif
+ )
+ return _error->Error(_("You don't have enough free space in %s."),
+ Dir.c_str());
+ }
+ }
+ return true;
+}
+ /*}}}*/
diff --git a/apt-private/private-download.h b/apt-private/private-download.h
index a108aa531..0a0ac6b95 100644
--- a/apt-private/private-download.h
+++ b/apt-private/private-download.h
@@ -3,9 +3,21 @@
#include <apt-pkg/macros.h>
+#include <string>
+
class pkgAcquire;
+APT_PUBLIC bool CheckDropPrivsMustBeDisabled(pkgAcquire &Fetcher);
+
+// Check if all files in the fetcher are authenticated
APT_PUBLIC bool CheckAuth(pkgAcquire& Fetcher, bool const PromptUser);
+
+// show a authentication warning prompt and return true if the system
+// should continue
+APT_PUBLIC bool AuthPrompt(std::string const &UntrustedList, bool const PromptUser);
+
APT_PUBLIC bool AcquireRun(pkgAcquire &Fetcher, int const PulseInterval, bool * const Failure, bool * const TransientNetworkFailure);
+APT_PUBLIC bool CheckFreeSpaceBeforeDownload(std::string const &Dir, unsigned long long FetchBytes);
+
#endif
diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc
index 107ed398e..acc6d42c2 100644
--- a/apt-private/private-install.cc
+++ b/apt-private/private-install.cc
@@ -19,16 +19,16 @@
#include <apt-pkg/macros.h>
#include <apt-pkg/packagemanager.h>
#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/upgrade.h>
+#include <apt-pkg/install-progress.h>
-#include <errno.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/statfs.h>
-#include <sys/statvfs.h>
#include <algorithm>
#include <iostream>
#include <set>
#include <vector>
+#include <map>
#include <apt-private/acqprogress.h>
#include <apt-private/private-install.h>
@@ -94,7 +94,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
{
pkgSimulate PM(Cache);
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+#if APT_PKG_ABI >= 413
APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory();
pkgPackageManager::OrderResult Res = PM.DoInstall(progress);
delete progress;
@@ -116,14 +116,14 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
return false;
// Create the download object
- pkgAcquire Fetcher;
- AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
+ AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0));
+ pkgAcquire Fetcher(&Stat);
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)
+ else if (Fetcher.GetLock(_config->FindDir("Dir::Cache::Archives")) == false)
return false;
// Read the source list
@@ -174,33 +174,9 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
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());
- }
- }
-
+ if (CheckFreeSpaceBeforeDownload(_config->FindDir("Dir::Cache::Archives"), (FetchBytes - FetchPBytes)) == false)
+ return false;
+
// Fail safe check
if (_config->FindI("quiet",0) >= 2 ||
_config->FindB("APT::Get::Assume-Yes",false) == true)
@@ -330,8 +306,8 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
}
_system->UnLock();
-
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+
+#if APT_PKG_ABI >= 413
APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory();
pkgPackageManager::OrderResult Res = PM->DoInstall(progress);
delete progress;
@@ -524,15 +500,14 @@ static bool DoAutomaticRemove(CacheFile &Cache)
static const unsigned short MOD_REMOVE = 1;
static const unsigned short MOD_INSTALL = 2;
-bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache)
+bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, int UpgradeMode)
{
std::map<unsigned short, APT::VersionSet> verset;
- return DoCacheManipulationFromCommandLine(CmdL, Cache, verset);
+ return DoCacheManipulationFromCommandLine(CmdL, Cache, verset, UpgradeMode);
}
bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
- std::map<unsigned short, APT::VersionSet> &verset)
+ std::map<unsigned short, APT::VersionSet> &verset, int UpgradeMode)
{
-
// Enter the special broken fixing mode if the user specified arguments
bool BrokenFix = false;
if (Cache->BrokenCount() != 0)
@@ -558,9 +533,9 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
std::list<APT::VersionSet::Modifier> mods;
mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+",
- APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDIDATE));
+ APT::VersionSet::Modifier::POSTFIX, APT::CacheSetHelper::CANDIDATE));
mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-",
- APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST));
+ APT::VersionSet::Modifier::POSTFIX, APT::CacheSetHelper::NEWEST));
CacheSetHelperAPTGet helper(c0out);
verset = APT::VersionSet::GroupedFromCommandLine(Cache,
CmdL.FileList + 1, mods, fallback, helper);
@@ -617,7 +592,17 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
if (Fix != NULL)
{
// Call the scored problem resolver
- Fix->Resolve(true);
+ OpTextProgress Progress(*_config);
+ bool const distUpgradeMode = strcmp(CmdL.FileList[0], "dist-upgrade") == 0 || strcmp(CmdL.FileList[0], "full-upgrade") == 0;
+
+ bool resolver_fail = false;
+ if (distUpgradeMode == true || UpgradeMode != APT::Upgrade::ALLOW_EVERYTHING)
+ resolver_fail = APT::Upgrade::Upgrade(Cache, UpgradeMode, &Progress);
+ else
+ resolver_fail = Fix->Resolve(true, &Progress);
+
+ if (resolver_fail == false && Cache->BrokenCount() == 0)
+ return false;
}
// Now we check the state of the packages,
@@ -669,13 +654,37 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
bool DoInstall(CommandLine &CmdL)
{
CacheFile Cache;
+ // first check for local pkgs and add them to the cache
+ for (const char **I = CmdL.FileList; *I != 0; I++)
+ {
+ if(FileExists(*I))
+ {
+ // FIXME: make this more elegant
+ std::string TypeStr = flExtension(*I) + "-file";
+ pkgSourceList::Type *Type = pkgSourceList::Type::GetType(TypeStr.c_str());
+ if(Type != 0)
+ {
+ std::vector<metaIndex *> List;
+ std::map<std::string, std::string> Options;
+ if(Type->CreateItem(List, *I, "", "", Options))
+ {
+ // we have our own CacheFile that gives us a SourceList
+ // with superpowerz
+ SourceList *sources = (SourceList*)Cache.GetSourceList();
+ sources->AddMetaIndex(List[0]);
+ }
+ }
+ }
+ }
+
+ // then open the cache
if (Cache.OpenForInstall() == false ||
Cache.CheckDeps(CmdL.FileSize() != 1) == false)
return false;
-
+
std::map<unsigned short, APT::VersionSet> verset;
- if(!DoCacheManipulationFromCommandLine(CmdL, Cache, verset))
+ if(!DoCacheManipulationFromCommandLine(CmdL, Cache, verset, 0))
return false;
/* Print out a list of packages that are going to be installed extra
@@ -801,3 +810,144 @@ bool DoInstall(CommandLine &CmdL)
return InstallPackages(Cache,false);
}
/*}}}*/
+
+// TryToInstall - Mark a package for installation /*{{{*/
+void TryToInstall::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 TryToInstall::propergateReleaseCandiateSwitching(std::list<std::pair<pkgCache::VerIterator, std::string> > const &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;
+ // the Changed list contains:
+ // first: "new version"
+ // second: "what-caused the change"
+ 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 TryToInstall::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 /*{{{*/
+void TryToRemove::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);
+}
+ /*}}}*/
diff --git a/apt-private/private-install.h b/apt-private/private-install.h
index 5e18560c5..62276fbff 100644
--- a/apt-private/private-install.h
+++ b/apt-private/private-install.h
@@ -3,43 +3,31 @@
#include <apt-pkg/cachefile.h>
#include <apt-pkg/configuration.h>
-#include <apt-pkg/depcache.h>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/cacheiterators.h>
#include <apt-pkg/cacheset.h>
-#include <apt-pkg/strutl.h>
-#include <apt-pkg/algorithms.h>
#include <apt-pkg/macros.h>
-#include <apt-private/private-output.h>
-
-#include <stddef.h>
-#include <iosfwd>
#include <list>
-#include <map>
#include <string>
#include <utility>
-
-#include <apti18n.h>
-
class CacheFile;
class CommandLine;
-
-#define RAMFS_MAGIC 0x858458f6
+class pkgProblemResolver;
APT_PUBLIC bool DoInstall(CommandLine &Cmd);
bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
- std::map<unsigned short, APT::VersionSet> &verset);
-bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache);
+ std::map<unsigned short, APT::VersionSet> &verset, int UpgradeMode);
+bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, int UpgradeMode);
APT_PUBLIC bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
bool Safety = true);
// TryToInstall - Mark a package for installation /*{{{*/
-struct TryToInstall {
+struct APT_PUBLIC TryToInstall {
pkgCacheFile* Cache;
pkgProblemResolver* Fix;
bool FixBroken;
@@ -49,109 +37,13 @@ struct TryToInstall {
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;
- // the Changed list contains:
- // first: "new version"
- // second: "what-caused the change"
- 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();
- }
+ void operator() (pkgCache::VerIterator const &Ver);
+ bool propergateReleaseCandiateSwitching(std::list<std::pair<pkgCache::VerIterator, std::string> > const &start, std::ostream &out);
+ void doAutoInstall();
};
/*}}}*/
// TryToRemove - Mark a package for removal /*{{{*/
-struct TryToRemove {
+struct APT_PUBLIC TryToRemove {
pkgCacheFile* Cache;
pkgProblemResolver* Fix;
bool PurgePkgs;
@@ -159,43 +51,7 @@ struct TryToRemove {
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);
- }
+ void operator() (pkgCache::VerIterator const &Ver);
};
/*}}}*/
diff --git a/apt-private/private-list.cc b/apt-private/private-list.cc
index b69002103..aa3a2c24b 100644
--- a/apt-private/private-list.cc
+++ b/apt-private/private-list.cc
@@ -37,28 +37,20 @@ struct PackageSortAlphabetic /*{{{*/
return (l_name < r_name);
}
};
- /*}}}*/
-class PackageNameMatcher : public Matcher /*{{{*/
+
+class PackageNameMatcher : public Matcher
{
-#ifdef PACKAGE_MATCHER_ABI_COMPAT
-#define PackageMatcher PackageNameMatchesFnmatch
-#endif
public:
PackageNameMatcher(const char **patterns)
{
for(int i=0; patterns[i] != NULL; ++i)
{
std::string pattern = patterns[i];
-#ifdef PACKAGE_MATCHER_ABI_COMPAT
- APT::CacheFilter::PackageNameMatchesFnmatch *cachefilter = NULL;
- cachefilter = new APT::CacheFilter::PackageNameMatchesFnmatch(pattern);
-#else
APT::CacheFilter::PackageMatcher *cachefilter = NULL;
if(_config->FindB("APT::Cmd::Use-Regexp", false) == true)
cachefilter = new APT::CacheFilter::PackageNameMatchesRegEx(pattern);
else
cachefilter = new APT::CacheFilter::PackageNameMatchesFnmatch(pattern);
-#endif
filters.push_back(cachefilter);
}
}
@@ -85,15 +77,14 @@ private:
};
/*}}}*/
static void ListAllVersions(pkgCacheFile &CacheFile, pkgRecords &records,/*{{{*/
- pkgCache::PkgIterator P,
- std::ostream &outs,
- bool include_summary=true)
+ pkgCache::PkgIterator const &P, std::ostream &outs,
+ std::string const &format)
{
for (pkgCache::VerIterator Ver = P.VersionList();
Ver.end() == false; ++Ver)
{
- ListSingleVersion(CacheFile, records, Ver, outs, include_summary);
- outs << "\n";
+ ListSingleVersion(CacheFile, records, Ver, outs, format);
+ outs << std::endl;
}
}
/*}}}*/
@@ -117,10 +108,9 @@ bool DoList(CommandLine &Cmd)
patterns = Cmd.FileList + 1;
}
- std::map<std::string, std::string> output_map;
- std::map<std::string, std::string>::const_iterator K;
-
- bool includeSummary = _config->FindB("APT::Cmd::List-Include-Summary");
+ std::string format = "${color:highlight}${Package}${color:neutral}/${Origin} ${Version} ${Architecture}${ }${apt:Status}";
+ if (_config->FindB("APT::Cmd::List-Include-Summary", false) == true)
+ format += "\n ${Description}\n";
PackageNameMatcher matcher(patterns);
LocalitySortedVersionSet bag;
@@ -129,37 +119,34 @@ bool DoList(CommandLine &Cmd)
Cache->Head().PackageCount,
Cache->Head().PackageCount,
_("Listing"));
- GetLocalitySortedVersionSet(CacheFile, bag, matcher, progress);
- bool ShowAllVersions = _config->FindB("APT::Cmd::All-Versions", false);
+ GetLocalitySortedVersionSet(CacheFile, &bag, matcher, &progress);
+ bool const ShowAllVersions = _config->FindB("APT::Cmd::All-Versions", false);
+ std::map<std::string, std::string> output_map;
for (LocalitySortedVersionSet::iterator V = bag.begin(); V != bag.end(); ++V)
{
std::stringstream outs;
if(ShowAllVersions == true)
- {
- ListAllVersions(CacheFile, records, V.ParentPkg(), outs, includeSummary);
- output_map.insert(std::make_pair<std::string, std::string>(
- V.ParentPkg().Name(), outs.str()));
- } else {
- ListSingleVersion(CacheFile, records, V, outs, includeSummary);
- output_map.insert(std::make_pair<std::string, std::string>(
- V.ParentPkg().Name(), outs.str()));
- }
+ ListAllVersions(CacheFile, records, V.ParentPkg(), outs, format);
+ else
+ ListSingleVersion(CacheFile, records, V, outs, format);
+ 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
+ std::map<std::string, std::string>::const_iterator K;
for (K = output_map.begin(); K != output_map.end(); ++K)
std::cout << (*K).second << std::endl;
-
// be nice and tell the user if there is more to see
if (bag.size() == 1 && ShowAllVersions == false)
{
// start with -1 as we already displayed one version
int versions = -1;
pkgCache::VerIterator Ver = *bag.begin();
- for ( ; Ver.end() == false; Ver++)
- versions++;
+ for ( ; Ver.end() == false; ++Ver)
+ ++versions;
if (versions > 0)
_error->Notice(P_("There is %i additional version. Please use the '-a' switch to see it", "There are %i additional versions. Please use the '-a' switch to see them.", versions), versions);
}
diff --git a/apt-private/private-output.cc b/apt-private/private-output.cc
index 7f3eef6c2..4e18030ab 100644
--- a/apt-private/private-output.cc
+++ b/apt-private/private-output.cc
@@ -23,6 +23,7 @@
#include <langinfo.h>
#include <unistd.h>
#include <signal.h>
+#include <sys/ioctl.h>
#include <apti18n.h>
/*}}}*/
@@ -51,14 +52,14 @@ static void SigWinch(int)
#endif
}
/*}}}*/
-bool InitOutput() /*{{{*/
+bool InitOutput(std::basic_streambuf<char> * const out) /*{{{*/
{
if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
_config->Set("quiet","1");
- c0out.rdbuf(cout.rdbuf());
- c1out.rdbuf(cout.rdbuf());
- c2out.rdbuf(cout.rdbuf());
+ c0out.rdbuf(out);
+ c1out.rdbuf(out);
+ c2out.rdbuf(out);
if (_config->FindI("quiet",0) > 0)
c0out.rdbuf(devnull.rdbuf());
if (_config->FindI("quiet",0) > 1)
@@ -93,7 +94,7 @@ bool InitOutput() /*{{{*/
static std::string GetArchiveSuite(pkgCacheFile &/*CacheFile*/, pkgCache::VerIterator ver) /*{{{*/
{
std::string suite = "";
- if (ver && ver.FileList() && ver.FileList())
+ if (ver && ver.FileList())
{
pkgCache::VerFileIterator VF = ver.FileList();
for (; VF.end() == false ; ++VF)
@@ -117,7 +118,7 @@ static std::string GetFlagsStr(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)
std::string flags_str;
if (state.NowBroken())
flags_str = "B";
- if (P.CurrentVer() && state.Upgradable())
+ if (P.CurrentVer() && state.Upgradable() && state.CandidateVer != NULL)
flags_str = "g";
else if (P.CurrentVer() != NULL)
flags_str = "i";
@@ -163,15 +164,26 @@ static std::string GetVersion(pkgCacheFile &/*CacheFile*/, pkgCache::VerIterator
/*}}}*/
static std::string GetArchitecture(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)/*{{{*/
{
- pkgPolicy *policy = CacheFile.GetPolicy();
- pkgCache::VerIterator inst = P.CurrentVer();
- pkgCache::VerIterator cand = policy->GetCandidateVer(P);
-
- // this may happen for packages in dpkg "deinstall ok config-file" state
- if (inst.IsGood() == false && cand.IsGood() == false)
- return P.VersionList().Arch();
-
- return inst ? inst.Arch() : cand.Arch();
+ if (P->CurrentVer == 0)
+ {
+ pkgDepCache * const DepCache = CacheFile.GetDepCache();
+ pkgDepCache::StateCache const &state = (*DepCache)[P];
+ if (state.CandidateVer != NULL)
+ {
+ pkgCache::VerIterator const CandV(CacheFile, state.CandidateVer);
+ return CandV.Arch();
+ }
+ else
+ {
+ pkgCache::VerIterator const V = P.VersionList();
+ if (V.end() == false)
+ return V.Arch();
+ else
+ return P.Arch();
+ }
+ }
+ else
+ return P.CurrentVer().Arch();
}
/*}}}*/
static std::string GetShortDescription(pkgCacheFile &CacheFile, pkgRecords &records, pkgCache::PkgIterator P)/*{{{*/
@@ -195,80 +207,90 @@ static std::string GetShortDescription(pkgCacheFile &CacheFile, pkgRecords &reco
return ShortDescription;
}
/*}}}*/
-void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records, /*{{{*/
- pkgCache::VerIterator V, std::ostream &out,
- bool include_summary)
+static std::string GetLongDescription(pkgCacheFile &CacheFile, pkgRecords &records, pkgCache::PkgIterator P)/*{{{*/
{
- pkgCache::PkgIterator P = V.ParentPkg();
+ pkgPolicy *policy = CacheFile.GetPolicy();
- pkgDepCache *DepCache = CacheFile.GetDepCache();
- pkgDepCache::StateCache &state = (*DepCache)[P];
+ pkgCache::VerIterator ver;
+ if (P->CurrentVer != 0)
+ ver = P.CurrentVer();
+ else
+ ver = policy->GetCandidateVer(P);
- std::string suite = GetArchiveSuite(CacheFile, V);
- std::string name_str = P.Name();
+ std::string const EmptyDescription = "(none)";
+ if(ver.end() == true)
+ return EmptyDescription;
+
+ pkgCache::DescIterator const Desc = ver.TranslatedDescription();
+ pkgRecords::Parser & parser = records.Lookup(Desc.FileList());
+ std::string const longdesc = parser.LongDesc();
+ if (longdesc.empty() == true)
+ return EmptyDescription;
+ return SubstVar(longdesc, "\n ", "\n ");
+}
+ /*}}}*/
+void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records, /*{{{*/
+ pkgCache::VerIterator const &V, std::ostream &out,
+ std::string const &format)
+{
+ pkgCache::PkgIterator const P = V.ParentPkg();
+ pkgDepCache * const DepCache = CacheFile.GetDepCache();
+ pkgDepCache::StateCache const &state = (*DepCache)[P];
+ std::string output;
if (_config->FindB("APT::Cmd::use-format", false))
+ output = _config->Find("APT::Cmd::format", "${db::Status-Abbrev} ${Package} ${Version} ${Origin} ${Description}");
+ else
+ output = format;
+
+ // FIXME: some of these names are really icky – and all is nowhere documented
+ output = SubstVar(output, "${db::Status-Abbrev}", GetFlagsStr(CacheFile, P));
+ output = SubstVar(output, "${Package}", P.Name());
+ std::string const ArchStr = GetArchitecture(CacheFile, P);
+ output = SubstVar(output, "${Architecture}", ArchStr);
+ std::string const InstalledVerStr = GetInstalledVersion(CacheFile, P);
+ output = SubstVar(output, "${installed:Version}", InstalledVerStr);
+ std::string const CandidateVerStr = GetCandidateVersion(CacheFile, P);
+ output = SubstVar(output, "${candidate:Version}", CandidateVerStr);
+ std::string const VersionStr = GetVersion(CacheFile, V);
+ output = SubstVar(output, "${Version}", VersionStr);
+ output = SubstVar(output, "${Origin}", GetArchiveSuite(CacheFile, V));
+
+ std::string StatusStr = "";
+ if (P->CurrentVer != 0)
{
- 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();
- std::string VersionStr = GetVersion(CacheFile, V);
- std::string CandidateVerStr = GetCandidateVersion(CacheFile, P);
- std::string InstalledVerStr = GetInstalledVersion(CacheFile, P);
- std::string StatusStr;
- if(P.CurrentVer() == V && state.Upgradable()) {
- strprintf(StatusStr, _("[installed,upgradable to: %s]"),
- CandidateVerStr.c_str());
- } else if (P.CurrentVer() == V) {
- if(!V.Downloadable())
- StatusStr = _("[installed,local]");
- else
- if(V.Automatic() && state.Garbage)
- StatusStr = _("[installed,auto-removable]");
- else if (state.Flags & pkgCache::Flag::Auto)
- StatusStr = _("[installed,automatic]");
- else
- StatusStr = _("[installed]");
- } else if (P.CurrentVer() &&
- policy->GetCandidateVer(P) == V &&
- state.Upgradable()) {
- strprintf(StatusStr, _("[upgradable from: %s]"),
- InstalledVerStr.c_str());
- } else {
- if (V.ParentPkg()->CurrentState == pkgCache::State::ConfigFiles)
- StatusStr = _("[residual-config]");
- else
- StatusStr = "";
- }
- out << std::setiosflags(std::ios::left)
- << _config->Find("APT::Color::Highlight", "")
- << name_str
- << _config->Find("APT::Color::Neutral", "")
- << "/" << suite
- << " "
- << VersionStr << " "
- << GetArchitecture(CacheFile, P);
- if (StatusStr != "")
- out << " " << StatusStr;
- if (include_summary)
+ if (P.CurrentVer() == V)
{
- out << std::endl
- << " " << GetShortDescription(CacheFile, records, P)
- << std::endl;
+ if (state.Upgradable() && state.CandidateVer != NULL)
+ strprintf(StatusStr, _("[installed,upgradable to: %s]"),
+ CandidateVerStr.c_str());
+ else if (V.Downloadable() == false)
+ StatusStr = _("[installed,local]");
+ else if(V.Automatic() == true && state.Garbage == true)
+ StatusStr = _("[installed,auto-removable]");
+ else if ((state.Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto)
+ StatusStr = _("[installed,automatic]");
+ else
+ StatusStr = _("[installed]");
}
+ else if (state.CandidateVer == V && state.Upgradable())
+ strprintf(StatusStr, _("[upgradable from: %s]"),
+ InstalledVerStr.c_str());
}
+ else if (V.ParentPkg()->CurrentState == pkgCache::State::ConfigFiles)
+ StatusStr = _("[residual-config]");
+ output = SubstVar(output, "${apt:Status}", StatusStr);
+ output = SubstVar(output, "${color:highlight}", _config->Find("APT::Color::Highlight", ""));
+ output = SubstVar(output, "${color:neutral}", _config->Find("APT::Color::Neutral", ""));
+ output = SubstVar(output, "${Description}", GetShortDescription(CacheFile, records, P));
+ output = SubstVar(output, "${LongDescription}", GetLongDescription(CacheFile, records, P));
+ output = SubstVar(output, "${ }${ }", "${ }");
+ output = SubstVar(output, "${ }\n", "\n");
+ output = SubstVar(output, "${ }", " ");
+ if (APT::String::Endswith(output, " ") == true)
+ output.erase(output.length() - 1);
+
+ out << output;
}
/*}}}*/
// ShowList - Show a list /*{{{*/
@@ -343,129 +365,141 @@ bool ShowList(ostream &out,string Title,string List,string VersionsList)
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)
+static void ShowBrokenPackage(ostream &out, pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg, bool const Now)
{
- if (Cache->BrokenCount() == 0)
+ if (Now == true)
+ {
+ if ((*Cache)[Pkg].NowBroken() == false)
+ return;
+ }
+ else
+ {
+ if ((*Cache)[Pkg].InstBroken() == false)
+ return;
+ }
+
+ // Print out each package and the failed dependencies
+ out << " " << Pkg.FullName(true) << " :";
+ unsigned const Indent = Pkg.FullName(true).size() + 3;
+ bool First = true;
+ pkgCache::VerIterator Ver;
+
+ if (Now == true)
+ Ver = Pkg.CurrentVer();
+ else
+ Ver = (*Cache)[Pkg].InstVerIter(*Cache);
+
+ if (Ver.end() == true)
+ {
+ out << endl;
return;
+ }
- out << _("The following packages have unmet dependencies:") << endl;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
{
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
-
+ // 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[I].NowBroken() == false)
+ if (((*Cache)[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
continue;
}
else
{
- if (Cache[I].InstBroken() == false)
+ if (((*Cache)[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
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;)
+
+ bool FirstOr = true;
+ while (1)
{
- // Compute a single dependency element (glob or)
- pkgCache::DepIterator Start;
- pkgCache::DepIterator End;
- D.GlobOr(Start,End); // advances D
+ if (First == false)
+ for (unsigned J = 0; J != Indent; J++)
+ out << ' ';
+ First = false;
- if (Cache->IsImportantDep(End) == false)
- continue;
-
- if (Now == true)
+ if (FirstOr == false)
{
- if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
- continue;
+ 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)
{
- 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;
+ out << ' ';
+ pkgCache::VerIterator Ver = (*Cache)[Targ].InstVerIter(*Cache);
+ if (Now == true)
+ Ver = Targ.CurrentVer();
- if (FirstOr == false)
+ if (Ver.end() == false)
{
- for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
- out << ' ';
+ if (Now == true)
+ ioprintf(out,_("but %s is installed"),Ver.VerStr());
+ else
+ ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
}
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 ((*Cache)[Targ].CandidateVerIter(*Cache).end() == true)
{
- if (Now == true)
- ioprintf(out,_("but %s is installed"),Ver.VerStr());
+ if (Targ->ProvidesList == 0)
+ out << _("but it is not installable");
else
- ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
- }
+ out << _("but it is a virtual package");
+ }
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"));
- }
+ 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;
- }
- }
- }
+ }
+
+ if (Start != End)
+ out << _(" or");
+ out << endl;
+
+ if (Start == End)
+ break;
+ ++Start;
+ }
+ }
+}
+void ShowBroken(ostream &out, CacheFile &Cache, bool const 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 const I(Cache,Cache.List[J]);
+ ShowBrokenPackage(out, &Cache, I, Now);
+ }
+}
+void ShowBroken(ostream &out, pkgCacheFile &Cache, bool const Now)
+{
+ if (Cache->BrokenCount() == 0)
+ return;
+
+ out << _("The following packages have unmet dependencies:") << endl;
+ for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
+ ShowBrokenPackage(out, &Cache, Pkg, Now);
}
/*}}}*/
// ShowNew - Show packages to newly install /*{{{*/
diff --git a/apt-private/private-output.h b/apt-private/private-output.h
index 9633d0c37..d5b57adec 100644
--- a/apt-private/private-output.h
+++ b/apt-private/private-output.h
@@ -6,6 +6,7 @@
#include <fstream>
#include <string>
+#include <iostream>
// forward declaration
class pkgCacheFile;
@@ -20,15 +21,16 @@ APT_PUBLIC extern std::ostream c2out;
APT_PUBLIC extern std::ofstream devnull;
APT_PUBLIC extern unsigned int ScreenWidth;
-APT_PUBLIC bool InitOutput();
+APT_PUBLIC bool InitOutput(std::basic_streambuf<char> * const out = std::cout.rdbuf());
void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records,
- pkgCache::VerIterator V, std::ostream &out,
- bool include_summary=true);
+ pkgCache::VerIterator const &V, std::ostream &out,
+ std::string const &format);
// helper to describe global state
-APT_PUBLIC void ShowBroken(std::ostream &out,CacheFile &Cache,bool Now);
+APT_PUBLIC void ShowBroken(std::ostream &out, CacheFile &Cache, bool const Now);
+APT_PUBLIC void ShowBroken(std::ostream &out, pkgCacheFile &Cache, bool const Now);
APT_PUBLIC bool ShowList(std::ostream &out, std::string Title, std::string List,
std::string VersionsList);
diff --git a/apt-private/private-search.cc b/apt-private/private-search.cc
index ecd5d7fad..6bce9ffa4 100644
--- a/apt-private/private-search.cc
+++ b/apt-private/private-search.cc
@@ -32,61 +32,95 @@ 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;
+ // Make sure there is at least one argument
+ unsigned int const NumPatterns = CmdL.FileSize() -1;
+ if (NumPatterns < 1)
+ return _error->Error(_("You must give at least one search pattern"));
+
+#define APT_FREE_PATTERNS() for (std::vector<regex_t>::iterator P = Patterns.begin(); \
+ P != Patterns.end(); ++P) { regfree(&(*P)); }
+
+ // Compile the regex pattern
+ std::vector<regex_t> Patterns;
+ for (unsigned int I = 0; I != NumPatterns; ++I)
+ {
+ regex_t pattern;
+ if (regcomp(&pattern, CmdL.FileList[I + 1], REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
+ {
+ APT_FREE_PATTERNS();
+ return _error->Error("Regex compilation error");
+ }
+ Patterns.push_back(pattern);
+ }
+
+ bool const NamesOnly = _config->FindB("APT::Cache::NamesOnly", false);
std::map<std::string, std::string> output_map;
- std::map<std::string, std::string>::const_iterator K;
LocalitySortedVersionSet bag;
OpTextProgress progress(*_config);
progress.OverallProgress(0, 100, 50, _("Sorting"));
- GetLocalitySortedVersionSet(CacheFile, bag, progress);
+ GetLocalitySortedVersionSet(CacheFile, &bag, &progress);
LocalitySortedVersionSet::iterator V = bag.begin();
progress.OverallProgress(50, 100, 50, _("Full Text Search"));
progress.SubProgress(bag.size());
+ pkgRecords records(CacheFile);
+
+ std::string format = "${color:highlight}${Package}${color:neutral}/${Origin} ${Version} ${Architecture}${ }${apt:Status}\n";
+ if (_config->FindB("APT::Cache::ShowFull",false) == false)
+ format += " ${Description}\n";
+ else
+ format += " ${LongDescription}\n";
+
int Done = 0;
+ std::vector<bool> PkgsDone(Cache->Head().PackageCount, false);
for ( ;V != bag.end(); ++V)
{
if (Done%500 == 0)
progress.Progress(Done);
++Done;
-
- int i;
+
+ // we want to list each package only once
+ pkgCache::PkgIterator const P = V.ParentPkg();
+ if (PkgsDone[P->ID] == true)
+ continue;
+
+ char const * const PkgName = P.Name();
pkgCache::DescIterator Desc = V.TranslatedDescription();
pkgRecords::Parser &parser = records.Lookup(Desc.FileList());
-
+ std::string const LongDesc = parser.LongDesc();
+
bool all_found = true;
- for(i=0; patterns[i] != NULL; ++i)
+ for (std::vector<regex_t>::const_iterator pattern = Patterns.begin();
+ pattern != Patterns.end(); ++pattern)
{
- // FIXME: use regexp instead of simple find()
- const char *pattern = patterns[i];
- all_found &= (
- strstr(V.ParentPkg().Name(), pattern) != NULL ||
- strcasestr(parser.ShortDesc().c_str(), pattern) != NULL ||
- strcasestr(parser.LongDesc().c_str(), pattern) != NULL);
- // search patterns are AND by default so we can skip looking further
- // on the first mismatch
- if(all_found == false)
- break;
+ if (regexec(&(*pattern), PkgName, 0, 0, 0) == 0)
+ continue;
+ else if (NamesOnly == false && regexec(&(*pattern), LongDesc.c_str(), 0, 0, 0) == 0)
+ continue;
+ // search patterns are AND, so one failing fails all
+ all_found = false;
+ break;
}
- if (all_found)
+ if (all_found == true)
{
- std::stringstream outs;
- ListSingleVersion(CacheFile, records, V, outs);
- output_map.insert(std::make_pair<std::string, std::string>(
- V.ParentPkg().Name(), outs.str()));
+ PkgsDone[P->ID] = true;
+ std::stringstream outs;
+ ListSingleVersion(CacheFile, records, V, outs, format);
+ output_map.insert(std::make_pair<std::string, std::string>(
+ PkgName, outs.str()));
}
}
+ APT_FREE_PATTERNS();
progress.Done();
// FIXME: SORT! and make sorting flexible (alphabetic, by pkg status)
// output the sorted map
+ std::map<std::string, std::string>::const_iterator K;
for (K = output_map.begin(); K != output_map.end(); ++K)
std::cout << (*K).second << std::endl;
diff --git a/apt-private/private-show.cc b/apt-private/private-show.cc
index 8ae6a6dac..790bc0092 100644
--- a/apt-private/private-show.cc
+++ b/apt-private/private-show.cc
@@ -97,28 +97,30 @@ static bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V,
manual_installed = 0;
// FIXME: add verbose that does not do the removal of the tags?
- TFRewriteData RW[] = {
- // delete, apt-cache show has this info and most users do not care
- {"MD5sum", NULL, NULL},
- {"SHA1", NULL, NULL},
- {"SHA256", NULL, NULL},
- {"Filename", NULL, NULL},
- {"Multi-Arch", NULL, NULL},
- {"Architecture", NULL, NULL},
- {"Conffiles", NULL, NULL},
- // we use the translated description
- {"Description", NULL, NULL},
- {"Description-md5", NULL, NULL},
- // improve
- {"Installed-Size", installed_size.c_str(), NULL},
- {"Size", package_size.c_str(), "Download-Size"},
- // add
- {"APT-Manual-Installed", manual_installed, NULL},
- {"APT-Sources", source_index_file.c_str(), NULL},
- {NULL, NULL, NULL}
- };
-
- if(TFRewrite(stdout, Tags, NULL, RW) == false)
+ std::vector<pkgTagSection::Tag> RW;
+ // delete, apt-cache show has this info and most users do not care
+ RW.push_back(pkgTagSection::Tag::Remove("MD5sum"));
+ RW.push_back(pkgTagSection::Tag::Remove("SHA1"));
+ RW.push_back(pkgTagSection::Tag::Remove("SHA256"));
+ RW.push_back(pkgTagSection::Tag::Remove("SHA512"));
+ RW.push_back(pkgTagSection::Tag::Remove("Filename"));
+ RW.push_back(pkgTagSection::Tag::Remove("Multi-Arch"));
+ RW.push_back(pkgTagSection::Tag::Remove("Architecture"));
+ RW.push_back(pkgTagSection::Tag::Remove("Conffiles"));
+ // we use the translated description
+ RW.push_back(pkgTagSection::Tag::Remove("Description"));
+ RW.push_back(pkgTagSection::Tag::Remove("Description-md5"));
+ // improve
+ RW.push_back(pkgTagSection::Tag::Rewrite("Installed-Size", installed_size));
+ RW.push_back(pkgTagSection::Tag::Remove("Size"));
+ RW.push_back(pkgTagSection::Tag::Rewrite("Download-Size", package_size));
+ // add
+ RW.push_back(pkgTagSection::Tag::Rewrite("APT-Manual-Installed", manual_installed));
+ RW.push_back(pkgTagSection::Tag::Rewrite("APT-Sources", source_index_file));
+
+ FileFd stdoutfd;
+ if (stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly, false) == false ||
+ Tags.Write(stdoutfd, TFRewritePackageOrder, RW) == false || stdoutfd.Close() == false)
return _error->Error("Internal Error, Unable to parse a package record");
// write the description
@@ -141,16 +143,16 @@ bool ShowPackage(CommandLine &CmdL) /*{{{*/
{
pkgCacheFile CacheFile;
CacheSetHelperVirtuals helper(true, GlobalError::NOTICE);
- APT::VersionList::Version const select = _config->FindB("APT::Cache::AllVersions", false) ?
- APT::VersionList::ALL : APT::VersionList::CANDIDATE;
+ APT::CacheSetHelper::VerSelector const select = _config->FindB("APT::Cache::AllVersions", false) ?
+ APT::CacheSetHelper::ALL : APT::CacheSetHelper::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;
- if (select == APT::VersionList::CANDIDATE)
+ if (select == APT::CacheSetHelper::CANDIDATE)
{
- APT::VersionList const verset_all = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, APT::VersionList::ALL, helper);
+ APT::VersionList const verset_all = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, APT::CacheSetHelper::ALL, helper);
int const records = verset_all.size() - verset.size();
if (records > 0)
_error->Notice(P_("There is %i additional record. Please use the '-a' switch to see it", "There are %i additional records. Please use the '-a' switch to see them.", records), records);
diff --git a/apt-private/private-update.cc b/apt-private/private-update.cc
index da83d7741..73a82e988 100644
--- a/apt-private/private-update.cc
+++ b/apt-private/private-update.cc
@@ -38,8 +38,8 @@ bool DoUpdate(CommandLine &CmdL)
pkgSourceList *List = Cache.GetSourceList();
// Create the progress
- AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
-
+ AcqTextStatus Stat(std::cout, 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)
{
@@ -47,19 +47,24 @@ bool DoUpdate(CommandLine &CmdL)
_config->CndSet("Acquire::ForceHash", "md5sum");
// get a fetcher
- pkgAcquire Fetcher;
- if (Fetcher.Setup(&Stat) == false)
- return false;
+ pkgAcquire Fetcher(&Stat);
// Populate it with the source selection and get all Indexes
// (GetAll=true)
if (List->GetIndexes(&Fetcher,true) == false)
return false;
+ std::string compExt = APT::Configuration::getCompressionTypes()[0];
pkgAcquire::UriIterator I = Fetcher.UriBegin();
for (; I != Fetcher.UriEnd(); ++I)
- c1out << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
+ {
+ std::string FileName = flNotDir(I->Owner->DestFile);
+ if(compExt.empty() == false &&
+ APT::String::Endswith(FileName, compExt))
+ FileName = FileName.substr(0, FileName.size() - compExt.size() - 1);
+ c1out << '\'' << I->URI << "' " << FileName << ' ' <<
I->Owner->FileSize << ' ' << I->Owner->HashSum() << std::endl;
+ }
return true;
}
@@ -75,6 +80,27 @@ bool DoUpdate(CommandLine &CmdL)
return false;
}
+ // show basic stats (if the user whishes)
+ if (_config->FindB("APT::Cmd::Show-Update-Stats", false) == true)
+ {
+ int upgradable = 0;
+ Cache.Open();
+ for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() != true; ++I)
+ {
+ pkgDepCache::StateCache &state = Cache[I];
+ if (I->CurrentVer != 0 && state.Upgradable() && state.CandidateVer != NULL)
+ upgradable++;
+ }
+ const char *msg = P_(
+ "%i package can be upgraded. Run 'apt list --upgradable' to see it.\n",
+ "%i packages can be upgraded. Run 'apt list --upgradable' to see them.\n",
+ upgradable);
+ if (upgradable == 0)
+ c1out << _("All packages are up to date.") << std::endl;
+ else
+ ioprintf(c1out, msg, upgradable);
+ }
+
return true;
}
/*}}}*/
diff --git a/apt-private/private-upgrade.cc b/apt-private/private-upgrade.cc
index 68b2c5e00..d13a6af49 100644
--- a/apt-private/private-upgrade.cc
+++ b/apt-private/private-upgrade.cc
@@ -22,19 +22,9 @@ static bool UpgradeHelper(CommandLine &CmdL, int UpgradeFlags)
if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
return false;
- c0out << _("Calculating upgrade... ") << std::flush;
- if (APT::Upgrade::Upgrade(Cache, UpgradeFlags) == false)
- {
- c0out << _("Failed") << std::endl;
- ShowBroken(c1out,Cache,false);
- return _error->Error(_("Internal error, Upgrade broke stuff"));
- }
- c0out << _("Done") << std::endl;
-
- // parse additional cmdline pkg manipulation switches
- if(!DoCacheManipulationFromCommandLine(CmdL, Cache))
+ if(!DoCacheManipulationFromCommandLine(CmdL, Cache, UpgradeFlags))
return false;
-
+
return InstallPackages(Cache,true);
}
@@ -43,7 +33,7 @@ static bool UpgradeHelper(CommandLine &CmdL, int UpgradeFlags)
/* Intelligent upgrader that will install and remove packages at will */
bool DoDistUpgrade(CommandLine &CmdL)
{
- return UpgradeHelper(CmdL, 0);
+ return UpgradeHelper(CmdL, APT::Upgrade::ALLOW_EVERYTHING);
}
/*}}}*/
bool DoUpgrade(CommandLine &CmdL) /*{{{*/
diff --git a/apt-private/private-utils.cc b/apt-private/private-utils.cc
index 9547a1b75..34af83c08 100644
--- a/apt-private/private-utils.cc
+++ b/apt-private/private-utils.cc
@@ -8,45 +8,69 @@
#include <cstdlib>
#include <unistd.h>
-// DisplayFileInPager - Display File with pager /*{{{*/
-void DisplayFileInPager(std::string filename)
+// DisplayFileInPager - Display File with pager /*{{{*/
+void DisplayFileInPager(std::string const &filename)
{
- std::string pager = _config->Find("Dir::Bin::Pager",
- "/usr/bin/sensible-pager");
-
pid_t Process = ExecFork();
if (Process == 0)
{
const char *Args[3];
- Args[0] = pager.c_str();
Args[1] = filename.c_str();
- Args[2] = 0;
+ Args[2] = NULL;
+ if (isatty(STDOUT_FILENO) == 1)
+ {
+ // likely installed, provided by sensible-utils
+ std::string const pager = _config->Find("Dir::Bin::Pager",
+ "sensible-pager");
+ Args[0] = pager.c_str();
+ execvp(Args[0],(char **)Args);
+ // lets try some obvious alternatives
+ Args[0] = getenv("PAGER");
+ if (Args[0] != NULL)
+ execvp(Args[0],(char **)Args);
+
+ Args[0] = "pager";
+ execvp(Args[0],(char **)Args);
+ }
+ // we could read the file ourselves, but… meh
+ Args[0] = "cat";
execvp(Args[0],(char **)Args);
exit(100);
}
-
+
// Wait for the subprocess
- ExecWait(Process, "sensible-pager", false);
+ ExecWait(Process, "pager", false);
}
/*}}}*/
-// EditFileInSensibleEditor - Edit File with editor /*{{{*/
-void EditFileInSensibleEditor(std::string filename)
+// EditFileInSensibleEditor - Edit File with editor /*{{{*/
+void EditFileInSensibleEditor(std::string const &filename)
{
- std::string editor = _config->Find("Dir::Bin::Editor",
- "/usr/bin/sensible-editor");
-
pid_t Process = ExecFork();
if (Process == 0)
{
+ // likely installed, provided by sensible-utils
+ std::string const editor = _config->Find("Dir::Bin::Editor",
+ "sensible-editor");
const char *Args[3];
Args[0] = editor.c_str();
Args[1] = filename.c_str();
- Args[2] = 0;
+ Args[2] = NULL;
+ execvp(Args[0],(char **)Args);
+ // the usual suspects we can try as an alternative
+ Args[0] = getenv("VISUAL");
+ if (Args[0] != NULL)
+ execvp(Args[0],(char **)Args);
+
+ Args[0] = getenv("EDITOR");
+ if (Args[0] != NULL)
+ execvp(Args[0],(char **)Args);
+
+ Args[0] = "editor";
execvp(Args[0],(char **)Args);
exit(100);
}
-
+
// Wait for the subprocess
- ExecWait(Process, "sensible-editor", false);
+ ExecWait(Process, "editor", false);
}
/*}}}*/
diff --git a/apt-private/private-utils.h b/apt-private/private-utils.h
index 432699787..8ba480bd4 100644
--- a/apt-private/private-utils.h
+++ b/apt-private/private-utils.h
@@ -5,7 +5,7 @@
#include <string>
-APT_PUBLIC void DisplayFileInPager(std::string filename);
-APT_PUBLIC void EditFileInSensibleEditor(std::string filename);
+APT_PUBLIC void DisplayFileInPager(std::string const &filename);
+APT_PUBLIC void EditFileInSensibleEditor(std::string const &filename);
#endif