1 // Include Files                                                        /*{{{*/ 
   4 #include <apt-pkg/acquire-item.h> 
   5 #include <apt-pkg/acquire.h> 
   6 #include <apt-pkg/algorithms.h> 
   7 #include <apt-pkg/aptconfiguration.h> 
   8 #include <apt-pkg/cachefile.h> 
   9 #include <apt-pkg/cacheiterators.h> 
  10 #include <apt-pkg/cacheset.h> 
  11 #include <apt-pkg/cmndline.h> 
  12 #include <apt-pkg/configuration.h> 
  13 #include <apt-pkg/depcache.h> 
  14 #include <apt-pkg/error.h> 
  15 #include <apt-pkg/fileutl.h> 
  16 #include <apt-pkg/hashes.h> 
  17 #include <apt-pkg/indexfile.h> 
  18 #include <apt-pkg/metaindex.h> 
  19 #include <apt-pkg/pkgcache.h> 
  20 #include <apt-pkg/sourcelist.h> 
  21 #include <apt-pkg/srcrecords.h> 
  22 #include <apt-pkg/strutl.h> 
  23 #include <apt-pkg/version.h> 
  25 #include <apt-private/private-cachefile.h> 
  26 #include <apt-private/private-cacheset.h> 
  27 #include <apt-private/private-download.h> 
  28 #include <apt-private/private-install.h> 
  29 #include <apt-private/private-source.h> 
  46 // TryToInstallBuildDep - Try to install a single package               /*{{{*/ 
  47 // --------------------------------------------------------------------- 
  48 /* This used to be inlined in DoInstall, but with the advent of regex package 
  49    name matching it was split out.. */ 
  50 static bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg
,pkgCacheFile 
&Cache
, 
  51                   pkgProblemResolver 
&Fix
,bool Remove
,bool BrokenFix
, 
  52                   bool AllowFail 
= true) 
  54    if (Cache
[Pkg
].CandidateVer 
== 0 && Pkg
->ProvidesList 
!= 0) 
  56       CacheSetHelperAPTGet 
helper(c1out
); 
  57       helper
.showErrors(false); 
  58       pkgCache::VerIterator Ver 
= helper
.canNotFindNewestVer(Cache
, Pkg
); 
  59       if (Ver
.end() == false) 
  60          Pkg 
= Ver
.ParentPkg(); 
  61       else if (helper
.showVirtualPackageErrors(Cache
) == false) 
  65    if (_config
->FindB("Debug::BuildDeps",false) == true) 
  68          std::cout 
<< "  Trying to remove " << Pkg 
<< std::endl
; 
  70          std::cout 
<< "  Trying to install " << Pkg 
<< std::endl
; 
  75       TryToRemove 
RemoveAction(Cache
, &Fix
); 
  76       RemoveAction(Pkg
.VersionList()); 
  77    } else if (Cache
[Pkg
].CandidateVer 
!= 0) { 
  78       TryToInstall 
InstallAction(Cache
, &Fix
, BrokenFix
); 
  79       InstallAction(Cache
[Pkg
].CandidateVerIter(Cache
)); 
  80       InstallAction
.doAutoInstall(); 
  87 // GetReleaseFileForSourceRecord - Return Suite for the given srcrecord /*{{{*/ 
  88 static pkgCache::RlsFileIterator 
GetReleaseFileForSourceRecord(CacheFile 
&CacheFile
, 
  89       pkgSourceList 
*SrcList
, pkgSrcRecords::Parser 
*Parse
) 
  91    // try to find release 
  92    const pkgIndexFile
& CurrentIndexFile 
= Parse
->Index(); 
  94    for (pkgSourceList::const_iterator S 
= SrcList
->begin();  
  95          S 
!= SrcList
->end(); ++S
) 
  97       std::vector
<pkgIndexFile 
*> *Indexes 
= (*S
)->GetIndexFiles(); 
  98       for (std::vector
<pkgIndexFile 
*>::const_iterator IF 
= Indexes
->begin(); 
  99             IF 
!= Indexes
->end(); ++IF
) 
 101          if (&CurrentIndexFile 
== (*IF
)) 
 102             return (*S
)->FindInCache(CacheFile
, false); 
 105    return pkgCache::RlsFileIterator(CacheFile
); 
 108 // FindSrc - Find a source record                                       /*{{{*/ 
 109 static pkgSrcRecords::Parser 
*FindSrc(const char *Name
, 
 110                                pkgSrcRecords 
&SrcRecs
,std::string 
&Src
, 
 111                                CacheFile 
&CacheFile
) 
 113    std::string VerTag
, UserRequestedVerTag
; 
 114    std::string ArchTag 
= ""; 
 115    std::string RelTag 
= _config
->Find("APT::Default-Release"); 
 116    std::string TmpSrc 
= Name
; 
 117    pkgDepCache 
*Cache 
= CacheFile
.GetDepCache(); 
 120    size_t found 
= TmpSrc
.find_last_of("/"); 
 121    if (found 
!= std::string::npos
) 
 123       RelTag 
= TmpSrc
.substr(found
+1); 
 124       TmpSrc 
= TmpSrc
.substr(0,found
); 
 126    // extract the version 
 127    found 
= TmpSrc
.find_last_of("="); 
 128    if (found 
!= std::string::npos
) 
 130       VerTag 
= UserRequestedVerTag 
= TmpSrc
.substr(found
+1); 
 131       TmpSrc 
= TmpSrc
.substr(0,found
); 
 134    found 
= TmpSrc
.find_last_of(":"); 
 135    if (found 
!= std::string::npos
) 
 137       ArchTag 
= TmpSrc
.substr(found
+1); 
 138       TmpSrc 
= TmpSrc
.substr(0,found
); 
 141    /* Lookup the version of the package we would install if we were to 
 142       install a version and determine the source package name, then look 
 143       in the archive for a source package of the same name. */ 
 144    bool MatchSrcOnly 
= _config
->FindB("APT::Get::Only-Source"); 
 145    pkgCache::PkgIterator Pkg
; 
 147       Pkg 
= Cache
->FindPkg(TmpSrc
, ArchTag
); 
 149       Pkg 
= Cache
->FindPkg(TmpSrc
); 
 151    // if we can't find a package but the user qualified with a arch, 
 153    if (Pkg
.end() && ArchTag 
!= "") 
 156       _error
->Error(_("Can not find a package for architecture '%s'"), 
 161    if (MatchSrcOnly 
== false && Pkg
.end() == false)  
 163       if(VerTag 
!= "" || RelTag 
!= "" || ArchTag 
!= "") 
 166          // we have a default release, try to locate the pkg. we do it like 
 167          // this because GetCandidateVer() will not "downgrade", that means 
 168          // "apt-get source -t stable apt" won't work on a unstable system 
 169          for (pkgCache::VerIterator Ver 
= Pkg
.VersionList();; ++Ver
) 
 171             // try first only exact matches, later fuzzy matches 
 172             if (Ver
.end() == true) 
 177                Ver 
= Pkg
.VersionList(); 
 178                // exit right away from the Pkg.VersionList() loop if we 
 179                // don't have any versions 
 180                if (Ver
.end() == true) 
 184             // ignore arches that are not for us 
 185             if (ArchTag 
!= "" && Ver
.Arch() != ArchTag
) 
 188             // pick highest version for the arch unless the user wants 
 190             if (ArchTag 
!= "" && VerTag 
== "" && RelTag 
== "") 
 191                if(Cache
->VS().CmpVersion(VerTag
, Ver
.VerStr()) < 0) 
 192                   VerTag 
= Ver
.VerStr(); 
 194             // We match against a concrete version (or a part of this version) 
 195             if (VerTag
.empty() == false && 
 196                   (fuzzy 
== true || Cache
->VS().CmpVersion(VerTag
, Ver
.VerStr()) != 0) && // exact match 
 197                   (fuzzy 
== false || strncmp(VerTag
.c_str(), Ver
.VerStr(), VerTag
.size()) != 0)) // fuzzy match 
 200             for (pkgCache::VerFileIterator VF 
= Ver
.FileList(); 
 201                   VF
.end() == false; ++VF
) 
 203                /* If this is the status file, and the current version is not the 
 204                   version in the status file (ie it is not installed, or somesuch) 
 205                   then it is not a candidate for installation, ever. This weeds 
 206                   out bogus entries that may be due to config-file states, or 
 208                if ((VF
.File()->Flags 
& pkgCache::Flag::NotSource
) == 
 209                      pkgCache::Flag::NotSource 
&& Pkg
.CurrentVer() != Ver
) 
 212                // or we match against a release 
 213                if(VerTag
.empty() == false || 
 214                      (VF
.File().Archive() != 0 && VF
.File().Archive() == RelTag
) || 
 215                      (VF
.File().Codename() != 0 && VF
.File().Codename() == RelTag
))  
 217                   // the Version we have is possibly fuzzy or includes binUploads, 
 218                   // so we use the Version of the SourcePkg (empty if same as package) 
 219                   Src 
= Ver
.SourcePkgName(); 
 220                   VerTag 
= Ver
.SourceVerStr(); 
 224             if (Src
.empty() == false) 
 229       if (Src 
== "" && ArchTag 
!= "") 
 232             _error
->Error(_("Can not find a package '%s' with version '%s'"), 
 233                   Pkg
.FullName().c_str(), VerTag
.c_str()); 
 235             _error
->Error(_("Can not find a package '%s' with release '%s'"), 
 236                   Pkg
.FullName().c_str(), RelTag
.c_str()); 
 242       if (Src
.empty() == true) 
 244          // if we don't have found a fitting package yet so we will 
 245          // choose a good candidate and proceed with that. 
 246          // Maybe we will find a source later on with the right VerTag 
 248          pkgCache::VerIterator 
const Ver 
= Cache
->GetCandidateVersion(Pkg
); 
 249          if (Ver
.end() == false) 
 251             if (strcmp(Ver
.SourcePkgName(),Ver
.ParentPkg().Name()) != 0) 
 252                Src 
= Ver
.SourcePkgName(); 
 253             if (VerTag
.empty() == true && strcmp(Ver
.SourceVerStr(),Ver
.VerStr()) != 0) 
 254                VerTag 
= Ver
.SourceVerStr(); 
 259    if (Src
.empty() == true) 
 265       /* if we have a source pkg name, make sure to only search 
 266          for srcpkg names, otherwise apt gets confused if there 
 267          is a binary package "pkg1" and a source package "pkg1" 
 268          with the same name but that comes from different packages */ 
 272          ioprintf(c1out
, _("Picking '%s' as source package instead of '%s'\n"), Src
.c_str(), TmpSrc
.c_str()); 
 277    pkgSrcRecords::Parser 
*Last 
= 0; 
 278    unsigned long Offset 
= 0; 
 280    pkgSourceList 
*SrcList 
= CacheFile
.GetSourceList(); 
 282    /* Iterate over all of the hits, which includes the resulting 
 283       binary packages in the search */ 
 284                pkgSrcRecords::Parser 
*Parse
; 
 288                   while ((Parse 
= SrcRecs
.Find(Src
.c_str(), MatchSrcOnly
)) != 0)  
 290                      const std::string Ver 
= Parse
->Version(); 
 291                      bool CorrectRelTag 
= false; 
 293                      // See if we need to look for a specific release tag 
 294                      if (RelTag 
!= "" && UserRequestedVerTag 
== "") 
 296                         pkgCache::RlsFileIterator 
const Rls 
= GetReleaseFileForSourceRecord(CacheFile
, SrcList
, Parse
); 
 297                         if (Rls
.end() == false) 
 299                            if ((Rls
->Archive 
!= 0 && RelTag 
== Rls
.Archive()) || 
 300                                  (Rls
->Codename 
!= 0 && RelTag 
== Rls
.Codename())) 
 301                               CorrectRelTag 
= true; 
 304                         CorrectRelTag 
= true; 
 306                      // Ignore all versions which doesn't fit 
 307                      if (VerTag
.empty() == false && 
 308                            Cache
->VS().CmpVersion(VerTag
, Ver
) != 0) // exact match 
 311                      // Newer version or an exact match? Save the hit 
 312                      if (CorrectRelTag 
&& (Last 
== 0 || Cache
->VS().CmpVersion(Version
,Ver
) < 0)) { 
 314                         Offset 
= Parse
->Offset(); 
 318                      // was the version check above an exact match? 
 319                      // If so, we don't need to look further 
 320                      if (VerTag
.empty() == false && (VerTag 
== Ver
)) 
 323                   if (UserRequestedVerTag 
== "" && Version 
!= "" && RelTag 
!= "") 
 324                      ioprintf(c1out
, "Selected version '%s' (%s) for %s\n",  
 325                            Version
.c_str(), RelTag
.c_str(), Src
.c_str()); 
 327                   if (Last 
!= 0 || VerTag
.empty() == true) 
 329                   _error
->Error(_("Can not find version '%s' of package '%s'"), VerTag
.c_str(), TmpSrc
.c_str()); 
 333                if (Last 
== 0 || Last
->Jump(Offset
) == false) 
 339 // DoSource - Fetch a source archive                                    /*{{{*/ 
 340 // --------------------------------------------------------------------- 
 341 /* Fetch souce packages */ 
 348 bool DoSource(CommandLine 
&CmdL
) 
 351    if (Cache
.Open(false) == false) 
 354    if (CmdL
.FileSize() <= 1) 
 355       return _error
->Error(_("Must specify at least one package to fetch source for")); 
 357    // Read the source list 
 358    if (Cache
.BuildSourceList() == false) 
 360    pkgSourceList 
*List 
= Cache
.GetSourceList(); 
 362    // Create the text record parsers 
 363    pkgSrcRecords 
SrcRecs(*List
); 
 364    if (_error
->PendingError() == true) 
 367    std::unique_ptr
<DscFile
[]> Dsc(new DscFile
[CmdL
.FileSize()]); 
 369    // insert all downloaded uris into this set to avoid downloading them 
 371    std::set
<std::string
> queued
; 
 373    // Diff only mode only fetches .diff files 
 374    bool const diffOnly 
= _config
->FindB("APT::Get::Diff-Only", false); 
 375    // Tar only mode only fetches .tar files 
 376    bool const tarOnly 
= _config
->FindB("APT::Get::Tar-Only", false); 
 377    // Dsc only mode only fetches .dsc files 
 378    bool const dscOnly 
= _config
->FindB("APT::Get::Dsc-Only", false); 
 380    // Load the requestd sources into the fetcher 
 381    aptAcquireWithTextStatus Fetcher
; 
 383    std::vector
<std::string
> UntrustedList
; 
 384    for (const char **I 
= CmdL
.FileList 
+ 1; *I 
!= 0; I
++, J
++) 
 387       pkgSrcRecords::Parser 
*Last 
= FindSrc(*I
,SrcRecs
,Src
,Cache
); 
 389          return _error
->Error(_("Unable to find a source package for %s"),Src
.c_str()); 
 392       if (Last
->Index().IsTrusted() == false) 
 393          UntrustedList
.push_back(Src
); 
 395       std::string srec 
= Last
->AsStr(); 
 396       std::string::size_type pos 
= srec
.find("\nVcs-"); 
 397       while (pos 
!= std::string::npos
) 
 399          pos 
+= strlen("\nVcs-"); 
 400          std::string vcs 
= srec
.substr(pos
,srec
.find(":",pos
)-pos
); 
 403             pos 
= srec
.find("\nVcs-", pos
); 
 406          pos 
+= vcs
.length()+2; 
 407          std::string::size_type epos 
= srec
.find("\n", pos
); 
 408          std::string 
const uri 
= srec
.substr(pos
,epos
-pos
); 
 409          ioprintf(c1out
, _("NOTICE: '%s' packaging is maintained in " 
 410                   "the '%s' version control system at:\n" 
 412                Src
.c_str(), vcs
.c_str(), uri
.c_str()); 
 415             vcscmd 
= "bzr branch " + uri
; 
 416          else if (vcs 
== "Git") 
 417             vcscmd 
= "git clone " + uri
; 
 419          if (vcscmd
.empty() == false) 
 420             ioprintf(c1out
,_("Please use:\n%s\n" 
 421                      "to retrieve the latest (possibly unreleased) " 
 422                      "updates to the package.\n"), 
 428       std::vector
<pkgSrcRecords::File2
> Lst
; 
 429       if (Last
->Files2(Lst
) == false) { 
 433       // Load them into the fetcher 
 434       for (std::vector
<pkgSrcRecords::File2
>::const_iterator I 
= Lst
.begin(); 
 437          // Try to guess what sort of file it is we are getting. 
 438          if (I
->Type 
== "dsc") 
 440             Dsc
[J
].Package 
= Last
->Package(); 
 441             Dsc
[J
].Version 
= Last
->Version(); 
 442             Dsc
[J
].Dsc 
= flNotDir(I
->Path
); 
 445          // Handle the only options so that multiple can be used at once 
 446          if (diffOnly 
== true || tarOnly 
== true || dscOnly 
== true) 
 448             if ((diffOnly 
== true && I
->Type 
== "diff") || 
 449                   (tarOnly 
== true && I
->Type 
== "tar") || 
 450                   (dscOnly 
== true && I
->Type 
== "dsc")) 
 451                ; // Fine, we want this file downloaded 
 456          // don't download the same uri twice (should this be moved to 
 457          // the fetcher interface itself?) 
 458          if(queued
.find(Last
->Index().ArchiveURI(I
->Path
)) != queued
.end()) 
 460          queued
.insert(Last
->Index().ArchiveURI(I
->Path
)); 
 462          // check if we have a file with that md5 sum already localy 
 463          std::string localFile 
= flNotDir(I
->Path
); 
 464          if (FileExists(localFile
) == true) 
 465             if(I
->Hashes
.VerifyFile(localFile
) == true) 
 467                ioprintf(c1out
,_("Skipping already downloaded file '%s'\n"), 
 472          // see if we have a hash (Acquire::ForceHash is the only way to have none) 
 473          if (I
->Hashes
.usable() == false && _config
->FindB("APT::Get::AllowUnauthenticated",false) == false) 
 475             ioprintf(c1out
, "Skipping download of file '%s' as requested hashsum is not available for authentication\n", 
 480          new pkgAcqFile(&Fetcher
,Last
->Index().ArchiveURI(I
->Path
), 
 481                I
->Hashes
, I
->FileSize
, Last
->Index().SourceInfo(*Last
,*I
), Src
); 
 485    // Display statistics 
 486    unsigned long long FetchBytes 
= Fetcher
.FetchNeeded(); 
 487    unsigned long long FetchPBytes 
= Fetcher
.PartialPresent(); 
 488    unsigned long long DebBytes 
= Fetcher
.TotalNeeded(); 
 490    if (CheckFreeSpaceBeforeDownload(".", (FetchBytes 
- FetchPBytes
)) == false) 
 494    if (DebBytes 
!= FetchBytes
) 
 495       //TRANSLATOR: The required space between number and unit is already included 
 496       // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB 
 497       ioprintf(c1out
,_("Need to get %sB/%sB of source archives.\n"), 
 498             SizeToStr(FetchBytes
).c_str(),SizeToStr(DebBytes
).c_str()); 
 500       //TRANSLATOR: The required space between number and unit is already included 
 501       // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB 
 502       ioprintf(c1out
,_("Need to get %sB of source archives.\n"), 
 503             SizeToStr(DebBytes
).c_str()); 
 505    if (_config
->FindB("APT::Get::Simulate",false) == true) 
 507       for (unsigned I 
= 0; I 
!= J
; I
++) 
 508          ioprintf(std::cout
,_("Fetch source %s\n"),Dsc
[I
].Package
.c_str()); 
 512    // Just print out the uris an exit if the --print-uris flag was used 
 513    if (_config
->FindB("APT::Get::Print-URIs") == true) 
 515       pkgAcquire::UriIterator I 
= Fetcher
.UriBegin(); 
 516       for (; I 
!= Fetcher
.UriEnd(); ++I
) 
 517          std::cout 
<< '\'' << I
->URI 
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<  
 518             I
->Owner
->FileSize 
<< ' ' << I
->Owner
->HashSum() << std::endl
; 
 522    // check authentication status of the source as well 
 523    if (UntrustedList
.empty() == false && AuthPrompt(UntrustedList
, false) == false) 
 528    if (AcquireRun(Fetcher
, 0, &Failed
, NULL
) == false || Failed 
== true) 
 530       return _error
->Error(_("Failed to fetch some archives.")); 
 533    if (_config
->FindB("APT::Get::Download-only",false) == true) 
 535       c1out 
<< _("Download complete and in download only mode") << std::endl
; 
 539    // Unpack the sources 
 540    pid_t Process 
= ExecFork(); 
 544       bool const fixBroken 
= _config
->FindB("APT::Get::Fix-Broken", false); 
 545       for (unsigned I 
= 0; I 
!= J
; ++I
) 
 547          std::string Dir 
= Dsc
[I
].Package 
+ '-' + Cache
->VS().UpstreamVersion(Dsc
[I
].Version
.c_str()); 
 549          // Diff only mode only fetches .diff files 
 550          if (_config
->FindB("APT::Get::Diff-Only",false) == true || 
 551                _config
->FindB("APT::Get::Tar-Only",false) == true || 
 552                Dsc
[I
].Dsc
.empty() == true) 
 555          // See if the package is already unpacked 
 557          if (fixBroken 
== false && stat(Dir
.c_str(),&Stat
) == 0 && 
 558                S_ISDIR(Stat
.st_mode
) != 0) 
 560             ioprintf(c0out 
,_("Skipping unpack of already unpacked source in %s\n"), 
 566             std::string 
const sourceopts 
= _config
->Find("DPkg::Source-Options", "-x"); 
 568             strprintf(S
, "%s %s %s", 
 569                   _config
->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(), 
 570                   sourceopts
.c_str(), Dsc
[I
].Dsc
.c_str()); 
 571             if (system(S
.c_str()) != 0) 
 573                fprintf(stderr
, _("Unpack command '%s' failed.\n"), S
.c_str()); 
 574                fprintf(stderr
, _("Check if the 'dpkg-dev' package is installed.\n")); 
 579          // Try to compile it with dpkg-buildpackage 
 580          if (_config
->FindB("APT::Get::Compile",false) == true) 
 582             std::string buildopts 
= _config
->Find("APT::Get::Host-Architecture"); 
 583             if (buildopts
.empty() == false) 
 584                buildopts 
= "-a" + buildopts 
+ " "; 
 586             // get all active build profiles 
 587             std::string 
const profiles 
= APT::Configuration::getBuildProfilesString(); 
 588             if (profiles
.empty() == false) 
 589                buildopts
.append(" -P").append(profiles
).append(" "); 
 591             buildopts
.append(_config
->Find("DPkg::Build-Options","-b -uc")); 
 593             // Call dpkg-buildpackage 
 595             strprintf(S
, "cd %s && %s %s", 
 597                   _config
->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(), 
 600             if (system(S
.c_str()) != 0) 
 602                fprintf(stderr
, _("Build command '%s' failed.\n"), S
.c_str()); 
 611    return ExecWait(Process
, "dpkg-source"); 
 614 // InstallBuildDepsLoop                                                 /*{{{*/ 
 615 static bool InstallBuildDepsLoop(CacheFile 
&Cache
, std::string 
const &Src
, 
 616       std::vector
<pkgSrcRecords::Parser::BuildDepRec
> const &BuildDeps
, 
 617       bool const StripMultiArch
, std::string 
const &hostArch
) 
 619    // Install the requested packages 
 620    std::vector 
<pkgSrcRecords::Parser::BuildDepRec
>::const_iterator D
; 
 621    pkgProblemResolver 
Fix(Cache
); 
 622    bool skipAlternatives 
= false; // skip remaining alternatives in an or group 
 623    for (D 
= BuildDeps
.begin(); D 
!= BuildDeps
.end(); ++D
) 
 625       bool hasAlternatives 
= (((*D
).Op 
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
); 
 627       if (skipAlternatives 
== true) 
 630           * if there are alternatives, we've already picked one, so skip 
 633           * TODO: this means that if there's a build-dep on A|B and B is 
 634           * installed, we'll still try to install A; more importantly, 
 635           * if A is currently broken, we cannot go back and try B. To fix 
 636           * this would require we do a Resolve cycle for each package we 
 637           * add to the install list. Ugh 
 639          if (!hasAlternatives
) 
 640             skipAlternatives 
= false; // end of or group 
 644       if ((*D
).Type 
== pkgSrcRecords::Parser::BuildConflict 
|| 
 645             (*D
).Type 
== pkgSrcRecords::Parser::BuildConflictIndep
) 
 647          pkgCache::GrpIterator Grp 
= Cache
->FindGrp((*D
).Package
); 
 648          // Build-conflicts on unknown packages are silently ignored 
 649          if (Grp
.end() == true) 
 652          for (pkgCache::PkgIterator Pkg 
= Grp
.PackageList(); Pkg
.end() == false; Pkg 
= Grp
.NextPkg(Pkg
)) 
 654             pkgCache::VerIterator IV 
= (*Cache
)[Pkg
].InstVerIter(*Cache
); 
 656              * Remove if we have an installed version that satisfies the 
 659             if (IV
.end() == false && 
 660                   Cache
->VS().CheckDep(IV
.VerStr(),(*D
).Op
,(*D
).Version
.c_str()) == true) 
 661                TryToInstallBuildDep(Pkg
,Cache
,Fix
,true,false); 
 664       else // BuildDep || BuildDepIndep 
 666          if (_config
->FindB("Debug::BuildDeps",false) == true) 
 667             std::cout 
<< "Looking for " << (*D
).Package 
<< "...\n"; 
 669          pkgCache::PkgIterator Pkg
; 
 672          if (StripMultiArch 
== false && D
->Type 
!= pkgSrcRecords::Parser::BuildDependIndep
) 
 674             size_t const colon 
= D
->Package
.find(":"); 
 675             if (colon 
!= std::string::npos
) 
 677                if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0 || strcmp(D
->Package
.c_str() + colon
, ":native") == 0) 
 678                   Pkg 
= Cache
->FindPkg(D
->Package
.substr(0,colon
)); 
 680                   Pkg 
= Cache
->FindPkg(D
->Package
); 
 683                Pkg 
= Cache
->FindPkg(D
->Package
, hostArch
); 
 685             // a bad version either is invalid or doesn't satify dependency 
 686 #define BADVER(Ver) (Ver.end() == true || \ 
 687       (D->Version.empty() == false && \ 
 688        Cache->VS().CheckDep(Ver.VerStr(),D->Op,D->Version.c_str()) == false)) 
 690             APT::VersionList verlist
; 
 691             if (Pkg
.end() == false) 
 693                pkgCache::VerIterator Ver 
= (*Cache
)[Pkg
].InstVerIter(*Cache
); 
 694                if (BADVER(Ver
) == false) 
 696                Ver 
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
); 
 697                if (BADVER(Ver
) == false) 
 700             if (verlist
.empty() == true) 
 702                pkgCache::PkgIterator BuildPkg 
= Cache
->FindPkg(D
->Package
, "native"); 
 703                if (BuildPkg
.end() == false && Pkg 
!= BuildPkg
) 
 705                   pkgCache::VerIterator Ver 
= (*Cache
)[BuildPkg
].InstVerIter(*Cache
); 
 706                   if (BADVER(Ver
) == false) 
 708                   Ver 
= (*Cache
)[BuildPkg
].CandidateVerIter(*Cache
); 
 709                   if (BADVER(Ver
) == false) 
 715             std::string forbidden
; 
 716             // We need to decide if host or build arch, so find a version we can look at 
 717             APT::VersionList::const_iterator Ver 
= verlist
.begin(); 
 718             for (; Ver 
!= verlist
.end(); ++Ver
) 
 721                if (Ver
->MultiArch 
== pkgCache::Version::No 
|| Ver
->MultiArch 
== pkgCache::Version::All
) 
 723                   if (colon 
== std::string::npos
) 
 724                      Pkg 
= Ver
.ParentPkg().Group().FindPkg(hostArch
); 
 725                   else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0) 
 726                      forbidden 
= "Multi-Arch: no"; 
 727                   else if (strcmp(D
->Package
.c_str() + colon
, ":native") == 0) 
 728                      Pkg 
= Ver
.ParentPkg().Group().FindPkg("native"); 
 730                else if (Ver
->MultiArch 
== pkgCache::Version::Same
) 
 732                   if (colon 
== std::string::npos
) 
 733                      Pkg 
= Ver
.ParentPkg().Group().FindPkg(hostArch
); 
 734                   else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0) 
 735                      forbidden 
= "Multi-Arch: same"; 
 736                   else if (strcmp(D
->Package
.c_str() + colon
, ":native") == 0) 
 737                      Pkg 
= Ver
.ParentPkg().Group().FindPkg("native"); 
 739                else if ((Ver
->MultiArch 
& pkgCache::Version::Foreign
) == pkgCache::Version::Foreign
) 
 741                   if (colon 
== std::string::npos
) 
 742                      Pkg 
= Ver
.ParentPkg().Group().FindPkg("native"); 
 743                   else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0 || 
 744                         strcmp(D
->Package
.c_str() + colon
, ":native") == 0) 
 745                      forbidden 
= "Multi-Arch: foreign"; 
 747                else if ((Ver
->MultiArch 
& pkgCache::Version::Allowed
) == pkgCache::Version::Allowed
) 
 749                   if (colon 
== std::string::npos
) 
 750                      Pkg 
= Ver
.ParentPkg().Group().FindPkg(hostArch
); 
 751                   else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0) 
 753                      // prefer any installed over preferred non-installed architectures 
 754                      pkgCache::GrpIterator Grp 
= Ver
.ParentPkg().Group(); 
 755                      // we don't check for version here as we are better of with upgrading than remove and install 
 756                      for (Pkg 
= Grp
.PackageList(); Pkg
.end() == false; Pkg 
= Grp
.NextPkg(Pkg
)) 
 757                         if (Pkg
.CurrentVer().end() == false) 
 759                      if (Pkg
.end() == true) 
 760                         Pkg 
= Grp
.FindPreferredPkg(true); 
 762                   else if (strcmp(D
->Package
.c_str() + colon
, ":native") == 0) 
 763                      Pkg 
= Ver
.ParentPkg().Group().FindPkg("native"); 
 766                if (forbidden
.empty() == false) 
 768                   if (_config
->FindB("Debug::BuildDeps",false) == true) 
 769                      std::cout 
<< D
->Package
.substr(colon
, std::string::npos
) << " is not allowed from " << forbidden 
<< " package " << (*D
).Package 
<< " (" << Ver
.VerStr() << ")" << std::endl
; 
 773                //we found a good version 
 776             if (Ver 
== verlist
.end()) 
 778                if (_config
->FindB("Debug::BuildDeps",false) == true) 
 779                   std::cout 
<< " No multiarch info as we have no satisfying installed nor candidate for " << D
->Package 
<< " on build or host arch" << std::endl
; 
 781                if (forbidden
.empty() == false) 
 785                   return _error
->Error(_("%s dependency for %s can't be satisfied " 
 786                            "because %s is not allowed on '%s' packages"), 
 787                         pkgSrcRecords::Parser::BuildDepType(D
->Type
), Src
.c_str(), 
 788                         D
->Package
.c_str(), forbidden
.c_str()); 
 793             Pkg 
= Cache
->FindPkg(D
->Package
); 
 795          if (Pkg
.end() == true || (Pkg
->VersionList 
== 0 && Pkg
->ProvidesList 
== 0)) 
 797             if (_config
->FindB("Debug::BuildDeps",false) == true) 
 798                std::cout 
<< " (not found)" << (*D
).Package 
<< std::endl
; 
 803             return _error
->Error(_("%s dependency for %s cannot be satisfied " 
 804                      "because the package %s cannot be found"), 
 805                   pkgSrcRecords::Parser::BuildDepType(D
->Type
), Src
.c_str(), 
 806                   (*D
).Package
.c_str()); 
 809          pkgCache::VerIterator IV 
= (*Cache
)[Pkg
].InstVerIter(*Cache
); 
 810          if (IV
.end() == false) 
 812             if (_config
->FindB("Debug::BuildDeps",false) == true) 
 813                std::cout 
<< "  Is installed\n"; 
 815             if (D
->Version
.empty() == true || 
 816                   Cache
->VS().CheckDep(IV
.VerStr(),(*D
).Op
,(*D
).Version
.c_str()) == true) 
 818                skipAlternatives 
= hasAlternatives
; 
 822             if (_config
->FindB("Debug::BuildDeps",false) == true) 
 823                std::cout 
<< "    ...but the installed version doesn't meet the version requirement\n"; 
 825             if (((*D
).Op 
& pkgCache::Dep::LessEq
) == pkgCache::Dep::LessEq
) 
 826                return _error
->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"), 
 827                      pkgSrcRecords::Parser::BuildDepType(D
->Type
), Src
.c_str(), Pkg
.FullName(true).c_str()); 
 830          // Only consider virtual packages if there is no versioned dependency 
 831          if ((*D
).Version
.empty() == true) 
 834              * If this is a virtual package, we need to check the list of 
 835              * packages that provide it and see if any of those are 
 838             pkgCache::PrvIterator Prv 
= Pkg
.ProvidesList(); 
 839             for (; Prv
.end() != true; ++Prv
) 
 841                if (_config
->FindB("Debug::BuildDeps",false) == true) 
 842                   std::cout 
<< "  Checking provider " << Prv
.OwnerPkg().FullName() << std::endl
; 
 844                if ((*Cache
)[Prv
.OwnerPkg()].InstVerIter(*Cache
).end() == false) 
 848             if (Prv
.end() == false) 
 850                if (_config
->FindB("Debug::BuildDeps",false) == true) 
 851                   std::cout 
<< "  Is provided by installed package " << Prv
.OwnerPkg().FullName() << std::endl
; 
 852                skipAlternatives 
= hasAlternatives
; 
 856          else // versioned dependency 
 858             pkgCache::VerIterator CV 
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
); 
 859             if (CV
.end() == true || 
 860                   Cache
->VS().CheckDep(CV
.VerStr(),(*D
).Op
,(*D
).Version
.c_str()) == false) 
 864                else if (CV
.end() == false) 
 865                   return _error
->Error(_("%s dependency for %s cannot be satisfied " 
 866                            "because candidate version of package %s " 
 867                            "can't satisfy version requirements"), 
 868                         pkgSrcRecords::Parser::BuildDepType(D
->Type
), Src
.c_str(), 
 871                   return _error
->Error(_("%s dependency for %s cannot be satisfied " 
 872                            "because package %s has no candidate version"), 
 873                         pkgSrcRecords::Parser::BuildDepType(D
->Type
), Src
.c_str(), 
 878          if (TryToInstallBuildDep(Pkg
,Cache
,Fix
,false,false,false) == true) 
 880             // We successfully installed something; skip remaining alternatives 
 881             skipAlternatives 
= hasAlternatives
; 
 882             if(_config
->FindB("APT::Get::Build-Dep-Automatic", false) == true) 
 883                Cache
->MarkAuto(Pkg
, true); 
 886          else if (hasAlternatives
) 
 888             if (_config
->FindB("Debug::BuildDeps",false) == true) 
 889                std::cout 
<< "  Unsatisfiable, trying alternatives\n"; 
 894             return _error
->Error(_("Failed to satisfy %s dependency for %s: %s"), 
 895                   pkgSrcRecords::Parser::BuildDepType(D
->Type
), 
 897                   (*D
).Package
.c_str()); 
 902    if (Fix
.Resolve(true) == false) 
 905    // Now we check the state of the packages, 
 906    if (Cache
->BrokenCount() != 0) 
 908       ShowBroken(std::cout
, Cache
, false); 
 909       return _error
->Error(_("Build-dependencies for %s could not be satisfied."), Src
.c_str()); 
 914 // DoBuildDep - Install/removes packages to satisfy build dependencies  /*{{{*/ 
 915 // --------------------------------------------------------------------- 
 916 /* This function will look at the build depends list of the given source  
 917    package and install the necessary packages to make it true, or fail. */ 
 918 static std::vector
<pkgSrcRecords::Parser::BuildDepRec
> GetBuildDeps(pkgSrcRecords::Parser 
* const Last
, 
 919       char const * const Src
, bool const StripMultiArch
, std::string 
const &hostArch
) 
 921    std::vector
<pkgSrcRecords::Parser::BuildDepRec
> BuildDeps
; 
 922    // FIXME: Can't specify architecture to use for [wildcard] matching, so switch default arch temporary 
 923    if (hostArch
.empty() == false) 
 925       std::string nativeArch 
= _config
->Find("APT::Architecture"); 
 926       _config
->Set("APT::Architecture", hostArch
); 
 927       bool Success 
= Last
->BuildDepends(BuildDeps
, _config
->FindB("APT::Get::Arch-Only", false), StripMultiArch
); 
 928       _config
->Set("APT::Architecture", nativeArch
); 
 929       if (Success 
== false) 
 931          _error
->Error(_("Unable to get build-dependency information for %s"), Src
); 
 935    else if (Last
->BuildDepends(BuildDeps
, _config
->FindB("APT::Get::Arch-Only", false), StripMultiArch
) == false) 
 937       _error
->Error(_("Unable to get build-dependency information for %s"), Src
); 
 941    if (BuildDeps
.empty() == true) 
 942       ioprintf(c1out
,_("%s has no build depends.\n"), Src
); 
 946 bool DoBuildDep(CommandLine 
&CmdL
) 
 949    std::vector
<char const *> VolatileCmdL
; 
 950    Cache
.GetSourceList()->AddVolatileFiles(CmdL
, &VolatileCmdL
); 
 952    _config
->Set("APT::Install-Recommends", false); 
 954    bool WantLock 
= _config
->FindB("APT::Get::Print-URIs", false) == false; 
 956    if (Cache
.Open(WantLock
) == false) 
 959    if (CmdL
.FileSize() <= 1 && VolatileCmdL
.empty()) 
 960       return _error
->Error(_("Must specify at least one package to check builddeps for")); 
 963    std::string hostArch 
= _config
->Find("APT::Get::Host-Architecture"); 
 964    if (hostArch
.empty() == false) 
 966       std::vector
<std::string
> archs 
= APT::Configuration::getArchitectures(); 
 967       if (std::find(archs
.begin(), archs
.end(), hostArch
) == archs
.end()) 
 968          return _error
->Error(_("No architecture information available for %s. See apt.conf(5) APT::Architectures for setup"), hostArch
.c_str()); 
 969       StripMultiArch 
= false; 
 972       StripMultiArch 
= true; 
 974    // deal with the build essentials first 
 976       std::vector
<pkgSrcRecords::Parser::BuildDepRec
> BuildDeps
; 
 978       Configuration::Item 
const *Opts 
= _config
->Tree("APT::Build-Essential"); 
 981       for (; Opts
; Opts 
= Opts
->Next
) 
 983          if (Opts
->Value
.empty() == true) 
 986          pkgSrcRecords::Parser::BuildDepRec rec
; 
 987          rec
.Package 
= Opts
->Value
; 
 988          rec
.Type 
= pkgSrcRecords::Parser::BuildDependIndep
; 
 990          BuildDeps
.push_back(rec
); 
 993       if (InstallBuildDepsLoop(Cache
, "APT::Build-Essential", BuildDeps
, StripMultiArch
, hostArch
) == false) 
 997    // Read the source list 
 998    if (Cache
.BuildSourceList() == false) 
1000    pkgSourceList 
*List 
= Cache
.GetSourceList(); 
1002    // FIXME: Avoid volatile sources == cmdline assumption 
1004       auto const VolatileSources 
= List
->GetVolatileFiles(); 
1005       if (VolatileSources
.size() == VolatileCmdL
.size()) 
1007          for (size_t i 
= 0; i 
< VolatileSources
.size(); ++i
) 
1009             char const * const Src 
= VolatileCmdL
[i
]; 
1010             if (DirectoryExists(Src
)) 
1011                ioprintf(c1out
, _("Note, using directory '%s' to get the build dependencies\n"), Src
); 
1013                ioprintf(c1out
, _("Note, using file '%s' to get the build dependencies\n"), Src
); 
1014             std::unique_ptr
<pkgSrcRecords::Parser
> Last(VolatileSources
[i
]->CreateSrcParser()); 
1015             if (Last 
== nullptr) 
1016                return _error
->Error(_("Unable to find a source package for %s"), Src
); 
1018             auto const BuildDeps 
= GetBuildDeps(Last
.get(), Src
, StripMultiArch
, hostArch
); 
1019             if (InstallBuildDepsLoop(Cache
, Src
, BuildDeps
, StripMultiArch
, hostArch
) == false) 
1024          _error
->Error("Implementation error: Volatile sources (%lu) and commandline elements (%lu) do not match!", VolatileSources
.size(), VolatileCmdL
.size()); 
1027    if (CmdL
.FileList
[1] != 0) 
1029       // Create the text record parsers 
1030       pkgSrcRecords 
SrcRecs(*List
); 
1031       if (_error
->PendingError() == true) 
1033       for (const char **I 
= CmdL
.FileList 
+ 1; *I 
!= 0; ++I
) 
1036          pkgSrcRecords::Parser 
* const Last 
= FindSrc(*I
,SrcRecs
,Src
,Cache
); 
1037          if (Last 
== nullptr) 
1038             return _error
->Error(_("Unable to find a source package for %s"), *I
); 
1040          auto const BuildDeps 
= GetBuildDeps(Last
, Src
.c_str(), StripMultiArch
, hostArch
); 
1041          if (InstallBuildDepsLoop(Cache
, Src
, BuildDeps
, StripMultiArch
, hostArch
) == false) 
1046    if (_error
->PendingError() || InstallPackages(Cache
, false, true) == false) 
1047       return _error
->Error(_("Failed to process build dependencies"));