// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: apt-get.cc,v 1.21 1998/12/05 02:56:45 jgg Exp $
+// $Id: apt-get.cc,v 1.43 1999/02/21 08:38:53 jgg Exp $
/* ######################################################################
apt-get - Cover for dpkg
#include <apt-pkg/acquire-item.h>
#include <apt-pkg/dpkgpm.h>
#include <apt-pkg/dpkginit.h>
-#include <strutl.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/clean.h>
#include <config.h>
#include <fstream.h>
#include <termios.h>
#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
#include <signal.h>
+#include <unistd.h>
#include <stdio.h>
/*}}}*/
{
if (_config->FindB("APT::Get::Assume-Yes",false) == true)
{
- c2out << 'Y' << endl;
+ c1out << 'Y' << endl;
return true;
}
pkgCache::DepIterator Start;
pkgCache::DepIterator End;
D.GlobOr(Start,End);
-
+
if (Cache.IsImportantDep(End) == false ||
(Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
continue;
for (;I.end() != true; I++)
if (Dep[I].Delete() == true)
List += string(I.Name()) + " ";
+
ShowList(out,"The following packages will be REMOVED:",List);
}
/*}}}*/
inline pkgDepCache *operator ->() {return Cache;};
inline pkgDepCache &operator *() {return *Cache;};
- bool Open();
+ bool Open(bool AllowBroken = false);
CacheFile() : File(0), Map(0), Cache(0) {};
~CacheFile()
{
// ---------------------------------------------------------------------
/* This routine generates the caches and then opens the dependency cache
and verifies that the system is OK. */
-bool CacheFile::Open()
+bool CacheFile::Open(bool AllowBroken)
{
if (_error->PendingError() == true)
return false;
pkgMakeStatusCache(List,Progress);
if (_error->PendingError() == true)
return _error->Error("The package lists or status file could not be parsed or opened.");
+ if (_error->empty() == false)
+ _error->Warning("You may want to run apt-get update to correct theses missing files");
Progress.Done();
return false;
// Nothing is broken
- if (Cache->BrokenCount() == 0)
+ if (Cache->BrokenCount() == 0 || AllowBroken == true)
return true;
// Attempt to fix broken things
ShowNew(c1out,Cache);
if (ShwKept == true)
ShowKept(c1out,Cache);
- Fail |= ShowHold(c1out,Cache);
+ Fail |= !ShowHold(c1out,Cache);
if (_config->FindB("APT::Get::Show-Upgraded",false) == true)
ShowUpgraded(c1out,Cache);
- Fail |= ShowEssential(c1out,Cache);
+ Fail |= !ShowEssential(c1out,Cache);
Stats(c1out,Cache);
// Sanity check
if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
Cache->BadCount() == 0)
- return true;
+ return true;
// Run the simulator ..
if (_config->FindB("APT::Get::Simulate") == true)
// Create the package manager and prepare to download
pkgDPkgPM PM(Cache);
- if (PM.GetArchives(&Fetcher,&List,&Recs) == false)
+ if (PM.GetArchives(&Fetcher,&List,&Recs) == false ||
+ _error->PendingError() == true)
return false;
// Display statistics
c0out << DebBytes << ',' << Cache->DebSize() << endl;
c0out << "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl;
}
-
+
+ // 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/Buf.f_bsize)
+ return _error->Error("Sorry, you don't have enough free space in %s",
+ OutputDir.c_str());
+
// Number of bytes
c1out << "Need to get ";
if (DebBytes != FetchBytes)
- c1out << SizeToStr(FetchBytes) << '/' << SizeToStr(DebBytes);
+ c1out << SizeToStr(FetchBytes) << "b/" << SizeToStr(DebBytes) << 'b';
else
- c1out << SizeToStr(DebBytes);
+ c1out << SizeToStr(DebBytes) << 'b';
c1out << " of archives. After unpacking ";
// Size delta
if (Cache->UsrSize() >= 0)
- c1out << SizeToStr(Cache->UsrSize()) << " will be used." << endl;
+ c1out << SizeToStr(Cache->UsrSize()) << "b will be used." << endl;
else
- c1out << SizeToStr(-1*Cache->UsrSize()) << " will be freed." << endl;
+ c1out << SizeToStr(-1*Cache->UsrSize()) << "b will be freed." << endl;
if (_error->PendingError() == true)
return false;
if (YnPrompt() == false)
exit(1);
}
+
+ if (_config->FindB("APT::Get::Print-URIs") == true)
+ {
+ pkgAcquire::UriIterator I = Fetcher.UriBegin();
+ for (; I != Fetcher.UriEnd(); I++)
+ cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
+ I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+ return true;
+ }
// Run it
if (Fetcher.Run() == false)
cerr << " " << (*I)->ErrorText << endl;
Failed = true;
}
-
- if (Failed == true && _config->FindB("APT::Fix-Missing",false) == false)
+
+ if (_config->FindB("APT::Get::Download-Only",false) == true)
+ return true;
+
+ if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
{
if (Transient == true)
{
bool DoInstall(CommandLine &CmdL)
{
CacheFile Cache;
- if (Cache.Open() == false)
+ if (Cache.Open(CmdL.FileSize() != 1) == false)
return false;
+ // Enter the special broken fixing mode if the user specified arguments
+ bool BrokenFix = false;
+ if (Cache->BrokenCount() != 0)
+ BrokenFix = true;
+
unsigned int ExpectedInst = 0;
unsigned int Packages = 0;
pkgProblemResolver Fix(Cache);
pkgCache::PkgIterator Pkg = I.OwnerPkg();
if ((*Cache)[Pkg].CandidateVerIter(*Cache) == I.OwnerVer())
- c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
-
- if ((*Cache)[Pkg].InstVerIter(*Cache) == I.OwnerVer())
- c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
- " [Installed]"<< endl;
+ {
+ if ((*Cache)[Pkg].Install() == true && (*Cache)[Pkg].NewInstall() == false)
+ c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
+ " [Installed]"<< endl;
+ else
+ c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
+ }
}
c1out << "You should explicly select one to install." << endl;
}
ExpectedInst++;
// Install it with autoinstalling enabled.
- if (State.InstBroken() == true)
+ if (State.InstBroken() == true && BrokenFix == false)
Cache->MarkInstall(Pkg,true);
}
+ /* If we are in the Broken fixing mode we do not attempt to fix the
+ problems. This is if the user invoked install without -f and gave
+ packages */
+ if (BrokenFix == true && Cache->BrokenCount() != 0)
+ {
+ c1out << "You might want to run `apt-get -f install' to correct these." << endl;
+ ShowBroken(c1out,Cache);
+
+ return _error->Error("Unmet dependencies. Try using -f.");
+ }
+
// Call the scored problem resolver
Fix.InstallProtect();
if (Fix.Resolve(true) == false)
/* Install the package only if it is a new install, the autoupgrader
will deal with the rest */
if (I->SelectedState == pkgCache::State::Install)
- Cache->MarkInstall(I);
+ Cache->MarkInstall(I,true);
}
// Apply erasures now, they override everything else.
Cache->MarkDelete(I);
}
- /* Use updates smart upgrade to do the rest, it will automatically
- ignore held items */
+ /* Resolve any problems that dselect created, allupgrade cannot handle
+ such things. We do so quite agressively too.. */
+ if (Cache->BrokenCount() != 0)
+ {
+ pkgProblemResolver Fix(Cache);
+
+ // Hold back held packages.
+ if (_config->FindB("APT::Ingore-Hold",false) == false)
+ {
+ for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++)
+ {
+ if (I->SelectedState == pkgCache::State::Hold)
+ {
+ Fix.Protect(I);
+ Cache->MarkKeep(I);
+ }
+ }
+ }
+
+ if (Fix.Resolve() == false)
+ {
+ ShowBroken(c1out,Cache);
+ return _error->Error("Internal Error, problem resolver broke stuff");
+ }
+ }
+
+ // Now upgrade everything
if (pkgAllUpgrade(Cache) == false)
{
ShowBroken(c1out,Cache);
- return _error->Error("Internal Error, AllUpgrade broke stuff");
+ return _error->Error("Internal Error, problem resolver broke stuff");
}
return InstallPackages(Cache,false);
return true;
}
/*}}}*/
+// DoAutoClean - Smartly remove downloaded archives /*{{{*/
+// ---------------------------------------------------------------------
+/* This is similar to clean but it only purges things that cannot be
+ downloaded, that is old versions of cached packages. */
+class LogCleaner : public pkgArchiveCleaner
+{
+ protected:
+ virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St)
+ {
+ cout << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "b]" << endl;
+ };
+};
+
+bool DoAutoClean(CommandLine &CmdL)
+{
+ CacheFile Cache;
+ if (Cache.Open(true) == false)
+ return false;
+
+ LogCleaner Cleaner;
+
+ return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) &&
+ Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache);
+}
+ /*}}}*/
// DoCheck - Perform the check operation /*{{{*/
// ---------------------------------------------------------------------
/* Opening automatically checks the system, this command is mostly used
// ShowHelp - Show a help screen /*{{{*/
// ---------------------------------------------------------------------
/* */
-int ShowHelp()
+bool ShowHelp(CommandLine &CmdL)
{
cout << PACKAGE << ' ' << VERSION << " for " << ARCHITECTURE <<
" compiled on " << __DATE__ << " " << __TIME__ << endl;
-
+ if (_config->FindB("version") == true)
+ return 100;
+
cout << "Usage: apt-get [options] command" << endl;
cout << " apt-get [options] install pkg1 [pkg2 ...]" << endl;
cout << endl;
cout << " dist-upgrade - Distribution upgrade, see apt-get(8)" << endl;
cout << " dselect-upgrade - Follow dselect selections" << endl;
cout << " clean - Erase downloaded archive files" << endl;
+ cout << " autoclean - Erase old downloaded archive files" << endl;
cout << " check - Verify that there are no broken dependencies" << endl;
cout << endl;
cout << "Options:" << endl;
cout << " -u Show a list of upgraded packages as well" << endl;
cout << " -c=? Read this configuration file" << endl;
cout << " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl;
- cout << "See the apt-get(8), sources.list(8) and apt.conf(8) manual" << endl;
+ cout << "See the apt-get(8), sources.list(5) and apt.conf(5) manual" << endl;
cout << "pages for more information." << endl;
return 100;
}
{
CommandLine::Args Args[] = {
{'h',"help","help",0},
+ {'v',"version","version",0},
{'q',"quiet","quiet",CommandLine::IntLevel},
{'q',"silent","quiet",CommandLine::IntLevel},
{'d',"download-only","APT::Get::Download-Only",0},
{0,"ignore-hold","APT::Ingore-Hold",0},
{0,"no-upgrade","APT::Get::no-upgrade",0},
{0,"force-yes","APT::Get::force-yes",0},
+ {0,"print-uris","APT::Get::Print-URIs",0},
{'c',"config-file",0,CommandLine::ConfigFile},
{'o',"option",0,CommandLine::ArbItem},
{0,0,0,0}};
{"dist-upgrade",&DoDistUpgrade},
{"dselect-upgrade",&DoDSelectUpgrade},
{"clean",&DoClean},
+ {"autoclean",&DoAutoClean},
{"check",&DoCheck},
+ {"help",&ShowHelp},
{0,0}};
// Parse the command line and initialize the package library
// See if the help should be shown
if (_config->FindB("help") == true ||
+ _config->FindB("version") == true ||
CmdL.FileSize() == 0)
- return ShowHelp();
+ return ShowHelp(CmdL);
// Setup the output streams
c0out.rdbuf(cout.rdbuf());
{
bool Errors = _error->PendingError();
_error->DumpErrors();
- if (Errors == true)
- cout << "Returning 100." << endl;
return Errors == true?100:0;
}