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 - Powerfull 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>
53 #include "acqprogress.h"
60 #include <sys/ioctl.h>
62 #include <sys/statfs.h>
63 #include <sys/statvfs.h>
75 #define RAMFS_MAGIC 0x858458f6
82 ofstream
devnull("/dev/null");
83 unsigned int ScreenWidth
= 80 - 1; /* - 1 for the cursor */
85 // class CacheFile - Cover class for some dependency cache functions /*{{{*/
86 // ---------------------------------------------------------------------
88 class CacheFile
: public pkgCacheFile
90 static pkgCache
*SortCache
;
91 static int NameComp(const void *a
,const void *b
);
94 pkgCache::Package
**List
;
97 bool CheckDeps(bool AllowBroken
= false);
98 bool BuildCaches(bool WithLock
= true)
100 OpTextProgress
Prog(*_config
);
101 if (pkgCacheFile::BuildCaches(&Prog
,WithLock
) == false)
105 bool Open(bool WithLock
= true)
107 OpTextProgress
Prog(*_config
);
108 if (pkgCacheFile::Open(&Prog
,WithLock
) == false)
114 bool OpenForInstall()
116 if (_config
->FindB("APT::Get::Print-URIs") == true)
121 CacheFile() : List(0) {};
128 // YnPrompt - Yes No Prompt. /*{{{*/
129 // ---------------------------------------------------------------------
130 /* Returns true on a Yes.*/
131 bool YnPrompt(bool Default
=true)
133 /* nl_langinfo does not support LANGUAGE setting, so we unset it here
134 to have the help-message (hopefully) match the expected characters */
135 char * language
= getenv("LANGUAGE");
136 if (language
!= NULL
)
137 language
= strdup(language
);
138 if (language
!= NULL
)
139 unsetenv("LANGUAGE");
142 // TRANSLATOR: Yes/No question help-text: defaulting to Y[es]
143 // e.g. "Do you want to continue? [Y/n] "
144 // The user has to answer with an input matching the
145 // YESEXPR/NOEXPR defined in your l10n.
146 c2out
<< " " << _("[Y/n]") << " " << std::flush
;
148 // TRANSLATOR: Yes/No question help-text: defaulting to N[o]
149 // e.g. "Should this file be removed? [y/N] "
150 // The user has to answer with an input matching the
151 // YESEXPR/NOEXPR defined in your l10n.
152 c2out
<< " " << _("[y/N]") << " " << std::flush
;
154 if (language
!= NULL
)
156 setenv("LANGUAGE", language
, 0);
160 if (_config
->FindB("APT::Get::Assume-Yes",false) == true)
162 // TRANSLATOR: "Yes" answer printed for a yes/no question if --assume-yes is set
163 c1out
<< _("Y") << endl
;
166 else if (_config
->FindB("APT::Get::Assume-No",false) == true)
168 // TRANSLATOR: "No" answer printed for a yes/no question if --assume-no is set
169 c1out
<< _("N") << endl
;
173 char response
[1024] = "";
174 cin
.getline(response
, sizeof(response
));
179 if (strlen(response
) == 0)
185 Res
= regcomp(&Pattern
, nl_langinfo(YESEXPR
),
186 REG_EXTENDED
|REG_ICASE
|REG_NOSUB
);
190 regerror(Res
,&Pattern
,Error
,sizeof(Error
));
191 return _error
->Error(_("Regex compilation error - %s"),Error
);
194 Res
= regexec(&Pattern
, response
, 0, NULL
, 0);
200 // AnalPrompt - Annoying Yes No Prompt. /*{{{*/
201 // ---------------------------------------------------------------------
202 /* Returns true on a Yes.*/
203 bool AnalPrompt(const char *Text
)
206 cin
.getline(Buf
,sizeof(Buf
));
207 if (strcmp(Buf
,Text
) == 0)
212 // ShowList - Show a list /*{{{*/
213 // ---------------------------------------------------------------------
214 /* This prints out a string of space separated words with a title and
215 a two space indent line wraped to the current screen width. */
216 bool ShowList(ostream
&out
,string Title
,string List
,string VersionsList
)
218 if (List
.empty() == true)
220 // trim trailing space
221 int NonSpace
= List
.find_last_not_of(' ');
224 List
= List
.erase(NonSpace
+ 1);
225 if (List
.empty() == true)
229 // Acount for the leading space
230 int ScreenWidth
= ::ScreenWidth
- 3;
232 out
<< Title
<< endl
;
233 string::size_type Start
= 0;
234 string::size_type VersionsStart
= 0;
235 while (Start
< List
.size())
237 if(_config
->FindB("APT::Get::Show-Versions",false) == true &&
238 VersionsList
.size() > 0) {
239 string::size_type End
;
240 string::size_type VersionsEnd
;
242 End
= List
.find(' ',Start
);
243 VersionsEnd
= VersionsList
.find('\n', VersionsStart
);
245 out
<< " " << string(List
,Start
,End
- Start
) << " (" <<
246 string(VersionsList
,VersionsStart
,VersionsEnd
- VersionsStart
) <<
249 if (End
== string::npos
|| End
< Start
)
250 End
= Start
+ ScreenWidth
;
253 VersionsStart
= VersionsEnd
+ 1;
255 string::size_type End
;
257 if (Start
+ ScreenWidth
>= List
.size())
260 End
= List
.rfind(' ',Start
+ScreenWidth
);
262 if (End
== string::npos
|| End
< Start
)
263 End
= Start
+ ScreenWidth
;
264 out
<< " " << string(List
,Start
,End
- Start
) << endl
;
272 // ShowBroken - Debugging aide /*{{{*/
273 // ---------------------------------------------------------------------
274 /* This prints out the names of all the packages that are broken along
275 with the name of each each broken dependency and a quite version
278 The output looks like:
279 The following packages have unmet dependencies:
280 exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed
281 Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
282 Depends: libsasl7 but it is not going to be installed
284 void ShowBroken(ostream
&out
,CacheFile
&Cache
,bool Now
)
286 if (Cache
->BrokenCount() == 0)
289 out
<< _("The following packages have unmet dependencies:") << endl
;
290 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
292 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
296 if (Cache
[I
].NowBroken() == false)
301 if (Cache
[I
].InstBroken() == false)
305 // Print out each package and the failed dependencies
306 out
<< " " << I
.FullName(true) << " :";
307 unsigned const Indent
= I
.FullName(true).size() + 3;
309 pkgCache::VerIterator Ver
;
312 Ver
= I
.CurrentVer();
314 Ver
= Cache
[I
].InstVerIter(Cache
);
316 if (Ver
.end() == true)
322 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false;)
324 // Compute a single dependency element (glob or)
325 pkgCache::DepIterator Start
;
326 pkgCache::DepIterator End
;
327 D
.GlobOr(Start
,End
); // advances D
329 if (Cache
->IsImportantDep(End
) == false)
334 if ((Cache
[End
] & pkgDepCache::DepGNow
) == pkgDepCache::DepGNow
)
339 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
347 for (unsigned J
= 0; J
!= Indent
; J
++)
351 if (FirstOr
== false)
353 for (unsigned J
= 0; J
!= strlen(End
.DepType()) + 3; J
++)
357 out
<< ' ' << End
.DepType() << ": ";
360 out
<< Start
.TargetPkg().FullName(true);
362 // Show a quick summary of the version requirements
363 if (Start
.TargetVer() != 0)
364 out
<< " (" << Start
.CompType() << " " << Start
.TargetVer() << ")";
366 /* Show a summary of the target package if possible. In the case
367 of virtual packages we show nothing */
368 pkgCache::PkgIterator Targ
= Start
.TargetPkg();
369 if (Targ
->ProvidesList
== 0)
372 pkgCache::VerIterator Ver
= Cache
[Targ
].InstVerIter(Cache
);
374 Ver
= Targ
.CurrentVer();
376 if (Ver
.end() == false)
379 ioprintf(out
,_("but %s is installed"),Ver
.VerStr());
381 ioprintf(out
,_("but %s is to be installed"),Ver
.VerStr());
385 if (Cache
[Targ
].CandidateVerIter(Cache
).end() == true)
387 if (Targ
->ProvidesList
== 0)
388 out
<< _("but it is not installable");
390 out
<< _("but it is a virtual package");
393 out
<< (Now
?_("but it is not installed"):_("but it is not going to be installed"));
409 // ShowNew - Show packages to newly install /*{{{*/
410 // ---------------------------------------------------------------------
412 void ShowNew(ostream
&out
,CacheFile
&Cache
)
414 /* Print out a list of packages that are going to be installed extra
415 to what the user asked */
418 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
420 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
421 if (Cache
[I
].NewInstall() == true) {
422 List
+= I
.FullName(true) + " ";
423 VersionsList
+= string(Cache
[I
].CandVersion
) + "\n";
427 ShowList(out
,_("The following NEW packages will be installed:"),List
,VersionsList
);
430 // ShowDel - Show packages to delete /*{{{*/
431 // ---------------------------------------------------------------------
433 void ShowDel(ostream
&out
,CacheFile
&Cache
)
435 /* Print out a list of packages that are going to be removed extra
436 to what the user asked */
439 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
441 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
442 if (Cache
[I
].Delete() == true)
444 if ((Cache
[I
].iFlags
& pkgDepCache::Purge
) == pkgDepCache::Purge
)
445 List
+= I
.FullName(true) + "* ";
447 List
+= I
.FullName(true) + " ";
449 VersionsList
+= string(Cache
[I
].CandVersion
)+ "\n";
453 ShowList(out
,_("The following packages will be REMOVED:"),List
,VersionsList
);
456 // ShowKept - Show kept packages /*{{{*/
457 // ---------------------------------------------------------------------
459 void ShowKept(ostream
&out
,CacheFile
&Cache
)
463 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
465 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
468 if (Cache
[I
].Upgrade() == true || Cache
[I
].Upgradable() == false ||
469 I
->CurrentVer
== 0 || Cache
[I
].Delete() == true)
472 List
+= I
.FullName(true) + " ";
473 VersionsList
+= string(Cache
[I
].CurVersion
) + " => " + Cache
[I
].CandVersion
+ "\n";
475 ShowList(out
,_("The following packages have been kept back:"),List
,VersionsList
);
478 // ShowUpgraded - Show upgraded packages /*{{{*/
479 // ---------------------------------------------------------------------
481 void ShowUpgraded(ostream
&out
,CacheFile
&Cache
)
485 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
487 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
490 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
493 List
+= I
.FullName(true) + " ";
494 VersionsList
+= string(Cache
[I
].CurVersion
) + " => " + Cache
[I
].CandVersion
+ "\n";
496 ShowList(out
,_("The following packages will be upgraded:"),List
,VersionsList
);
499 // ShowDowngraded - Show downgraded packages /*{{{*/
500 // ---------------------------------------------------------------------
502 bool ShowDowngraded(ostream
&out
,CacheFile
&Cache
)
506 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
508 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
511 if (Cache
[I
].Downgrade() == false || Cache
[I
].NewInstall() == true)
514 List
+= I
.FullName(true) + " ";
515 VersionsList
+= string(Cache
[I
].CurVersion
) + " => " + Cache
[I
].CandVersion
+ "\n";
517 return ShowList(out
,_("The following packages will be DOWNGRADED:"),List
,VersionsList
);
520 // ShowHold - Show held but changed packages /*{{{*/
521 // ---------------------------------------------------------------------
523 bool ShowHold(ostream
&out
,CacheFile
&Cache
)
527 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
529 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
530 if (Cache
[I
].InstallVer
!= (pkgCache::Version
*)I
.CurrentVer() &&
531 I
->SelectedState
== pkgCache::State::Hold
) {
532 List
+= I
.FullName(true) + " ";
533 VersionsList
+= string(Cache
[I
].CurVersion
) + " => " + Cache
[I
].CandVersion
+ "\n";
537 return ShowList(out
,_("The following held packages will be changed:"),List
,VersionsList
);
540 // ShowEssential - Show an essential package warning /*{{{*/
541 // ---------------------------------------------------------------------
542 /* This prints out a warning message that is not to be ignored. It shows
543 all essential packages and their dependents that are to be removed.
544 It is insanely risky to remove the dependents of an essential package! */
545 bool ShowEssential(ostream
&out
,CacheFile
&Cache
)
549 bool *Added
= new bool[Cache
->Head().PackageCount
];
550 for (unsigned int I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
553 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
555 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
556 if ((I
->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
&&
557 (I
->Flags
& pkgCache::Flag::Important
) != pkgCache::Flag::Important
)
560 // The essential package is being removed
561 if (Cache
[I
].Delete() == true)
563 if (Added
[I
->ID
] == false)
566 List
+= I
.FullName(true) + " ";
567 //VersionsList += string(Cache[I].CurVersion) + "\n"; ???
573 if (I
->CurrentVer
== 0)
576 // Print out any essential package depenendents that are to be removed
577 for (pkgCache::DepIterator D
= I
.CurrentVer().DependsList(); D
.end() == false; ++D
)
579 // Skip everything but depends
580 if (D
->Type
!= pkgCache::Dep::PreDepends
&&
581 D
->Type
!= pkgCache::Dep::Depends
)
584 pkgCache::PkgIterator P
= D
.SmartTargetPkg();
585 if (Cache
[P
].Delete() == true)
587 if (Added
[P
->ID
] == true)
592 snprintf(S
,sizeof(S
),_("%s (due to %s) "),P
.FullName(true).c_str(),I
.FullName(true).c_str());
594 //VersionsList += "\n"; ???
600 return ShowList(out
,_("WARNING: The following essential packages will be removed.\n"
601 "This should NOT be done unless you know exactly what you are doing!"),List
,VersionsList
);
605 // Stats - Show some statistics /*{{{*/
606 // ---------------------------------------------------------------------
608 void Stats(ostream
&out
,pkgDepCache
&Dep
)
610 unsigned long Upgrade
= 0;
611 unsigned long Downgrade
= 0;
612 unsigned long Install
= 0;
613 unsigned long ReInstall
= 0;
614 for (pkgCache::PkgIterator I
= Dep
.PkgBegin(); I
.end() == false; ++I
)
616 if (Dep
[I
].NewInstall() == true)
620 if (Dep
[I
].Upgrade() == true)
623 if (Dep
[I
].Downgrade() == true)
627 if (Dep
[I
].Delete() == false && (Dep
[I
].iFlags
& pkgDepCache::ReInstall
) == pkgDepCache::ReInstall
)
631 ioprintf(out
,_("%lu upgraded, %lu newly installed, "),
635 ioprintf(out
,_("%lu reinstalled, "),ReInstall
);
637 ioprintf(out
,_("%lu downgraded, "),Downgrade
);
639 ioprintf(out
,_("%lu to remove and %lu not upgraded.\n"),
640 Dep
.DelCount(),Dep
.KeepCount());
642 if (Dep
.BadCount() != 0)
643 ioprintf(out
,_("%lu not fully installed or removed.\n"),
647 // CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/
648 class CacheSetHelperAPTGet
: public APT::CacheSetHelper
{
649 /** \brief stream message should be printed to */
651 /** \brief were things like Task or RegEx used to select packages? */
652 bool explicitlyNamed
;
654 APT::PackageSet virtualPkgs
;
657 std::list
<std::pair
<pkgCache::VerIterator
, std::string
> > selectedByRelease
;
659 CacheSetHelperAPTGet(std::ostream
&out
) : APT::CacheSetHelper(true), out(out
) {
660 explicitlyNamed
= true;
663 virtual void showTaskSelection(pkgCache::PkgIterator
const &Pkg
, string
const &pattern
) {
664 ioprintf(out
, _("Note, selecting '%s' for task '%s'\n"),
665 Pkg
.FullName(true).c_str(), pattern
.c_str());
666 explicitlyNamed
= false;
668 virtual void showRegExSelection(pkgCache::PkgIterator
const &Pkg
, string
const &pattern
) {
669 ioprintf(out
, _("Note, selecting '%s' for regex '%s'\n"),
670 Pkg
.FullName(true).c_str(), pattern
.c_str());
671 explicitlyNamed
= false;
673 virtual void showSelectedVersion(pkgCache::PkgIterator
const &Pkg
, pkgCache::VerIterator
const Ver
,
674 string
const &ver
, bool const verIsRel
) {
675 if (ver
== Ver
.VerStr())
677 selectedByRelease
.push_back(make_pair(Ver
, ver
));
680 bool showVirtualPackageErrors(pkgCacheFile
&Cache
) {
681 if (virtualPkgs
.empty() == true)
683 for (APT::PackageSet::const_iterator Pkg
= virtualPkgs
.begin();
684 Pkg
!= virtualPkgs
.end(); ++Pkg
) {
685 if (Pkg
->ProvidesList
!= 0) {
686 ioprintf(c1out
,_("Package %s is a virtual package provided by:\n"),
687 Pkg
.FullName(true).c_str());
689 pkgCache::PrvIterator I
= Pkg
.ProvidesList();
690 unsigned short provider
= 0;
691 for (; I
.end() == false; ++I
) {
692 pkgCache::PkgIterator Pkg
= I
.OwnerPkg();
694 if (Cache
[Pkg
].CandidateVerIter(Cache
) == I
.OwnerVer()) {
695 c1out
<< " " << Pkg
.FullName(true) << " " << I
.OwnerVer().VerStr();
696 if (Cache
[Pkg
].Install() == true && Cache
[Pkg
].NewInstall() == false)
697 c1out
<< _(" [Installed]");
702 // if we found no candidate which provide this package, show non-candidates
704 for (I
= Pkg
.ProvidesList(); I
.end() == false; ++I
)
705 c1out
<< " " << I
.OwnerPkg().FullName(true) << " " << I
.OwnerVer().VerStr()
706 << _(" [Not candidate version]") << endl
;
708 out
<< _("You should explicitly select one to install.") << endl
;
711 _("Package %s is not available, but is referred to by another package.\n"
712 "This may mean that the package is missing, has been obsoleted, or\n"
713 "is only available from another source\n"),Pkg
.FullName(true).c_str());
717 SPtrArray
<bool> Seen
= new bool[Cache
.GetPkgCache()->Head().PackageCount
];
718 memset(Seen
,0,Cache
.GetPkgCache()->Head().PackageCount
*sizeof(*Seen
));
719 for (pkgCache::DepIterator Dep
= Pkg
.RevDependsList();
720 Dep
.end() == false; ++Dep
) {
721 if (Dep
->Type
!= pkgCache::Dep::Replaces
)
723 if (Seen
[Dep
.ParentPkg()->ID
] == true)
725 Seen
[Dep
.ParentPkg()->ID
] = true;
726 List
+= Dep
.ParentPkg().FullName(true) + " ";
727 //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ???
729 ShowList(c1out
,_("However the following packages replace it:"),List
,VersionsList
);
736 virtual pkgCache::VerIterator
canNotFindCandidateVer(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &Pkg
) {
737 APT::VersionSet
const verset
= tryVirtualPackage(Cache
, Pkg
, APT::VersionSet::CANDIDATE
);
738 if (verset
.empty() == false)
739 return *(verset
.begin());
740 else if (ShowError
== true) {
741 _error
->Error(_("Package '%s' has no installation candidate"),Pkg
.FullName(true).c_str());
742 virtualPkgs
.insert(Pkg
);
744 return pkgCache::VerIterator(Cache
, 0);
747 virtual pkgCache::VerIterator
canNotFindNewestVer(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &Pkg
) {
748 if (Pkg
->ProvidesList
!= 0)
750 APT::VersionSet
const verset
= tryVirtualPackage(Cache
, Pkg
, APT::VersionSet::NEWEST
);
751 if (verset
.empty() == false)
752 return *(verset
.begin());
753 if (ShowError
== true)
754 ioprintf(out
, _("Virtual packages like '%s' can't be removed\n"), Pkg
.FullName(true).c_str());
758 pkgCache::GrpIterator Grp
= Pkg
.Group();
759 pkgCache::PkgIterator P
= Grp
.PackageList();
760 for (; P
.end() != true; P
= Grp
.NextPkg(P
))
764 if (P
->CurrentVer
!= 0) {
765 // TRANSLATORS: Note, this is not an interactive question
766 ioprintf(c1out
,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
767 Pkg
.FullName(true).c_str(), P
.FullName(true).c_str());
772 ioprintf(c1out
,_("Package '%s' is not installed, so not removed\n"),Pkg
.FullName(true).c_str());
774 return pkgCache::VerIterator(Cache
, 0);
777 APT::VersionSet
tryVirtualPackage(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &Pkg
,
778 APT::VersionSet::Version
const &select
) {
779 /* This is a pure virtual package and there is a single available
780 candidate providing it. */
781 if (unlikely(Cache
[Pkg
].CandidateVer
!= 0) || Pkg
->ProvidesList
== 0)
782 return APT::VersionSet();
784 pkgCache::PkgIterator Prov
;
785 bool found_one
= false;
786 for (pkgCache::PrvIterator P
= Pkg
.ProvidesList(); P
; ++P
) {
787 pkgCache::VerIterator
const PVer
= P
.OwnerVer();
788 pkgCache::PkgIterator
const PPkg
= PVer
.ParentPkg();
790 /* Ignore versions that are not a candidate. */
791 if (Cache
[PPkg
].CandidateVer
!= PVer
)
794 if (found_one
== false) {
797 } else if (PPkg
!= Prov
) {
798 // same group, so it's a foreign package
799 if (PPkg
->Group
== Prov
->Group
) {
800 // do we already have the requested arch?
801 if (strcmp(Pkg
.Arch(), Prov
.Arch()) == 0 ||
802 strcmp(Prov
.Arch(), "all") == 0 ||
803 unlikely(strcmp(PPkg
.Arch(), Prov
.Arch()) == 0)) // packages have only on candidate, but just to be sure
805 // see which architecture we prefer more and switch to it
806 std::vector
<std::string
> archs
= APT::Configuration::getArchitectures();
807 if (std::find(archs
.begin(), archs
.end(), PPkg
.Arch()) < std::find(archs
.begin(), archs
.end(), Prov
.Arch()))
811 found_one
= false; // we found at least two
816 if (found_one
== true) {
817 ioprintf(out
, _("Note, selecting '%s' instead of '%s'\n"),
818 Prov
.FullName(true).c_str(), Pkg
.FullName(true).c_str());
819 return APT::VersionSet::FromPackage(Cache
, Prov
, select
, *this);
821 return APT::VersionSet();
824 inline bool allPkgNamedExplicitly() const { return explicitlyNamed
; }
828 // TryToInstall - Mark a package for installation /*{{{*/
829 struct TryToInstall
{
831 pkgProblemResolver
* Fix
;
833 unsigned long AutoMarkChanged
;
834 APT::PackageSet doAutoInstallLater
;
836 TryToInstall(pkgCacheFile
&Cache
, pkgProblemResolver
*PM
, bool const FixBroken
) : Cache(&Cache
), Fix(PM
),
837 FixBroken(FixBroken
), AutoMarkChanged(0) {};
839 void operator() (pkgCache::VerIterator
const &Ver
) {
840 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
842 Cache
->GetDepCache()->SetCandidateVersion(Ver
);
843 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
845 // Handle the no-upgrade case
846 if (_config
->FindB("APT::Get::upgrade",true) == false && Pkg
->CurrentVer
!= 0)
847 ioprintf(c1out
,_("Skipping %s, it is already installed and upgrade is not set.\n"),
848 Pkg
.FullName(true).c_str());
849 // Ignore request for install if package would be new
850 else if (_config
->FindB("APT::Get::Only-Upgrade", false) == true && Pkg
->CurrentVer
== 0)
851 ioprintf(c1out
,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
852 Pkg
.FullName(true).c_str());
858 Cache
->GetDepCache()->MarkInstall(Pkg
,false);
860 if (State
.Install() == false) {
861 if (_config
->FindB("APT::Get::ReInstall",false) == true) {
862 if (Pkg
->CurrentVer
== 0 || Pkg
.CurrentVer().Downloadable() == false)
863 ioprintf(c1out
,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
864 Pkg
.FullName(true).c_str());
866 Cache
->GetDepCache()->SetReInstall(Pkg
, true);
868 ioprintf(c1out
,_("%s is already the newest version.\n"),
869 Pkg
.FullName(true).c_str());
872 // Install it with autoinstalling enabled (if we not respect the minial
873 // required deps or the policy)
874 if (FixBroken
== false)
875 doAutoInstallLater
.insert(Pkg
);
878 // see if we need to fix the auto-mark flag
879 // e.g. apt-get install foo
880 // where foo is marked automatic
881 if (State
.Install() == false &&
882 (State
.Flags
& pkgCache::Flag::Auto
) &&
883 _config
->FindB("APT::Get::ReInstall",false) == false &&
884 _config
->FindB("APT::Get::Only-Upgrade",false) == false &&
885 _config
->FindB("APT::Get::Download-Only",false) == false)
887 ioprintf(c1out
,_("%s set to manually installed.\n"),
888 Pkg
.FullName(true).c_str());
889 Cache
->GetDepCache()->MarkAuto(Pkg
,false);
894 bool propergateReleaseCandiateSwitching(std::list
<std::pair
<pkgCache::VerIterator
, std::string
> > start
, std::ostream
&out
)
896 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
897 s
!= start
.end(); ++s
)
898 Cache
->GetDepCache()->SetCandidateVersion(s
->first
);
901 std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> > Changed
;
902 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
903 s
!= start
.end(); ++s
)
905 Changed
.push_back(std::make_pair(s
->first
, pkgCache::VerIterator(*Cache
)));
906 // We continue here even if it failed to enhance the ShowBroken output
907 Success
&= Cache
->GetDepCache()->SetCandidateRelease(s
->first
, s
->second
, Changed
);
909 for (std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> >::const_iterator c
= Changed
.begin();
910 c
!= Changed
.end(); ++c
)
912 if (c
->second
.end() == true)
913 ioprintf(out
, _("Selected version '%s' (%s) for '%s'\n"),
914 c
->first
.VerStr(), c
->first
.RelStr().c_str(), c
->first
.ParentPkg().FullName(true).c_str());
915 else if (c
->first
.ParentPkg()->Group
!= c
->second
.ParentPkg()->Group
)
917 pkgCache::VerIterator V
= (*Cache
)[c
->first
.ParentPkg()].CandidateVerIter(*Cache
);
918 ioprintf(out
, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V
.VerStr(),
919 V
.RelStr().c_str(), V
.ParentPkg().FullName(true).c_str(), c
->second
.ParentPkg().FullName(true).c_str());
925 void doAutoInstall() {
926 for (APT::PackageSet::const_iterator P
= doAutoInstallLater
.begin();
927 P
!= doAutoInstallLater
.end(); ++P
) {
928 pkgDepCache::StateCache
&State
= (*Cache
)[P
];
929 if (State
.InstBroken() == false && State
.InstPolicyBroken() == false)
931 Cache
->GetDepCache()->MarkInstall(P
, true);
933 doAutoInstallLater
.clear();
937 // TryToRemove - Mark a package for removal /*{{{*/
940 pkgProblemResolver
* Fix
;
943 TryToRemove(pkgCacheFile
&Cache
, pkgProblemResolver
*PM
) : Cache(&Cache
), Fix(PM
),
944 PurgePkgs(_config
->FindB("APT::Get::Purge", false)) {};
946 void operator() (pkgCache::VerIterator
const &Ver
)
948 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
957 if ((Pkg
->CurrentVer
== 0 && PurgePkgs
== false) ||
958 (PurgePkgs
== true && Pkg
->CurrentState
== pkgCache::State::NotInstalled
))
960 pkgCache::GrpIterator Grp
= Pkg
.Group();
961 pkgCache::PkgIterator P
= Grp
.PackageList();
962 for (; P
.end() != true; P
= Grp
.NextPkg(P
))
966 if (P
->CurrentVer
!= 0 || (PurgePkgs
== true && P
->CurrentState
!= pkgCache::State::NotInstalled
))
968 // TRANSLATORS: Note, this is not an interactive question
969 ioprintf(c1out
,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
970 Pkg
.FullName(true).c_str(), P
.FullName(true).c_str());
975 ioprintf(c1out
,_("Package '%s' is not installed, so not removed\n"),Pkg
.FullName(true).c_str());
977 // MarkInstall refuses to install packages on hold
978 Pkg
->SelectedState
= pkgCache::State::Hold
;
981 Cache
->GetDepCache()->MarkDelete(Pkg
, PurgePkgs
);
985 // CacheFile::NameComp - QSort compare by name /*{{{*/
986 // ---------------------------------------------------------------------
988 pkgCache
*CacheFile::SortCache
= 0;
989 int CacheFile::NameComp(const void *a
,const void *b
)
991 if (*(pkgCache::Package
**)a
== 0 || *(pkgCache::Package
**)b
== 0)
992 return *(pkgCache::Package
**)a
- *(pkgCache::Package
**)b
;
994 const pkgCache::Package
&A
= **(pkgCache::Package
**)a
;
995 const pkgCache::Package
&B
= **(pkgCache::Package
**)b
;
997 return strcmp(SortCache
->StrP
+ A
.Name
,SortCache
->StrP
+ B
.Name
);
1000 // CacheFile::Sort - Sort by name /*{{{*/
1001 // ---------------------------------------------------------------------
1003 void CacheFile::Sort()
1006 List
= new pkgCache::Package
*[Cache
->Head().PackageCount
];
1007 memset(List
,0,sizeof(*List
)*Cache
->Head().PackageCount
);
1008 pkgCache::PkgIterator I
= Cache
->PkgBegin();
1009 for (;I
.end() != true; ++I
)
1013 qsort(List
,Cache
->Head().PackageCount
,sizeof(*List
),NameComp
);
1016 // CacheFile::CheckDeps - Open the cache file /*{{{*/
1017 // ---------------------------------------------------------------------
1018 /* This routine generates the caches and then opens the dependency cache
1019 and verifies that the system is OK. */
1020 bool CacheFile::CheckDeps(bool AllowBroken
)
1022 bool FixBroken
= _config
->FindB("APT::Get::Fix-Broken",false);
1024 if (_error
->PendingError() == true)
1027 // Check that the system is OK
1028 if (DCache
->DelCount() != 0 || DCache
->InstCount() != 0)
1029 return _error
->Error("Internal error, non-zero counts");
1031 // Apply corrections for half-installed packages
1032 if (pkgApplyStatus(*DCache
) == false)
1035 if (_config
->FindB("APT::Get::Fix-Policy-Broken",false) == true)
1038 if ((DCache
->PolicyBrokenCount() > 0))
1040 // upgrade all policy-broken packages with ForceImportantDeps=True
1041 for (pkgCache::PkgIterator I
= Cache
->PkgBegin(); !I
.end(); ++I
)
1042 if ((*DCache
)[I
].NowPolicyBroken() == true)
1043 DCache
->MarkInstall(I
,true,0, false, true);
1047 // Nothing is broken
1048 if (DCache
->BrokenCount() == 0 || AllowBroken
== true)
1051 // Attempt to fix broken things
1052 if (FixBroken
== true)
1054 c1out
<< _("Correcting dependencies...") << flush
;
1055 if (pkgFixBroken(*DCache
) == false || DCache
->BrokenCount() != 0)
1057 c1out
<< _(" failed.") << endl
;
1058 ShowBroken(c1out
,*this,true);
1060 return _error
->Error(_("Unable to correct dependencies"));
1062 if (pkgMinimizeUpgrade(*DCache
) == false)
1063 return _error
->Error(_("Unable to minimize the upgrade set"));
1065 c1out
<< _(" Done") << endl
;
1069 c1out
<< _("You might want to run 'apt-get -f install' to correct these.") << endl
;
1070 ShowBroken(c1out
,*this,true);
1072 return _error
->Error(_("Unmet dependencies. Try using -f."));
1078 // CheckAuth - check if each download comes form a trusted source /*{{{*/
1079 // ---------------------------------------------------------------------
1081 static bool CheckAuth(pkgAcquire
& Fetcher
)
1083 string UntrustedList
;
1084 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
< Fetcher
.ItemsEnd(); ++I
)
1086 if (!(*I
)->IsTrusted())
1088 UntrustedList
+= string((*I
)->ShortDesc()) + " ";
1092 if (UntrustedList
== "")
1097 ShowList(c2out
,_("WARNING: The following packages cannot be authenticated!"),UntrustedList
,"");
1099 if (_config
->FindB("APT::Get::AllowUnauthenticated",false) == true)
1101 c2out
<< _("Authentication warning overridden.\n");
1105 if (_config
->FindI("quiet",0) < 2
1106 && _config
->FindB("APT::Get::Assume-Yes",false) == false)
1108 c2out
<< _("Install these packages without verification?") << flush
;
1109 if (!YnPrompt(false))
1110 return _error
->Error(_("Some packages could not be authenticated"));
1114 else if (_config
->FindB("APT::Get::Force-Yes",false) == true)
1119 return _error
->Error(_("There are problems and -y was used without --force-yes"));
1122 // InstallPackages - Actually download and install the packages /*{{{*/
1123 // ---------------------------------------------------------------------
1124 /* This displays the informative messages describing what is going to
1125 happen and then calls the download routines */
1126 bool InstallPackages(CacheFile
&Cache
,bool ShwKept
,bool Ask
= true,
1129 if (_config
->FindB("APT::Get::Purge",false) == true)
1131 pkgCache::PkgIterator I
= Cache
->PkgBegin();
1132 for (; I
.end() == false; ++I
)
1134 if (I
.Purge() == false && Cache
[I
].Mode
== pkgDepCache::ModeDelete
)
1135 Cache
->MarkDelete(I
,true);
1140 bool Essential
= false;
1142 // Show all the various warning indicators
1143 ShowDel(c1out
,Cache
);
1144 ShowNew(c1out
,Cache
);
1145 if (ShwKept
== true)
1146 ShowKept(c1out
,Cache
);
1147 Fail
|= !ShowHold(c1out
,Cache
);
1148 if (_config
->FindB("APT::Get::Show-Upgraded",true) == true)
1149 ShowUpgraded(c1out
,Cache
);
1150 Fail
|= !ShowDowngraded(c1out
,Cache
);
1151 if (_config
->FindB("APT::Get::Download-Only",false) == false)
1152 Essential
= !ShowEssential(c1out
,Cache
);
1157 if (Cache
->BrokenCount() != 0)
1159 ShowBroken(c1out
,Cache
,false);
1160 return _error
->Error(_("Internal error, InstallPackages was called with broken packages!"));
1163 if (Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
1164 Cache
->BadCount() == 0)
1168 if (Cache
->DelCount() != 0 && _config
->FindB("APT::Get::Remove",true) == false)
1169 return _error
->Error(_("Packages need to be removed but remove is disabled."));
1171 // Run the simulator ..
1172 if (_config
->FindB("APT::Get::Simulate") == true)
1174 pkgSimulate
PM(Cache
);
1175 int status_fd
= _config
->FindI("APT::Status-Fd",-1);
1176 pkgPackageManager::OrderResult Res
= PM
.DoInstall(status_fd
);
1177 if (Res
== pkgPackageManager::Failed
)
1179 if (Res
!= pkgPackageManager::Completed
)
1180 return _error
->Error(_("Internal error, Ordering didn't finish"));
1184 // Create the text record parser
1185 pkgRecords
Recs(Cache
);
1186 if (_error
->PendingError() == true)
1189 // Create the download object
1191 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
1192 if (_config
->FindB("APT::Get::Print-URIs", false) == true)
1194 // force a hashsum for compatibility reasons
1195 _config
->CndSet("Acquire::ForceHash", "md5sum");
1197 else if (Fetcher
.Setup(&Stat
, _config
->FindDir("Dir::Cache::Archives")) == false)
1200 // Read the source list
1201 if (Cache
.BuildSourceList() == false)
1203 pkgSourceList
*List
= Cache
.GetSourceList();
1205 // Create the package manager and prepare to download
1206 SPtr
<pkgPackageManager
> PM
= _system
->CreatePM(Cache
);
1207 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false ||
1208 _error
->PendingError() == true)
1211 // Display statistics
1212 unsigned long long FetchBytes
= Fetcher
.FetchNeeded();
1213 unsigned long long FetchPBytes
= Fetcher
.PartialPresent();
1214 unsigned long long DebBytes
= Fetcher
.TotalNeeded();
1215 if (DebBytes
!= Cache
->DebSize())
1217 c0out
<< DebBytes
<< ',' << Cache
->DebSize() << endl
;
1218 c0out
<< _("How odd.. The sizes didn't match, email apt@packages.debian.org") << endl
;
1222 if (DebBytes
!= FetchBytes
)
1223 //TRANSLATOR: The required space between number and unit is already included
1224 // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
1225 ioprintf(c1out
,_("Need to get %sB/%sB of archives.\n"),
1226 SizeToStr(FetchBytes
).c_str(),SizeToStr(DebBytes
).c_str());
1227 else if (DebBytes
!= 0)
1228 //TRANSLATOR: The required space between number and unit is already included
1229 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
1230 ioprintf(c1out
,_("Need to get %sB of archives.\n"),
1231 SizeToStr(DebBytes
).c_str());
1234 if (Cache
->UsrSize() >= 0)
1235 //TRANSLATOR: The required space between number and unit is already included
1236 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
1237 ioprintf(c1out
,_("After this operation, %sB of additional disk space will be used.\n"),
1238 SizeToStr(Cache
->UsrSize()).c_str());
1240 //TRANSLATOR: The required space between number and unit is already included
1241 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
1242 ioprintf(c1out
,_("After this operation, %sB disk space will be freed.\n"),
1243 SizeToStr(-1*Cache
->UsrSize()).c_str());
1245 if (_error
->PendingError() == true)
1248 /* Check for enough free space, but only if we are actually going to
1250 if (_config
->FindB("APT::Get::Print-URIs") == false &&
1251 _config
->FindB("APT::Get::Download",true) == true)
1254 string OutputDir
= _config
->FindDir("Dir::Cache::Archives");
1255 if (statvfs(OutputDir
.c_str(),&Buf
) != 0) {
1256 if (errno
== EOVERFLOW
)
1257 return _error
->WarningE("statvfs",_("Couldn't determine free space in %s"),
1260 return _error
->Errno("statvfs",_("Couldn't determine free space in %s"),
1262 } else if (unsigned(Buf
.f_bfree
) < (FetchBytes
- FetchPBytes
)/Buf
.f_bsize
)
1265 if (statfs(OutputDir
.c_str(),&Stat
) != 0
1266 #if HAVE_STRUCT_STATFS_F_TYPE
1267 || unsigned(Stat
.f_type
) != RAMFS_MAGIC
1270 return _error
->Error(_("You don't have enough free space in %s."),
1276 if (_config
->FindI("quiet",0) >= 2 ||
1277 _config
->FindB("APT::Get::Assume-Yes",false) == true)
1279 if (Fail
== true && _config
->FindB("APT::Get::Force-Yes",false) == false)
1280 return _error
->Error(_("There are problems and -y was used without --force-yes"));
1283 if (Essential
== true && Safety
== true)
1285 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
1286 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
1288 // TRANSLATOR: This string needs to be typed by the user as a confirmation, so be
1289 // careful with hard to type or special characters (like non-breaking spaces)
1290 const char *Prompt
= _("Yes, do as I say!");
1292 _("You are about to do something potentially harmful.\n"
1293 "To continue type in the phrase '%s'\n"
1296 if (AnalPrompt(Prompt
) == false)
1298 c2out
<< _("Abort.") << endl
;
1304 // Prompt to continue
1305 if (Ask
== true || Fail
== true)
1307 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
1308 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
1310 if (_config
->FindI("quiet",0) < 2 &&
1311 _config
->FindB("APT::Get::Assume-Yes",false) == false)
1313 c2out
<< _("Do you want to continue?") << flush
;
1315 if (YnPrompt() == false)
1317 c2out
<< _("Abort.") << endl
;
1324 // Just print out the uris an exit if the --print-uris flag was used
1325 if (_config
->FindB("APT::Get::Print-URIs") == true)
1327 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
1328 for (; I
!= Fetcher
.UriEnd(); ++I
)
1329 cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
1330 I
->Owner
->FileSize
<< ' ' << I
->Owner
->HashSum() << endl
;
1334 if (!CheckAuth(Fetcher
))
1337 /* Unlock the dpkg lock if we are not going to be doing an install
1339 if (_config
->FindB("APT::Get::Download-Only",false) == true)
1345 bool Transient
= false;
1346 if (_config
->FindB("APT::Get::Download",true) == false)
1348 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
< Fetcher
.ItemsEnd();)
1350 if ((*I
)->Local
== true)
1356 // Close the item and check if it was found in cache
1358 if ((*I
)->Complete
== false)
1361 // Clear it out of the fetch list
1363 I
= Fetcher
.ItemsBegin();
1367 if (Fetcher
.Run() == pkgAcquire::Failed
)
1371 bool Failed
= false;
1372 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); ++I
)
1374 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
1375 (*I
)->Complete
== true)
1378 if ((*I
)->Status
== pkgAcquire::Item::StatIdle
)
1385 fprintf(stderr
,_("Failed to fetch %s %s\n"),(*I
)->DescURI().c_str(),
1386 (*I
)->ErrorText
.c_str());
1390 /* If we are in no download mode and missing files and there were
1391 'failures' then the user must specify -m. Furthermore, there
1392 is no such thing as a transient error in no-download mode! */
1393 if (Transient
== true &&
1394 _config
->FindB("APT::Get::Download",true) == false)
1400 if (_config
->FindB("APT::Get::Download-Only",false) == true)
1402 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
1403 return _error
->Error(_("Some files failed to download"));
1404 c1out
<< _("Download complete and in download only mode") << endl
;
1408 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
1410 return _error
->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
1413 if (Transient
== true && Failed
== true)
1414 return _error
->Error(_("--fix-missing and media swapping is not currently supported"));
1416 // Try to deal with missing package files
1417 if (Failed
== true && PM
->FixMissing() == false)
1419 cerr
<< _("Unable to correct missing packages.") << endl
;
1420 return _error
->Error(_("Aborting install."));
1424 int status_fd
= _config
->FindI("APT::Status-Fd",-1);
1425 pkgPackageManager::OrderResult Res
= PM
->DoInstall(status_fd
);
1426 if (Res
== pkgPackageManager::Failed
|| _error
->PendingError() == true)
1428 if (Res
== pkgPackageManager::Completed
)
1431 // Reload the fetcher object and loop again for media swapping
1433 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false)
1439 std::set
<std::string
> const disappearedPkgs
= PM
->GetDisappearedPackages();
1440 if (disappearedPkgs
.empty() == true)
1444 for (std::set
<std::string
>::const_iterator d
= disappearedPkgs
.begin();
1445 d
!= disappearedPkgs
.end(); ++d
)
1446 disappear
.append(*d
).append(" ");
1448 ShowList(c1out
, P_("The following package disappeared from your system as\n"
1449 "all files have been overwritten by other packages:",
1450 "The following packages disappeared from your system as\n"
1451 "all files have been overwritten by other packages:", disappearedPkgs
.size()), disappear
, "");
1452 c0out
<< _("Note: This is done automatically and on purpose by dpkg.") << std::endl
;
1457 // TryToInstallBuildDep - Try to install a single package /*{{{*/
1458 // ---------------------------------------------------------------------
1459 /* This used to be inlined in DoInstall, but with the advent of regex package
1460 name matching it was split out.. */
1461 bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg
,pkgCacheFile
&Cache
,
1462 pkgProblemResolver
&Fix
,bool Remove
,bool BrokenFix
,
1463 bool AllowFail
= true)
1465 if (Cache
[Pkg
].CandidateVer
== 0 && Pkg
->ProvidesList
!= 0)
1467 CacheSetHelperAPTGet
helper(c1out
);
1468 helper
.showErrors(false);
1469 pkgCache::VerIterator Ver
= helper
.canNotFindNewestVer(Cache
, Pkg
);
1470 if (Ver
.end() == false)
1471 Pkg
= Ver
.ParentPkg();
1472 else if (helper
.showVirtualPackageErrors(Cache
) == false)
1476 if (_config
->FindB("Debug::BuildDeps",false) == true)
1479 cout
<< " Trying to remove " << Pkg
<< endl
;
1481 cout
<< " Trying to install " << Pkg
<< endl
;
1486 TryToRemove
RemoveAction(Cache
, &Fix
);
1487 RemoveAction(Pkg
.VersionList());
1488 } else if (Cache
[Pkg
].CandidateVer
!= 0) {
1489 TryToInstall
InstallAction(Cache
, &Fix
, BrokenFix
);
1490 InstallAction(Cache
[Pkg
].CandidateVerIter(Cache
));
1491 InstallAction
.doAutoInstall();
1498 // FindSrc - Find a source record /*{{{*/
1499 // ---------------------------------------------------------------------
1501 pkgSrcRecords::Parser
*FindSrc(const char *Name
,pkgRecords
&Recs
,
1502 pkgSrcRecords
&SrcRecs
,string
&Src
,
1506 string DefRel
= _config
->Find("APT::Default-Release");
1507 string TmpSrc
= Name
;
1509 // extract the version/release from the pkgname
1510 const size_t found
= TmpSrc
.find_last_of("/=");
1511 if (found
!= string::npos
) {
1512 if (TmpSrc
[found
] == '/')
1513 DefRel
= TmpSrc
.substr(found
+1);
1515 VerTag
= TmpSrc
.substr(found
+1);
1516 TmpSrc
= TmpSrc
.substr(0,found
);
1519 /* Lookup the version of the package we would install if we were to
1520 install a version and determine the source package name, then look
1521 in the archive for a source package of the same name. */
1522 bool MatchSrcOnly
= _config
->FindB("APT::Get::Only-Source");
1523 const pkgCache::PkgIterator Pkg
= Cache
.FindPkg(TmpSrc
);
1524 if (MatchSrcOnly
== false && Pkg
.end() == false)
1526 if(VerTag
.empty() == false || DefRel
.empty() == false)
1529 // we have a default release, try to locate the pkg. we do it like
1530 // this because GetCandidateVer() will not "downgrade", that means
1531 // "apt-get source -t stable apt" won't work on a unstable system
1532 for (pkgCache::VerIterator Ver
= Pkg
.VersionList();; ++Ver
)
1534 // try first only exact matches, later fuzzy matches
1535 if (Ver
.end() == true)
1540 Ver
= Pkg
.VersionList();
1541 // exit right away from the Pkg.VersionList() loop if we
1542 // don't have any versions
1543 if (Ver
.end() == true)
1546 // We match against a concrete version (or a part of this version)
1547 if (VerTag
.empty() == false &&
1548 (fuzzy
== true || Cache
.VS().CmpVersion(VerTag
, Ver
.VerStr()) != 0) && // exact match
1549 (fuzzy
== false || strncmp(VerTag
.c_str(), Ver
.VerStr(), VerTag
.size()) != 0)) // fuzzy match
1552 for (pkgCache::VerFileIterator VF
= Ver
.FileList();
1553 VF
.end() == false; ++VF
)
1555 /* If this is the status file, and the current version is not the
1556 version in the status file (ie it is not installed, or somesuch)
1557 then it is not a candidate for installation, ever. This weeds
1558 out bogus entries that may be due to config-file states, or
1560 if ((VF
.File()->Flags
& pkgCache::Flag::NotSource
) ==
1561 pkgCache::Flag::NotSource
&& Pkg
.CurrentVer() != Ver
)
1564 // or we match against a release
1565 if(VerTag
.empty() == false ||
1566 (VF
.File().Archive() != 0 && VF
.File().Archive() == DefRel
) ||
1567 (VF
.File().Codename() != 0 && VF
.File().Codename() == DefRel
))
1569 pkgRecords::Parser
&Parse
= Recs
.Lookup(VF
);
1570 Src
= Parse
.SourcePkg();
1571 // no SourcePkg name, so it is the "binary" name
1572 if (Src
.empty() == true)
1574 // the Version we have is possibly fuzzy or includes binUploads,
1575 // so we use the Version of the SourcePkg (empty if same as package)
1576 VerTag
= Parse
.SourceVer();
1577 if (VerTag
.empty() == true)
1578 VerTag
= Ver
.VerStr();
1582 if (Src
.empty() == false)
1585 if (Src
.empty() == true)
1587 // Sources files have no codename information
1588 if (VerTag
.empty() == true && DefRel
.empty() == false)
1590 _error
->Error(_("Ignore unavailable target release '%s' of package '%s'"), DefRel
.c_str(), TmpSrc
.c_str());
1595 if (Src
.empty() == true)
1597 // if we don't have found a fitting package yet so we will
1598 // choose a good candidate and proceed with that.
1599 // Maybe we will find a source later on with the right VerTag
1600 pkgCache::VerIterator Ver
= Cache
.GetCandidateVer(Pkg
);
1601 if (Ver
.end() == false)
1603 pkgRecords::Parser
&Parse
= Recs
.Lookup(Ver
.FileList());
1604 Src
= Parse
.SourcePkg();
1605 if (VerTag
.empty() == true)
1606 VerTag
= Parse
.SourceVer();
1611 if (Src
.empty() == true)
1615 /* if we have a source pkg name, make sure to only search
1616 for srcpkg names, otherwise apt gets confused if there
1617 is a binary package "pkg1" and a source package "pkg1"
1618 with the same name but that comes from different packages */
1619 MatchSrcOnly
= true;
1622 ioprintf(c1out
, _("Picking '%s' as source package instead of '%s'\n"), Src
.c_str(), TmpSrc
.c_str());
1627 pkgSrcRecords::Parser
*Last
= 0;
1628 unsigned long Offset
= 0;
1631 /* Iterate over all of the hits, which includes the resulting
1632 binary packages in the search */
1633 pkgSrcRecords::Parser
*Parse
;
1637 while ((Parse
= SrcRecs
.Find(Src
.c_str(), MatchSrcOnly
)) != 0)
1639 const string Ver
= Parse
->Version();
1641 // Ignore all versions which doesn't fit
1642 if (VerTag
.empty() == false &&
1643 Cache
.VS().CmpVersion(VerTag
, Ver
) != 0) // exact match
1646 // Newer version or an exact match? Save the hit
1647 if (Last
== 0 || Cache
.VS().CmpVersion(Version
,Ver
) < 0) {
1649 Offset
= Parse
->Offset();
1653 // was the version check above an exact match? If so, we don't need to look further
1654 if (VerTag
.empty() == false && VerTag
.size() == Ver
.size())
1657 if (Last
!= 0 || VerTag
.empty() == true)
1659 //if (VerTag.empty() == false && Last == 0)
1660 _error
->Error(_("Ignore unavailable version '%s' of package '%s'"), VerTag
.c_str(), TmpSrc
.c_str());
1664 if (Last
== 0 || Last
->Jump(Offset
) == false)
1670 // DoUpdate - Update the package lists /*{{{*/
1671 // ---------------------------------------------------------------------
1673 bool DoUpdate(CommandLine
&CmdL
)
1675 if (CmdL
.FileSize() != 1)
1676 return _error
->Error(_("The update command takes no arguments"));
1680 // Get the source list
1681 if (Cache
.BuildSourceList() == false)
1683 pkgSourceList
*List
= Cache
.GetSourceList();
1685 // Create the progress
1686 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
1688 // Just print out the uris an exit if the --print-uris flag was used
1689 if (_config
->FindB("APT::Get::Print-URIs") == true)
1691 // force a hashsum for compatibility reasons
1692 _config
->CndSet("Acquire::ForceHash", "md5sum");
1696 if (Fetcher
.Setup(&Stat
) == false)
1699 // Populate it with the source selection and get all Indexes
1701 if (List
->GetIndexes(&Fetcher
,true) == false)
1704 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
1705 for (; I
!= Fetcher
.UriEnd(); ++I
)
1706 cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
1707 I
->Owner
->FileSize
<< ' ' << I
->Owner
->HashSum() << endl
;
1712 if (_config
->FindB("APT::Get::Download",true) == true)
1713 ListUpdate(Stat
, *List
);
1715 // Rebuild the cache.
1716 if (_config
->FindB("pkgCacheFile::Generate", true) == true)
1718 pkgCacheFile::RemoveCaches();
1719 if (Cache
.BuildCaches() == false)
1726 // DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
1727 // ---------------------------------------------------------------------
1728 /* Remove unused automatic packages */
1729 bool DoAutomaticRemove(CacheFile
&Cache
)
1731 bool Debug
= _config
->FindI("Debug::pkgAutoRemove",false);
1732 bool doAutoRemove
= _config
->FindB("APT::Get::AutomaticRemove", false);
1733 bool hideAutoRemove
= _config
->FindB("APT::Get::HideAutoRemove");
1735 pkgDepCache::ActionGroup
group(*Cache
);
1737 std::cout
<< "DoAutomaticRemove()" << std::endl
;
1739 if (doAutoRemove
== true &&
1740 _config
->FindB("APT::Get::Remove",true) == false)
1742 c1out
<< _("We are not supposed to delete stuff, can't start "
1743 "AutoRemover") << std::endl
;
1747 bool purgePkgs
= _config
->FindB("APT::Get::Purge", false);
1748 bool smallList
= (hideAutoRemove
== false &&
1749 strcasecmp(_config
->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
1751 unsigned long autoRemoveCount
= 0;
1752 APT::PackageSet tooMuch
;
1753 APT::PackageList autoRemoveList
;
1754 // look over the cache to see what can be removed
1755 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; ++J
)
1757 pkgCache::PkgIterator
Pkg(Cache
,Cache
.List
[J
]);
1758 if (Cache
[Pkg
].Garbage
)
1760 if(Pkg
.CurrentVer() != 0 || Cache
[Pkg
].Install())
1762 std::cout
<< "We could delete %s" << Pkg
.FullName(true).c_str() << std::endl
;
1766 if(Pkg
.CurrentVer() != 0 &&
1767 Pkg
->CurrentState
!= pkgCache::State::ConfigFiles
)
1768 Cache
->MarkDelete(Pkg
, purgePkgs
, 0, false);
1770 Cache
->MarkKeep(Pkg
, false, false);
1774 if (hideAutoRemove
== false && Cache
[Pkg
].Delete() == false)
1775 autoRemoveList
.insert(Pkg
);
1776 // if the package is a new install and already garbage we don't need to
1777 // install it in the first place, so nuke it instead of show it
1778 if (Cache
[Pkg
].Install() == true && Pkg
.CurrentVer() == 0)
1780 if (Pkg
.CandVersion() != 0)
1781 tooMuch
.insert(Pkg
);
1782 Cache
->MarkDelete(Pkg
, false, 0, false);
1784 // only show stuff in the list that is not yet marked for removal
1785 else if(hideAutoRemove
== false && Cache
[Pkg
].Delete() == false)
1791 // we could have removed a new dependency of a garbage package,
1792 // so check if a reverse depends is broken and if so install it again.
1793 if (tooMuch
.empty() == false && (Cache
->BrokenCount() != 0 || Cache
->PolicyBrokenCount() != 0))
1798 for (APT::PackageSet::const_iterator Pkg
= tooMuch
.begin();
1799 Pkg
!= tooMuch
.end() && Changed
== false; ++Pkg
)
1801 APT::PackageSet too
;
1803 for (pkgCache::PrvIterator Prv
= Cache
[Pkg
].CandidateVerIter(Cache
).ProvidesList();
1804 Prv
.end() == false; ++Prv
)
1805 too
.insert(Prv
.ParentPkg());
1806 for (APT::PackageSet::const_iterator P
= too
.begin();
1807 P
!= too
.end() && Changed
== false; ++P
) {
1808 for (pkgCache::DepIterator R
= P
.RevDependsList();
1809 R
.end() == false; ++R
)
1811 if (R
.IsNegative() == true ||
1812 Cache
->IsImportantDep(R
) == false)
1814 pkgCache::PkgIterator N
= R
.ParentPkg();
1815 if (N
.end() == true || (N
->CurrentVer
== 0 && (*Cache
)[N
].Install() == false))
1818 std::clog
<< "Save " << Pkg
<< " as another installed garbage package depends on it" << std::endl
;
1819 Cache
->MarkInstall(Pkg
, false, 0, false);
1820 if (hideAutoRemove
== false)
1828 } while (Changed
== true);
1831 std::string autoremovelist
, autoremoveversions
;
1832 if (smallList
== false && autoRemoveCount
!= 0)
1834 for (APT::PackageList::const_iterator Pkg
= autoRemoveList
.begin(); Pkg
!= autoRemoveList
.end(); ++Pkg
)
1836 if (Cache
[Pkg
].Garbage
== false)
1838 autoremovelist
+= Pkg
.FullName(true) + " ";
1839 autoremoveversions
+= string(Cache
[Pkg
].CandVersion
) + "\n";
1843 // Now see if we had destroyed anything (if we had done anything)
1844 if (Cache
->BrokenCount() != 0)
1846 c1out
<< _("Hmm, seems like the AutoRemover destroyed something which really\n"
1847 "shouldn't happen. Please file a bug report against apt.") << endl
;
1849 c1out
<< _("The following information may help to resolve the situation:") << endl
;
1851 ShowBroken(c1out
,Cache
,false);
1853 return _error
->Error(_("Internal Error, AutoRemover broke stuff"));
1856 // if we don't remove them, we should show them!
1857 if (doAutoRemove
== false && (autoremovelist
.empty() == false || autoRemoveCount
!= 0))
1859 if (smallList
== false)
1860 ShowList(c1out
, P_("The following package was automatically installed and is no longer required:",
1861 "The following packages were automatically installed and are no longer required:",
1862 autoRemoveCount
), autoremovelist
, autoremoveversions
);
1864 ioprintf(c1out
, P_("%lu package was automatically installed and is no longer required.\n",
1865 "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount
), autoRemoveCount
);
1866 c1out
<< P_("Use 'apt-get autoremove' to remove it.", "Use 'apt-get autoremove' to remove them.", autoRemoveCount
) << std::endl
;
1871 // DoUpgrade - Upgrade all packages /*{{{*/
1872 // ---------------------------------------------------------------------
1873 /* Upgrade all packages without installing new packages or erasing old
1875 bool DoUpgrade(CommandLine
&CmdL
)
1878 if (Cache
.OpenForInstall() == false || Cache
.CheckDeps() == false)
1882 if (pkgAllUpgrade(Cache
) == false)
1884 ShowBroken(c1out
,Cache
,false);
1885 return _error
->Error(_("Internal error, AllUpgrade broke stuff"));
1888 return InstallPackages(Cache
,true);
1891 // DoInstall - Install packages from the command line /*{{{*/
1892 // ---------------------------------------------------------------------
1893 /* Install named packages */
1894 bool DoInstall(CommandLine
&CmdL
)
1897 if (Cache
.OpenForInstall() == false ||
1898 Cache
.CheckDeps(CmdL
.FileSize() != 1) == false)
1901 // Enter the special broken fixing mode if the user specified arguments
1902 bool BrokenFix
= false;
1903 if (Cache
->BrokenCount() != 0)
1906 pkgProblemResolver
* Fix
= NULL
;
1907 if (_config
->FindB("APT::Get::CallResolver", true) == true)
1908 Fix
= new pkgProblemResolver(Cache
);
1910 static const unsigned short MOD_REMOVE
= 1;
1911 static const unsigned short MOD_INSTALL
= 2;
1913 unsigned short fallback
= MOD_INSTALL
;
1914 if (strcasecmp(CmdL
.FileList
[0],"remove") == 0)
1915 fallback
= MOD_REMOVE
;
1916 else if (strcasecmp(CmdL
.FileList
[0], "purge") == 0)
1918 _config
->Set("APT::Get::Purge", true);
1919 fallback
= MOD_REMOVE
;
1921 else if (strcasecmp(CmdL
.FileList
[0], "autoremove") == 0)
1923 _config
->Set("APT::Get::AutomaticRemove", "true");
1924 fallback
= MOD_REMOVE
;
1927 std::list
<APT::VersionSet::Modifier
> mods
;
1928 mods
.push_back(APT::VersionSet::Modifier(MOD_INSTALL
, "+",
1929 APT::VersionSet::Modifier::POSTFIX
, APT::VersionSet::CANDIDATE
));
1930 mods
.push_back(APT::VersionSet::Modifier(MOD_REMOVE
, "-",
1931 APT::VersionSet::Modifier::POSTFIX
, APT::VersionSet::NEWEST
));
1932 CacheSetHelperAPTGet
helper(c0out
);
1933 std::map
<unsigned short, APT::VersionSet
> verset
= APT::VersionSet::GroupedFromCommandLine(Cache
,
1934 CmdL
.FileList
+ 1, mods
, fallback
, helper
);
1936 if (_error
->PendingError() == true)
1938 helper
.showVirtualPackageErrors(Cache
);
1945 TryToInstall
InstallAction(Cache
, Fix
, BrokenFix
);
1946 TryToRemove
RemoveAction(Cache
, Fix
);
1948 // new scope for the ActionGroup
1950 pkgDepCache::ActionGroup
group(Cache
);
1951 unsigned short const order
[] = { MOD_REMOVE
, MOD_INSTALL
, 0 };
1953 for (unsigned short i
= 0; order
[i
] != 0; ++i
)
1955 if (order
[i
] == MOD_INSTALL
)
1956 InstallAction
= std::for_each(verset
[MOD_INSTALL
].begin(), verset
[MOD_INSTALL
].end(), InstallAction
);
1957 else if (order
[i
] == MOD_REMOVE
)
1958 RemoveAction
= std::for_each(verset
[MOD_REMOVE
].begin(), verset
[MOD_REMOVE
].end(), RemoveAction
);
1961 if (Fix
!= NULL
&& _config
->FindB("APT::Get::AutoSolving", true) == true)
1963 for (unsigned short i
= 0; order
[i
] != 0; ++i
)
1965 if (order
[i
] != MOD_INSTALL
)
1967 InstallAction
.propergateReleaseCandiateSwitching(helper
.selectedByRelease
, c0out
);
1968 InstallAction
.doAutoInstall();
1972 if (_error
->PendingError() == true)
1979 /* If we are in the Broken fixing mode we do not attempt to fix the
1980 problems. This is if the user invoked install without -f and gave
1982 if (BrokenFix
== true && Cache
->BrokenCount() != 0)
1984 c1out
<< _("You might want to run 'apt-get -f install' to correct these:") << endl
;
1985 ShowBroken(c1out
,Cache
,false);
1988 return _error
->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
1993 // Call the scored problem resolver
1998 // Now we check the state of the packages,
1999 if (Cache
->BrokenCount() != 0)
2002 _("Some packages could not be installed. This may mean that you have\n"
2003 "requested an impossible situation or if you are using the unstable\n"
2004 "distribution that some required packages have not yet been created\n"
2005 "or been moved out of Incoming.") << endl
;
2011 _("Since you only requested a single operation it is extremely likely that\n"
2012 "the package is simply not installable and a bug report against\n"
2013 "that package should be filed.") << endl;
2017 c1out
<< _("The following information may help to resolve the situation:") << endl
;
2019 ShowBroken(c1out
,Cache
,false);
2020 if (_error
->PendingError() == true)
2023 return _error
->Error(_("Broken packages"));
2026 if (!DoAutomaticRemove(Cache
))
2029 /* Print out a list of packages that are going to be installed extra
2030 to what the user asked */
2031 if (Cache
->InstCount() != verset
[MOD_INSTALL
].size())
2034 string VersionsList
;
2035 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
2037 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
2038 if ((*Cache
)[I
].Install() == false)
2040 pkgCache::VerIterator Cand
= Cache
[I
].CandidateVerIter(Cache
);
2042 if (verset
[MOD_INSTALL
].find(Cand
) != verset
[MOD_INSTALL
].end())
2045 List
+= I
.FullName(true) + " ";
2046 VersionsList
+= string(Cache
[I
].CandVersion
) + "\n";
2049 ShowList(c1out
,_("The following extra packages will be installed:"),List
,VersionsList
);
2052 /* Print out a list of suggested and recommended packages */
2054 string SuggestsList
, RecommendsList
;
2055 string SuggestsVersions
, RecommendsVersions
;
2056 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
2058 pkgCache::PkgIterator
Pkg(Cache
,Cache
.List
[J
]);
2060 /* Just look at the ones we want to install */
2061 if ((*Cache
)[Pkg
].Install() == false)
2064 // get the recommends/suggests for the candidate ver
2065 pkgCache::VerIterator CV
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
2066 for (pkgCache::DepIterator D
= CV
.DependsList(); D
.end() == false; )
2068 pkgCache::DepIterator Start
;
2069 pkgCache::DepIterator End
;
2070 D
.GlobOr(Start
,End
); // advances D
2072 // FIXME: we really should display a or-group as a or-group to the user
2073 // the problem is that ShowList is incapable of doing this
2074 string RecommendsOrList
,RecommendsOrVersions
;
2075 string SuggestsOrList
,SuggestsOrVersions
;
2076 bool foundInstalledInOrGroup
= false;
2079 /* Skip if package is installed already, or is about to be */
2080 string target
= Start
.TargetPkg().FullName(true) + " ";
2081 pkgCache::PkgIterator
const TarPkg
= Start
.TargetPkg();
2082 if (TarPkg
->SelectedState
== pkgCache::State::Install
||
2083 TarPkg
->SelectedState
== pkgCache::State::Hold
||
2084 Cache
[Start
.TargetPkg()].Install())
2086 foundInstalledInOrGroup
=true;
2090 /* Skip if we already saw it */
2091 if (int(SuggestsList
.find(target
)) != -1 || int(RecommendsList
.find(target
)) != -1)
2093 foundInstalledInOrGroup
=true;
2097 // this is a dep on a virtual pkg, check if any package that provides it
2098 // should be installed
2099 if(Start
.TargetPkg().ProvidesList() != 0)
2101 pkgCache::PrvIterator I
= Start
.TargetPkg().ProvidesList();
2102 for (; I
.end() == false; ++I
)
2104 pkgCache::PkgIterator Pkg
= I
.OwnerPkg();
2105 if (Cache
[Pkg
].CandidateVerIter(Cache
) == I
.OwnerVer() &&
2106 Pkg
.CurrentVer() != 0)
2107 foundInstalledInOrGroup
=true;
2111 if (Start
->Type
== pkgCache::Dep::Suggests
)
2113 SuggestsOrList
+= target
;
2114 SuggestsOrVersions
+= string(Cache
[Start
.TargetPkg()].CandVersion
) + "\n";
2117 if (Start
->Type
== pkgCache::Dep::Recommends
)
2119 RecommendsOrList
+= target
;
2120 RecommendsOrVersions
+= string(Cache
[Start
.TargetPkg()].CandVersion
) + "\n";
2128 if(foundInstalledInOrGroup
== false)
2130 RecommendsList
+= RecommendsOrList
;
2131 RecommendsVersions
+= RecommendsOrVersions
;
2132 SuggestsList
+= SuggestsOrList
;
2133 SuggestsVersions
+= SuggestsOrVersions
;
2139 ShowList(c1out
,_("Suggested packages:"),SuggestsList
,SuggestsVersions
);
2140 ShowList(c1out
,_("Recommended packages:"),RecommendsList
,RecommendsVersions
);
2144 // if nothing changed in the cache, but only the automark information
2145 // we write the StateFile here, otherwise it will be written in
2147 if (InstallAction
.AutoMarkChanged
> 0 &&
2148 Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
2149 Cache
->BadCount() == 0 &&
2150 _config
->FindB("APT::Get::Simulate",false) == false)
2151 Cache
->writeStateFile(NULL
);
2153 // See if we need to prompt
2154 // FIXME: check if really the packages in the set are going to be installed
2155 if (Cache
->InstCount() == verset
[MOD_INSTALL
].size() && Cache
->DelCount() == 0)
2156 return InstallPackages(Cache
,false,false);
2158 return InstallPackages(Cache
,false);
2161 /* mark packages as automatically/manually installed. {{{*/
2162 bool DoMarkAuto(CommandLine
&CmdL
)
2165 int AutoMarkChanged
= 0;
2166 OpTextProgress progress
;
2168 if (Cache
.Open() == false)
2171 if (strcasecmp(CmdL
.FileList
[0],"markauto") == 0)
2173 else if (strcasecmp(CmdL
.FileList
[0],"unmarkauto") == 0)
2176 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
2179 // Locate the package
2180 pkgCache::PkgIterator Pkg
= Cache
->FindPkg(S
);
2181 if (Pkg
.end() == true) {
2182 return _error
->Error(_("Couldn't find package %s"),S
);
2187 ioprintf(c1out
,_("%s set to manually installed.\n"), Pkg
.Name());
2189 ioprintf(c1out
,_("%s set to automatically installed.\n"),
2192 Cache
->MarkAuto(Pkg
,Action
);
2197 _error
->Notice(_("This command is deprecated. Please use 'apt-mark auto' and 'apt-mark manual' instead."));
2199 if (AutoMarkChanged
&& ! _config
->FindB("APT::Get::Simulate",false))
2200 return Cache
->writeStateFile(NULL
);
2204 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
2205 // ---------------------------------------------------------------------
2206 /* Intelligent upgrader that will install and remove packages at will */
2207 bool DoDistUpgrade(CommandLine
&CmdL
)
2210 if (Cache
.OpenForInstall() == false || Cache
.CheckDeps() == false)
2213 c0out
<< _("Calculating upgrade... ") << flush
;
2214 if (pkgDistUpgrade(*Cache
) == false)
2216 c0out
<< _("Failed") << endl
;
2217 ShowBroken(c1out
,Cache
,false);
2221 c0out
<< _("Done") << endl
;
2223 return InstallPackages(Cache
,true);
2226 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
2227 // ---------------------------------------------------------------------
2228 /* Follows dselect's selections */
2229 bool DoDSelectUpgrade(CommandLine
&CmdL
)
2232 if (Cache
.OpenForInstall() == false || Cache
.CheckDeps() == false)
2235 pkgDepCache::ActionGroup
group(Cache
);
2237 // Install everything with the install flag set
2238 pkgCache::PkgIterator I
= Cache
->PkgBegin();
2239 for (;I
.end() != true; ++I
)
2241 /* Install the package only if it is a new install, the autoupgrader
2242 will deal with the rest */
2243 if (I
->SelectedState
== pkgCache::State::Install
)
2244 Cache
->MarkInstall(I
,false);
2247 /* Now install their deps too, if we do this above then order of
2248 the status file is significant for | groups */
2249 for (I
= Cache
->PkgBegin();I
.end() != true; ++I
)
2251 /* Install the package only if it is a new install, the autoupgrader
2252 will deal with the rest */
2253 if (I
->SelectedState
== pkgCache::State::Install
)
2254 Cache
->MarkInstall(I
,true);
2257 // Apply erasures now, they override everything else.
2258 for (I
= Cache
->PkgBegin();I
.end() != true; ++I
)
2261 if (I
->SelectedState
== pkgCache::State::DeInstall
||
2262 I
->SelectedState
== pkgCache::State::Purge
)
2263 Cache
->MarkDelete(I
,I
->SelectedState
== pkgCache::State::Purge
);
2266 /* Resolve any problems that dselect created, allupgrade cannot handle
2267 such things. We do so quite agressively too.. */
2268 if (Cache
->BrokenCount() != 0)
2270 pkgProblemResolver
Fix(Cache
);
2272 // Hold back held packages.
2273 if (_config
->FindB("APT::Ignore-Hold",false) == false)
2275 for (pkgCache::PkgIterator I
= Cache
->PkgBegin(); I
.end() == false; ++I
)
2277 if (I
->SelectedState
== pkgCache::State::Hold
)
2285 if (Fix
.Resolve() == false)
2287 ShowBroken(c1out
,Cache
,false);
2288 return _error
->Error(_("Internal error, problem resolver broke stuff"));
2292 // Now upgrade everything
2293 if (pkgAllUpgrade(Cache
) == false)
2295 ShowBroken(c1out
,Cache
,false);
2296 return _error
->Error(_("Internal error, problem resolver broke stuff"));
2299 return InstallPackages(Cache
,false);
2302 // DoClean - Remove download archives /*{{{*/
2303 // ---------------------------------------------------------------------
2305 bool DoClean(CommandLine
&CmdL
)
2307 std::string
const archivedir
= _config
->FindDir("Dir::Cache::archives");
2308 std::string
const pkgcache
= _config
->FindFile("Dir::cache::pkgcache");
2309 std::string
const srcpkgcache
= _config
->FindFile("Dir::cache::srcpkgcache");
2311 if (_config
->FindB("APT::Get::Simulate") == true)
2313 cout
<< "Del " << archivedir
<< "* " << archivedir
<< "partial/*"<< endl
2314 << "Del " << pkgcache
<< " " << srcpkgcache
<< endl
;
2318 // Lock the archive directory
2320 if (_config
->FindB("Debug::NoLocking",false) == false)
2322 int lock_fd
= GetLock(archivedir
+ "lock");
2324 return _error
->Error(_("Unable to lock the download directory"));
2329 Fetcher
.Clean(archivedir
);
2330 Fetcher
.Clean(archivedir
+ "partial/");
2332 pkgCacheFile::RemoveCaches();
2337 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
2338 // ---------------------------------------------------------------------
2339 /* This is similar to clean but it only purges things that cannot be
2340 downloaded, that is old versions of cached packages. */
2341 class LogCleaner
: public pkgArchiveCleaner
2344 virtual void Erase(const char *File
,string Pkg
,string Ver
,struct stat
&St
)
2346 c1out
<< "Del " << Pkg
<< " " << Ver
<< " [" << SizeToStr(St
.st_size
) << "B]" << endl
;
2348 if (_config
->FindB("APT::Get::Simulate") == false)
2353 bool DoAutoClean(CommandLine
&CmdL
)
2355 // Lock the archive directory
2357 if (_config
->FindB("Debug::NoLocking",false) == false)
2359 int lock_fd
= GetLock(_config
->FindDir("Dir::Cache::Archives") + "lock");
2361 return _error
->Error(_("Unable to lock the download directory"));
2366 if (Cache
.Open() == false)
2371 return Cleaner
.Go(_config
->FindDir("Dir::Cache::archives"),*Cache
) &&
2372 Cleaner
.Go(_config
->FindDir("Dir::Cache::archives") + "partial/",*Cache
);
2375 // DoDownload - download a binary /*{{{*/
2376 // ---------------------------------------------------------------------
2377 bool DoDownload(CommandLine
&CmdL
)
2380 if (Cache
.ReadOnlyOpen() == false)
2383 APT::CacheSetHelper
helper(c0out
);
2384 APT::VersionList verset
= APT::VersionList::FromCommandLine(Cache
,
2385 CmdL
.FileList
+ 1, APT::VersionList::CANDIDATE
, helper
);
2387 if (verset
.empty() == true)
2391 AcqTextStatus
Stat(ScreenWidth
, _config
->FindI("quiet",0));
2392 if (_config
->FindB("APT::Get::Print-URIs") == false)
2393 Fetcher
.Setup(&Stat
);
2395 pkgRecords
Recs(Cache
);
2396 pkgSourceList
*SrcList
= Cache
.GetSourceList();
2399 for (APT::VersionList::const_iterator Ver
= verset
.begin();
2400 Ver
!= verset
.end();
2404 // get the right version
2405 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
2406 pkgRecords::Parser
&rec
=Recs
.Lookup(Ver
.FileList());
2407 pkgCache::VerFileIterator Vf
= Ver
.FileList();
2408 if (Vf
.end() == true)
2410 _error
->Error("Can not find VerFile for %s in version %s", Pkg
.FullName().c_str(), Ver
.VerStr());
2414 pkgCache::PkgFileIterator F
= Vf
.File();
2415 pkgIndexFile
*index
;
2416 if(SrcList
->FindIndex(F
, index
) == false)
2418 _error
->Error(_("Can't find a source to download version '%s' of '%s'"), Ver
.VerStr(), Pkg
.FullName().c_str());
2422 string uri
= index
->ArchiveURI(rec
.FileName());
2423 strprintf(descr
, _("Downloading %s %s"), Pkg
.Name(), Ver
.VerStr());
2424 // get the most appropriate hash
2426 if (rec
.SHA512Hash() != "")
2427 hash
= HashString("sha512", rec
.SHA512Hash());
2428 else if (rec
.SHA256Hash() != "")
2429 hash
= HashString("sha256", rec
.SHA256Hash());
2430 else if (rec
.SHA1Hash() != "")
2431 hash
= HashString("sha1", rec
.SHA1Hash());
2432 else if (rec
.MD5Hash() != "")
2433 hash
= HashString("md5", rec
.MD5Hash());
2435 new pkgAcqFile(&Fetcher
, uri
, hash
.toStr(), (*Ver
)->Size
, descr
, Pkg
.Name(), ".");
2437 if (gotAll
== false)
2440 // Just print out the uris and exit if the --print-uris flag was used
2441 if (_config
->FindB("APT::Get::Print-URIs") == true)
2443 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
2444 for (; I
!= Fetcher
.UriEnd(); ++I
)
2445 cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
2446 I
->Owner
->FileSize
<< ' ' << I
->Owner
->HashSum() << endl
;
2450 return (Fetcher
.Run() == pkgAcquire::Continue
);
2453 // DoCheck - Perform the check operation /*{{{*/
2454 // ---------------------------------------------------------------------
2455 /* Opening automatically checks the system, this command is mostly used
2457 bool DoCheck(CommandLine
&CmdL
)
2466 // DoSource - Fetch a source archive /*{{{*/
2467 // ---------------------------------------------------------------------
2468 /* Fetch souce packages */
2476 bool DoSource(CommandLine
&CmdL
)
2479 if (Cache
.Open(false) == false)
2482 if (CmdL
.FileSize() <= 1)
2483 return _error
->Error(_("Must specify at least one package to fetch source for"));
2485 // Read the source list
2486 if (Cache
.BuildSourceList() == false)
2488 pkgSourceList
*List
= Cache
.GetSourceList();
2490 // Create the text record parsers
2491 pkgRecords
Recs(Cache
);
2492 pkgSrcRecords
SrcRecs(*List
);
2493 if (_error
->PendingError() == true)
2496 // Create the download object
2497 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
2499 Fetcher
.SetLog(&Stat
);
2501 DscFile
*Dsc
= new DscFile
[CmdL
.FileSize()];
2503 // insert all downloaded uris into this set to avoid downloading them
2507 // Diff only mode only fetches .diff files
2508 bool const diffOnly
= _config
->FindB("APT::Get::Diff-Only", false);
2509 // Tar only mode only fetches .tar files
2510 bool const tarOnly
= _config
->FindB("APT::Get::Tar-Only", false);
2511 // Dsc only mode only fetches .dsc files
2512 bool const dscOnly
= _config
->FindB("APT::Get::Dsc-Only", false);
2514 // Load the requestd sources into the fetcher
2516 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++, J
++)
2519 pkgSrcRecords::Parser
*Last
= FindSrc(*I
,Recs
,SrcRecs
,Src
,*Cache
);
2523 return _error
->Error(_("Unable to find a source package for %s"),Src
.c_str());
2526 string srec
= Last
->AsStr();
2527 string::size_type pos
= srec
.find("\nVcs-");
2528 while (pos
!= string::npos
)
2530 pos
+= strlen("\nVcs-");
2531 string vcs
= srec
.substr(pos
,srec
.find(":",pos
)-pos
);
2532 if(vcs
== "Browser")
2534 pos
= srec
.find("\nVcs-", pos
);
2537 pos
+= vcs
.length()+2;
2538 string::size_type epos
= srec
.find("\n", pos
);
2539 string uri
= srec
.substr(pos
,epos
-pos
).c_str();
2540 ioprintf(c1out
, _("NOTICE: '%s' packaging is maintained in "
2541 "the '%s' version control system at:\n"
2543 Src
.c_str(), vcs
.c_str(), uri
.c_str());
2545 ioprintf(c1out
,_("Please use:\n"
2547 "to retrieve the latest (possibly unreleased) "
2548 "updates to the package.\n"),
2554 vector
<pkgSrcRecords::File
> Lst
;
2555 if (Last
->Files(Lst
) == false) {
2560 // Load them into the fetcher
2561 for (vector
<pkgSrcRecords::File
>::const_iterator I
= Lst
.begin();
2562 I
!= Lst
.end(); ++I
)
2564 // Try to guess what sort of file it is we are getting.
2565 if (I
->Type
== "dsc")
2567 Dsc
[J
].Package
= Last
->Package();
2568 Dsc
[J
].Version
= Last
->Version();
2569 Dsc
[J
].Dsc
= flNotDir(I
->Path
);
2572 // Handle the only options so that multiple can be used at once
2573 if (diffOnly
== true || tarOnly
== true || dscOnly
== true)
2575 if ((diffOnly
== true && I
->Type
== "diff") ||
2576 (tarOnly
== true && I
->Type
== "tar") ||
2577 (dscOnly
== true && I
->Type
== "dsc"))
2578 ; // Fine, we want this file downloaded
2583 // don't download the same uri twice (should this be moved to
2584 // the fetcher interface itself?)
2585 if(queued
.find(Last
->Index().ArchiveURI(I
->Path
)) != queued
.end())
2587 queued
.insert(Last
->Index().ArchiveURI(I
->Path
));
2589 // check if we have a file with that md5 sum already localy
2590 if(!I
->MD5Hash
.empty() && FileExists(flNotDir(I
->Path
)))
2592 FileFd
Fd(flNotDir(I
->Path
), FileFd::ReadOnly
);
2594 sum
.AddFD(Fd
.Fd(), Fd
.Size());
2596 if((string
)sum
.Result() == I
->MD5Hash
)
2598 ioprintf(c1out
,_("Skipping already downloaded file '%s'\n"),
2599 flNotDir(I
->Path
).c_str());
2604 new pkgAcqFile(&Fetcher
,Last
->Index().ArchiveURI(I
->Path
),
2606 Last
->Index().SourceInfo(*Last
,*I
),Src
);
2610 // Display statistics
2611 unsigned long long FetchBytes
= Fetcher
.FetchNeeded();
2612 unsigned long long FetchPBytes
= Fetcher
.PartialPresent();
2613 unsigned long long DebBytes
= Fetcher
.TotalNeeded();
2615 // Check for enough free space
2617 string OutputDir
= ".";
2618 if (statvfs(OutputDir
.c_str(),&Buf
) != 0) {
2620 if (errno
== EOVERFLOW
)
2621 return _error
->WarningE("statvfs",_("Couldn't determine free space in %s"),
2624 return _error
->Errno("statvfs",_("Couldn't determine free space in %s"),
2626 } else if (unsigned(Buf
.f_bfree
) < (FetchBytes
- FetchPBytes
)/Buf
.f_bsize
)
2629 if (statfs(OutputDir
.c_str(),&Stat
) != 0
2630 #if HAVE_STRUCT_STATFS_F_TYPE
2631 || unsigned(Stat
.f_type
) != RAMFS_MAGIC
2635 return _error
->Error(_("You don't have enough free space in %s"),
2641 if (DebBytes
!= FetchBytes
)
2642 //TRANSLATOR: The required space between number and unit is already included
2643 // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
2644 ioprintf(c1out
,_("Need to get %sB/%sB of source archives.\n"),
2645 SizeToStr(FetchBytes
).c_str(),SizeToStr(DebBytes
).c_str());
2647 //TRANSLATOR: The required space between number and unit is already included
2648 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
2649 ioprintf(c1out
,_("Need to get %sB of source archives.\n"),
2650 SizeToStr(DebBytes
).c_str());
2652 if (_config
->FindB("APT::Get::Simulate",false) == true)
2654 for (unsigned I
= 0; I
!= J
; I
++)
2655 ioprintf(cout
,_("Fetch source %s\n"),Dsc
[I
].Package
.c_str());
2660 // Just print out the uris an exit if the --print-uris flag was used
2661 if (_config
->FindB("APT::Get::Print-URIs") == true)
2663 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
2664 for (; I
!= Fetcher
.UriEnd(); ++I
)
2665 cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
2666 I
->Owner
->FileSize
<< ' ' << I
->Owner
->HashSum() << endl
;
2672 if (Fetcher
.Run() == pkgAcquire::Failed
)
2678 // Print error messages
2679 bool Failed
= false;
2680 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); ++I
)
2682 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
2683 (*I
)->Complete
== true)
2686 fprintf(stderr
,_("Failed to fetch %s %s\n"),(*I
)->DescURI().c_str(),
2687 (*I
)->ErrorText
.c_str());
2693 return _error
->Error(_("Failed to fetch some archives."));
2696 if (_config
->FindB("APT::Get::Download-only",false) == true)
2698 c1out
<< _("Download complete and in download only mode") << endl
;
2703 // Unpack the sources
2704 pid_t Process
= ExecFork();
2708 bool const fixBroken
= _config
->FindB("APT::Get::Fix-Broken", false);
2709 for (unsigned I
= 0; I
!= J
; ++I
)
2711 string Dir
= Dsc
[I
].Package
+ '-' + Cache
->VS().UpstreamVersion(Dsc
[I
].Version
.c_str());
2713 // Diff only mode only fetches .diff files
2714 if (_config
->FindB("APT::Get::Diff-Only",false) == true ||
2715 _config
->FindB("APT::Get::Tar-Only",false) == true ||
2716 Dsc
[I
].Dsc
.empty() == true)
2719 // See if the package is already unpacked
2721 if (fixBroken
== false && stat(Dir
.c_str(),&Stat
) == 0 &&
2722 S_ISDIR(Stat
.st_mode
) != 0)
2724 ioprintf(c0out
,_("Skipping unpack of already unpacked source in %s\n"),
2731 snprintf(S
,sizeof(S
),"%s -x %s",
2732 _config
->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
2733 Dsc
[I
].Dsc
.c_str());
2736 fprintf(stderr
,_("Unpack command '%s' failed.\n"),S
);
2737 fprintf(stderr
,_("Check if the 'dpkg-dev' package is installed.\n"));
2742 // Try to compile it with dpkg-buildpackage
2743 if (_config
->FindB("APT::Get::Compile",false) == true)
2745 string buildopts
= _config
->Find("APT::Get::Host-Architecture");
2746 if (buildopts
.empty() == false)
2747 buildopts
= "-a" + buildopts
+ " ";
2748 buildopts
.append(_config
->Find("DPkg::Build-Options","-b -uc"));
2750 // Call dpkg-buildpackage
2752 snprintf(S
,sizeof(S
),"cd %s && %s %s",
2754 _config
->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
2759 fprintf(stderr
,_("Build command '%s' failed.\n"),S
);
2769 // Wait for the subprocess
2771 while (waitpid(Process
,&Status
,0) != Process
)
2775 return _error
->Errno("waitpid","Couldn't wait for subprocess");
2778 if (WIFEXITED(Status
) == 0 || WEXITSTATUS(Status
) != 0)
2779 return _error
->Error(_("Child process failed"));
2784 // DoBuildDep - Install/removes packages to satisfy build dependencies /*{{{*/
2785 // ---------------------------------------------------------------------
2786 /* This function will look at the build depends list of the given source
2787 package and install the necessary packages to make it true, or fail. */
2788 bool DoBuildDep(CommandLine
&CmdL
)
2792 _config
->Set("APT::Install-Recommends", false);
2794 if (Cache
.Open(true) == false)
2797 if (CmdL
.FileSize() <= 1)
2798 return _error
->Error(_("Must specify at least one package to check builddeps for"));
2800 // Read the source list
2801 if (Cache
.BuildSourceList() == false)
2803 pkgSourceList
*List
= Cache
.GetSourceList();
2805 // Create the text record parsers
2806 pkgRecords
Recs(Cache
);
2807 pkgSrcRecords
SrcRecs(*List
);
2808 if (_error
->PendingError() == true)
2811 // Create the download object
2812 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
2814 if (Fetcher
.Setup(&Stat
) == false)
2817 bool StripMultiArch
;
2818 string hostArch
= _config
->Find("APT::Get::Host-Architecture");
2819 if (hostArch
.empty() == false)
2821 std::vector
<std::string
> archs
= APT::Configuration::getArchitectures();
2822 if (std::find(archs
.begin(), archs
.end(), hostArch
) == archs
.end())
2823 return _error
->Error(_("No architecture information available for %s. See apt.conf(5) APT::Architectures for setup"), hostArch
.c_str());
2824 StripMultiArch
= false;
2827 StripMultiArch
= true;
2830 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++, J
++)
2833 pkgSrcRecords::Parser
*Last
= FindSrc(*I
,Recs
,SrcRecs
,Src
,*Cache
);
2835 return _error
->Error(_("Unable to find a source package for %s"),Src
.c_str());
2837 // Process the build-dependencies
2838 vector
<pkgSrcRecords::Parser::BuildDepRec
> BuildDeps
;
2839 // FIXME: Can't specify architecture to use for [wildcard] matching, so switch default arch temporary
2840 if (hostArch
.empty() == false)
2842 std::string nativeArch
= _config
->Find("APT::Architecture");
2843 _config
->Set("APT::Architecture", hostArch
);
2844 bool Success
= Last
->BuildDepends(BuildDeps
, _config
->FindB("APT::Get::Arch-Only", false), StripMultiArch
);
2845 _config
->Set("APT::Architecture", nativeArch
);
2846 if (Success
== false)
2847 return _error
->Error(_("Unable to get build-dependency information for %s"),Src
.c_str());
2849 else if (Last
->BuildDepends(BuildDeps
, _config
->FindB("APT::Get::Arch-Only", false), StripMultiArch
) == false)
2850 return _error
->Error(_("Unable to get build-dependency information for %s"),Src
.c_str());
2852 // Also ensure that build-essential packages are present
2853 Configuration::Item
const *Opts
= _config
->Tree("APT::Build-Essential");
2856 for (; Opts
; Opts
= Opts
->Next
)
2858 if (Opts
->Value
.empty() == true)
2861 pkgSrcRecords::Parser::BuildDepRec rec
;
2862 rec
.Package
= Opts
->Value
;
2863 rec
.Type
= pkgSrcRecords::Parser::BuildDependIndep
;
2865 BuildDeps
.push_back(rec
);
2868 if (BuildDeps
.empty() == true)
2870 ioprintf(c1out
,_("%s has no build depends.\n"),Src
.c_str());
2874 // Install the requested packages
2875 vector
<pkgSrcRecords::Parser::BuildDepRec
>::iterator D
;
2876 pkgProblemResolver
Fix(Cache
);
2877 bool skipAlternatives
= false; // skip remaining alternatives in an or group
2878 for (D
= BuildDeps
.begin(); D
!= BuildDeps
.end(); ++D
)
2880 bool hasAlternatives
= (((*D
).Op
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
);
2882 if (skipAlternatives
== true)
2885 * if there are alternatives, we've already picked one, so skip
2888 * TODO: this means that if there's a build-dep on A|B and B is
2889 * installed, we'll still try to install A; more importantly,
2890 * if A is currently broken, we cannot go back and try B. To fix
2891 * this would require we do a Resolve cycle for each package we
2892 * add to the install list. Ugh
2894 if (!hasAlternatives
)
2895 skipAlternatives
= false; // end of or group
2899 if ((*D
).Type
== pkgSrcRecords::Parser::BuildConflict
||
2900 (*D
).Type
== pkgSrcRecords::Parser::BuildConflictIndep
)
2902 pkgCache::GrpIterator Grp
= Cache
->FindGrp((*D
).Package
);
2903 // Build-conflicts on unknown packages are silently ignored
2904 if (Grp
.end() == true)
2907 for (pkgCache::PkgIterator Pkg
= Grp
.PackageList(); Pkg
.end() == false; Pkg
= Grp
.NextPkg(Pkg
))
2909 pkgCache::VerIterator IV
= (*Cache
)[Pkg
].InstVerIter(*Cache
);
2911 * Remove if we have an installed version that satisfies the
2914 if (IV
.end() == false &&
2915 Cache
->VS().CheckDep(IV
.VerStr(),(*D
).Op
,(*D
).Version
.c_str()) == true)
2916 TryToInstallBuildDep(Pkg
,Cache
,Fix
,true,false);
2919 else // BuildDep || BuildDepIndep
2921 if (_config
->FindB("Debug::BuildDeps",false) == true)
2922 cout
<< "Looking for " << (*D
).Package
<< "...\n";
2924 pkgCache::PkgIterator Pkg
;
2927 if (StripMultiArch
== false && D
->Type
!= pkgSrcRecords::Parser::BuildDependIndep
)
2929 size_t const colon
= D
->Package
.find(":");
2930 if (colon
!= string::npos
)
2932 if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0 || strcmp(D
->Package
.c_str() + colon
, ":native") == 0)
2933 Pkg
= Cache
->FindPkg(D
->Package
.substr(0,colon
));
2935 Pkg
= Cache
->FindPkg(D
->Package
);
2938 Pkg
= Cache
->FindPkg(D
->Package
, hostArch
);
2940 // a bad version either is invalid or doesn't satify dependency
2941 #define BADVER(Ver) (Ver.end() == true || \
2942 (D->Version.empty() == false && \
2943 Cache->VS().CheckDep(Ver.VerStr(),D->Op,D->Version.c_str()) == false))
2945 APT::VersionList verlist
;
2946 if (Pkg
.end() == false)
2948 pkgCache::VerIterator Ver
= (*Cache
)[Pkg
].InstVerIter(*Cache
);
2949 if (BADVER(Ver
) == false)
2950 verlist
.insert(Ver
);
2951 Ver
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
2952 if (BADVER(Ver
) == false)
2953 verlist
.insert(Ver
);
2955 if (verlist
.empty() == true)
2957 pkgCache::PkgIterator BuildPkg
= Cache
->FindPkg(D
->Package
, "native");
2958 if (BuildPkg
.end() == false && Pkg
!= BuildPkg
)
2960 pkgCache::VerIterator Ver
= (*Cache
)[BuildPkg
].InstVerIter(*Cache
);
2961 if (BADVER(Ver
) == false)
2962 verlist
.insert(Ver
);
2963 Ver
= (*Cache
)[BuildPkg
].CandidateVerIter(*Cache
);
2964 if (BADVER(Ver
) == false)
2965 verlist
.insert(Ver
);
2971 // We need to decide if host or build arch, so find a version we can look at
2972 APT::VersionList::const_iterator Ver
= verlist
.begin();
2973 for (; Ver
!= verlist
.end(); ++Ver
)
2976 if (Ver
->MultiArch
== pkgCache::Version::None
|| Ver
->MultiArch
== pkgCache::Version::All
)
2978 if (colon
== string::npos
)
2979 Pkg
= Ver
.ParentPkg().Group().FindPkg(hostArch
);
2980 else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0)
2981 forbidden
= "Multi-Arch: none";
2982 else if (strcmp(D
->Package
.c_str() + colon
, ":native") == 0)
2983 Pkg
= Ver
.ParentPkg().Group().FindPkg("native");
2985 else if (Ver
->MultiArch
== pkgCache::Version::Same
)
2987 if (colon
== string::npos
)
2988 Pkg
= Ver
.ParentPkg().Group().FindPkg(hostArch
);
2989 else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0)
2990 forbidden
= "Multi-Arch: same";
2991 else if (strcmp(D
->Package
.c_str() + colon
, ":native") == 0)
2992 Pkg
= Ver
.ParentPkg().Group().FindPkg("native");
2994 else if ((Ver
->MultiArch
& pkgCache::Version::Foreign
) == pkgCache::Version::Foreign
)
2996 if (colon
== string::npos
)
2997 Pkg
= Ver
.ParentPkg().Group().FindPkg("native");
2998 else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0 ||
2999 strcmp(D
->Package
.c_str() + colon
, ":native") == 0)
3000 forbidden
= "Multi-Arch: foreign";
3002 else if ((Ver
->MultiArch
& pkgCache::Version::Allowed
) == pkgCache::Version::Allowed
)
3004 if (colon
== string::npos
)
3005 Pkg
= Ver
.ParentPkg().Group().FindPkg(hostArch
);
3006 else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0)
3008 // prefer any installed over preferred non-installed architectures
3009 pkgCache::GrpIterator Grp
= Ver
.ParentPkg().Group();
3010 // we don't check for version here as we are better of with upgrading than remove and install
3011 for (Pkg
= Grp
.PackageList(); Pkg
.end() == false; Pkg
= Grp
.NextPkg(Pkg
))
3012 if (Pkg
.CurrentVer().end() == false)
3014 if (Pkg
.end() == true)
3015 Pkg
= Grp
.FindPreferredPkg(true);
3017 else if (strcmp(D
->Package
.c_str() + colon
, ":native") == 0)
3018 Pkg
= Ver
.ParentPkg().Group().FindPkg("native");
3021 if (forbidden
.empty() == false)
3023 if (_config
->FindB("Debug::BuildDeps",false) == true)
3024 cout
<< D
->Package
.substr(colon
, string::npos
) << " is not allowed from " << forbidden
<< " package " << (*D
).Package
<< " (" << Ver
.VerStr() << ")" << endl
;
3028 //we found a good version
3031 if (Ver
== verlist
.end())
3033 if (_config
->FindB("Debug::BuildDeps",false) == true)
3034 cout
<< " No multiarch info as we have no satisfying installed nor candidate for " << D
->Package
<< " on build or host arch" << endl
;
3036 if (forbidden
.empty() == false)
3038 if (hasAlternatives
)
3040 return _error
->Error(_("%s dependency for %s can't be satisfied "
3041 "because %s is not allowed on '%s' packages"),
3042 Last
->BuildDepType(D
->Type
), Src
.c_str(),
3043 D
->Package
.c_str(), forbidden
.c_str());
3048 Pkg
= Cache
->FindPkg(D
->Package
);
3050 if (Pkg
.end() == true || (Pkg
->VersionList
== 0 && Pkg
->ProvidesList
== 0))
3052 if (_config
->FindB("Debug::BuildDeps",false) == true)
3053 cout
<< " (not found)" << (*D
).Package
<< endl
;
3055 if (hasAlternatives
)
3058 return _error
->Error(_("%s dependency for %s cannot be satisfied "
3059 "because the package %s cannot be found"),
3060 Last
->BuildDepType((*D
).Type
),Src
.c_str(),
3061 (*D
).Package
.c_str());
3064 pkgCache::VerIterator IV
= (*Cache
)[Pkg
].InstVerIter(*Cache
);
3065 if (IV
.end() == false)
3067 if (_config
->FindB("Debug::BuildDeps",false) == true)
3068 cout
<< " Is installed\n";
3070 if (D
->Version
.empty() == true ||
3071 Cache
->VS().CheckDep(IV
.VerStr(),(*D
).Op
,(*D
).Version
.c_str()) == true)
3073 skipAlternatives
= hasAlternatives
;
3077 if (_config
->FindB("Debug::BuildDeps",false) == true)
3078 cout
<< " ...but the installed version doesn't meet the version requirement\n";
3080 if (((*D
).Op
& pkgCache::Dep::LessEq
) == pkgCache::Dep::LessEq
)
3081 return _error
->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"),
3082 Last
->BuildDepType((*D
).Type
), Src
.c_str(), Pkg
.FullName(true).c_str());
3085 // Only consider virtual packages if there is no versioned dependency
3086 if ((*D
).Version
.empty() == true)
3089 * If this is a virtual package, we need to check the list of
3090 * packages that provide it and see if any of those are
3093 pkgCache::PrvIterator Prv
= Pkg
.ProvidesList();
3094 for (; Prv
.end() != true; ++Prv
)
3096 if (_config
->FindB("Debug::BuildDeps",false) == true)
3097 cout
<< " Checking provider " << Prv
.OwnerPkg().FullName() << endl
;
3099 if ((*Cache
)[Prv
.OwnerPkg()].InstVerIter(*Cache
).end() == false)
3103 if (Prv
.end() == false)
3105 if (_config
->FindB("Debug::BuildDeps",false) == true)
3106 cout
<< " Is provided by installed package " << Prv
.OwnerPkg().FullName() << endl
;
3107 skipAlternatives
= hasAlternatives
;
3111 else // versioned dependency
3113 pkgCache::VerIterator CV
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
3114 if (CV
.end() == true ||
3115 Cache
->VS().CheckDep(CV
.VerStr(),(*D
).Op
,(*D
).Version
.c_str()) == false)
3117 if (hasAlternatives
)
3119 else if (CV
.end() == false)
3120 return _error
->Error(_("%s dependency for %s cannot be satisfied "
3121 "because candidate version of package %s "
3122 "can't satisfy version requirements"),
3123 Last
->BuildDepType(D
->Type
), Src
.c_str(),
3124 D
->Package
.c_str());
3126 return _error
->Error(_("%s dependency for %s cannot be satisfied "
3127 "because package %s has no candidate version"),
3128 Last
->BuildDepType(D
->Type
), Src
.c_str(),
3129 D
->Package
.c_str());
3133 if (TryToInstallBuildDep(Pkg
,Cache
,Fix
,false,false,false) == true)
3135 // We successfully installed something; skip remaining alternatives
3136 skipAlternatives
= hasAlternatives
;
3137 if(_config
->FindB("APT::Get::Build-Dep-Automatic", false) == true)
3138 Cache
->MarkAuto(Pkg
, true);
3141 else if (hasAlternatives
)
3143 if (_config
->FindB("Debug::BuildDeps",false) == true)
3144 cout
<< " Unsatisfiable, trying alternatives\n";
3149 return _error
->Error(_("Failed to satisfy %s dependency for %s: %s"),
3150 Last
->BuildDepType((*D
).Type
),
3152 (*D
).Package
.c_str());
3157 if (Fix
.Resolve(true) == false)
3160 // Now we check the state of the packages,
3161 if (Cache
->BrokenCount() != 0)
3163 ShowBroken(cout
, Cache
, false);
3164 return _error
->Error(_("Build-dependencies for %s could not be satisfied."),*I
);
3168 if (InstallPackages(Cache
, false, true) == false)
3169 return _error
->Error(_("Failed to process build dependencies"));
3173 // GetChangelogPath - return a path pointing to a changelog file or dir /*{{{*/
3174 // ---------------------------------------------------------------------
3175 /* This returns a "path" string for the changelog url construction.
3176 * Please note that its not complete, it either needs a "/changelog"
3177 * appended (for the packages.debian.org/changelogs site) or a
3178 * ".changelog" (for third party sites that store the changelog in the
3179 * pool/ next to the deb itself)
3180 * Example return: "pool/main/a/apt/apt_0.8.8ubuntu3"
3182 string
GetChangelogPath(CacheFile
&Cache
,
3183 pkgCache::PkgIterator Pkg
,
3184 pkgCache::VerIterator Ver
)
3188 pkgRecords
Recs(Cache
);
3189 pkgRecords::Parser
&rec
=Recs
.Lookup(Ver
.FileList());
3190 string srcpkg
= rec
.SourcePkg().empty() ? Pkg
.Name() : rec
.SourcePkg();
3191 string ver
= Ver
.VerStr();
3192 // if there is a source version it always wins
3193 if (rec
.SourceVer() != "")
3194 ver
= rec
.SourceVer();
3195 path
= flNotFile(rec
.FileName());
3196 path
+= srcpkg
+ "_" + StripEpoch(ver
);
3200 // GuessThirdPartyChangelogUri - return url /*{{{*/
3201 // ---------------------------------------------------------------------
3202 /* Contruct a changelog file path for third party sites that do not use
3203 * packages.debian.org/changelogs
3204 * This simply uses the ArchiveURI() of the source pkg and looks for
3205 * a .changelog file there, Example for "mediabuntu":
3206 * apt-get changelog mplayer-doc:
3207 * http://packages.medibuntu.org/pool/non-free/m/mplayer/mplayer_1.0~rc4~try1.dsfg1-1ubuntu1+medibuntu1.changelog
3209 bool GuessThirdPartyChangelogUri(CacheFile
&Cache
,
3210 pkgCache::PkgIterator Pkg
,
3211 pkgCache::VerIterator Ver
,
3214 // get the binary deb server path
3215 pkgCache::VerFileIterator Vf
= Ver
.FileList();
3216 if (Vf
.end() == true)
3218 pkgCache::PkgFileIterator F
= Vf
.File();
3219 pkgIndexFile
*index
;
3220 pkgSourceList
*SrcList
= Cache
.GetSourceList();
3221 if(SrcList
->FindIndex(F
, index
) == false)
3224 // get archive uri for the binary deb
3225 string path_without_dot_changelog
= GetChangelogPath(Cache
, Pkg
, Ver
);
3226 out_uri
= index
->ArchiveURI(path_without_dot_changelog
+ ".changelog");
3228 // now strip away the filename and add srcpkg_srcver.changelog
3232 // DownloadChangelog - Download the changelog /*{{{*/
3233 // ---------------------------------------------------------------------
3234 bool DownloadChangelog(CacheFile
&CacheFile
, pkgAcquire
&Fetcher
,
3235 pkgCache::VerIterator Ver
, string targetfile
)
3236 /* Download a changelog file for the given package version to
3237 * targetfile. This will first try the server from Apt::Changelogs::Server
3238 * (http://packages.debian.org/changelogs by default) and if that gives
3239 * a 404 tries to get it from the archive directly (see
3240 * GuessThirdPartyChangelogUri for details how)
3246 string changelog_uri
;
3248 // data structures we need
3249 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
3251 // make the server root configurable
3252 server
= _config
->Find("Apt::Changelogs::Server",
3253 "http://packages.debian.org/changelogs");
3254 path
= GetChangelogPath(CacheFile
, Pkg
, Ver
);
3255 strprintf(changelog_uri
, "%s/%s/changelog", server
.c_str(), path
.c_str());
3256 if (_config
->FindB("APT::Get::Print-URIs", false) == true)
3258 std::cout
<< '\'' << changelog_uri
<< '\'' << std::endl
;
3262 strprintf(descr
, _("Changelog for %s (%s)"), Pkg
.Name(), changelog_uri
.c_str());
3264 new pkgAcqFile(&Fetcher
, changelog_uri
, "", 0, descr
, Pkg
.Name(), "ignored", targetfile
);
3266 // try downloading it, if that fails, try third-party-changelogs location
3267 // FIXME: Fetcher.Run() is "Continue" even if I get a 404?!?
3269 if (!FileExists(targetfile
))
3271 string third_party_uri
;
3272 if (GuessThirdPartyChangelogUri(CacheFile
, Pkg
, Ver
, third_party_uri
))
3274 strprintf(descr
, _("Changelog for %s (%s)"), Pkg
.Name(), third_party_uri
.c_str());
3275 new pkgAcqFile(&Fetcher
, third_party_uri
, "", 0, descr
, Pkg
.Name(), "ignored", targetfile
);
3280 if (FileExists(targetfile
))
3284 return _error
->Error("changelog download failed");
3287 // DisplayFileInPager - Display File with pager /*{{{*/
3288 void DisplayFileInPager(string filename
)
3290 pid_t Process
= ExecFork();
3293 const char *Args
[3];
3294 Args
[0] = "/usr/bin/sensible-pager";
3295 Args
[1] = filename
.c_str();
3297 execvp(Args
[0],(char **)Args
);
3301 // Wait for the subprocess
3302 ExecWait(Process
, "sensible-pager", false);
3305 // DoChangelog - Get changelog from the command line /*{{{*/
3306 // ---------------------------------------------------------------------
3307 bool DoChangelog(CommandLine
&CmdL
)
3310 if (Cache
.ReadOnlyOpen() == false)
3313 APT::CacheSetHelper
helper(c0out
);
3314 APT::VersionList verset
= APT::VersionList::FromCommandLine(Cache
,
3315 CmdL
.FileList
+ 1, APT::VersionList::CANDIDATE
, helper
);
3316 if (verset
.empty() == true)
3320 if (_config
->FindB("APT::Get::Print-URIs", false) == true)
3322 bool Success
= true;
3323 for (APT::VersionList::const_iterator Ver
= verset
.begin();
3324 Ver
!= verset
.end(); ++Ver
)
3325 Success
&= DownloadChangelog(Cache
, Fetcher
, Ver
, "");
3329 AcqTextStatus
Stat(ScreenWidth
, _config
->FindI("quiet",0));
3330 Fetcher
.Setup(&Stat
);
3332 bool const downOnly
= _config
->FindB("APT::Get::Download-Only", false);
3335 char* tmpdir
= NULL
;
3336 if (downOnly
== false)
3338 const char* const tmpDir
= getenv("TMPDIR");
3339 if (tmpDir
!= NULL
&& *tmpDir
!= '\0')
3340 snprintf(tmpname
, sizeof(tmpname
), "%s/apt-changelog-XXXXXX", tmpDir
);
3342 strncpy(tmpname
, "/tmp/apt-changelog-XXXXXX", sizeof(tmpname
));
3343 tmpdir
= mkdtemp(tmpname
);
3345 return _error
->Errno("mkdtemp", "mkdtemp failed");
3348 for (APT::VersionList::const_iterator Ver
= verset
.begin();
3349 Ver
!= verset
.end();
3352 string changelogfile
;
3353 if (downOnly
== false)
3354 changelogfile
.append(tmpname
).append("changelog");
3356 changelogfile
.append(Ver
.ParentPkg().Name()).append(".changelog");
3357 if (DownloadChangelog(Cache
, Fetcher
, Ver
, changelogfile
) && downOnly
== false)
3359 DisplayFileInPager(changelogfile
);
3360 // cleanup temp file
3361 unlink(changelogfile
.c_str());
3370 // DoMoo - Never Ask, Never Tell /*{{{*/
3371 // ---------------------------------------------------------------------
3373 bool DoMoo(CommandLine
&CmdL
)
3382 "....\"Have you mooed today?\"...\n";
3387 // ShowHelp - Show a help screen /*{{{*/
3388 // ---------------------------------------------------------------------
3390 bool ShowHelp(CommandLine
&CmdL
)
3392 ioprintf(cout
,_("%s %s for %s compiled on %s %s\n"),PACKAGE
,PACKAGE_VERSION
,
3393 COMMON_ARCH
,__DATE__
,__TIME__
);
3395 if (_config
->FindB("version") == true)
3397 cout
<< _("Supported modules:") << endl
;
3399 for (unsigned I
= 0; I
!= pkgVersioningSystem::GlobalListLen
; I
++)
3401 pkgVersioningSystem
*VS
= pkgVersioningSystem::GlobalList
[I
];
3402 if (_system
!= 0 && _system
->VS
== VS
)
3406 cout
<< "Ver: " << VS
->Label
<< endl
;
3408 /* Print out all the packaging systems that will work with
3410 for (unsigned J
= 0; J
!= pkgSystem::GlobalListLen
; J
++)
3412 pkgSystem
*Sys
= pkgSystem::GlobalList
[J
];
3417 if (Sys
->VS
->TestCompatibility(*VS
) == true)
3418 cout
<< "Pkg: " << Sys
->Label
<< " (Priority " << Sys
->Score(*_config
) << ")" << endl
;
3422 for (unsigned I
= 0; I
!= pkgSourceList::Type::GlobalListLen
; I
++)
3424 pkgSourceList::Type
*Type
= pkgSourceList::Type::GlobalList
[I
];
3425 cout
<< " S.L: '" << Type
->Name
<< "' " << Type
->Label
<< endl
;
3428 for (unsigned I
= 0; I
!= pkgIndexFile::Type::GlobalListLen
; I
++)
3430 pkgIndexFile::Type
*Type
= pkgIndexFile::Type::GlobalList
[I
];
3431 cout
<< " Idx: " << Type
->Label
<< endl
;
3438 _("Usage: apt-get [options] command\n"
3439 " apt-get [options] install|remove pkg1 [pkg2 ...]\n"
3440 " apt-get [options] source pkg1 [pkg2 ...]\n"
3442 "apt-get is a simple command line interface for downloading and\n"
3443 "installing packages. The most frequently used commands are update\n"
3447 " update - Retrieve new lists of packages\n"
3448 " upgrade - Perform an upgrade\n"
3449 " install - Install new packages (pkg is libc6 not libc6.deb)\n"
3450 " remove - Remove packages\n"
3451 " autoremove - Remove automatically all unused packages\n"
3452 " purge - Remove packages and config files\n"
3453 " source - Download source archives\n"
3454 " build-dep - Configure build-dependencies for source packages\n"
3455 " dist-upgrade - Distribution upgrade, see apt-get(8)\n"
3456 " dselect-upgrade - Follow dselect selections\n"
3457 " clean - Erase downloaded archive files\n"
3458 " autoclean - Erase old downloaded archive files\n"
3459 " check - Verify that there are no broken dependencies\n"
3460 " changelog - Download and display the changelog for the given package\n"
3461 " download - Download the binary package into the current directory\n"
3464 " -h This help text.\n"
3465 " -q Loggable output - no progress indicator\n"
3466 " -qq No output except for errors\n"
3467 " -d Download only - do NOT install or unpack archives\n"
3468 " -s No-act. Perform ordering simulation\n"
3469 " -y Assume Yes to all queries and do not prompt\n"
3470 " -f Attempt to correct a system with broken dependencies in place\n"
3471 " -m Attempt to continue if archives are unlocatable\n"
3472 " -u Show a list of upgraded packages as well\n"
3473 " -b Build the source package after fetching it\n"
3474 " -V Show verbose version numbers\n"
3475 " -c=? Read this configuration file\n"
3476 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
3477 "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n"
3478 "pages for more information and options.\n"
3479 " This APT has Super Cow Powers.\n");
3483 // SigWinch - Window size change signal handler /*{{{*/
3484 // ---------------------------------------------------------------------
3488 // Riped from GNU ls
3492 if (ioctl(1, TIOCGWINSZ
, &ws
) != -1 && ws
.ws_col
>= 5)
3493 ScreenWidth
= ws
.ws_col
- 1;
3497 int main(int argc
,const char *argv
[]) /*{{{*/
3499 CommandLine::Args Args
[] = {
3500 {'h',"help","help",0},
3501 {'v',"version","version",0},
3502 {'V',"verbose-versions","APT::Get::Show-Versions",0},
3503 {'q',"quiet","quiet",CommandLine::IntLevel
},
3504 {'q',"silent","quiet",CommandLine::IntLevel
},
3505 {'d',"download-only","APT::Get::Download-Only",0},
3506 {'b',"compile","APT::Get::Compile",0},
3507 {'b',"build","APT::Get::Compile",0},
3508 {'s',"simulate","APT::Get::Simulate",0},
3509 {'s',"just-print","APT::Get::Simulate",0},
3510 {'s',"recon","APT::Get::Simulate",0},
3511 {'s',"dry-run","APT::Get::Simulate",0},
3512 {'s',"no-act","APT::Get::Simulate",0},
3513 {'y',"yes","APT::Get::Assume-Yes",0},
3514 {'y',"assume-yes","APT::Get::Assume-Yes",0},
3515 {0,"assume-no","APT::Get::Assume-No",0},
3516 {'f',"fix-broken","APT::Get::Fix-Broken",0},
3517 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
3518 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
3519 {'t',"target-release","APT::Default-Release",CommandLine::HasArg
},
3520 {'t',"default-release","APT::Default-Release",CommandLine::HasArg
},
3521 {'a',"host-architecture","APT::Get::Host-Architecture",CommandLine::HasArg
},
3522 {0,"download","APT::Get::Download",0},
3523 {0,"fix-missing","APT::Get::Fix-Missing",0},
3524 {0,"ignore-hold","APT::Ignore-Hold",0},
3525 {0,"upgrade","APT::Get::upgrade",0},
3526 {0,"only-upgrade","APT::Get::Only-Upgrade",0},
3527 {0,"force-yes","APT::Get::force-yes",0},
3528 {0,"print-uris","APT::Get::Print-URIs",0},
3529 {0,"diff-only","APT::Get::Diff-Only",0},
3530 {0,"debian-only","APT::Get::Diff-Only",0},
3531 {0,"tar-only","APT::Get::Tar-Only",0},
3532 {0,"dsc-only","APT::Get::Dsc-Only",0},
3533 {0,"purge","APT::Get::Purge",0},
3534 {0,"list-cleanup","APT::Get::List-Cleanup",0},
3535 {0,"reinstall","APT::Get::ReInstall",0},
3536 {0,"trivial-only","APT::Get::Trivial-Only",0},
3537 {0,"remove","APT::Get::Remove",0},
3538 {0,"only-source","APT::Get::Only-Source",0},
3539 {0,"arch-only","APT::Get::Arch-Only",0},
3540 {0,"auto-remove","APT::Get::AutomaticRemove",0},
3541 {0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0},
3542 {0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean
},
3543 {0,"install-suggests","APT::Install-Suggests",CommandLine::Boolean
},
3544 {0,"fix-policy","APT::Get::Fix-Policy-Broken",0},
3545 {0,"solver","APT::Solver",CommandLine::HasArg
},
3546 {'c',"config-file",0,CommandLine::ConfigFile
},
3547 {'o',"option",0,CommandLine::ArbItem
},
3549 CommandLine::Dispatch Cmds
[] = {{"update",&DoUpdate
},
3550 {"upgrade",&DoUpgrade
},
3551 {"install",&DoInstall
},
3552 {"remove",&DoInstall
},
3553 {"purge",&DoInstall
},
3554 {"autoremove",&DoInstall
},
3555 {"markauto",&DoMarkAuto
},
3556 {"unmarkauto",&DoMarkAuto
},
3557 {"dist-upgrade",&DoDistUpgrade
},
3558 {"dselect-upgrade",&DoDSelectUpgrade
},
3559 {"build-dep",&DoBuildDep
},
3561 {"autoclean",&DoAutoClean
},
3563 {"source",&DoSource
},
3564 {"download",&DoDownload
},
3565 {"changelog",&DoChangelog
},
3570 // Set up gettext support
3571 setlocale(LC_ALL
,"");
3572 textdomain(PACKAGE
);
3574 // Parse the command line and initialize the package library
3575 CommandLine
CmdL(Args
,_config
);
3576 if (pkgInitConfig(*_config
) == false ||
3577 CmdL
.Parse(argc
,argv
) == false ||
3578 pkgInitSystem(*_config
,_system
) == false)
3580 if (_config
->FindB("version") == true)
3583 _error
->DumpErrors();
3587 // See if the help should be shown
3588 if (_config
->FindB("help") == true ||
3589 _config
->FindB("version") == true ||
3590 CmdL
.FileSize() == 0)
3596 // simulate user-friendly if apt-get has no root privileges
3597 if (getuid() != 0 && _config
->FindB("APT::Get::Simulate") == true &&
3598 (CmdL
.FileSize() == 0 ||
3599 (strcmp(CmdL
.FileList
[0], "source") != 0 && strcmp(CmdL
.FileList
[0], "download") != 0 &&
3600 strcmp(CmdL
.FileList
[0], "changelog") != 0)))
3602 if (_config
->FindB("APT::Get::Show-User-Simulation-Note",true) == true)
3603 cout
<< _("NOTE: This is only a simulation!\n"
3604 " apt-get needs root privileges for real execution.\n"
3605 " Keep also in mind that locking is deactivated,\n"
3606 " so don't depend on the relevance to the real current situation!"
3608 _config
->Set("Debug::NoLocking",true);
3611 // Deal with stdout not being a tty
3612 if (!isatty(STDOUT_FILENO
) && _config
->FindI("quiet", -1) == -1)
3613 _config
->Set("quiet","1");
3615 // Setup the output streams
3616 c0out
.rdbuf(cout
.rdbuf());
3617 c1out
.rdbuf(cout
.rdbuf());
3618 c2out
.rdbuf(cout
.rdbuf());
3619 if (_config
->FindI("quiet",0) > 0)
3620 c0out
.rdbuf(devnull
.rdbuf());
3621 if (_config
->FindI("quiet",0) > 1)
3622 c1out
.rdbuf(devnull
.rdbuf());
3624 // Setup the signals
3625 signal(SIGPIPE
,SIG_IGN
);
3626 signal(SIGWINCH
,SigWinch
);
3629 // Match the operation
3630 CmdL
.DispatchArg(Cmds
);
3632 // Print any errors or warnings found during parsing
3633 bool const Errors
= _error
->PendingError();
3634 if (_config
->FindI("quiet",0) > 0)
3635 _error
->DumpErrors();
3637 _error
->DumpErrors(GlobalError::DEBUG
);
3638 return Errors
== true ? 100 : 0;