// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: apt-get.cc,v 1.68 1999/07/09 04:11:34 jgg Exp $
+// $Id: apt-get.cc,v 1.77 1999/09/30 06:30:34 jgg Exp $
/* ######################################################################
apt-get - Cover for dpkg
ofstream devnull("/dev/null");
unsigned int ScreenWidth = 80;
+// 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 Open(bool WithLock = true)
+ {
+ OpTextProgress Prog(*_config);
+ if (pkgCacheFile::Open(Prog,WithLock) == false)
+ return false;
+ Sort();
+ return true;
+ };
+ CacheFile() : List(0) {};
+};
+ /*}}}*/
+
// YnPrompt - Yes No Prompt. /*{{{*/
// ---------------------------------------------------------------------
/* Returns true on a Yes.*/
/* 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. */
-void ShowBroken(ostream &out,pkgDepCache &Cache)
+void ShowBroken(ostream &out,CacheFile &Cache,bool Now)
{
out << "Sorry, but the following packages have unmet dependencies:" << endl;
- pkgCache::PkgIterator I = Cache.PkgBegin();
- for (;I.end() != true; I++)
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
{
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+
if (Cache[I].InstBroken() == false)
continue;
pkgCache::DepIterator End;
D.GlobOr(Start,End);
- if (Cache.IsImportantDep(End) == false ||
+ if (Cache->IsImportantDep(End) == false ||
(Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
continue;
")";
/* Show a summary of the target package if possible. In the case
- of virtual packages we show nothing */
-
+ of virtual packages we show nothing */
pkgCache::PkgIterator Targ = End.TargetPkg();
if (Targ->ProvidesList == 0)
{
out << " but ";
pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
if (Ver.end() == false)
- out << Ver.VerStr() << " is installed";
+ out << Ver.VerStr() << (Now?" is installed":" is to be installed");
else
{
if (Cache[Targ].CandidateVerIter(Cache).end() == true)
out << "it is a virtual package";
}
else
- out << "it is not installed";
+ out << (Now?"it is not installed":"it is not going to be installed");
}
}
// ShowNew - Show packages to newly install /*{{{*/
// ---------------------------------------------------------------------
/* */
-void ShowNew(ostream &out,pkgDepCache &Dep)
+void ShowNew(ostream &out,CacheFile &Cache)
{
/* Print out a list of packages that are going to be removed extra
to what the user asked */
- pkgCache::PkgIterator I = Dep.PkgBegin();
string List;
- for (;I.end() != true; I++)
- if (Dep[I].NewInstall() == true)
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ {
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if (Cache[I].NewInstall() == true)
List += string(I.Name()) + " ";
+ }
+
ShowList(out,"The following NEW packages will be installed:",List);
}
/*}}}*/
// ShowDel - Show packages to delete /*{{{*/
// ---------------------------------------------------------------------
/* */
-void ShowDel(ostream &out,pkgDepCache &Dep)
+void ShowDel(ostream &out,CacheFile &Cache)
{
/* Print out a list of packages that are going to be removed extra
to what the user asked */
- pkgCache::PkgIterator I = Dep.PkgBegin();
string List;
- for (;I.end() != true; I++)
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
{
- if (Dep[I].Delete() == true)
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if (Cache[I].Delete() == true)
{
- if ((Dep[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
+ if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
List += string(I.Name()) + "* ";
else
List += string(I.Name()) + " ";
// ShowKept - Show kept packages /*{{{*/
// ---------------------------------------------------------------------
/* */
-void ShowKept(ostream &out,pkgDepCache &Dep)
+void ShowKept(ostream &out,CacheFile &Cache)
{
- pkgCache::PkgIterator I = Dep.PkgBegin();
string List;
- for (;I.end() != true; I++)
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
{
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+
// Not interesting
- if (Dep[I].Upgrade() == true || Dep[I].Upgradable() == false ||
- I->CurrentVer == 0 || Dep[I].Delete() == true)
+ if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false ||
+ I->CurrentVer == 0 || Cache[I].Delete() == true)
continue;
List += string(I.Name()) + " ";
// ShowUpgraded - Show upgraded packages /*{{{*/
// ---------------------------------------------------------------------
/* */
-void ShowUpgraded(ostream &out,pkgDepCache &Dep)
+void ShowUpgraded(ostream &out,CacheFile &Cache)
{
- pkgCache::PkgIterator I = Dep.PkgBegin();
string List;
- for (;I.end() != true; I++)
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
{
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+
// Not interesting
- if (Dep[I].Upgrade() == false || Dep[I].NewInstall() == true)
+ if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
continue;
List += string(I.Name()) + " ";
// ShowHold - Show held but changed packages /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool ShowHold(ostream &out,pkgDepCache &Dep)
+bool ShowHold(ostream &out,CacheFile &Cache)
{
- pkgCache::PkgIterator I = Dep.PkgBegin();
string List;
- for (;I.end() != true; I++)
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
{
- if (Dep[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
+ if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
I->SelectedState == pkgCache::State::Hold)
List += string(I.Name()) + " ";
}
/* 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,pkgDepCache &Dep)
+bool ShowEssential(ostream &out,CacheFile &Cache)
{
- pkgCache::PkgIterator I = Dep.PkgBegin();
string List;
- bool *Added = new bool[Dep.HeaderP->PackageCount];
- for (unsigned int I = 0; I != Dep.HeaderP->PackageCount; I++)
+ bool *Added = new bool[Cache->HeaderP->PackageCount];
+ for (unsigned int I = 0; I != Cache->HeaderP->PackageCount; I++)
Added[I] = false;
- for (;I.end() != true; I++)
+ 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)
continue;
// The essential package is being removed
- if (Dep[I].Delete() == true)
+ if (Cache[I].Delete() == true)
{
if (Added[I->ID] == false)
{
continue;
pkgCache::PkgIterator P = D.SmartTargetPkg();
- if (Dep[P].Delete() == true)
+ if (Cache[P].Delete() == true)
{
if (Added[P->ID] == true)
continue;
}
/*}}}*/
-// class CacheFile - Cover class for some dependency cache functions /*{{{*/
+// CacheFile::NameComp - QSort compare by name /*{{{*/
// ---------------------------------------------------------------------
/* */
-class CacheFile : public pkgCacheFile
+pkgCache *CacheFile::SortCache = 0;
+int CacheFile::NameComp(const void *a,const void *b)
{
- public:
+ if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0)
+ return *(pkgCache::Package **)a - *(pkgCache::Package **)b;
- bool CheckDeps(bool AllowBroken = false);
- bool Open(bool WithLock = true)
- {
- OpTextProgress Prog(*_config);
- return pkgCacheFile::Open(Prog,WithLock);
- };
-};
+ 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::Open - Open the cache file /*{{{*/
// ---------------------------------------------------------------------
if (pkgFixBroken(*Cache) == false || Cache->BrokenCount() != 0)
{
c1out << " failed." << endl;
- ShowBroken(c1out,*this);
+ ShowBroken(c1out,*this,true);
return _error->Error("Unable to correct dependencies");
}
else
{
c1out << "You might want to run `apt-get -f install' to correct these." << endl;
- ShowBroken(c1out,*this);
+ ShowBroken(c1out,*this,true);
return _error->Error("Unmet dependencies. Try using -f.");
}
{
pkgCache::PkgIterator I = Cache->PkgBegin();
for (; I.end() == false; I++)
- Cache[I].iFlags |= pkgDepCache::Purge;
+ {
+ if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
+ Cache->MarkDelete(I,true);
+ }
}
bool Fail = false;
// Sanity check
if (Cache->BrokenCount() != 0)
{
- ShowBroken(c1out,Cache);
+ ShowBroken(c1out,Cache,false);
return _error->Error("Internal Error, InstallPackages was called with broken packages!");
}
if (Fetcher.Run() == pkgAcquire::Failed)
return false;
+ bool Failed = false;
+ for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
+ {
+ if ((*I)->Status == pkgAcquire::Item::StatDone)
+ continue;
+
+ (*I)->Finished();
+
+ cerr << "Failed to fetch " << (*I)->DescURI() << endl;
+ cerr << " " << (*I)->ErrorText << endl;
+ Failed = true;
+ }
+
// Clean out any old list files
- if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
- Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
- return false;
+ if (_config->FindB("APT::Get::List-Cleanup",false) == false)
+ {
+ if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
+ Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
+ return false;
+ }
// Prepare the cache.
CacheFile Cache;
if (Cache.Open() == false)
return false;
+ if (Failed == true)
+ return _error->Error("Some index files failed to download, they have been ignored, or old ones used instead.");
return true;
}
/*}}}*/
// Do the upgrade
if (pkgAllUpgrade(Cache) == false)
{
- ShowBroken(c1out,Cache);
+ ShowBroken(c1out,Cache,false);
return _error->Error("Internal Error, AllUpgrade broke stuff");
}
if (Remove == true)
{
Fix.Remove(Pkg);
- Cache->MarkDelete(Pkg);
+ Cache->MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
continue;
}
if (BrokenFix == true && Cache->BrokenCount() != 0)
{
c1out << "You might want to run `apt-get -f install' to correct these:" << endl;
- ShowBroken(c1out,Cache);
+ ShowBroken(c1out,Cache,false);
return _error->Error("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).");
}
c1out << "The following information may help to resolve the situation:" << endl;
c1out << endl;
- ShowBroken(c1out,Cache);
+ ShowBroken(c1out,Cache,false);
return _error->Error("Sorry, broken packages");
}
if (Cache->InstCount() != ExpectedInst)
{
string List;
- pkgCache::PkgIterator I = Cache->PkgBegin();
- for (;I.end() != true; I++)
+ for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
{
+ pkgCache::PkgIterator I(Cache,Cache.List[J]);
if ((*Cache)[I].Install() == false)
continue;
if (pkgDistUpgrade(*Cache) == false)
{
c0out << "Failed" << endl;
- ShowBroken(c1out,Cache);
+ ShowBroken(c1out,Cache,false);
return false;
}
// Remove packages
if (I->SelectedState == pkgCache::State::DeInstall ||
I->SelectedState == pkgCache::State::Purge)
- Cache->MarkDelete(I);
- if (I->SelectedState == pkgCache::State::Purge)
- Cache[I].iFlags |= pkgDepCache::Purge;
+ Cache->MarkDelete(I,I->SelectedState == pkgCache::State::Purge);
}
/* Resolve any problems that dselect created, allupgrade cannot handle
if (Fix.Resolve() == false)
{
- ShowBroken(c1out,Cache);
+ ShowBroken(c1out,Cache,false);
return _error->Error("Internal Error, problem resolver broke stuff");
}
}
// Now upgrade everything
if (pkgAllUpgrade(Cache) == false)
{
- ShowBroken(c1out,Cache);
+ ShowBroken(c1out,Cache,false);
return _error->Error("Internal Error, problem resolver broke stuff");
}
if (I->Path.find(".diff.gz") != string::npos)
Comp = "diff";
+ // Diff only mode only fetches .diff files
+ if (_config->FindB("APT::Get::Diff-Only",false) == true &&
+ Comp != "diff")
+ continue;
+
+ // Tar only mode only fetches .tar files
+ if (_config->FindB("APT::Get::Tar-Only",false) == true &&
+ Comp != "tar")
+ continue;
+
new pkgAcqFile(&Fetcher,Last->Source()->ArchiveURI(I->Path),
I->MD5Hash,I->Size,Last->Source()->SourceInfo(Src,
Last->Version(),Comp),Src);
{
string Dir = Dsc[I].Package + '-' + pkgBaseVersion(Dsc[I].Version.c_str());
+ // Diff only mode only fetches .diff files
+ if (_config->FindB("APT::Get::Diff-Only",false) == true ||
+ _config->FindB("APT::Get::Tar-Only",false) == true)
+ continue;
+
// See if the package is already unpacked
struct stat Stat;
if (stat(Dir.c_str(),&Stat) == 0 &&
_config->Set("APT::Get::Assume-Yes",false);
_config->Set("APT::Get::Fix-Broken",false);
_config->Set("APT::Get::Force-Yes",false);
+ _config->Set("APT::Get::APT::Get::No-List-Cleanup",true);
}
/*}}}*/
// SigWinch - Window size change signal handler /*{{{*/
{0,"no-upgrade","APT::Get::no-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,"tar-only","APT::Get::tar-Only",0},
{0,"purge","APT::Get::Purge",0},
+ {0,"list-cleanup","APT::Get::List-Cleanup",0},
{'c',"config-file",0,CommandLine::ConfigFile},
{'o',"option",0,CommandLine::ArbItem},
{0,0,0,0}};