- if (Dep[I].NewInstall() == true)
- Install++;
- else
- {
- if (Dep[I].Upgrade() == true)
- Upgrade++;
- else
- if (Dep[I].Downgrade() == true)
- Downgrade++;
- }
-
- if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
- ReInstall++;
- }
-
- ioprintf(out,_("%lu upgraded, %lu newly installed, "),
- Upgrade,Install);
-
- if (ReInstall != 0)
- ioprintf(out,_("%lu reinstalled, "),ReInstall);
- if (Downgrade != 0)
- ioprintf(out,_("%lu downgraded, "),Downgrade);
-
- ioprintf(out,_("%lu to remove and %lu not upgraded.\n"),
- Dep.DelCount(),Dep.KeepCount());
-
- if (Dep.BadCount() != 0)
- ioprintf(out,_("%lu not fully installed or removed.\n"),
- Dep.BadCount());
-}
- /*}}}*/
-// CacheFile::NameComp - QSort compare by name /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-pkgCache *CacheFile::SortCache = 0;
-int CacheFile::NameComp(const void *a,const void *b)
-{
- if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0)
- return *(pkgCache::Package **)a - *(pkgCache::Package **)b;
-
- 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::CheckDeps - Open the cache file /*{{{*/
-// ---------------------------------------------------------------------
-/* This routine generates the caches and then opens the dependency cache
- and verifies that the system is OK. */
-bool CacheFile::CheckDeps(bool AllowBroken)
-{
- bool FixBroken = _config->FindB("APT::Get::Fix-Broken",false);
-
- if (_error->PendingError() == true)
- return false;
-
- // Check that the system is OK
- if (DCache->DelCount() != 0 || DCache->InstCount() != 0)
- return _error->Error("Internal error, non-zero counts");
-
- // Apply corrections for half-installed packages
- if (pkgApplyStatus(*DCache) == false)
- return false;
-
- if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true)
- {
- FixBroken = true;
- if ((DCache->PolicyBrokenCount() > 0))
- {
- // upgrade all policy-broken packages with ForceImportantDeps=True
- for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); I++)
- if ((*DCache)[I].NowPolicyBroken() == true)
- DCache->MarkInstall(I,true,0, false, true);
- }
- }
-
- // Nothing is broken
- if (DCache->BrokenCount() == 0 || AllowBroken == true)
- return true;
-
- // Attempt to fix broken things
- if (FixBroken == true)
- {
- c1out << _("Correcting dependencies...") << flush;
- if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
- {
- c1out << _(" failed.") << endl;
- ShowBroken(c1out,*this,true);
-
- return _error->Error(_("Unable to correct dependencies"));
- }
- if (pkgMinimizeUpgrade(*DCache) == false)
- return _error->Error(_("Unable to minimize the upgrade set"));
-
- c1out << _(" Done") << endl;
- }
- else
- {
- c1out << _("You might want to run `apt-get -f install' to correct these.") << endl;
- ShowBroken(c1out,*this,true);
-
- return _error->Error(_("Unmet dependencies. Try using -f."));
- }
-
- return true;
-}
- /*}}}*/
-// CheckAuth - check if each download comes form a trusted source /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-static bool CheckAuth(pkgAcquire& Fetcher)
-{
- string UntrustedList;
- for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I)
- {
- if (!(*I)->IsTrusted())
- {
- UntrustedList += string((*I)->ShortDesc()) + " ";
- }
- }
-
- if (UntrustedList == "")
- {
- return true;
- }
-
- ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,"");
-
- if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true)
- {
- c2out << _("Authentication warning overridden.\n");
- return true;
- }
-
- if (_config->FindI("quiet",0) < 2
- && _config->FindB("APT::Get::Assume-Yes",false) == false)
- {
- c2out << _("Install these packages without verification [y/N]? ") << flush;
- if (!YnPrompt(false))
- return _error->Error(_("Some packages could not be authenticated"));
-
- return true;
- }
- else if (_config->FindB("APT::Get::Force-Yes",false) == true)
- {
- return true;
- }
-
- return _error->Error(_("There are problems and -y was used without --force-yes"));
-}
- /*}}}*/
-// InstallPackages - Actually download and install the packages /*{{{*/
-// ---------------------------------------------------------------------
-/* 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 Safety = true)
-{
- if (_config->FindB("APT::Get::Purge",false) == true)
- {
- pkgCache::PkgIterator I = Cache->PkgBegin();
- for (; I.end() == false; I++)
- {
- if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
- Cache->MarkDelete(I,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);
- if (_config->FindB("APT::Get::Show-Upgraded",true) == true)
- ShowUpgraded(c1out,Cache);
- Fail |= !ShowDowngraded(c1out,Cache);
- if (_config->FindB("APT::Get::Download-Only",false) == false)
- Essential = !ShowEssential(c1out,Cache);
- Fail |= Essential;
- Stats(c1out,Cache);
-
- // Sanity check
- if (Cache->BrokenCount() != 0)
- {
- ShowBroken(c1out,Cache,false);
- return _error->Error(_("Internal error, InstallPackages was called with broken packages!"));
- }
-
- if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
- Cache->BadCount() == 0)
- return true;
-
- // No remove flag
- if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
- return _error->Error(_("Packages need to be removed but remove is disabled."));
-
- // Run the simulator ..
- if (_config->FindB("APT::Get::Simulate") == true)
- {
- pkgSimulate PM(Cache);
- int status_fd = _config->FindI("APT::Status-Fd",-1);
- pkgPackageManager::OrderResult Res = PM.DoInstall(status_fd);
- if (Res == pkgPackageManager::Failed)
- return false;
- if (Res != pkgPackageManager::Completed)
- return _error->Error(_("Internal error, Ordering didn't finish"));
- return true;
- }
-
- // Create the text record parser
- pkgRecords Recs(Cache);
- if (_error->PendingError() == true)
- return false;
-
- // Lock the archive directory
- FileFd Lock;
- if (_config->FindB("Debug::NoLocking",false) == false &&
- _config->FindB("APT::Get::Print-URIs") == false)
- {
- Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
- if (_error->PendingError() == true)
- return _error->Error(_("Unable to lock the download directory"));
- }
-
- // Create the download object
- AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
- pkgAcquire Fetcher(&Stat);
-
- // Read the source list
- pkgSourceList List;
- if (List.ReadMainList() == false)
- return _error->Error(_("The list of sources could not be read."));
-
- // Create the package manager and prepare to download
- SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
- if (PM->GetArchives(&Fetcher,&List,&Recs) == false ||
- _error->PendingError() == true)
- return false;
-
- // Display statistics
- double FetchBytes = Fetcher.FetchNeeded();
- double FetchPBytes = Fetcher.PartialPresent();
- double 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;
- }
-
- // Number of bytes
- if (DebBytes != FetchBytes)
- ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
- SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
- else if (DebBytes != 0)
- ioprintf(c1out,_("Need to get %sB of archives.\n"),
- SizeToStr(DebBytes).c_str());
-
- // Size delta
- if (Cache->UsrSize() >= 0)
- ioprintf(c1out,_("After this operation, %sB of additional disk space will be used.\n"),
- SizeToStr(Cache->UsrSize()).c_str());
- else
- ioprintf(c1out,_("After this operation, %sB disk space will be freed.\n"),
- SizeToStr(-1*Cache->UsrSize()).c_str());
-
- 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;
- 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());
- }
- }
-
- // Fail safe check
- 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"));
- }
-
- if (Essential == true && Safety == true)
- {
- if (_config->FindB("APT::Get::Trivial-Only",false) == true)
- return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
-
- const char *Prompt = _("Yes, do as I say!");
- ioprintf(c2out,
- _("You are about to do something potentially harmful.\n"
- "To continue type in the phrase '%s'\n"
- " ?] "),Prompt);
- c2out << flush;
- if (AnalPrompt(Prompt) == false)
- {
- c2out << _("Abort.") << endl;
- exit(1);
- }
- }
- 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)
- {
- 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->HashSum() << endl;
- return true;
- }
-
- if (!CheckAuth(Fetcher))
- return false;
-
- /* Unlock the dpkg lock if we are not going to be doing an install
- after. */
- if (_config->FindB("APT::Get::Download-Only",false) == true)
- _system->UnLock();
-
- // Run it
- while (1)
- {
- bool Transient = false;
- if (_config->FindB("APT::Get::Download",true) == false)
- {
- for (pkgAcquire::ItemIterator 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;
- for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
- {
- if ((*I)->Status == pkgAcquire::Item::StatDone &&
- (*I)->Complete == true)
- continue;
-
- if ((*I)->Status == pkgAcquire::Item::StatIdle)
- {
- Transient = true;
- // Failed = true;
- continue;
- }
-
- fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
- (*I)->ErrorText.c_str());
- Failed = true;
- }
-
- /* 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 &&
- _config->FindB("APT::Get::Download",true) == false)
- {
- Transient = false;
- Failed = true;
- }
-
- if (_config->FindB("APT::Get::Download-Only",false) == true)
- {
- if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
- return _error->Error(_("Some files failed to download"));
- c1out << _("Download complete and in download only mode") << endl;
- return true;
- }
-
- if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
- {
- return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
- }
-
- if (Transient == true && Failed == true)
- return _error->Error(_("--fix-missing and media swapping is not currently supported"));
-
- // Try to deal with missing package files
- if (Failed == true && PM->FixMissing() == false)
- {
- cerr << _("Unable to correct missing packages.") << endl;
- return _error->Error(_("Aborting install."));
- }
-
- _system->UnLock();
- int status_fd = _config->FindI("APT::Status-Fd",-1);
- pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd);
- if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
- return false;
- if (Res == pkgPackageManager::Completed)
- return true;
-
- // Reload the fetcher object and loop again for media swapping
- Fetcher.Shutdown();
- if (PM->GetArchives(&Fetcher,&List,&Recs) == false)
- return false;
-
- _system->Lock();
- }
-}
- /*}}}*/
-// TryToInstall - Try to install a single package /*{{{*/
-// ---------------------------------------------------------------------
-/* This used to be inlined in DoInstall, but with the advent of regex package
- name matching it was split out.. */
-bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
- pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
- unsigned int &ExpectedInst,bool AllowFail = true)
-{
- /* This is a pure virtual package and there is a single available
- candidate providing it. */
- if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0)
- {
- pkgCache::PkgIterator Prov;
- bool found_one = false;
-
- for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; P++)
- {
- pkgCache::VerIterator const PVer = P.OwnerVer();
- pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
-
- /* Ignore versions that are not a candidate. */
- if (Cache[PPkg].CandidateVer != PVer)
- continue;
-
- if (found_one == false)
- {
- Prov = PPkg;
- found_one = true;
- }
- else if (PPkg != Prov)
- {
- found_one = false; // we found at least two
- break;
- }
- }
-
- if (found_one == true)
- {
- ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
- Prov.Name(),Pkg.Name());
- Pkg = Prov;
- }
- }
-
- // Handle the no-upgrade case
- if (_config->FindB("APT::Get::upgrade",true) == false &&
- Pkg->CurrentVer != 0)
- {
- if (AllowFail == true)
- ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
- Pkg.Name());
- return true;
- }
-
- // Ignore request for install if package would be new
- if (_config->FindB("APT::Get::Only-Upgrade", false) == true &&
- Pkg->CurrentVer == 0)
- {
- if (AllowFail == true)
- ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
- Pkg.Name());
- return true;
- }
-
- // Check if there is something at all to install
- pkgDepCache::StateCache &State = Cache[Pkg];
- if (Remove == true && Pkg->CurrentVer == 0)
- {
- Fix.Clear(Pkg);
- Fix.Protect(Pkg);
- Fix.Remove(Pkg);
-
- /* We want to continue searching for regex hits, so we return false here
- otherwise this is not really an error. */
- if (AllowFail == false)
- return false;
-
- ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.Name());
- return true;
- }
-
- if (State.CandidateVer == 0 && Remove == false)
- {
- if (AllowFail == false)
- return false;
-
- if (Pkg->ProvidesList != 0)
- {
- ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
- Pkg.Name());
-
- pkgCache::PrvIterator I = Pkg.ProvidesList();
- for (; I.end() == false; I++)
- {
- pkgCache::PkgIterator Pkg = I.OwnerPkg();
-
- if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer())
- {
- 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 explicitly select one to install.") << endl;
- }
- else
- {
- ioprintf(c1out,
- _("Package %s is not available, but is referred to by another package.\n"
- "This may mean that the package is missing, has been obsoleted, or\n"
- "is only available from another source\n"),Pkg.Name());
-
- string List;
- string VersionsList;
- SPtrArray<bool> Seen = new bool[Cache.Head().PackageCount];
- memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen));
- pkgCache::DepIterator Dep = Pkg.RevDependsList();
- for (; Dep.end() == false; Dep++)
- {
- if (Dep->Type != pkgCache::Dep::Replaces)
- continue;
- if (Seen[Dep.ParentPkg()->ID] == true)
- continue;
- Seen[Dep.ParentPkg()->ID] = true;
- List += string(Dep.ParentPkg().Name()) + " ";
- //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ???
- }
- ShowList(c1out,_("However the following packages replace it:"),List,VersionsList);
- }
-
- _error->Error(_("Package %s has no installation candidate"),Pkg.Name());
- return false;
- }
-
- Fix.Clear(Pkg);
- Fix.Protect(Pkg);
- if (Remove == true)
- {
- Fix.Remove(Pkg);
- Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
- return true;
- }
-
- // Install it
- Cache.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.Name());
- else
- Cache.SetReInstall(Pkg,true);
- }
- else
- {
- if (AllowFail == true)
- ioprintf(c1out,_("%s is already the newest version.\n"),
- Pkg.Name());
- }
- }
- else
- ExpectedInst++;
-
- // Install it with autoinstalling enabled (if we not respect the minial
- // required deps or the policy)
- if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && BrokenFix == false)
- Cache.MarkInstall(Pkg,true);
-
- return true;
-}
- /*}}}*/
-// TryToChangeVer - Try to change a candidate version /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
- const char *VerTag,bool IsRel)
-{
- pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release :
- pkgVersionMatch::Version));
-
- pkgCache::VerIterator Ver = Match.Find(Pkg);
-
- if (Ver.end() == true)
- {
- if (IsRel == true)
- return _error->Error(_("Release '%s' for '%s' was not found"),
- VerTag,Pkg.Name());
- return _error->Error(_("Version '%s' for '%s' was not found"),
- VerTag,Pkg.Name());
- }
-
- if (strcmp(VerTag,Ver.VerStr()) != 0)
- {
- ioprintf(c1out,_("Selected version %s (%s) for %s\n"),
- Ver.VerStr(),Ver.RelStr().c_str(),Pkg.Name());
- }
-
- Cache.SetCandidateVersion(Ver);
- return true;
-}
- /*}}}*/
-// FindSrc - Find a source record /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
- pkgSrcRecords &SrcRecs,string &Src,
- pkgDepCache &Cache)
-{
- string VerTag;
- string DefRel = _config->Find("APT::Default-Release");
- string TmpSrc = Name;
-
- // extract the version/release from the pkgname
- const size_t found = TmpSrc.find_last_of("/=");
- if (found != string::npos) {
- if (TmpSrc[found] == '/')
- DefRel = TmpSrc.substr(found+1);
- else
- VerTag = TmpSrc.substr(found+1);
- TmpSrc = TmpSrc.substr(0,found);
- }
-
- /* 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. */
- bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source");
- const pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc);
- if (MatchSrcOnly == false && Pkg.end() == false)
- {
- if(VerTag.empty() == false || DefRel.empty() == false)