X-Git-Url: https://git.hcoop.net/ntk/apt.git/blobdiff_plain/f01fe790891daf085b3a16ce8be3498fcc329d6e..fb0ee66e0bc8a2ae176d3b10da49fcf31c66b838:/cmdline/apt-get.cc diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 31dfe97c..504cde33 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1,6 +1,6 @@ // -*- 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.54 1999/04/19 06:03:09 jgg Exp $ /* ###################################################################### apt-get - Cover for dpkg @@ -30,12 +30,14 @@ #include #include #include -#include #include #include #include -#include -#include +#include +#include +#include +#include +#include #include @@ -44,7 +46,10 @@ #include #include #include +#include +#include #include +#include #include /*}}}*/ @@ -61,7 +66,7 @@ bool YnPrompt() { if (_config->FindB("APT::Get::Assume-Yes",false) == true) { - c2out << 'Y' << endl; + c1out << 'Y' << endl; return true; } @@ -75,6 +80,18 @@ bool YnPrompt() return true; } /*}}}*/ +// AnalPrompt - Annoying Yes No Prompt. /*{{{*/ +// --------------------------------------------------------------------- +/* Returns true on a Yes.*/ +bool AnalPrompt(const char *Text) +{ + char Buf[1024]; + cin.getline(Buf,sizeof(Buf)); + if (strcmp(Buf,Text) == 0) + return true; + return false; +} + /*}}}*/ // ShowList - Show a list /*{{{*/ // --------------------------------------------------------------------- /* This prints out a string of space seperated words with a title and @@ -135,7 +152,7 @@ void ShowBroken(ostream &out,pkgDepCache &Cache) pkgCache::DepIterator Start; pkgCache::DepIterator End; D.GlobOr(Start,End); - + if (Cache.IsImportantDep(End) == false || (Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) continue; @@ -145,7 +162,7 @@ void ShowBroken(ostream &out,pkgDepCache &Cache) out << ' '; First = false; - cout << ' ' << End.DepType() << ": " << End.TargetPkg().Name(); + out << ' ' << End.DepType() << ": " << End.TargetPkg().Name(); // Show a quick summary of the version requirements if (End.TargetVer() != 0) @@ -208,6 +225,7 @@ void ShowDel(ostream &out,pkgDepCache &Dep) for (;I.end() != true; I++) if (Dep[I].Delete() == true) List += string(I.Name()) + " "; + ShowList(out,"The following packages will be REMOVED:",List); } /*}}}*/ @@ -353,68 +371,27 @@ void Stats(ostream &out,pkgDepCache &Dep) // class CacheFile - Cover class for some dependency cache functions /*{{{*/ // --------------------------------------------------------------------- /* */ -class CacheFile +class CacheFile : public pkgCacheFile { public: - FileFd *File; - MMap *Map; - pkgDepCache *Cache; - pkgDpkgLock Lock; - - inline operator pkgDepCache &() {return *Cache;}; - inline pkgDepCache *operator ->() {return Cache;}; - inline pkgDepCache &operator *() {return *Cache;}; - - bool Open(); - CacheFile() : File(0), Map(0), Cache(0) {}; - ~CacheFile() + bool CheckDeps(bool AllowBroken = false); + bool Open(bool WithLock = true) { - delete Cache; - delete Map; - delete File; - } + OpTextProgress Prog(*_config); + return pkgCacheFile::Open(Prog,WithLock); + }; }; /*}}}*/ // CacheFile::Open - Open the cache file /*{{{*/ // --------------------------------------------------------------------- /* This routine generates the caches and then opens the dependency cache and verifies that the system is OK. */ -bool CacheFile::Open() +bool CacheFile::CheckDeps(bool AllowBroken) { if (_error->PendingError() == true) return false; - - // Create a progress class - OpTextProgress Progress(*_config); - - // Read the source list - pkgSourceList List; - if (List.ReadMainList() == false) - return _error->Error("The list of sources could not be read."); - - // Build all of the caches - pkgMakeStatusCache(List,Progress); - if (_error->PendingError() == true) - return _error->Error("The package lists or status file could not be parsed or opened."); - - Progress.Done(); - - // Open the cache file - File = new FileFd(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly); - if (_error->PendingError() == true) - return false; - - Map = new MMap(*File,MMap::Public | MMap::ReadOnly); - if (_error->PendingError() == true) - return false; - - Cache = new pkgDepCache(*Map,Progress); - if (_error->PendingError() == true) - return false; - Progress.Done(); - // Check that the system is OK if (Cache->DelCount() != 0 || Cache->InstCount() != 0) return _error->Error("Internal Error, non-zero counts"); @@ -424,7 +401,7 @@ bool CacheFile::Open() return false; // Nothing is broken - if (Cache->BrokenCount() == 0) + if (Cache->BrokenCount() == 0 || AllowBroken == true) return true; // Attempt to fix broken things @@ -459,19 +436,21 @@ bool CacheFile::Open() // --------------------------------------------------------------------- /* 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 InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey = true) { bool Fail = false; + bool Essential = false; // Show all the various warning indicators ShowDel(c1out,Cache); ShowNew(c1out,Cache); if (ShwKept == true) ShowKept(c1out,Cache); - Fail |= ShowHold(c1out,Cache); + Fail |= !ShowHold(c1out,Cache); if (_config->FindB("APT::Get::Show-Upgraded",false) == true) ShowUpgraded(c1out,Cache); - Fail |= ShowEssential(c1out,Cache); + Essential = !ShowEssential(c1out,Cache); + Fail |= Essential; Stats(c1out,Cache); // Sanity check @@ -483,7 +462,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true) if (Cache->DelCount() == 0 && Cache->InstCount() == 0 && Cache->BadCount() == 0) - return true; + return true; // Run the simulator .. if (_config->FindB("APT::Get::Simulate") == true) @@ -498,9 +477,10 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true) return false; // Lock the archive directory + FileFd Lock; if (_config->FindB("Debug::NoLocking",false) == false) { - FileFd Lock(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock")); + Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock")); if (_error->PendingError() == true) return _error->Error("Unable to lock the download directory"); } @@ -516,53 +496,95 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = 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 unsigned long FetchBytes = Fetcher.FetchNeeded(); + unsigned long FetchPBytes = Fetcher.PartialPresent(); unsigned long DebBytes = Fetcher.TotalNeeded(); if (DebBytes != Cache->DebSize()) { c0out << DebBytes << ',' << Cache->DebSize() << endl; c0out << "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl; } - + + // 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", + 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; // Fail safe check - if (_config->FindB("APT::Get::Assume-Yes",false) == true) + if (_config->FindI("quiet",0) >= 2 || + _config->FindB("APT::Get::Assume-Yes",false) == true) { if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false) return _error->Error("There are problems and -y was used without --force-yes"); } - - // Prompt to continue - if (Ask == true) - { - if (_config->FindI("quiet",0) < 2 || - _config->FindB("APT::Get::Assume-Yes",false) == false) - c2out << "Do you want to continue? [Y/n] " << flush; - - if (YnPrompt() == false) + + if (Essential == true && Saftey == true) + { + 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; + if (AnalPrompt("Yes, I understand this may be bad") == false) + { + c2out << "Abort." << endl; exit(1); - } + } + } + else + { + // Prompt to continue + if (Ask == true || Fail == true) + { + if (_config->FindI("quiet",0) < 2 && + _config->FindB("APT::Get::Assume-Yes",false) == false) + { + c2out << "Do you want to continue? [Y/n] " << flush; + + if (YnPrompt() == false) + { + c2out << "Abort." << endl; + exit(1); + } + } + } + } + + // Just print out the uris an exit if the --print-uris flag was used + if (_config->FindB("APT::Get::Print-URIs") == true) + { + pkgAcquire::UriIterator I = Fetcher.UriBegin(); + for (; I != Fetcher.UriEnd(); I++) + cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << + I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl; + return true; + } // Run it if (Fetcher.Run() == false) @@ -584,12 +606,15 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true) continue; } - cerr << "Failed to fetch " << (*I)->Describe() << endl; + cerr << "Failed to fetch " << (*I)->DescURI() << endl; 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) { @@ -607,7 +632,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true) return _error->Error("Aborting Install."); } - Cache.Lock.Close(); + Cache.ReleaseLock(); return PM.DoInstall(); } /*}}}*/ @@ -623,9 +648,10 @@ bool DoUpdate(CommandLine &) return false; // Lock the list directory + FileFd Lock; if (_config->FindB("Debug::NoLocking",false) == false) { - FileFd Lock(GetLock(_config->FindDir("Dir::State::Lists") + "lock")); + Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock")); if (_error->PendingError() == true) return _error->Error("Unable to lock the list directory"); } @@ -667,7 +693,7 @@ bool DoUpdate(CommandLine &) bool DoUpgrade(CommandLine &CmdL) { CacheFile Cache; - if (Cache.Open() == false) + if (Cache.Open() == false || Cache.CheckDeps() == false) return false; // Do the upgrade @@ -686,9 +712,14 @@ bool DoUpgrade(CommandLine &CmdL) bool DoInstall(CommandLine &CmdL) { CacheFile Cache; - if (Cache.Open() == false) + if (Cache.Open() == false || Cache.CheckDeps(CmdL.FileSize() != 1) == false) return false; + // Enter the special broken fixing mode if the user specified arguments + bool BrokenFix = false; + if (Cache->BrokenCount() != 0) + BrokenFix = true; + unsigned int ExpectedInst = 0; unsigned int Packages = 0; pkgProblemResolver Fix(Cache); @@ -751,11 +782,13 @@ bool DoInstall(CommandLine &CmdL) 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; } @@ -795,10 +828,21 @@ bool DoInstall(CommandLine &CmdL) 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) @@ -861,7 +905,7 @@ bool DoInstall(CommandLine &CmdL) bool DoDistUpgrade(CommandLine &CmdL) { CacheFile Cache; - if (Cache.Open() == false) + if (Cache.Open() == false || Cache.CheckDeps() == false) return false; c0out << "Calculating Upgrade... " << flush; @@ -883,7 +927,7 @@ bool DoDistUpgrade(CommandLine &CmdL) bool DoDSelectUpgrade(CommandLine &CmdL) { CacheFile Cache; - if (Cache.Open() == false) + if (Cache.Open() == false || Cache.CheckDeps() == false) return false; // Install everything with the install flag set @@ -903,7 +947,7 @@ bool DoDSelectUpgrade(CommandLine &CmdL) /* 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. @@ -915,12 +959,37 @@ bool DoDSelectUpgrade(CommandLine &CmdL) 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); @@ -937,6 +1006,31 @@ bool DoClean(CommandLine &CmdL) 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() == 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 @@ -945,19 +1039,231 @@ bool DoCheck(CommandLine &CmdL) { CacheFile Cache; Cache.Open(); + Cache.CheckDeps(); return true; } /*}}}*/ +// DoSource - Fetch a source archive /*{{{*/ +// --------------------------------------------------------------------- +/* Fetch souce packages */ +struct DscFile +{ + string Package; + string Version; + string Dsc; +}; + +bool DoSource(CommandLine &CmdL) +{ + CacheFile Cache; + if (Cache.Open(false) == false) + return false; + + if (CmdL.FileSize() <= 1) + return _error->Error("Must specify at least one package to fetch source for"); + + // Read the source list + pkgSourceList List; + if (List.ReadMainList() == false) + return _error->Error("The list of sources could not be read."); + + // Create the text record parsers + pkgRecords Recs(Cache); + pkgSrcRecords SrcRecs(List); + if (_error->PendingError() == true) + return false; + + // Create the download object + AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); + pkgAcquire Fetcher(&Stat); + + DscFile *Dsc = new DscFile[CmdL.FileSize()]; + + // Load the requestd sources into the fetcher + unsigned J = 0; + for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) + { + string Src; + + /* Lookup the version of the package we would install if we were to + install a version and determine the source package name, then look + in the archive for a source package of the same name. In theory + we could stash the version string as well and match that too but + today there aren't multi source versions in the archive. */ + pkgCache::PkgIterator Pkg = Cache->FindPkg(*I); + if (Pkg.end() == false) + { + pkgCache::VerIterator Ver = Cache->GetCandidateVer(Pkg); + if (Ver.end() == false) + { + pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); + Src = Parse.SourcePkg(); + } + } + + // No source package name.. + if (Src.empty() == true) + Src = *I; + + // The best hit + pkgSrcRecords::Parser *Last = 0; + unsigned long Offset = 0; + string Version; + + // Iterate over all of the hits + pkgSrcRecords::Parser *Parse; + SrcRecs.Restart(); + while ((Parse = SrcRecs.Find(Src.c_str(),false)) != 0) + { + string Ver = Parse->Version(); + if (Last == 0 || pkgVersionCompare(Version,Ver) < 0) + { + Last = Parse; + Offset = Parse->Offset(); + Version = Ver; + } + } + if (Last == 0) + return _error->Error("Unable to find a source package for %s",Src.c_str()); + + // Back track + vector Lst; + if (Last->Jump(Offset) == false || Last->Files(Lst) == false) + return false; + + // Load them into the fetcher + for (vector::const_iterator I = Lst.begin(); + I != Lst.end(); I++) + { + // Try to guess what sort of file it is we are getting. + string Comp; + if (I->Path.find(".dsc") != string::npos) + { + Comp = "dsc"; + Dsc[J].Package = Last->Package(); + Dsc[J].Version = Last->Version(); + Dsc[J].Dsc = flNotDir(I->Path); + } + + if (I->Path.find(".tar.gz") != string::npos) + Comp = "tar"; + if (I->Path.find(".diff.gz") != string::npos) + Comp = "diff"; + + new pkgAcqFile(&Fetcher,Last->Source()->ArchiveURI(I->Path), + I->MD5Hash,I->Size,Last->Source()->SourceInfo(Src, + Last->Version(),Comp),Src); + } + } + + // Display statistics + unsigned long FetchBytes = Fetcher.FetchNeeded(); + unsigned long FetchPBytes = Fetcher.PartialPresent(); + unsigned long DebBytes = Fetcher.TotalNeeded(); + + // Check for enough free space + struct statfs Buf; + string OutputDir = "."; + 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", + OutputDir.c_str()); + + // Number of bytes + c1out << "Need to get "; + if (DebBytes != FetchBytes) + c1out << SizeToStr(FetchBytes) << "b/" << SizeToStr(DebBytes) << 'b'; + else + c1out << SizeToStr(DebBytes) << 'b'; + c1out << " of source archives." << endl; + + // Just print out the uris an exit if the --print-uris flag was used + if (_config->FindB("APT::Get::Print-URIs") == true) + { + pkgAcquire::UriIterator I = Fetcher.UriBegin(); + for (; I != Fetcher.UriEnd(); I++) + cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << + I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl; + return true; + } + + // Run it + if (Fetcher.Run() == false) + return false; + + // Print error messages + bool Failed = false; + for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++) + { + if ((*I)->Status == pkgAcquire::Item::StatDone && + (*I)->Complete == true) + continue; + + cerr << "Failed to fetch " << (*I)->DescURI() << endl; + cerr << " " << (*I)->ErrorText << endl; + Failed = true; + } + if (Failed == true) + return _error->Error("Failed to fetch some archives."); + + if (_config->FindB("APT::Get::Download-only",false) == true) + return true; + + // Unpack the sources + for (unsigned I = 0; I != J; I++) + { + string Dir = Dsc[I].Package + '-' + pkgBaseVersion(Dsc[I].Version.c_str()); + + // See if the package is already unpacked + struct stat Stat; + if (stat(Dir.c_str(),&Stat) == 0 && + S_ISDIR(Stat.st_mode) != 0) + { + c0out << "Skipping unpack of already unpacked source in " << Dir << endl; + } + else + { + // Call dpkg-source + char S[500]; + snprintf(S,sizeof(S),"%s -x %s", + _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(), + Dsc[I].Dsc.c_str()); + if (system(S) != 0) + return _error->Error("Unpack command '%s' failed.",S); + } + + // Try to compile it with dpkg-buildpackage + if (_config->FindB("APT::Get::Compile",false) == true) + { + // Call dpkg-buildpackage + char S[500]; + snprintf(S,sizeof(S),"cd %s && %s %s", + Dir.c_str(), + _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(), + _config->Find("DPkg::Build-Options","-b -uc").c_str()); + + if (system(S) != 0) + return _error->Error("Build command '%s' failed.",S); + } + } + return true; +} + /*}}}*/ + // 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; @@ -970,9 +1276,11 @@ int ShowHelp() cout << " upgrade - Perform an upgrade" << endl; cout << " install - Install new packages (pkg is libc6 not libc6.deb)" << endl; cout << " remove - Remove packages" << endl; + cout << " source - Download source archives" << 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; @@ -986,8 +1294,8 @@ int ShowHelp() cout << " -m Attempt to continue if archives are unlocatable" << 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 << " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" << endl; + cout << "See the apt-get(8), sources.list(5) and apt.conf(5) manual" << endl; cout << "pages for more information." << endl; return 100; } @@ -1025,9 +1333,12 @@ int main(int argc,const char *argv[]) { 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}, + {'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}, @@ -1041,6 +1352,7 @@ int main(int argc,const char *argv[]) {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}}; @@ -1051,7 +1363,10 @@ int main(int argc,const char *argv[]) {"dist-upgrade",&DoDistUpgrade}, {"dselect-upgrade",&DoDSelectUpgrade}, {"clean",&DoClean}, + {"autoclean",&DoAutoClean}, {"check",&DoCheck}, + {"source",&DoSource}, + {"help",&ShowHelp}, {0,0}}; // Parse the command line and initialize the package library @@ -1065,9 +1380,14 @@ int main(int argc,const char *argv[]) // See if the help should be shown if (_config->FindB("help") == true || + _config->FindB("version") == true || CmdL.FileSize() == 0) - return ShowHelp(); + return ShowHelp(CmdL); + // Deal with stdout not being a tty + if (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()); @@ -1090,8 +1410,6 @@ int main(int argc,const char *argv[]) { bool Errors = _error->PendingError(); _error->DumpErrors(); - if (Errors == true) - cout << "Returning 100." << endl; return Errors == true?100:0; }