// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: apt-get.cc,v 1.82 1999/10/22 04:05:47 jgg Exp $
+// $Id: apt-get.cc,v 1.96 2000/05/10 06:03:01 jgg Exp $
/* ######################################################################
apt-get - Cover for dpkg
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
-#include <sys/vfs.h>
+#include <sys/statvfs.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
{
unsigned long Upgrade = 0;
unsigned long Install = 0;
+ unsigned long ReInstall = 0;
for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++)
{
if (Dep[I].NewInstall() == true)
else
if (Dep[I].Upgrade() == true)
Upgrade++;
+ if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
+ ReInstall++;
}
out << Upgrade << " packages upgraded, " <<
- Install << " newly installed, " <<
- Dep.DelCount() << " to remove and " <<
+ Install << " newly installed, ";
+ if (ReInstall != 0)
+ out << ReInstall << " reinstalled, ";
+ out << Dep.DelCount() << " to remove and " <<
Dep.KeepCount() << " not upgraded." << endl;
if (Dep.BadCount() != 0)
// ---------------------------------------------------------------------
/* This displays the informative messages describing what is going to
happen and then calls the download routines */
-bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey = true)
+bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
+ bool Saftey = true)
{
if (_config->FindB("APT::Get::Purge",false) == true)
{
return _error->Error("Internal Error, InstallPackages was called with broken packages!");
}
- if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
+ if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
Cache->BadCount() == 0)
return true;
+ // No remove flag
+ if (Cache->DelCount() != 0 && _config->FindB("APT::Get::No-Remove",false) == true)
+ return _error->Error("Packages need to be removed but No Remove was specified.");
+
// Run the simulator ..
if (_config->FindB("APT::Get::Simulate") == true)
{
c1out << SizeToStr(DebBytes) << 'B';
c1out << " of archives. After unpacking ";
-
- // Check for enough free space
- struct statfs Buf;
- string OutputDir = _config->FindDir("Dir::Cache::Archives");
- if (statfs(OutputDir.c_str(),&Buf) != 0)
- return _error->Errno("statfs","Couldn't determine free space in %s",
- OutputDir.c_str());
- if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
- return _error->Error("Sorry, you don't have enough free space in %s to hold all the .debs.",
- OutputDir.c_str());
// Size delta
if (Cache->UsrSize() >= 0)
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)
+ {
+ struct statvfs Buf;
+ string OutputDir = _config->FindDir("Dir::Cache::Archives");
+ if (statvfs(OutputDir.c_str(),&Buf) != 0)
+ return _error->Errno("statvfs","Couldn't determine free space in %s",
+ OutputDir.c_str());
+ if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
+ return _error->Error("Sorry, you don't have enough free space in %s to hold all the .debs.",
+ OutputDir.c_str());
+ }
+
// Fail safe check
if (_config->FindI("quiet",0) >= 2 ||
_config->FindB("APT::Get::Assume-Yes",false) == true)
if (Essential == true && Saftey == true)
{
+ if (_config->FindB("APT::Get::Trivial-Only",false) == true)
+ return _error->Error("Trivial Only specified but this is not a trivial operation.");
+
c2out << "You are about to do something potentially harmful" << endl;
c2out << "To continue type in the phrase 'Yes, I understand this may be bad'" << endl;
c2out << " ?] " << flush;
}
}
else
- {
+ {
// Prompt to continue
if (Ask == true || Fail == true)
{
+ if (_config->FindB("APT::Get::Trivial-Only",false) == true)
+ return _error->Error("Trivial Only specified but this is not a trivial operation.");
+
if (_config->FindI("quiet",0) < 2 &&
_config->FindB("APT::Get::Assume-Yes",false) == false)
{
// Run it
while (1)
{
- if (_config->FindB("APT::Get::No-Download",false) == false)
- if (Fetcher.Run() == pkgAcquire::Failed)
- return false;
+ bool Transient = false;
+ if (_config->FindB("APT::Get::No-Download",false) == true)
+ {
+ for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
+ {
+ if ((*I)->Local == true)
+ {
+ I++;
+ continue;
+ }
+
+ // Close the item and check if it was found in cache
+ (*I)->Finished();
+ if ((*I)->Complete == false)
+ Transient = true;
+
+ // Clear it out of the fetch list
+ delete *I;
+ I = Fetcher.ItemsBegin();
+ }
+ }
+
+ if (Fetcher.Run() == pkgAcquire::Failed)
+ return false;
// Print out errors
bool Failed = false;
- bool Transient = false;
for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
{
if ((*I)->Status == pkgAcquire::Item::StatDone &&
// Failed = true;
continue;
}
-
+
cerr << "Failed to fetch " << (*I)->DescURI() << endl;
cerr << " " << (*I)->ErrorText << endl;
Failed = true;
}
- /* If we are in no download mode and missing files then there were
+ /* If we are in no download mode and missing files and there were
'failures' then the user must specify -m. Furthermore, there
is no such thing as a transient error in no-download mode! */
- if (Transient == true &&
+ if (Transient == true &&
_config->FindB("APT::Get::No-Download",false) == true)
{
Transient = false;
cerr << "Unable to correct missing packages." << endl;
return _error->Error("Aborting Install.");
}
-
+
Cache.ReleaseLock();
pkgPackageManager::OrderResult Res = PM.DoInstall();
if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
Pkg.ProvidesList()->NextProvides == 0)
{
pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg();
- c1out << "Note, installing " << Tmp.Name() << " instead of " << Pkg.Name() << endl;
+ c1out << "Note, selecting " << Tmp.Name() << " instead of " << Pkg.Name() << endl;
Pkg = Tmp;
}
// Check if there is something at all to install
pkgDepCache::StateCache &State = Cache[Pkg];
- if (State.CandidateVer == 0)
+ if (Remove == true && Pkg->CurrentVer == 0)
+ {
+ if (AllowFail == false)
+ return false;
+ return _error->Error("Package %s is not installed",Pkg.Name());
+ }
+
+ if (State.CandidateVer == 0 && Remove == false)
{
if (AllowFail == false)
return false;
{
c1out << "Package " << Pkg.Name() << " has no available version, but exists in the database." << endl;
c1out << "This typically means that the package was mentioned in a dependency and " << endl;
- c1out << "never uploaded, or that it is an obsolete package." << endl;
+ c1out << "never uploaded, has been obsoleted or is not available with the contents " << endl;
+ c1out << "of sources.list" << endl;
string List;
pkgCache::DepIterator Dep = Pkg.RevDependsList();
_error->Error("Package %s has no installation candidate",Pkg.Name());
return false;
}
-
- Fix.Protect(Pkg);
+
+ Fix.Clear(Pkg);
+ Fix.Protect(Pkg);
if (Remove == true)
{
Fix.Remove(Pkg);
Cache.MarkInstall(Pkg,false);
if (State.Install() == false)
{
- if (AllowFail == true)
- c1out << "Sorry, " << Pkg.Name() << " is already the newest version" << endl;
+ if (_config->FindB("APT::Get::ReInstall",false) == true)
+ {
+ if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
+ c1out << "Sorry, re-installation of " << Pkg.Name() << " is not possible, it cannot be downloaded" << endl;
+ else
+ Cache.SetReInstall(Pkg,true);
+ }
+ else
+ {
+ if (AllowFail == true)
+ c1out << "Sorry, " << Pkg.Name() << " is already the newest version" << endl;
+ }
}
else
ExpectedInst++;
}
// Clean out any old list files
- if (_config->FindB("APT::Get::List-Cleanup",false) == false)
+ if (_config->FindB("APT::Get::List-Cleanup",true) == true)
{
if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
/* */
bool DoClean(CommandLine &CmdL)
{
+ if (_config->FindB("APT::Get::Simulate") == true)
+ {
+ cout << "Del " << _config->FindDir("Dir::Cache::archives") << "* " <<
+ _config->FindDir("Dir::Cache::archives") << "partial/*" << endl;
+ return true;
+ }
+
+ // Lock the archive directory
+ FileFd Lock;
+ if (_config->FindB("Debug::NoLocking",false) == false)
+ {
+ Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
+ if (_error->PendingError() == true)
+ return _error->Error("Unable to lock the download directory");
+ }
+
pkgAcquire Fetcher;
Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
bool DoAutoClean(CommandLine &CmdL)
{
+ // Lock the archive directory
+ FileFd Lock;
+ if (_config->FindB("Debug::NoLocking",false) == false)
+ {
+ Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
+ if (_error->PendingError() == true)
+ return _error->Error("Unable to lock the download directory");
+ }
+
CacheFile Cache;
if (Cache.Open() == false)
return false;
unsigned long DebBytes = Fetcher.TotalNeeded();
// Check for enough free space
- struct statfs Buf;
+ struct statvfs Buf;
string OutputDir = ".";
- if (statfs(OutputDir.c_str(),&Buf) != 0)
- return _error->Errno("statfs","Couldn't determine free space in %s",
+ if (statvfs(OutputDir.c_str(),&Buf) != 0)
+ return _error->Errno("statvfs","Couldn't determine free space in %s",
OutputDir.c_str());
if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
return _error->Error("Sorry, you don't have enough free space in %s",
// Diff only mode only fetches .diff files
if (_config->FindB("APT::Get::Diff-Only",false) == true ||
- _config->FindB("APT::Get::Tar-Only",false) == true)
+ _config->FindB("APT::Get::Tar-Only",false) == true ||
+ Dsc[I].Dsc.empty() == true)
continue;
-
+
// See if the package is already unpacked
struct stat Stat;
if (stat(Dir.c_str(),&Stat) == 0 &&
{'d',"download-only","APT::Get::Download-Only",0},
{'b',"compile","APT::Get::Compile",0},
{'b',"build","APT::Get::Compile",0},
- {'s',"simulate","APT::Get::Simulate",0},
- {'s',"just-print","APT::Get::Simulate",0},
- {'s',"recon","APT::Get::Simulate",0},
- {'s',"no-act","APT::Get::Simulate",0},
- {'y',"yes","APT::Get::Assume-Yes",0},
+ {'s',"simulate","APT::Get::Simulate",0},
+ {'s',"just-print","APT::Get::Simulate",0},
+ {'s',"recon","APT::Get::Simulate",0},
+ {'s',"no-act","APT::Get::Simulate",0},
+ {'y',"yes","APT::Get::Assume-Yes",0},
{'y',"assume-yes","APT::Get::Assume-Yes",0},
{'f',"fix-broken","APT::Get::Fix-Broken",0},
{'u',"show-upgraded","APT::Get::Show-Upgraded",0},
{0,"tar-only","APT::Get::tar-Only",0},
{0,"purge","APT::Get::Purge",0},
{0,"list-cleanup","APT::Get::List-Cleanup",0},
+ {0,"reinstall","APT::Get::ReInstall",0},
+ {0,"trivial-only","APT::Get::Trivial-Only",0},
+ {0,"no-remove","APT::Get::No-Remove",0},
{'c',"config-file",0,CommandLine::ConfigFile},
{'o',"option",0,CommandLine::ArbItem},
{0,0,0,0}};
_config->FindB("version") == true ||
CmdL.FileSize() == 0)
return ShowHelp(CmdL);
-
+
// Deal with stdout not being a tty
if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
_config->Set("quiet","1");
-
+
// Setup the output streams
c0out.rdbuf(cout.rdbuf());
c1out.rdbuf(cout.rdbuf());