1 // -*- mode: cpp; mode: fold -*- 
   3 // $Id: apt-get.cc,v 1.156 2004/08/28 01:05:16 mdz Exp $ 
   4 /* ###################################################################### 
   6    apt-get - Cover for dpkg 
   8    This is an allout cover for dpkg implementing a safer front end. It is 
   9    based largely on libapt-pkg. 
  11    The syntax is different,  
  12       apt-get [opt] command [things] 
  14       update - Resyncronize the package files from their sources 
  15       upgrade - Smart-Download the newest versions of all packages 
  16       dselect-upgrade - Follows dselect's changes to the Status: field 
  17                        and installes new and removes old packages 
  18       dist-upgrade - Powerful upgrader designed to handle the issues with 
  20       install - Download and install a given package (by name, not by .deb) 
  21       check - Update the package cache and check for broken packages 
  22       clean - Erase the .debs downloaded to /var/cache/apt/archives and 
  25    ##################################################################### */ 
  27 // Include Files                                                        /*{{{*/ 
  30 #include <apt-pkg/aptconfiguration.h> 
  31 #include <apt-pkg/error.h> 
  32 #include <apt-pkg/cmndline.h> 
  33 #include <apt-pkg/init.h> 
  34 #include <apt-pkg/depcache.h> 
  35 #include <apt-pkg/sourcelist.h> 
  36 #include <apt-pkg/algorithms.h> 
  37 #include <apt-pkg/acquire-item.h> 
  38 #include <apt-pkg/strutl.h> 
  39 #include <apt-pkg/fileutl.h> 
  40 #include <apt-pkg/clean.h> 
  41 #include <apt-pkg/srcrecords.h> 
  42 #include <apt-pkg/version.h> 
  43 #include <apt-pkg/cachefile.h> 
  44 #include <apt-pkg/cacheset.h> 
  45 #include <apt-pkg/sptr.h> 
  46 #include <apt-pkg/md5.h> 
  47 #include <apt-pkg/versionmatch.h> 
  48 #include <apt-pkg/progress.h> 
  49 #include <apt-pkg/pkgsystem.h> 
  50 #include <apt-pkg/pkgrecords.h> 
  51 #include <apt-pkg/indexfile.h> 
  52 #include <apt-pkg/upgrade.h> 
  53 #include <apt-pkg/metaindex.h> 
  54 #include <apt-pkg/indexrecords.h> 
  56 #include <apt-private/private-download.h> 
  57 #include <apt-private/private-install.h> 
  58 #include <apt-private/private-upgrade.h> 
  59 #include <apt-private/private-output.h> 
  60 #include <apt-private/private-cacheset.h> 
  61 #include <apt-private/private-update.h> 
  62 #include <apt-private/private-cmndline.h> 
  63 #include <apt-private/private-moo.h> 
  64 #include <apt-private/private-utils.h> 
  66 #include <apt-pkg/debmetaindex.h> 
  68 #include <apt-private/acqprogress.h> 
  77 #include <sys/ioctl.h> 
  79 #include <sys/statfs.h> 
  80 #include <sys/statvfs.h> 
  88 #include <apt-private/private-output.h> 
  89 #include <apt-private/private-main.h> 
  96 // TryToInstallBuildDep - Try to install a single package               /*{{{*/ 
  97 // --------------------------------------------------------------------- 
  98 /* This used to be inlined in DoInstall, but with the advent of regex package 
  99    name matching it was split out.. */ 
 100 bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg
,pkgCacheFile 
&Cache
, 
 101                   pkgProblemResolver 
&Fix
,bool Remove
,bool BrokenFix
, 
 102                   bool AllowFail 
= true) 
 104    if (Cache
[Pkg
].CandidateVer 
== 0 && Pkg
->ProvidesList 
!= 0) 
 106       CacheSetHelperAPTGet 
helper(c1out
); 
 107       helper
.showErrors(false); 
 108       pkgCache::VerIterator Ver 
= helper
.canNotFindNewestVer(Cache
, Pkg
); 
 109       if (Ver
.end() == false) 
 110          Pkg 
= Ver
.ParentPkg(); 
 111       else if (helper
.showVirtualPackageErrors(Cache
) == false) 
 115    if (_config
->FindB("Debug::BuildDeps",false) == true) 
 118          cout 
<< "  Trying to remove " << Pkg 
<< endl
; 
 120          cout 
<< "  Trying to install " << Pkg 
<< endl
; 
 125       TryToRemove 
RemoveAction(Cache
, &Fix
); 
 126       RemoveAction(Pkg
.VersionList()); 
 127    } else if (Cache
[Pkg
].CandidateVer 
!= 0) { 
 128       TryToInstall 
InstallAction(Cache
, &Fix
, BrokenFix
); 
 129       InstallAction(Cache
[Pkg
].CandidateVerIter(Cache
)); 
 130       InstallAction
.doAutoInstall(); 
 139 // helper that can go wit hthe next ABI break 
 140 #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) 
 141 std::string 
MetaIndexFileNameOnDisk(metaIndex 
*metaindex
) 
 143    // FIXME: this cast is the horror, the horror 
 144    debReleaseIndex 
*r 
= (debReleaseIndex
*)metaindex
; 
 146    // see if we have a InRelease file 
 147    std::string PathInRelease 
=  r
->MetaIndexFile("InRelease"); 
 148    if (FileExists(PathInRelease
)) 
 149       return PathInRelease
; 
 151    // and if not return the normal one 
 152    if (FileExists(PathInRelease
)) 
 153       return r
->MetaIndexFile("Release"); 
 159 // GetReleaseForSourceRecord - Return Suite for the given srcrecord     /*{{{*/ 
 160 // --------------------------------------------------------------------- 
 162 std::string 
GetReleaseForSourceRecord(pkgSourceList 
*SrcList
, 
 163                                       pkgSrcRecords::Parser 
*Parse
) 
 165    // try to find release 
 166    const pkgIndexFile
& CurrentIndexFile 
= Parse
->Index(); 
 168    for (pkgSourceList::const_iterator S 
= SrcList
->begin();  
 169         S 
!= SrcList
->end(); ++S
) 
 171       vector
<pkgIndexFile 
*> *Indexes 
= (*S
)->GetIndexFiles(); 
 172       for (vector
<pkgIndexFile 
*>::const_iterator IF 
= Indexes
->begin(); 
 173            IF 
!= Indexes
->end(); ++IF
) 
 175          if (&CurrentIndexFile 
== (*IF
)) 
 177 #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) 
 178             std::string path 
= MetaIndexFileNameOnDisk(*S
); 
 180             std::string path 
= (*S
)->LocalFileName(); 
 184                indexRecords records
; 
 186                return records
.GetSuite(); 
 194 // FindSrc - Find a source record                                       /*{{{*/ 
 195 // --------------------------------------------------------------------- 
 197 pkgSrcRecords::Parser 
*FindSrc(const char *Name
,pkgRecords 
&Recs
, 
 198                                pkgSrcRecords 
&SrcRecs
,string 
&Src
, 
 199                                CacheFile 
&CacheFile
) 
 201    string VerTag
, UserRequestedVerTag
; 
 203    string RelTag 
= _config
->Find("APT::Default-Release"); 
 204    string TmpSrc 
= Name
; 
 205    pkgDepCache 
*Cache 
= CacheFile
.GetDepCache(); 
 208    size_t found 
= TmpSrc
.find_last_of("/"); 
 209    if (found 
!= string::npos
)  
 211       RelTag 
= TmpSrc
.substr(found
+1); 
 212       TmpSrc 
= TmpSrc
.substr(0,found
); 
 214    // extract the version 
 215    found 
= TmpSrc
.find_last_of("="); 
 216    if (found 
!= string::npos
)  
 218       VerTag 
= UserRequestedVerTag 
= TmpSrc
.substr(found
+1); 
 219       TmpSrc 
= TmpSrc
.substr(0,found
); 
 222    found 
= TmpSrc
.find_last_of(":"); 
 223    if (found 
!= string::npos
)  
 225       ArchTag 
= TmpSrc
.substr(found
+1); 
 226       TmpSrc 
= TmpSrc
.substr(0,found
); 
 229    /* Lookup the version of the package we would install if we were to 
 230       install a version and determine the source package name, then look 
 231       in the archive for a source package of the same name. */ 
 232    bool MatchSrcOnly 
= _config
->FindB("APT::Get::Only-Source"); 
 233    pkgCache::PkgIterator Pkg
; 
 235       Pkg 
= Cache
->FindPkg(TmpSrc
, ArchTag
); 
 237       Pkg 
= Cache
->FindPkg(TmpSrc
); 
 239    // if we can't find a package but the user qualified with a arch, 
 241    if (Pkg
.end() && ArchTag 
!= "") 
 244       _error
->Error(_("Can not find a package for architecture '%s'"), 
 249    if (MatchSrcOnly 
== false && Pkg
.end() == false)  
 251       if(VerTag 
!= "" || RelTag 
!= "" || ArchTag 
!= "") 
 254          // we have a default release, try to locate the pkg. we do it like 
 255          // this because GetCandidateVer() will not "downgrade", that means 
 256          // "apt-get source -t stable apt" won't work on a unstable system 
 257          for (pkgCache::VerIterator Ver 
= Pkg
.VersionList();; ++Ver
) 
 259             // try first only exact matches, later fuzzy matches 
 260             if (Ver
.end() == true) 
 265                Ver 
= Pkg
.VersionList(); 
 266                // exit right away from the Pkg.VersionList() loop if we 
 267                // don't have any versions 
 268                if (Ver
.end() == true) 
 272             // ignore arches that are not for us 
 273             if (ArchTag 
!= "" && Ver
.Arch() != ArchTag
) 
 276             // pick highest version for the arch unless the user wants 
 278             if (ArchTag 
!= "" && VerTag 
== "" && RelTag 
== "") 
 279                if(Cache
->VS().CmpVersion(VerTag
, Ver
.VerStr()) < 0) 
 280                   VerTag 
= Ver
.VerStr(); 
 282             // We match against a concrete version (or a part of this version) 
 283             if (VerTag
.empty() == false && 
 284                 (fuzzy 
== true || Cache
->VS().CmpVersion(VerTag
, Ver
.VerStr()) != 0) && // exact match 
 285                 (fuzzy 
== false || strncmp(VerTag
.c_str(), Ver
.VerStr(), VerTag
.size()) != 0)) // fuzzy match 
 288             for (pkgCache::VerFileIterator VF 
= Ver
.FileList(); 
 289                  VF
.end() == false; ++VF
) 
 291                /* If this is the status file, and the current version is not the 
 292                   version in the status file (ie it is not installed, or somesuch) 
 293                   then it is not a candidate for installation, ever. This weeds 
 294                   out bogus entries that may be due to config-file states, or 
 296                if ((VF
.File()->Flags 
& pkgCache::Flag::NotSource
) == 
 297                    pkgCache::Flag::NotSource 
&& Pkg
.CurrentVer() != Ver
) 
 300                // or we match against a release 
 301                if(VerTag
.empty() == false || 
 302                   (VF
.File().Archive() != 0 && VF
.File().Archive() == RelTag
) || 
 303                   (VF
.File().Codename() != 0 && VF
.File().Codename() == RelTag
))  
 305                   pkgRecords::Parser 
&Parse 
= Recs
.Lookup(VF
); 
 306                   Src 
= Parse
.SourcePkg(); 
 307                   // no SourcePkg name, so it is the "binary" name 
 308                   if (Src
.empty() == true) 
 310                   // the Version we have is possibly fuzzy or includes binUploads, 
 311                   // so we use the Version of the SourcePkg (empty if same as package) 
 312                   VerTag 
= Parse
.SourceVer(); 
 313                   if (VerTag
.empty() == true) 
 314                      VerTag 
= Ver
.VerStr(); 
 318             if (Src
.empty() == false) 
 323       if (Src 
== "" && ArchTag 
!= "") 
 326             _error
->Error(_("Can not find a package '%s' with version '%s'"), 
 327                           Pkg
.FullName().c_str(), VerTag
.c_str()); 
 329             _error
->Error(_("Can not find a package '%s' with release '%s'"), 
 330                           Pkg
.FullName().c_str(), RelTag
.c_str()); 
 336       if (Src
.empty() == true) 
 338          // if we don't have found a fitting package yet so we will 
 339          // choose a good candidate and proceed with that. 
 340          // Maybe we will find a source later on with the right VerTag 
 342          pkgCache::VerIterator Ver 
= Cache
->GetCandidateVer(Pkg
); 
 343          if (Ver
.end() == false)  
 345             pkgRecords::Parser 
&Parse 
= Recs
.Lookup(Ver
.FileList()); 
 346             Src 
= Parse
.SourcePkg(); 
 347             if (VerTag
.empty() == true) 
 348                VerTag 
= Parse
.SourceVer(); 
 353    if (Src
.empty() == true) 
 359       /* if we have a source pkg name, make sure to only search 
 360          for srcpkg names, otherwise apt gets confused if there 
 361          is a binary package "pkg1" and a source package "pkg1" 
 362          with the same name but that comes from different packages */ 
 366          ioprintf(c1out
, _("Picking '%s' as source package instead of '%s'\n"), Src
.c_str(), TmpSrc
.c_str()); 
 371    pkgSrcRecords::Parser 
*Last 
= 0; 
 372    unsigned long Offset 
= 0; 
 374    pkgSourceList 
*SrcList 
= CacheFile
.GetSourceList(); 
 376    /* Iterate over all of the hits, which includes the resulting 
 377       binary packages in the search */ 
 378    pkgSrcRecords::Parser 
*Parse
; 
 382       while ((Parse 
= SrcRecs
.Find(Src
.c_str(), MatchSrcOnly
)) != 0)  
 384          const string Ver 
= Parse
->Version(); 
 386          // See if we need to look for a specific release tag 
 387          if (RelTag 
!= "" && UserRequestedVerTag 
== "") 
 389             const string Rel 
= GetReleaseForSourceRecord(SrcList
, Parse
); 
 394                Offset 
= Parse
->Offset(); 
 399          // Ignore all versions which doesn't fit 
 400          if (VerTag
.empty() == false && 
 401              Cache
->VS().CmpVersion(VerTag
, Ver
) != 0) // exact match 
 404          // Newer version or an exact match? Save the hit 
 405          if (Last 
== 0 || Cache
->VS().CmpVersion(Version
,Ver
) < 0) { 
 407             Offset 
= Parse
->Offset(); 
 411          // was the version check above an exact match? 
 412          // If so, we don't need to look further 
 413          if (VerTag
.empty() == false && (VerTag 
== Ver
)) 
 416       if (UserRequestedVerTag 
== "" && Version 
!= "" && RelTag 
!= "") 
 417          ioprintf(c1out
, "Selected version '%s' (%s) for %s\n",  
 418                   Version
.c_str(), RelTag
.c_str(), Src
.c_str()); 
 420       if (Last 
!= 0 || VerTag
.empty() == true) 
 422       _error
->Error(_("Can not find version '%s' of package '%s'"), VerTag
.c_str(), TmpSrc
.c_str()); 
 426    if (Last 
== 0 || Last
->Jump(Offset
) == false) 
 432 /* mark packages as automatically/manually installed.                   {{{*/ 
 433 bool DoMarkAuto(CommandLine 
&CmdL
) 
 436    int AutoMarkChanged 
= 0; 
 437    OpTextProgress progress
; 
 439    if (Cache
.Open() == false) 
 442    if (strcasecmp(CmdL
.FileList
[0],"markauto") == 0) 
 444    else if (strcasecmp(CmdL
.FileList
[0],"unmarkauto") == 0) 
 447    for (const char **I 
= CmdL
.FileList 
+ 1; *I 
!= 0; I
++) 
 450       // Locate the package 
 451       pkgCache::PkgIterator Pkg 
= Cache
->FindPkg(S
); 
 452       if (Pkg
.end() == true) { 
 453          return _error
->Error(_("Couldn't find package %s"),S
); 
 458             ioprintf(c1out
,_("%s set to manually installed.\n"), Pkg
.Name()); 
 460             ioprintf(c1out
,_("%s set to automatically installed.\n"), 
 463          Cache
->MarkAuto(Pkg
,Action
); 
 468    _error
->Notice(_("This command is deprecated. Please use 'apt-mark auto' and 'apt-mark manual' instead.")); 
 470    if (AutoMarkChanged 
&& ! _config
->FindB("APT::Get::Simulate",false)) 
 471       return Cache
->writeStateFile(NULL
); 
 475 // DoDSelectUpgrade - Do an upgrade by following dselects selections    /*{{{*/ 
 476 // --------------------------------------------------------------------- 
 477 /* Follows dselect's selections */ 
 478 bool DoDSelectUpgrade(CommandLine 
&CmdL
) 
 481    if (Cache
.OpenForInstall() == false || Cache
.CheckDeps() == false) 
 484    pkgDepCache::ActionGroup 
group(Cache
); 
 486    // Install everything with the install flag set 
 487    pkgCache::PkgIterator I 
= Cache
->PkgBegin(); 
 488    for (;I
.end() != true; ++I
) 
 490       /* Install the package only if it is a new install, the autoupgrader 
 491          will deal with the rest */ 
 492       if (I
->SelectedState 
== pkgCache::State::Install
) 
 493          Cache
->MarkInstall(I
,false); 
 496    /* Now install their deps too, if we do this above then order of 
 497       the status file is significant for | groups */ 
 498    for (I 
= Cache
->PkgBegin();I
.end() != true; ++I
) 
 500       /* Install the package only if it is a new install, the autoupgrader 
 501          will deal with the rest */ 
 502       if (I
->SelectedState 
== pkgCache::State::Install
) 
 503          Cache
->MarkInstall(I
,true); 
 506    // Apply erasures now, they override everything else. 
 507    for (I 
= Cache
->PkgBegin();I
.end() != true; ++I
) 
 510       if (I
->SelectedState 
== pkgCache::State::DeInstall 
|| 
 511           I
->SelectedState 
== pkgCache::State::Purge
) 
 512          Cache
->MarkDelete(I
,I
->SelectedState 
== pkgCache::State::Purge
); 
 515    /* Resolve any problems that dselect created, allupgrade cannot handle 
 516       such things. We do so quite aggressively too.. */ 
 517    if (Cache
->BrokenCount() != 0) 
 519       pkgProblemResolver 
Fix(Cache
); 
 521       // Hold back held packages. 
 522       if (_config
->FindB("APT::Ignore-Hold",false) == false) 
 524          for (pkgCache::PkgIterator I 
= Cache
->PkgBegin(); I
.end() == false; ++I
) 
 526             if (I
->SelectedState 
== pkgCache::State::Hold
) 
 534       if (Fix
.Resolve() == false) 
 536          ShowBroken(c1out
,Cache
,false); 
 537          return _error
->Error(_("Internal error, problem resolver broke stuff")); 
 541    // Now upgrade everything 
 542    if (pkgAllUpgrade(Cache
) == false) 
 544       ShowBroken(c1out
,Cache
,false); 
 545       return _error
->Error(_("Internal error, problem resolver broke stuff")); 
 548    return InstallPackages(Cache
,false); 
 551 // DoClean - Remove download archives                                   /*{{{*/ 
 552 // --------------------------------------------------------------------- 
 554 bool DoClean(CommandLine 
&CmdL
) 
 556    std::string 
const archivedir 
= _config
->FindDir("Dir::Cache::archives"); 
 557    std::string 
const pkgcache 
= _config
->FindFile("Dir::cache::pkgcache"); 
 558    std::string 
const srcpkgcache 
= _config
->FindFile("Dir::cache::srcpkgcache"); 
 560    if (_config
->FindB("APT::Get::Simulate") == true) 
 562       cout 
<< "Del " << archivedir 
<< "* " << archivedir 
<< "partial/*"<< endl
 
 563            << "Del " << pkgcache 
<< " " << srcpkgcache 
<< endl
; 
 567    // Lock the archive directory 
 569    if (_config
->FindB("Debug::NoLocking",false) == false) 
 571       int lock_fd 
= GetLock(archivedir 
+ "lock"); 
 573          return _error
->Error(_("Unable to lock the download directory")); 
 578    Fetcher
.Clean(archivedir
); 
 579    Fetcher
.Clean(archivedir 
+ "partial/"); 
 581    pkgCacheFile::RemoveCaches(); 
 586 // DoAutoClean - Smartly remove downloaded archives                     /*{{{*/ 
 587 // --------------------------------------------------------------------- 
 588 /* This is similar to clean but it only purges things that cannot be  
 589    downloaded, that is old versions of cached packages. */ 
 590 class LogCleaner 
: public pkgArchiveCleaner
 
 593    virtual void Erase(const char *File
,string Pkg
,string Ver
,struct stat 
&St
)  
 595       c1out 
<< "Del " << Pkg 
<< " " << Ver 
<< " [" << SizeToStr(St
.st_size
) << "B]" << endl
; 
 597       if (_config
->FindB("APT::Get::Simulate") == false) 
 602 bool DoAutoClean(CommandLine 
&CmdL
) 
 604    // Lock the archive directory 
 606    if (_config
->FindB("Debug::NoLocking",false) == false) 
 608       int lock_fd 
= GetLock(_config
->FindDir("Dir::Cache::Archives") + "lock"); 
 610          return _error
->Error(_("Unable to lock the download directory")); 
 615    if (Cache
.Open() == false) 
 620    return Cleaner
.Go(_config
->FindDir("Dir::Cache::archives"),*Cache
) && 
 621       Cleaner
.Go(_config
->FindDir("Dir::Cache::archives") + "partial/",*Cache
); 
 624 // DoDownload - download a binary                                       /*{{{*/ 
 625 // --------------------------------------------------------------------- 
 626 bool DoDownload(CommandLine 
&CmdL
) 
 629    if (Cache
.ReadOnlyOpen() == false) 
 632    APT::CacheSetHelper 
helper(c0out
); 
 633    APT::VersionSet verset 
= APT::VersionSet::FromCommandLine(Cache
, 
 634                 CmdL
.FileList 
+ 1, APT::VersionSet::CANDIDATE
, helper
); 
 636    if (verset
.empty() == true) 
 639    AcqTextStatus 
Stat(ScreenWidth
, _config
->FindI("quiet", 0)); 
 641    if (Fetcher
.Setup(&Stat
) == false) 
 644    pkgRecords 
Recs(Cache
); 
 645    pkgSourceList 
*SrcList 
= Cache
.GetSourceList(); 
 647    // reuse the usual acquire methods for deb files, but don't drop them into 
 648    // the usual directories - keep everything in the current directory 
 649    std::vector
<std::string
> storefile(verset
.size()); 
 650    std::string 
const cwd 
= SafeGetCWD(); 
 651    _config
->Set("Dir::Cache::Archives", cwd
); 
 653    for (APT::VersionSet::const_iterator Ver 
= verset
.begin(); 
 654          Ver 
!= verset
.end(); ++Ver
, ++i
) 
 656       pkgAcquire::Item 
*I 
= new pkgAcqArchive(&Fetcher
, SrcList
, &Recs
, *Ver
, storefile
[i
]); 
 657       std::string 
const filename 
= cwd 
+ flNotDir(storefile
[i
]); 
 658       storefile
[i
].assign(filename
); 
 659       I
->DestFile
.assign(filename
); 
 662    // Just print out the uris and exit if the --print-uris flag was used 
 663    if (_config
->FindB("APT::Get::Print-URIs") == true) 
 665       pkgAcquire::UriIterator I 
= Fetcher
.UriBegin(); 
 666       for (; I 
!= Fetcher
.UriEnd(); ++I
) 
 667          cout 
<< '\'' << I
->URI 
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' << 
 668                I
->Owner
->FileSize 
<< ' ' << I
->Owner
->HashSum() << endl
; 
 672    if (_error
->PendingError() == true || CheckAuth(Fetcher
, false) == false) 
 676    if (AcquireRun(Fetcher
, 0, &Failed
, NULL
) == false) 
 679    // copy files in local sources to the current directory 
 680    for (pkgAcquire::ItemIterator I 
= Fetcher
.ItemsBegin(); I 
!= Fetcher
.ItemsEnd(); ++I
) 
 682       std::string 
const filename 
= cwd 
+ flNotDir((*I
)->DestFile
); 
 683       if ((*I
)->Local 
== true && 
 684           filename 
!= (*I
)->DestFile 
&& 
 685           (*I
)->Status 
== pkgAcquire::Item::StatDone
) 
 687          std::ifstream 
src((*I
)->DestFile
.c_str(), std::ios::binary
); 
 688          std::ofstream 
dst(filename
.c_str(), std::ios::binary
); 
 692    return Failed 
== false; 
 695 // DoCheck - Perform the check operation                                /*{{{*/ 
 696 // --------------------------------------------------------------------- 
 697 /* Opening automatically checks the system, this command is mostly used 
 699 bool DoCheck(CommandLine 
&CmdL
) 
 708 // DoSource - Fetch a source archive                                    /*{{{*/ 
 709 // --------------------------------------------------------------------- 
 710 /* Fetch souce packages */ 
 718 bool DoSource(CommandLine 
&CmdL
) 
 721    if (Cache
.Open(false) == false) 
 724    if (CmdL
.FileSize() <= 1) 
 725       return _error
->Error(_("Must specify at least one package to fetch source for")); 
 727    // Read the source list 
 728    if (Cache
.BuildSourceList() == false) 
 730    pkgSourceList 
*List 
= Cache
.GetSourceList(); 
 732    // Create the text record parsers 
 733    pkgRecords 
Recs(Cache
); 
 734    pkgSrcRecords 
SrcRecs(*List
); 
 735    if (_error
->PendingError() == true) 
 738    // Create the download object 
 739    AcqTextStatus 
Stat(ScreenWidth
,_config
->FindI("quiet",0));    
 741    Fetcher
.SetLog(&Stat
); 
 743    DscFile 
*Dsc 
= new DscFile
[CmdL
.FileSize()]; 
 745    // insert all downloaded uris into this set to avoid downloading them 
 749    // Diff only mode only fetches .diff files 
 750    bool const diffOnly 
= _config
->FindB("APT::Get::Diff-Only", false); 
 751    // Tar only mode only fetches .tar files 
 752    bool const tarOnly 
= _config
->FindB("APT::Get::Tar-Only", false); 
 753    // Dsc only mode only fetches .dsc files 
 754    bool const dscOnly 
= _config
->FindB("APT::Get::Dsc-Only", false); 
 756    // Load the requestd sources into the fetcher 
 758    for (const char **I 
= CmdL
.FileList 
+ 1; *I 
!= 0; I
++, J
++) 
 761       pkgSrcRecords::Parser 
*Last 
= FindSrc(*I
,Recs
,SrcRecs
,Src
,Cache
); 
 765          return _error
->Error(_("Unable to find a source package for %s"),Src
.c_str()); 
 768       string srec 
= Last
->AsStr(); 
 769       string::size_type pos 
= srec
.find("\nVcs-"); 
 770       while (pos 
!= string::npos
) 
 772          pos 
+= strlen("\nVcs-"); 
 773          string vcs 
= srec
.substr(pos
,srec
.find(":",pos
)-pos
); 
 776             pos 
= srec
.find("\nVcs-", pos
); 
 779          pos 
+= vcs
.length()+2; 
 780          string::size_type epos 
= srec
.find("\n", pos
); 
 781          string uri 
= srec
.substr(pos
,epos
-pos
).c_str(); 
 782          ioprintf(c1out
, _("NOTICE: '%s' packaging is maintained in " 
 783                            "the '%s' version control system at:\n" 
 785                   Src
.c_str(), vcs
.c_str(), uri
.c_str()); 
 787             ioprintf(c1out
,_("Please use:\n" 
 789                              "to retrieve the latest (possibly unreleased) " 
 790                              "updates to the package.\n"), 
 796       vector
<pkgSrcRecords::File
> Lst
; 
 797       if (Last
->Files(Lst
) == false) { 
 802       // Load them into the fetcher 
 803       for (vector
<pkgSrcRecords::File
>::const_iterator I 
= Lst
.begin(); 
 806          // Try to guess what sort of file it is we are getting. 
 807          if (I
->Type 
== "dsc") 
 809             Dsc
[J
].Package 
= Last
->Package(); 
 810             Dsc
[J
].Version 
= Last
->Version(); 
 811             Dsc
[J
].Dsc 
= flNotDir(I
->Path
); 
 814          // Handle the only options so that multiple can be used at once 
 815          if (diffOnly 
== true || tarOnly 
== true || dscOnly 
== true) 
 817             if ((diffOnly 
== true && I
->Type 
== "diff") || 
 818                 (tarOnly 
== true && I
->Type 
== "tar") || 
 819                 (dscOnly 
== true && I
->Type 
== "dsc")) 
 820                 ; // Fine, we want this file downloaded 
 825          // don't download the same uri twice (should this be moved to 
 826          // the fetcher interface itself?) 
 827          if(queued
.find(Last
->Index().ArchiveURI(I
->Path
)) != queued
.end()) 
 829          queued
.insert(Last
->Index().ArchiveURI(I
->Path
)); 
 831          // check if we have a file with that md5 sum already localy 
 832          if(!I
->MD5Hash
.empty() && FileExists(flNotDir(I
->Path
)))   
 834             FileFd 
Fd(flNotDir(I
->Path
), FileFd::ReadOnly
); 
 836             sum
.AddFD(Fd
.Fd(), Fd
.Size()); 
 838             if((string
)sum
.Result() == I
->MD5Hash
)  
 840                ioprintf(c1out
,_("Skipping already downloaded file '%s'\n"), 
 841                         flNotDir(I
->Path
).c_str()); 
 846          new pkgAcqFile(&Fetcher
,Last
->Index().ArchiveURI(I
->Path
), 
 848                         Last
->Index().SourceInfo(*Last
,*I
),Src
); 
 852    // Display statistics 
 853    unsigned long long FetchBytes 
= Fetcher
.FetchNeeded(); 
 854    unsigned long long FetchPBytes 
= Fetcher
.PartialPresent(); 
 855    unsigned long long DebBytes 
= Fetcher
.TotalNeeded(); 
 857    // Check for enough free space 
 859    string OutputDir 
= "."; 
 860    if (statvfs(OutputDir
.c_str(),&Buf
) != 0) { 
 862       if (errno 
== EOVERFLOW
) 
 863          return _error
->WarningE("statvfs",_("Couldn't determine free space in %s"), 
 866          return _error
->Errno("statvfs",_("Couldn't determine free space in %s"), 
 868    } else if (unsigned(Buf
.f_bfree
) < (FetchBytes 
- FetchPBytes
)/Buf
.f_bsize
) 
 871        if (statfs(OutputDir
.c_str(),&Stat
) != 0 
 872 #if HAVE_STRUCT_STATFS_F_TYPE 
 873            || unsigned(Stat
.f_type
) != RAMFS_MAGIC
 
 877           return _error
->Error(_("You don't have enough free space in %s"), 
 883    if (DebBytes 
!= FetchBytes
) 
 884       //TRANSLATOR: The required space between number and unit is already included 
 885       // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB 
 886       ioprintf(c1out
,_("Need to get %sB/%sB of source archives.\n"), 
 887                SizeToStr(FetchBytes
).c_str(),SizeToStr(DebBytes
).c_str()); 
 889       //TRANSLATOR: The required space between number and unit is already included 
 890       // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB 
 891       ioprintf(c1out
,_("Need to get %sB of source archives.\n"), 
 892                SizeToStr(DebBytes
).c_str()); 
 894    if (_config
->FindB("APT::Get::Simulate",false) == true) 
 896       for (unsigned I 
= 0; I 
!= J
; I
++) 
 897          ioprintf(cout
,_("Fetch source %s\n"),Dsc
[I
].Package
.c_str()); 
 902    // Just print out the uris an exit if the --print-uris flag was used 
 903    if (_config
->FindB("APT::Get::Print-URIs") == true) 
 905       pkgAcquire::UriIterator I 
= Fetcher
.UriBegin(); 
 906       for (; I 
!= Fetcher
.UriEnd(); ++I
) 
 907          cout 
<< '\'' << I
->URI 
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<  
 908                I
->Owner
->FileSize 
<< ' ' << I
->Owner
->HashSum() << endl
; 
 915    if (AcquireRun(Fetcher
, 0, &Failed
, NULL
) == false || Failed 
== true) 
 918       return _error
->Error(_("Failed to fetch some archives.")); 
 921    if (_config
->FindB("APT::Get::Download-only",false) == true) 
 923       c1out 
<< _("Download complete and in download only mode") << endl
; 
 928    // Unpack the sources 
 929    pid_t Process 
= ExecFork(); 
 933       bool const fixBroken 
= _config
->FindB("APT::Get::Fix-Broken", false); 
 934       for (unsigned I 
= 0; I 
!= J
; ++I
) 
 936          string Dir 
= Dsc
[I
].Package 
+ '-' + Cache
->VS().UpstreamVersion(Dsc
[I
].Version
.c_str()); 
 938          // Diff only mode only fetches .diff files 
 939          if (_config
->FindB("APT::Get::Diff-Only",false) == true || 
 940              _config
->FindB("APT::Get::Tar-Only",false) == true || 
 941              Dsc
[I
].Dsc
.empty() == true) 
 944          // See if the package is already unpacked 
 946          if (fixBroken 
== false && stat(Dir
.c_str(),&Stat
) == 0 && 
 947              S_ISDIR(Stat
.st_mode
) != 0) 
 949             ioprintf(c0out 
,_("Skipping unpack of already unpacked source in %s\n"), 
 956             snprintf(S
,sizeof(S
),"%s -x %s", 
 957                      _config
->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(), 
 961                fprintf(stderr
,_("Unpack command '%s' failed.\n"),S
); 
 962                fprintf(stderr
,_("Check if the 'dpkg-dev' package is installed.\n")); 
 967          // Try to compile it with dpkg-buildpackage 
 968          if (_config
->FindB("APT::Get::Compile",false) == true) 
 970             string buildopts 
= _config
->Find("APT::Get::Host-Architecture"); 
 971             if (buildopts
.empty() == false) 
 972                buildopts 
= "-a" + buildopts 
+ " "; 
 974             // get all active build profiles 
 975             std::string 
const profiles 
= APT::Configuration::getBuildProfilesString(); 
 976             if (profiles
.empty() == false) 
 977                buildopts
.append(" -P").append(profiles
).append(" "); 
 979             buildopts
.append(_config
->Find("DPkg::Build-Options","-b -uc")); 
 981             // Call dpkg-buildpackage 
 983             snprintf(S
,sizeof(S
),"cd %s && %s %s", 
 985                      _config
->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(), 
 990                fprintf(stderr
,_("Build command '%s' failed.\n"),S
); 
1000    // Wait for the subprocess 
1002    while (waitpid(Process
,&Status
,0) != Process
) 
1006       return _error
->Errno("waitpid","Couldn't wait for subprocess"); 
1009    if (WIFEXITED(Status
) == 0 || WEXITSTATUS(Status
) != 0) 
1010       return _error
->Error(_("Child process failed")); 
1015 // DoBuildDep - Install/removes packages to satisfy build dependencies  /*{{{*/ 
1016 // --------------------------------------------------------------------- 
1017 /* This function will look at the build depends list of the given source  
1018    package and install the necessary packages to make it true, or fail. */ 
1019 bool DoBuildDep(CommandLine 
&CmdL
) 
1023    _config
->Set("APT::Install-Recommends", false); 
1025    if (Cache
.Open(true) == false) 
1028    if (CmdL
.FileSize() <= 1) 
1029       return _error
->Error(_("Must specify at least one package to check builddeps for")); 
1031    // Read the source list 
1032    if (Cache
.BuildSourceList() == false) 
1034    pkgSourceList 
*List 
= Cache
.GetSourceList(); 
1036    // Create the text record parsers 
1037    pkgRecords 
Recs(Cache
); 
1038    pkgSrcRecords 
SrcRecs(*List
); 
1039    if (_error
->PendingError() == true) 
1042    // Create the download object 
1043    AcqTextStatus 
Stat(ScreenWidth
,_config
->FindI("quiet",0));    
1045    if (Fetcher
.Setup(&Stat
) == false) 
1048    bool StripMultiArch
; 
1049    string hostArch 
= _config
->Find("APT::Get::Host-Architecture"); 
1050    if (hostArch
.empty() == false) 
1052       std::vector
<std::string
> archs 
= APT::Configuration::getArchitectures(); 
1053       if (std::find(archs
.begin(), archs
.end(), hostArch
) == archs
.end()) 
1054          return _error
->Error(_("No architecture information available for %s. See apt.conf(5) APT::Architectures for setup"), hostArch
.c_str()); 
1055       StripMultiArch 
= false; 
1058       StripMultiArch 
= true; 
1061    for (const char **I 
= CmdL
.FileList 
+ 1; *I 
!= 0; I
++, J
++) 
1064       pkgSrcRecords::Parser 
*Last 
= FindSrc(*I
,Recs
,SrcRecs
,Src
,Cache
); 
1066          return _error
->Error(_("Unable to find a source package for %s"),Src
.c_str()); 
1068       // Process the build-dependencies 
1069       vector
<pkgSrcRecords::Parser::BuildDepRec
> BuildDeps
; 
1070       // FIXME: Can't specify architecture to use for [wildcard] matching, so switch default arch temporary 
1071       if (hostArch
.empty() == false) 
1073          std::string nativeArch 
= _config
->Find("APT::Architecture"); 
1074          _config
->Set("APT::Architecture", hostArch
); 
1075          bool Success 
= Last
->BuildDepends(BuildDeps
, _config
->FindB("APT::Get::Arch-Only", false), StripMultiArch
); 
1076          _config
->Set("APT::Architecture", nativeArch
); 
1077          if (Success 
== false) 
1078             return _error
->Error(_("Unable to get build-dependency information for %s"),Src
.c_str()); 
1080       else if (Last
->BuildDepends(BuildDeps
, _config
->FindB("APT::Get::Arch-Only", false), StripMultiArch
) == false) 
1081             return _error
->Error(_("Unable to get build-dependency information for %s"),Src
.c_str()); 
1083       // Also ensure that build-essential packages are present 
1084       Configuration::Item 
const *Opts 
= _config
->Tree("APT::Build-Essential"); 
1087       for (; Opts
; Opts 
= Opts
->Next
) 
1089          if (Opts
->Value
.empty() == true) 
1092          pkgSrcRecords::Parser::BuildDepRec rec
; 
1093          rec
.Package 
= Opts
->Value
; 
1094          rec
.Type 
= pkgSrcRecords::Parser::BuildDependIndep
; 
1096          BuildDeps
.push_back(rec
); 
1099       if (BuildDeps
.empty() == true) 
1101          ioprintf(c1out
,_("%s has no build depends.\n"),Src
.c_str()); 
1105       // Install the requested packages 
1106       vector 
<pkgSrcRecords::Parser::BuildDepRec
>::iterator D
; 
1107       pkgProblemResolver 
Fix(Cache
); 
1108       bool skipAlternatives 
= false; // skip remaining alternatives in an or group 
1109       for (D 
= BuildDeps
.begin(); D 
!= BuildDeps
.end(); ++D
) 
1111          bool hasAlternatives 
= (((*D
).Op 
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
); 
1113          if (skipAlternatives 
== true) 
1116              * if there are alternatives, we've already picked one, so skip 
1119              * TODO: this means that if there's a build-dep on A|B and B is 
1120              * installed, we'll still try to install A; more importantly, 
1121              * if A is currently broken, we cannot go back and try B. To fix  
1122              * this would require we do a Resolve cycle for each package we  
1123              * add to the install list. Ugh 
1125             if (!hasAlternatives
) 
1126                skipAlternatives 
= false; // end of or group 
1130          if ((*D
).Type 
== pkgSrcRecords::Parser::BuildConflict 
|| 
1131              (*D
).Type 
== pkgSrcRecords::Parser::BuildConflictIndep
) 
1133             pkgCache::GrpIterator Grp 
= Cache
->FindGrp((*D
).Package
); 
1134             // Build-conflicts on unknown packages are silently ignored 
1135             if (Grp
.end() == true) 
1138             for (pkgCache::PkgIterator Pkg 
= Grp
.PackageList(); Pkg
.end() == false; Pkg 
= Grp
.NextPkg(Pkg
)) 
1140                pkgCache::VerIterator IV 
= (*Cache
)[Pkg
].InstVerIter(*Cache
); 
1142                 * Remove if we have an installed version that satisfies the 
1145                if (IV
.end() == false && 
1146                    Cache
->VS().CheckDep(IV
.VerStr(),(*D
).Op
,(*D
).Version
.c_str()) == true) 
1147                   TryToInstallBuildDep(Pkg
,Cache
,Fix
,true,false); 
1150          else // BuildDep || BuildDepIndep 
1152             if (_config
->FindB("Debug::BuildDeps",false) == true) 
1153                  cout 
<< "Looking for " << (*D
).Package 
<< "...\n"; 
1155             pkgCache::PkgIterator Pkg
; 
1158             if (StripMultiArch 
== false && D
->Type 
!= pkgSrcRecords::Parser::BuildDependIndep
) 
1160                size_t const colon 
= D
->Package
.find(":"); 
1161                if (colon 
!= string::npos
) 
1163                   if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0 || strcmp(D
->Package
.c_str() + colon
, ":native") == 0) 
1164                      Pkg 
= Cache
->FindPkg(D
->Package
.substr(0,colon
)); 
1166                      Pkg 
= Cache
->FindPkg(D
->Package
); 
1169                   Pkg 
= Cache
->FindPkg(D
->Package
, hostArch
); 
1171                // a bad version either is invalid or doesn't satify dependency 
1172                #define BADVER(Ver) (Ver.end() == true || \ 
1173                                     (D->Version.empty() == false && \ 
1174                                      Cache->VS().CheckDep(Ver.VerStr(),D->Op,D->Version.c_str()) == false)) 
1176                APT::VersionList verlist
; 
1177                if (Pkg
.end() == false) 
1179                   pkgCache::VerIterator Ver 
= (*Cache
)[Pkg
].InstVerIter(*Cache
); 
1180                   if (BADVER(Ver
) == false) 
1181                      verlist
.insert(Ver
); 
1182                   Ver 
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
); 
1183                   if (BADVER(Ver
) == false) 
1184                      verlist
.insert(Ver
); 
1186                if (verlist
.empty() == true) 
1188                   pkgCache::PkgIterator BuildPkg 
= Cache
->FindPkg(D
->Package
, "native"); 
1189                   if (BuildPkg
.end() == false && Pkg 
!= BuildPkg
) 
1191                      pkgCache::VerIterator Ver 
= (*Cache
)[BuildPkg
].InstVerIter(*Cache
); 
1192                      if (BADVER(Ver
) == false) 
1193                         verlist
.insert(Ver
); 
1194                      Ver 
= (*Cache
)[BuildPkg
].CandidateVerIter(*Cache
); 
1195                      if (BADVER(Ver
) == false) 
1196                         verlist
.insert(Ver
); 
1202                // We need to decide if host or build arch, so find a version we can look at 
1203                APT::VersionList::const_iterator Ver 
= verlist
.begin(); 
1204                for (; Ver 
!= verlist
.end(); ++Ver
) 
1207                   if (Ver
->MultiArch 
== pkgCache::Version::None 
|| Ver
->MultiArch 
== pkgCache::Version::All
) 
1209                      if (colon 
== string::npos
) 
1210                         Pkg 
= Ver
.ParentPkg().Group().FindPkg(hostArch
); 
1211                      else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0) 
1212                         forbidden 
= "Multi-Arch: none"; 
1213                      else if (strcmp(D
->Package
.c_str() + colon
, ":native") == 0) 
1214                         Pkg 
= Ver
.ParentPkg().Group().FindPkg("native"); 
1216                   else if (Ver
->MultiArch 
== pkgCache::Version::Same
) 
1218                      if (colon 
== string::npos
) 
1219                         Pkg 
= Ver
.ParentPkg().Group().FindPkg(hostArch
); 
1220                      else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0) 
1221                         forbidden 
= "Multi-Arch: same"; 
1222                      else if (strcmp(D
->Package
.c_str() + colon
, ":native") == 0) 
1223                         Pkg 
= Ver
.ParentPkg().Group().FindPkg("native"); 
1225                   else if ((Ver
->MultiArch 
& pkgCache::Version::Foreign
) == pkgCache::Version::Foreign
) 
1227                      if (colon 
== string::npos
) 
1228                         Pkg 
= Ver
.ParentPkg().Group().FindPkg("native"); 
1229                      else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0 || 
1230                               strcmp(D
->Package
.c_str() + colon
, ":native") == 0) 
1231                         forbidden 
= "Multi-Arch: foreign"; 
1233                   else if ((Ver
->MultiArch 
& pkgCache::Version::Allowed
) == pkgCache::Version::Allowed
) 
1235                      if (colon 
== string::npos
) 
1236                         Pkg 
= Ver
.ParentPkg().Group().FindPkg(hostArch
); 
1237                      else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0) 
1239                         // prefer any installed over preferred non-installed architectures 
1240                         pkgCache::GrpIterator Grp 
= Ver
.ParentPkg().Group(); 
1241                         // we don't check for version here as we are better of with upgrading than remove and install 
1242                         for (Pkg 
= Grp
.PackageList(); Pkg
.end() == false; Pkg 
= Grp
.NextPkg(Pkg
)) 
1243                            if (Pkg
.CurrentVer().end() == false) 
1245                         if (Pkg
.end() == true) 
1246                            Pkg 
= Grp
.FindPreferredPkg(true); 
1248                      else if (strcmp(D
->Package
.c_str() + colon
, ":native") == 0) 
1249                         Pkg 
= Ver
.ParentPkg().Group().FindPkg("native"); 
1252                   if (forbidden
.empty() == false) 
1254                      if (_config
->FindB("Debug::BuildDeps",false) == true) 
1255                         cout 
<< D
->Package
.substr(colon
, string::npos
) << " is not allowed from " << forbidden 
<< " package " << (*D
).Package 
<< " (" << Ver
.VerStr() << ")" << endl
; 
1259                   //we found a good version 
1262                if (Ver 
== verlist
.end()) 
1264                   if (_config
->FindB("Debug::BuildDeps",false) == true) 
1265                      cout 
<< " No multiarch info as we have no satisfying installed nor candidate for " << D
->Package 
<< " on build or host arch" << endl
; 
1267                   if (forbidden
.empty() == false) 
1269                      if (hasAlternatives
) 
1271                      return _error
->Error(_("%s dependency for %s can't be satisfied " 
1272                                             "because %s is not allowed on '%s' packages"), 
1273                                           Last
->BuildDepType(D
->Type
), Src
.c_str(), 
1274                                           D
->Package
.c_str(), forbidden
.c_str()); 
1279                Pkg 
= Cache
->FindPkg(D
->Package
); 
1281             if (Pkg
.end() == true || (Pkg
->VersionList 
== 0 && Pkg
->ProvidesList 
== 0)) 
1283                if (_config
->FindB("Debug::BuildDeps",false) == true) 
1284                     cout 
<< " (not found)" << (*D
).Package 
<< endl
; 
1286                if (hasAlternatives
) 
1289                return _error
->Error(_("%s dependency for %s cannot be satisfied " 
1290                                       "because the package %s cannot be found"), 
1291                                     Last
->BuildDepType((*D
).Type
),Src
.c_str(), 
1292                                     (*D
).Package
.c_str()); 
1295             pkgCache::VerIterator IV 
= (*Cache
)[Pkg
].InstVerIter(*Cache
); 
1296             if (IV
.end() == false) 
1298                if (_config
->FindB("Debug::BuildDeps",false) == true) 
1299                   cout 
<< "  Is installed\n"; 
1301                if (D
->Version
.empty() == true || 
1302                    Cache
->VS().CheckDep(IV
.VerStr(),(*D
).Op
,(*D
).Version
.c_str()) == true) 
1304                   skipAlternatives 
= hasAlternatives
; 
1308                if (_config
->FindB("Debug::BuildDeps",false) == true) 
1309                   cout 
<< "    ...but the installed version doesn't meet the version requirement\n"; 
1311                if (((*D
).Op 
& pkgCache::Dep::LessEq
) == pkgCache::Dep::LessEq
) 
1312                   return _error
->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"), 
1313                                         Last
->BuildDepType((*D
).Type
), Src
.c_str(), Pkg
.FullName(true).c_str()); 
1316             // Only consider virtual packages if there is no versioned dependency 
1317             if ((*D
).Version
.empty() == true) 
1320                 * If this is a virtual package, we need to check the list of 
1321                 * packages that provide it and see if any of those are 
1324                pkgCache::PrvIterator Prv 
= Pkg
.ProvidesList(); 
1325                for (; Prv
.end() != true; ++Prv
) 
1327                   if (_config
->FindB("Debug::BuildDeps",false) == true) 
1328                      cout 
<< "  Checking provider " << Prv
.OwnerPkg().FullName() << endl
; 
1330                   if ((*Cache
)[Prv
.OwnerPkg()].InstVerIter(*Cache
).end() == false) 
1334                if (Prv
.end() == false) 
1336                   if (_config
->FindB("Debug::BuildDeps",false) == true) 
1337                      cout 
<< "  Is provided by installed package " << Prv
.OwnerPkg().FullName() << endl
; 
1338                   skipAlternatives 
= hasAlternatives
; 
1342             else // versioned dependency 
1344                pkgCache::VerIterator CV 
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
); 
1345                if (CV
.end() == true || 
1346                    Cache
->VS().CheckDep(CV
.VerStr(),(*D
).Op
,(*D
).Version
.c_str()) == false) 
1348                   if (hasAlternatives
) 
1350                   else if (CV
.end() == false) 
1351                      return _error
->Error(_("%s dependency for %s cannot be satisfied " 
1352                                             "because candidate version of package %s " 
1353                                             "can't satisfy version requirements"), 
1354                                           Last
->BuildDepType(D
->Type
), Src
.c_str(), 
1355                                           D
->Package
.c_str()); 
1357                      return _error
->Error(_("%s dependency for %s cannot be satisfied " 
1358                                             "because package %s has no candidate version"), 
1359                                           Last
->BuildDepType(D
->Type
), Src
.c_str(), 
1360                                           D
->Package
.c_str()); 
1364             if (TryToInstallBuildDep(Pkg
,Cache
,Fix
,false,false,false) == true) 
1366                // We successfully installed something; skip remaining alternatives 
1367                skipAlternatives 
= hasAlternatives
; 
1368                if(_config
->FindB("APT::Get::Build-Dep-Automatic", false) == true) 
1369                   Cache
->MarkAuto(Pkg
, true); 
1372             else if (hasAlternatives
) 
1374                if (_config
->FindB("Debug::BuildDeps",false) == true) 
1375                   cout 
<< "  Unsatisfiable, trying alternatives\n"; 
1380                return _error
->Error(_("Failed to satisfy %s dependency for %s: %s"), 
1381                                     Last
->BuildDepType((*D
).Type
), 
1383                                     (*D
).Package
.c_str()); 
1388       if (Fix
.Resolve(true) == false) 
1391       // Now we check the state of the packages, 
1392       if (Cache
->BrokenCount() != 0) 
1394          ShowBroken(cout
, Cache
, false); 
1395          return _error
->Error(_("Build-dependencies for %s could not be satisfied."),*I
); 
1399    if (InstallPackages(Cache
, false, true) == false) 
1400       return _error
->Error(_("Failed to process build dependencies")); 
1404 // GetChangelogPath - return a path pointing to a changelog file or dir /*{{{*/ 
1405 // --------------------------------------------------------------------- 
1406 /* This returns a "path" string for the changelog url construction. 
1407  * Please note that its not complete, it either needs a "/changelog" 
1408  * appended (for the packages.debian.org/changelogs site) or a 
1409  * ".changelog" (for third party sites that store the changelog in the 
1410  * pool/ next to the deb itself) 
1411  * Example return: "pool/main/a/apt/apt_0.8.8ubuntu3"  
1413 string 
GetChangelogPath(CacheFile 
&Cache
,  
1414                         pkgCache::PkgIterator Pkg
, 
1415                         pkgCache::VerIterator Ver
) 
1419    pkgRecords 
Recs(Cache
); 
1420    pkgRecords::Parser 
&rec
=Recs
.Lookup(Ver
.FileList()); 
1421    string srcpkg 
= rec
.SourcePkg().empty() ? Pkg
.Name() : rec
.SourcePkg(); 
1422    string ver 
= Ver
.VerStr(); 
1423    // if there is a source version it always wins 
1424    if (rec
.SourceVer() != "") 
1425       ver 
= rec
.SourceVer(); 
1426    path 
= flNotFile(rec
.FileName()); 
1427    path 
+= srcpkg 
+ "_" + StripEpoch(ver
); 
1431 // GuessThirdPartyChangelogUri - return url                             /*{{{*/ 
1432 // --------------------------------------------------------------------- 
1433 /* Contruct a changelog file path for third party sites that do not use 
1434  * packages.debian.org/changelogs 
1435  * This simply uses the ArchiveURI() of the source pkg and looks for 
1436  * a .changelog file there, Example for "mediabuntu": 
1437  * apt-get changelog mplayer-doc: 
1438  *  http://packages.medibuntu.org/pool/non-free/m/mplayer/mplayer_1.0~rc4~try1.dsfg1-1ubuntu1+medibuntu1.changelog 
1440 bool GuessThirdPartyChangelogUri(CacheFile 
&Cache
,  
1441                                  pkgCache::PkgIterator Pkg
, 
1442                                  pkgCache::VerIterator Ver
, 
1445    // get the binary deb server path 
1446    pkgCache::VerFileIterator Vf 
= Ver
.FileList(); 
1447    if (Vf
.end() == true) 
1449    pkgCache::PkgFileIterator F 
= Vf
.File(); 
1450    pkgIndexFile 
*index
; 
1451    pkgSourceList 
*SrcList 
= Cache
.GetSourceList(); 
1452    if(SrcList
->FindIndex(F
, index
) == false) 
1455    // get archive uri for the binary deb 
1456    string path_without_dot_changelog 
= GetChangelogPath(Cache
, Pkg
, Ver
); 
1457    out_uri 
= index
->ArchiveURI(path_without_dot_changelog 
+ ".changelog"); 
1459    // now strip away the filename and add srcpkg_srcver.changelog 
1463 // DownloadChangelog - Download the changelog                           /*{{{*/ 
1464 // --------------------------------------------------------------------- 
1465 bool DownloadChangelog(CacheFile 
&CacheFile
, pkgAcquire 
&Fetcher
,  
1466                        pkgCache::VerIterator Ver
, string targetfile
) 
1467 /* Download a changelog file for the given package version to 
1468  * targetfile. This will first try the server from Apt::Changelogs::Server 
1469  * (http://packages.debian.org/changelogs by default) and if that gives 
1470  * a 404 tries to get it from the archive directly (see  
1471  * GuessThirdPartyChangelogUri for details how) 
1477    string changelog_uri
; 
1479    // data structures we need 
1480    pkgCache::PkgIterator Pkg 
= Ver
.ParentPkg(); 
1482    // make the server root configurable 
1483    server 
= _config
->Find("Apt::Changelogs::Server", 
1484                           "http://packages.debian.org/changelogs"); 
1485    path 
= GetChangelogPath(CacheFile
, Pkg
, Ver
); 
1486    strprintf(changelog_uri
, "%s/%s/changelog", server
.c_str(), path
.c_str()); 
1487    if (_config
->FindB("APT::Get::Print-URIs", false) == true) 
1489       std::cout 
<< '\'' << changelog_uri 
<< '\'' << std::endl
; 
1493    strprintf(descr
, _("Changelog for %s (%s)"), Pkg
.Name(), changelog_uri
.c_str()); 
1495    new pkgAcqFile(&Fetcher
, changelog_uri
, "", 0, descr
, Pkg
.Name(), "ignored", targetfile
); 
1497    // try downloading it, if that fails, try third-party-changelogs location 
1498    // FIXME: Fetcher.Run() is "Continue" even if I get a 404?!? 
1500    if (!FileExists(targetfile
)) 
1502       string third_party_uri
; 
1503       if (GuessThirdPartyChangelogUri(CacheFile
, Pkg
, Ver
, third_party_uri
)) 
1505          strprintf(descr
, _("Changelog for %s (%s)"), Pkg
.Name(), third_party_uri
.c_str()); 
1506          new pkgAcqFile(&Fetcher
, third_party_uri
, "", 0, descr
, Pkg
.Name(), "ignored", targetfile
); 
1511    if (FileExists(targetfile
)) 
1515    return _error
->Error("changelog download failed"); 
1518 // DoChangelog - Get changelog from the command line                    /*{{{*/ 
1519 // --------------------------------------------------------------------- 
1520 bool DoChangelog(CommandLine 
&CmdL
) 
1523    if (Cache
.ReadOnlyOpen() == false) 
1526    APT::CacheSetHelper 
helper(c0out
); 
1527    APT::VersionList verset 
= APT::VersionList::FromCommandLine(Cache
, 
1528                 CmdL
.FileList 
+ 1, APT::VersionList::CANDIDATE
, helper
); 
1529    if (verset
.empty() == true) 
1533    if (_config
->FindB("APT::Get::Print-URIs", false) == true) 
1535       bool Success 
= true; 
1536       for (APT::VersionList::const_iterator Ver 
= verset
.begin(); 
1537            Ver 
!= verset
.end(); ++Ver
) 
1538          Success 
&= DownloadChangelog(Cache
, Fetcher
, Ver
, ""); 
1542    AcqTextStatus 
Stat(ScreenWidth
, _config
->FindI("quiet",0)); 
1543    Fetcher
.Setup(&Stat
); 
1545    bool const downOnly 
= _config
->FindB("APT::Get::Download-Only", false); 
1548    const char* tmpdir 
= NULL
; 
1549    if (downOnly 
== false) 
1551       std::string systemTemp 
= GetTempDir(); 
1552       snprintf(tmpname
, sizeof(tmpname
), "%s/apt-changelog-XXXXXX",  
1553                systemTemp
.c_str()); 
1554       tmpdir 
= mkdtemp(tmpname
); 
1556          return _error
->Errno("mkdtemp", "mkdtemp failed"); 
1559    for (APT::VersionList::const_iterator Ver 
= verset
.begin();  
1560         Ver 
!= verset
.end();  
1563       string changelogfile
; 
1564       if (downOnly 
== false) 
1565          changelogfile
.append(tmpname
).append("changelog"); 
1567          changelogfile
.append(Ver
.ParentPkg().Name()).append(".changelog"); 
1568       if (DownloadChangelog(Cache
, Fetcher
, Ver
, changelogfile
) && downOnly 
== false) 
1570          DisplayFileInPager(changelogfile
); 
1571          // cleanup temp file 
1572          unlink(changelogfile
.c_str()); 
1581 // ShowHelp - Show a help screen                                        /*{{{*/ 
1582 // --------------------------------------------------------------------- 
1584 bool ShowHelp(CommandLine 
&CmdL
) 
1586    ioprintf(cout
,_("%s %s for %s compiled on %s %s\n"),PACKAGE
,PACKAGE_VERSION
, 
1587             COMMON_ARCH
,__DATE__
,__TIME__
); 
1589    if (_config
->FindB("version") == true) 
1591       cout 
<< _("Supported modules:") << endl
; 
1593       for (unsigned I 
= 0; I 
!= pkgVersioningSystem::GlobalListLen
; I
++) 
1595          pkgVersioningSystem 
*VS 
= pkgVersioningSystem::GlobalList
[I
]; 
1596          if (_system 
!= 0 && _system
->VS 
== VS
) 
1600          cout 
<< "Ver: " << VS
->Label 
<< endl
; 
1602          /* Print out all the packaging systems that will work with  
1604          for (unsigned J 
= 0; J 
!= pkgSystem::GlobalListLen
; J
++) 
1606             pkgSystem 
*Sys 
= pkgSystem::GlobalList
[J
]; 
1611             if (Sys
->VS
->TestCompatibility(*VS
) == true) 
1612                cout 
<< "Pkg:  " << Sys
->Label 
<< " (Priority " << Sys
->Score(*_config
) << ")" << endl
; 
1616       for (unsigned I 
= 0; I 
!= pkgSourceList::Type::GlobalListLen
; I
++) 
1618          pkgSourceList::Type 
*Type 
= pkgSourceList::Type::GlobalList
[I
]; 
1619          cout 
<< " S.L: '" << Type
->Name 
<< "' " << Type
->Label 
<< endl
; 
1622       for (unsigned I 
= 0; I 
!= pkgIndexFile::Type::GlobalListLen
; I
++) 
1624          pkgIndexFile::Type 
*Type 
= pkgIndexFile::Type::GlobalList
[I
]; 
1625          cout 
<< " Idx: " << Type
->Label 
<< endl
; 
1632     _("Usage: apt-get [options] command\n" 
1633       "       apt-get [options] install|remove pkg1 [pkg2 ...]\n" 
1634       "       apt-get [options] source pkg1 [pkg2 ...]\n" 
1636       "apt-get is a simple command line interface for downloading and\n" 
1637       "installing packages. The most frequently used commands are update\n" 
1641       "   update - Retrieve new lists of packages\n" 
1642       "   upgrade - Perform an upgrade\n" 
1643       "   install - Install new packages (pkg is libc6 not libc6.deb)\n" 
1644       "   remove - Remove packages\n" 
1645       "   autoremove - Remove automatically all unused packages\n" 
1646       "   purge - Remove packages and config files\n" 
1647       "   source - Download source archives\n" 
1648       "   build-dep - Configure build-dependencies for source packages\n" 
1649       "   dist-upgrade - Distribution upgrade, see apt-get(8)\n" 
1650       "   dselect-upgrade - Follow dselect selections\n" 
1651       "   clean - Erase downloaded archive files\n" 
1652       "   autoclean - Erase old downloaded archive files\n" 
1653       "   check - Verify that there are no broken dependencies\n" 
1654       "   changelog - Download and display the changelog for the given package\n" 
1655       "   download - Download the binary package into the current directory\n" 
1658       "  -h  This help text.\n" 
1659       "  -q  Loggable output - no progress indicator\n" 
1660       "  -qq No output except for errors\n" 
1661       "  -d  Download only - do NOT install or unpack archives\n" 
1662       "  -s  No-act. Perform ordering simulation\n" 
1663       "  -y  Assume Yes to all queries and do not prompt\n" 
1664       "  -f  Attempt to correct a system with broken dependencies in place\n" 
1665       "  -m  Attempt to continue if archives are unlocatable\n" 
1666       "  -u  Show a list of upgraded packages as well\n" 
1667       "  -b  Build the source package after fetching it\n" 
1668       "  -V  Show verbose version numbers\n" 
1669       "  -c=? Read this configuration file\n" 
1670       "  -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n" 
1671       "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n" 
1672       "pages for more information and options.\n" 
1673       "                       This APT has Super Cow Powers.\n"); 
1677 // SigWinch - Window size change signal handler                         /*{{{*/ 
1678 // --------------------------------------------------------------------- 
1682    // Riped from GNU ls 
1686    if (ioctl(1, TIOCGWINSZ
, &ws
) != -1 && ws
.ws_col 
>= 5) 
1687       ScreenWidth 
= ws
.ws_col 
- 1; 
1691 int main(int argc
,const char *argv
[])                                   /*{{{*/ 
1693    CommandLine::Dispatch Cmds
[] = {{"update",&DoUpdate
}, 
1694                                    {"upgrade",&DoUpgrade
}, 
1695                                    {"install",&DoInstall
}, 
1696                                    {"remove",&DoInstall
}, 
1697                                    {"purge",&DoInstall
}, 
1698                                    {"autoremove",&DoInstall
}, 
1699                                    {"markauto",&DoMarkAuto
}, 
1700                                    {"unmarkauto",&DoMarkAuto
}, 
1701                                    {"dist-upgrade",&DoDistUpgrade
}, 
1702                                    {"dselect-upgrade",&DoDSelectUpgrade
}, 
1703                                    {"build-dep",&DoBuildDep
}, 
1705                                    {"autoclean",&DoAutoClean
}, 
1707                                    {"source",&DoSource
}, 
1708                                    {"download",&DoDownload
}, 
1709                                    {"changelog",&DoChangelog
}, 
1714    std::vector
<CommandLine::Args
> Args 
= getCommandArgs("apt-get", CommandLine::GetCommand(Cmds
, argc
, argv
)); 
1716    // Set up gettext support 
1717    setlocale(LC_ALL
,""); 
1718    textdomain(PACKAGE
); 
1720    // Parse the command line and initialize the package library 
1721    CommandLine 
CmdL(Args
.data(),_config
); 
1722    if (pkgInitConfig(*_config
) == false || 
1723        CmdL
.Parse(argc
,argv
) == false || 
1724        pkgInitSystem(*_config
,_system
) == false) 
1726       if (_config
->FindB("version") == true) 
1729       _error
->DumpErrors(); 
1733    // See if the help should be shown 
1734    if (_config
->FindB("help") == true || 
1735        _config
->FindB("version") == true || 
1736        CmdL
.FileSize() == 0) 
1742    // see if we are in simulate mode 
1743    CheckSimulateMode(CmdL
); 
1745    // Setup the output streams 
1748    // Setup the signals 
1749    signal(SIGPIPE
,SIG_IGN
); 
1750    signal(SIGWINCH
,SigWinch
); 
1753    // Match the operation 
1754    CmdL
.DispatchArg(Cmds
); 
1756    // Print any errors or warnings found during parsing 
1757    bool const Errors 
= _error
->PendingError(); 
1758    if (_config
->FindI("quiet",0) > 0) 
1759       _error
->DumpErrors(); 
1761       _error
->DumpErrors(GlobalError::DEBUG
); 
1762    return Errors 
== true ? 100 : 0;