]>
git.saurik.com Git - apt.git/blob - cmdline/apt-get.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-get.cc,v 1.54 1999/04/19 06:03:09 jgg 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 /*{{{*/
28 #include <apt-pkg/error.h>
29 #include <apt-pkg/cmndline.h>
30 #include <apt-pkg/init.h>
31 #include <apt-pkg/depcache.h>
32 #include <apt-pkg/sourcelist.h>
33 #include <apt-pkg/algorithms.h>
34 #include <apt-pkg/acquire-item.h>
35 #include <apt-pkg/dpkgpm.h>
36 #include <apt-pkg/strutl.h>
37 #include <apt-pkg/clean.h>
38 #include <apt-pkg/srcrecords.h>
39 #include <apt-pkg/version.h>
40 #include <apt-pkg/cachefile.h>
44 #include "acqprogress.h"
48 #include <sys/ioctl.h>
59 ofstream
devnull("/dev/null");
60 unsigned int ScreenWidth
= 80;
62 // YnPrompt - Yes No Prompt. /*{{{*/
63 // ---------------------------------------------------------------------
64 /* Returns true on a Yes.*/
67 if (_config
->FindB("APT::Get::Assume-Yes",false) == true)
75 read(STDIN_FILENO
,&C
,1);
76 while (C
!= '\n' && Jnk
!= '\n') read(STDIN_FILENO
,&Jnk
,1);
78 if (!(C
== 'Y' || C
== 'y' || C
== '\n' || C
== '\r'))
83 // AnalPrompt - Annoying Yes No Prompt. /*{{{*/
84 // ---------------------------------------------------------------------
85 /* Returns true on a Yes.*/
86 bool AnalPrompt(const char *Text
)
89 cin
.getline(Buf
,sizeof(Buf
));
90 if (strcmp(Buf
,Text
) == 0)
95 // ShowList - Show a list /*{{{*/
96 // ---------------------------------------------------------------------
97 /* This prints out a string of space seperated words with a title and
98 a two space indent line wraped to the current screen width. */
99 bool ShowList(ostream
&out
,string Title
,string List
)
101 if (List
.empty() == true)
104 // Acount for the leading space
105 int ScreenWidth
= ::ScreenWidth
- 3;
107 out
<< Title
<< endl
;
108 string::size_type Start
= 0;
109 while (Start
< List
.size())
111 string::size_type End
;
112 if (Start
+ ScreenWidth
>= List
.size())
115 End
= List
.rfind(' ',Start
+ScreenWidth
);
117 if (End
== string::npos
|| End
< Start
)
118 End
= Start
+ ScreenWidth
;
119 out
<< " " << string(List
,Start
,End
- Start
) << endl
;
125 // ShowBroken - Debugging aide /*{{{*/
126 // ---------------------------------------------------------------------
127 /* This prints out the names of all the packages that are broken along
128 with the name of each each broken dependency and a quite version
130 void ShowBroken(ostream
&out
,pkgDepCache
&Cache
)
132 out
<< "Sorry, but the following packages have unmet dependencies:" << endl
;
133 pkgCache::PkgIterator I
= Cache
.PkgBegin();
134 for (;I
.end() != true; I
++)
136 if (Cache
[I
].InstBroken() == false)
139 // Print out each package and the failed dependencies
140 out
<<" " << I
.Name() << ":";
141 int Indent
= strlen(I
.Name()) + 3;
143 if (Cache
[I
].InstVerIter(Cache
).end() == true)
149 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
151 // Compute a single dependency element (glob or)
152 pkgCache::DepIterator Start
;
153 pkgCache::DepIterator End
;
156 if (Cache
.IsImportantDep(End
) == false ||
157 (Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
161 for (int J
= 0; J
!= Indent
; J
++)
165 out
<< ' ' << End
.DepType() << ": " << End
.TargetPkg().Name();
167 // Show a quick summary of the version requirements
168 if (End
.TargetVer() != 0)
169 out
<< " (" << End
.CompType() << " " << End
.TargetVer() <<
172 /* Show a summary of the target package if possible. In the case
173 of virtual packages we show nothing */
175 pkgCache::PkgIterator Targ
= End
.TargetPkg();
176 if (Targ
->ProvidesList
== 0)
179 pkgCache::VerIterator Ver
= Cache
[Targ
].InstVerIter(Cache
);
180 if (Ver
.end() == false)
181 out
<< Ver
.VerStr() << " is installed";
184 if (Cache
[Targ
].CandidateVerIter(Cache
).end() == true)
186 if (Targ
->ProvidesList
== 0)
187 out
<< "it is not installable";
189 out
<< "it is a virtual package";
192 out
<< "it is not installed";
201 // ShowNew - Show packages to newly install /*{{{*/
202 // ---------------------------------------------------------------------
204 void ShowNew(ostream
&out
,pkgDepCache
&Dep
)
206 /* Print out a list of packages that are going to be removed extra
207 to what the user asked */
208 pkgCache::PkgIterator I
= Dep
.PkgBegin();
210 for (;I
.end() != true; I
++)
211 if (Dep
[I
].NewInstall() == true)
212 List
+= string(I
.Name()) + " ";
213 ShowList(out
,"The following NEW packages will be installed:",List
);
216 // ShowDel - Show packages to delete /*{{{*/
217 // ---------------------------------------------------------------------
219 void ShowDel(ostream
&out
,pkgDepCache
&Dep
)
221 /* Print out a list of packages that are going to be removed extra
222 to what the user asked */
223 pkgCache::PkgIterator I
= Dep
.PkgBegin();
225 for (;I
.end() != true; I
++)
226 if (Dep
[I
].Delete() == true)
227 List
+= string(I
.Name()) + " ";
229 ShowList(out
,"The following packages will be REMOVED:",List
);
232 // ShowKept - Show kept packages /*{{{*/
233 // ---------------------------------------------------------------------
235 void ShowKept(ostream
&out
,pkgDepCache
&Dep
)
237 pkgCache::PkgIterator I
= Dep
.PkgBegin();
239 for (;I
.end() != true; I
++)
242 if (Dep
[I
].Upgrade() == true || Dep
[I
].Upgradable() == false ||
243 I
->CurrentVer
== 0 || Dep
[I
].Delete() == true)
246 List
+= string(I
.Name()) + " ";
248 ShowList(out
,"The following packages have been kept back",List
);
251 // ShowUpgraded - Show upgraded packages /*{{{*/
252 // ---------------------------------------------------------------------
254 void ShowUpgraded(ostream
&out
,pkgDepCache
&Dep
)
256 pkgCache::PkgIterator I
= Dep
.PkgBegin();
258 for (;I
.end() != true; I
++)
261 if (Dep
[I
].Upgrade() == false || Dep
[I
].NewInstall() == true)
264 List
+= string(I
.Name()) + " ";
266 ShowList(out
,"The following packages will be upgraded",List
);
269 // ShowHold - Show held but changed packages /*{{{*/
270 // ---------------------------------------------------------------------
272 bool ShowHold(ostream
&out
,pkgDepCache
&Dep
)
274 pkgCache::PkgIterator I
= Dep
.PkgBegin();
276 for (;I
.end() != true; I
++)
278 if (Dep
[I
].InstallVer
!= (pkgCache::Version
*)I
.CurrentVer() &&
279 I
->SelectedState
== pkgCache::State::Hold
)
280 List
+= string(I
.Name()) + " ";
283 return ShowList(out
,"The following held packages will be changed:",List
);
286 // ShowEssential - Show an essential package warning /*{{{*/
287 // ---------------------------------------------------------------------
288 /* This prints out a warning message that is not to be ignored. It shows
289 all essential packages and their dependents that are to be removed.
290 It is insanely risky to remove the dependents of an essential package! */
291 bool ShowEssential(ostream
&out
,pkgDepCache
&Dep
)
293 pkgCache::PkgIterator I
= Dep
.PkgBegin();
295 bool *Added
= new bool[Dep
.HeaderP
->PackageCount
];
296 for (unsigned int I
= 0; I
!= Dep
.HeaderP
->PackageCount
; I
++)
299 for (;I
.end() != true; I
++)
301 if ((I
->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
304 // The essential package is being removed
305 if (Dep
[I
].Delete() == true)
307 if (Added
[I
->ID
] == false)
310 List
+= string(I
.Name()) + " ";
314 if (I
->CurrentVer
== 0)
317 // Print out any essential package depenendents that are to be removed
318 for (pkgDepCache::DepIterator D
= I
.CurrentVer().DependsList(); D
.end() == false; D
++)
320 // Skip everything but depends
321 if (D
->Type
!= pkgCache::Dep::PreDepends
&&
322 D
->Type
!= pkgCache::Dep::Depends
)
325 pkgCache::PkgIterator P
= D
.SmartTargetPkg();
326 if (Dep
[P
].Delete() == true)
328 if (Added
[P
->ID
] == true)
333 sprintf(S
,"%s (due to %s) ",P
.Name(),I
.Name());
340 if (List
.empty() == false)
341 out
<< "WARNING: The following essential packages will be removed" << endl
;
342 return ShowList(out
,"This should NOT be done unless you know exactly what you are doing!",List
);
345 // Stats - Show some statistics /*{{{*/
346 // ---------------------------------------------------------------------
348 void Stats(ostream
&out
,pkgDepCache
&Dep
)
350 unsigned long Upgrade
= 0;
351 unsigned long Install
= 0;
352 for (pkgCache::PkgIterator I
= Dep
.PkgBegin(); I
.end() == false; I
++)
354 if (Dep
[I
].NewInstall() == true)
357 if (Dep
[I
].Upgrade() == true)
361 out
<< Upgrade
<< " packages upgraded, " <<
362 Install
<< " newly installed, " <<
363 Dep
.DelCount() << " to remove and " <<
364 Dep
.KeepCount() << " not upgraded." << endl
;
366 if (Dep
.BadCount() != 0)
367 out
<< Dep
.BadCount() << " packages not fully installed or removed." << endl
;
371 // class CacheFile - Cover class for some dependency cache functions /*{{{*/
372 // ---------------------------------------------------------------------
374 class CacheFile
: public pkgCacheFile
378 bool CheckDeps(bool AllowBroken
= false);
379 bool Open(bool WithLock
= true)
381 OpTextProgress
Prog(*_config
);
382 return pkgCacheFile::Open(Prog
,WithLock
);
386 // CacheFile::Open - Open the cache file /*{{{*/
387 // ---------------------------------------------------------------------
388 /* This routine generates the caches and then opens the dependency cache
389 and verifies that the system is OK. */
390 bool CacheFile::CheckDeps(bool AllowBroken
)
392 if (_error
->PendingError() == true)
395 // Check that the system is OK
396 if (Cache
->DelCount() != 0 || Cache
->InstCount() != 0)
397 return _error
->Error("Internal Error, non-zero counts");
399 // Apply corrections for half-installed packages
400 if (pkgApplyStatus(*Cache
) == false)
404 if (Cache
->BrokenCount() == 0 || AllowBroken
== true)
407 // Attempt to fix broken things
408 if (_config
->FindB("APT::Get::Fix-Broken",false) == true)
410 c1out
<< "Correcting dependencies..." << flush
;
411 if (pkgFixBroken(*Cache
) == false || Cache
->BrokenCount() != 0)
413 c1out
<< " failed." << endl
;
414 ShowBroken(c1out
,*this);
416 return _error
->Error("Unable to correct dependencies");
418 if (pkgMinimizeUpgrade(*Cache
) == false)
419 return _error
->Error("Unable to minimize the upgrade set");
421 c1out
<< " Done" << endl
;
425 c1out
<< "You might want to run `apt-get -f install' to correct these." << endl
;
426 ShowBroken(c1out
,*this);
428 return _error
->Error("Unmet dependencies. Try using -f.");
435 // InstallPackages - Actually download and install the packages /*{{{*/
436 // ---------------------------------------------------------------------
437 /* This displays the informative messages describing what is going to
438 happen and then calls the download routines */
439 bool InstallPackages(CacheFile
&Cache
,bool ShwKept
,bool Ask
= true,bool Saftey
= true)
442 bool Essential
= false;
444 // Show all the various warning indicators
445 ShowDel(c1out
,Cache
);
446 ShowNew(c1out
,Cache
);
448 ShowKept(c1out
,Cache
);
449 Fail
|= !ShowHold(c1out
,Cache
);
450 if (_config
->FindB("APT::Get::Show-Upgraded",false) == true)
451 ShowUpgraded(c1out
,Cache
);
452 Essential
= !ShowEssential(c1out
,Cache
);
457 if (Cache
->BrokenCount() != 0)
459 ShowBroken(c1out
,Cache
);
460 return _error
->Error("Internal Error, InstallPackages was called with broken packages!");
463 if (Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
464 Cache
->BadCount() == 0)
467 // Run the simulator ..
468 if (_config
->FindB("APT::Get::Simulate") == true)
470 pkgSimulate
PM(Cache
);
471 return PM
.DoInstall();
474 // Create the text record parser
475 pkgRecords
Recs(Cache
);
476 if (_error
->PendingError() == true)
479 // Lock the archive directory
481 if (_config
->FindB("Debug::NoLocking",false) == false)
483 Lock
.Fd(GetLock(_config
->FindDir("Dir::Cache::Archives") + "lock"));
484 if (_error
->PendingError() == true)
485 return _error
->Error("Unable to lock the download directory");
488 // Create the download object
489 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
490 pkgAcquire
Fetcher(&Stat
);
492 // Read the source list
494 if (List
.ReadMainList() == false)
495 return _error
->Error("The list of sources could not be read.");
497 // Create the package manager and prepare to download
499 if (PM
.GetArchives(&Fetcher
,&List
,&Recs
) == false ||
500 _error
->PendingError() == true)
503 // Display statistics
504 unsigned long FetchBytes
= Fetcher
.FetchNeeded();
505 unsigned long FetchPBytes
= Fetcher
.PartialPresent();
506 unsigned long DebBytes
= Fetcher
.TotalNeeded();
507 if (DebBytes
!= Cache
->DebSize())
509 c0out
<< DebBytes
<< ',' << Cache
->DebSize() << endl
;
510 c0out
<< "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl
;
513 // Check for enough free space
515 string OutputDir
= _config
->FindDir("Dir::Cache::Archives");
516 if (statfs(OutputDir
.c_str(),&Buf
) != 0)
517 return _error
->Errno("statfs","Couldn't determine free space in %s",
519 if (unsigned(Buf
.f_bfree
) < (FetchBytes
- FetchPBytes
)/Buf
.f_bsize
)
520 return _error
->Error("Sorry, you don't have enough free space in %s",
524 c1out
<< "Need to get ";
525 if (DebBytes
!= FetchBytes
)
526 c1out
<< SizeToStr(FetchBytes
) << "b/" << SizeToStr(DebBytes
) << 'b';
528 c1out
<< SizeToStr(DebBytes
) << 'b';
530 c1out
<< " of archives. After unpacking ";
533 if (Cache
->UsrSize() >= 0)
534 c1out
<< SizeToStr(Cache
->UsrSize()) << "b will be used." << endl
;
536 c1out
<< SizeToStr(-1*Cache
->UsrSize()) << "b will be freed." << endl
;
538 if (_error
->PendingError() == true)
542 if (_config
->FindI("quiet",0) >= 2 ||
543 _config
->FindB("APT::Get::Assume-Yes",false) == true)
545 if (Fail
== true && _config
->FindB("APT::Get::Force-Yes",false) == false)
546 return _error
->Error("There are problems and -y was used without --force-yes");
549 if (Essential
== true && Saftey
== true)
551 c2out
<< "You are about to do something potentially harmful" << endl
;
552 c2out
<< "To continue type in the phrase 'Yes, I understand this may be bad'" << endl
;
553 c2out
<< " ?] " << flush
;
554 if (AnalPrompt("Yes, I understand this may be bad") == false)
556 c2out
<< "Abort." << endl
;
562 // Prompt to continue
563 if (Ask
== true || Fail
== true)
565 if (_config
->FindI("quiet",0) < 2 &&
566 _config
->FindB("APT::Get::Assume-Yes",false) == false)
568 c2out
<< "Do you want to continue? [Y/n] " << flush
;
570 if (YnPrompt() == false)
572 c2out
<< "Abort." << endl
;
579 // Just print out the uris an exit if the --print-uris flag was used
580 if (_config
->FindB("APT::Get::Print-URIs") == true)
582 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
583 for (; I
!= Fetcher
.UriEnd(); I
++)
584 cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
585 I
->Owner
->FileSize
<< ' ' << I
->Owner
->MD5Sum() << endl
;
590 if (Fetcher
.Run() == false)
595 bool Transient
= false;
596 for (pkgAcquire::Item
**I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); I
++)
598 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
599 (*I
)->Complete
== true)
602 if ((*I
)->Status
== pkgAcquire::Item::StatIdle
)
609 cerr
<< "Failed to fetch " << (*I
)->DescURI() << endl
;
610 cerr
<< " " << (*I
)->ErrorText
<< endl
;
614 if (_config
->FindB("APT::Get::Download-Only",false) == true)
617 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
619 if (Transient
== true)
621 c2out
<< "Upgrading with disk swapping is not supported in this version." << endl
;
622 c2out
<< "Try running multiple times with --fix-missing" << endl
;
625 return _error
->Error("Unable to fetch some archives, maybe try with --fix-missing?");
628 // Try to deal with missing package files
629 if (PM
.FixMissing() == false)
631 cerr
<< "Unable to correct missing packages." << endl
;
632 return _error
->Error("Aborting Install.");
636 return PM
.DoInstall();
640 // DoUpdate - Update the package lists /*{{{*/
641 // ---------------------------------------------------------------------
643 bool DoUpdate(CommandLine
&)
645 // Get the source list
647 if (List
.ReadMainList() == false)
650 // Lock the list directory
652 if (_config
->FindB("Debug::NoLocking",false) == false)
654 Lock
.Fd(GetLock(_config
->FindDir("Dir::State::Lists") + "lock"));
655 if (_error
->PendingError() == true)
656 return _error
->Error("Unable to lock the list directory");
659 // Create the download object
660 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
661 pkgAcquire
Fetcher(&Stat
);
663 // Populate it with the source selection
664 pkgSourceList::const_iterator I
;
665 for (I
= List
.begin(); I
!= List
.end(); I
++)
667 new pkgAcqIndex(&Fetcher
,I
);
668 if (_error
->PendingError() == true)
673 if (Fetcher
.Run() == false)
676 // Clean out any old list files
677 if (Fetcher
.Clean(_config
->FindDir("Dir::State::lists")) == false ||
678 Fetcher
.Clean(_config
->FindDir("Dir::State::lists") + "partial/") == false)
681 // Prepare the cache.
683 if (Cache
.Open() == false)
689 // DoUpgrade - Upgrade all packages /*{{{*/
690 // ---------------------------------------------------------------------
691 /* Upgrade all packages without installing new packages or erasing old
693 bool DoUpgrade(CommandLine
&CmdL
)
696 if (Cache
.Open() == false || Cache
.CheckDeps() == false)
700 if (pkgAllUpgrade(Cache
) == false)
702 ShowBroken(c1out
,Cache
);
703 return _error
->Error("Internal Error, AllUpgrade broke stuff");
706 return InstallPackages(Cache
,true);
709 // DoInstall - Install packages from the command line /*{{{*/
710 // ---------------------------------------------------------------------
711 /* Install named packages */
712 bool DoInstall(CommandLine
&CmdL
)
715 if (Cache
.Open() == false || Cache
.CheckDeps(CmdL
.FileSize() != 1) == false)
718 // Enter the special broken fixing mode if the user specified arguments
719 bool BrokenFix
= false;
720 if (Cache
->BrokenCount() != 0)
723 unsigned int ExpectedInst
= 0;
724 unsigned int Packages
= 0;
725 pkgProblemResolver
Fix(Cache
);
727 bool DefRemove
= false;
728 if (strcasecmp(CmdL
.FileList
[0],"remove") == 0)
731 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
733 // Duplicate the string
734 unsigned int Length
= strlen(*I
);
736 if (Length
>= sizeof(S
))
740 // See if we are removing the package
741 bool Remove
= DefRemove
;
742 if (Cache
->FindPkg(S
).end() == true)
744 // Handle an optional end tag indicating what to do
745 if (S
[Length
- 1] == '-')
750 if (S
[Length
- 1] == '+')
757 // Locate the package
758 pkgCache::PkgIterator Pkg
= Cache
->FindPkg(S
);
760 if (Pkg
.end() == true)
761 return _error
->Error("Couldn't find package %s",S
);
763 // Handle the no-upgrade case
764 if (_config
->FindB("APT::Get::no-upgrade",false) == true &&
765 Pkg
->CurrentVer
!= 0)
767 c1out
<< "Skipping " << Pkg
.Name() << ", it is already installed and no-upgrade is set." << endl
;
771 // Check if there is something new to install
772 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
773 if (State
.CandidateVer
== 0)
775 if (Pkg
->ProvidesList
!= 0)
777 c1out
<< "Package " << S
<< " is a virtual package provided by:" << endl
;
779 pkgCache::PrvIterator I
= Pkg
.ProvidesList();
780 for (; I
.end() == false; I
++)
782 pkgCache::PkgIterator Pkg
= I
.OwnerPkg();
784 if ((*Cache
)[Pkg
].CandidateVerIter(*Cache
) == I
.OwnerVer())
786 if ((*Cache
)[Pkg
].Install() == true && (*Cache
)[Pkg
].NewInstall() == false)
787 c1out
<< " " << Pkg
.Name() << " " << I
.OwnerVer().VerStr() <<
788 " [Installed]"<< endl
;
790 c1out
<< " " << Pkg
.Name() << " " << I
.OwnerVer().VerStr() << endl
;
793 c1out
<< "You should explicly select one to install." << endl
;
797 c1out
<< "Package " << S
<< " has no available version, but exists in the database." << endl
;
798 c1out
<< "This typically means that the package was mentioned in a dependency and " << endl
;
799 c1out
<< "never uploaded, or that it is an obsolete package." << endl
;
802 pkgCache::DepIterator Dep
= Pkg
.RevDependsList();
803 for (; Dep
.end() == false; Dep
++)
805 if (Dep
->Type
!= pkgCache::Dep::Replaces
)
807 List
+= string(Dep
.ParentPkg().Name()) + " ";
809 ShowList(c1out
,"However the following packages replace it:",List
);
812 return _error
->Error("Package %s has no installation candidate",S
);
819 Cache
->MarkDelete(Pkg
);
824 Cache
->MarkInstall(Pkg
,false);
825 if (State
.Install() == false)
826 c1out
<< "Sorry, " << S
<< " is already the newest version" << endl
;
830 // Install it with autoinstalling enabled.
831 if (State
.InstBroken() == true && BrokenFix
== false)
832 Cache
->MarkInstall(Pkg
,true);
835 /* If we are in the Broken fixing mode we do not attempt to fix the
836 problems. This is if the user invoked install without -f and gave
838 if (BrokenFix
== true && Cache
->BrokenCount() != 0)
840 c1out
<< "You might want to run `apt-get -f install' to correct these." << endl
;
841 ShowBroken(c1out
,Cache
);
843 return _error
->Error("Unmet dependencies. Try using -f.");
846 // Call the scored problem resolver
847 Fix
.InstallProtect();
848 if (Fix
.Resolve(true) == false)
851 // Now we check the state of the packages,
852 if (Cache
->BrokenCount() != 0)
854 c1out
<< "Some packages could not be installed. This may mean that you have" << endl
;
855 c1out
<< "requested an impossible situation or if you are using the unstable" << endl
;
856 c1out
<< "distribution that some required packages have not yet been created" << endl
;
857 c1out
<< "or been moved out of Incoming." << endl
;
861 c1out
<< "Since you only requested a single operation it is extremely likely that" << endl
;
862 c1out
<< "the package is simply not installable and a bug report against" << endl
;
863 c1out
<< "that package should be filed." << endl
;
866 c1out
<< "The following information may help to resolve the situation:" << endl
;
868 ShowBroken(c1out
,Cache
);
869 return _error
->Error("Sorry, broken packages");
872 /* Print out a list of packages that are going to be installed extra
873 to what the user asked */
874 if (Cache
->InstCount() != ExpectedInst
)
877 pkgCache::PkgIterator I
= Cache
->PkgBegin();
878 for (;I
.end() != true; I
++)
880 if ((*Cache
)[I
].Install() == false)
884 for (J
= CmdL
.FileList
+ 1; *J
!= 0; J
++)
885 if (strcmp(*J
,I
.Name()) == 0)
889 List
+= string(I
.Name()) + " ";
892 ShowList(c1out
,"The following extra packages will be installed:",List
);
895 // See if we need to prompt
896 if (Cache
->InstCount() == ExpectedInst
&& Cache
->DelCount() == 0)
897 return InstallPackages(Cache
,false,false);
899 return InstallPackages(Cache
,false);
902 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
903 // ---------------------------------------------------------------------
904 /* Intelligent upgrader that will install and remove packages at will */
905 bool DoDistUpgrade(CommandLine
&CmdL
)
908 if (Cache
.Open() == false || Cache
.CheckDeps() == false)
911 c0out
<< "Calculating Upgrade... " << flush
;
912 if (pkgDistUpgrade(*Cache
) == false)
914 c0out
<< "Failed" << endl
;
915 ShowBroken(c1out
,Cache
);
919 c0out
<< "Done" << endl
;
921 return InstallPackages(Cache
,true);
924 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
925 // ---------------------------------------------------------------------
926 /* Follows dselect's selections */
927 bool DoDSelectUpgrade(CommandLine
&CmdL
)
930 if (Cache
.Open() == false || Cache
.CheckDeps() == false)
933 // Install everything with the install flag set
934 pkgCache::PkgIterator I
= Cache
->PkgBegin();
935 for (;I
.end() != true; I
++)
937 /* Install the package only if it is a new install, the autoupgrader
938 will deal with the rest */
939 if (I
->SelectedState
== pkgCache::State::Install
)
940 Cache
->MarkInstall(I
,false);
943 /* Now install their deps too, if we do this above then order of
944 the status file is significant for | groups */
945 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
947 /* Install the package only if it is a new install, the autoupgrader
948 will deal with the rest */
949 if (I
->SelectedState
== pkgCache::State::Install
)
950 Cache
->MarkInstall(I
,true);
953 // Apply erasures now, they override everything else.
954 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
957 if (I
->SelectedState
== pkgCache::State::DeInstall
||
958 I
->SelectedState
== pkgCache::State::Purge
)
959 Cache
->MarkDelete(I
);
962 /* Resolve any problems that dselect created, allupgrade cannot handle
963 such things. We do so quite agressively too.. */
964 if (Cache
->BrokenCount() != 0)
966 pkgProblemResolver
Fix(Cache
);
968 // Hold back held packages.
969 if (_config
->FindB("APT::Ingore-Hold",false) == false)
971 for (pkgCache::PkgIterator I
= Cache
->PkgBegin(); I
.end() == false; I
++)
973 if (I
->SelectedState
== pkgCache::State::Hold
)
981 if (Fix
.Resolve() == false)
983 ShowBroken(c1out
,Cache
);
984 return _error
->Error("Internal Error, problem resolver broke stuff");
988 // Now upgrade everything
989 if (pkgAllUpgrade(Cache
) == false)
991 ShowBroken(c1out
,Cache
);
992 return _error
->Error("Internal Error, problem resolver broke stuff");
995 return InstallPackages(Cache
,false);
998 // DoClean - Remove download archives /*{{{*/
999 // ---------------------------------------------------------------------
1001 bool DoClean(CommandLine
&CmdL
)
1004 Fetcher
.Clean(_config
->FindDir("Dir::Cache::archives"));
1005 Fetcher
.Clean(_config
->FindDir("Dir::Cache::archives") + "partial/");
1009 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
1010 // ---------------------------------------------------------------------
1011 /* This is similar to clean but it only purges things that cannot be
1012 downloaded, that is old versions of cached packages. */
1013 class LogCleaner
: public pkgArchiveCleaner
1016 virtual void Erase(const char *File
,string Pkg
,string Ver
,struct stat
&St
)
1018 cout
<< "Del " << Pkg
<< " " << Ver
<< " [" << SizeToStr(St
.st_size
) << "b]" << endl
;
1022 bool DoAutoClean(CommandLine
&CmdL
)
1025 if (Cache
.Open() == false)
1030 return Cleaner
.Go(_config
->FindDir("Dir::Cache::archives"),*Cache
) &&
1031 Cleaner
.Go(_config
->FindDir("Dir::Cache::archives") + "partial/",*Cache
);
1034 // DoCheck - Perform the check operation /*{{{*/
1035 // ---------------------------------------------------------------------
1036 /* Opening automatically checks the system, this command is mostly used
1038 bool DoCheck(CommandLine
&CmdL
)
1047 // DoSource - Fetch a source archive /*{{{*/
1048 // ---------------------------------------------------------------------
1049 /* Fetch souce packages */
1057 bool DoSource(CommandLine
&CmdL
)
1060 if (Cache
.Open(false) == false)
1063 if (CmdL
.FileSize() <= 1)
1064 return _error
->Error("Must specify at least one package to fetch source for");
1066 // Read the source list
1068 if (List
.ReadMainList() == false)
1069 return _error
->Error("The list of sources could not be read.");
1071 // Create the text record parsers
1072 pkgRecords
Recs(Cache
);
1073 pkgSrcRecords
SrcRecs(List
);
1074 if (_error
->PendingError() == true)
1077 // Create the download object
1078 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
1079 pkgAcquire
Fetcher(&Stat
);
1081 DscFile
*Dsc
= new DscFile
[CmdL
.FileSize()];
1083 // Load the requestd sources into the fetcher
1085 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++, J
++)
1089 /* Lookup the version of the package we would install if we were to
1090 install a version and determine the source package name, then look
1091 in the archive for a source package of the same name. In theory
1092 we could stash the version string as well and match that too but
1093 today there aren't multi source versions in the archive. */
1094 pkgCache::PkgIterator Pkg
= Cache
->FindPkg(*I
);
1095 if (Pkg
.end() == false)
1097 pkgCache::VerIterator Ver
= Cache
->GetCandidateVer(Pkg
);
1098 if (Ver
.end() == false)
1100 pkgRecords::Parser
&Parse
= Recs
.Lookup(Ver
.FileList());
1101 Src
= Parse
.SourcePkg();
1105 // No source package name..
1106 if (Src
.empty() == true)
1110 pkgSrcRecords::Parser
*Last
= 0;
1111 unsigned long Offset
= 0;
1114 // Iterate over all of the hits
1115 pkgSrcRecords::Parser
*Parse
;
1117 while ((Parse
= SrcRecs
.Find(Src
.c_str(),false)) != 0)
1119 string Ver
= Parse
->Version();
1120 if (Last
== 0 || pkgVersionCompare(Version
,Ver
) < 0)
1123 Offset
= Parse
->Offset();
1129 return _error
->Error("Unable to find a source package for %s",Src
.c_str());
1132 vector
<pkgSrcRecords::File
> Lst
;
1133 if (Last
->Jump(Offset
) == false || Last
->Files(Lst
) == false)
1136 // Load them into the fetcher
1137 for (vector
<pkgSrcRecords::File
>::const_iterator I
= Lst
.begin();
1138 I
!= Lst
.end(); I
++)
1140 // Try to guess what sort of file it is we are getting.
1142 if (I
->Path
.find(".dsc") != string::npos
)
1145 Dsc
[J
].Package
= Last
->Package();
1146 Dsc
[J
].Version
= Last
->Version();
1147 Dsc
[J
].Dsc
= flNotDir(I
->Path
);
1150 if (I
->Path
.find(".tar.gz") != string::npos
)
1152 if (I
->Path
.find(".diff.gz") != string::npos
)
1155 new pkgAcqFile(&Fetcher
,Last
->Source()->ArchiveURI(I
->Path
),
1156 I
->MD5Hash
,I
->Size
,Last
->Source()->SourceInfo(Src
,
1157 Last
->Version(),Comp
),Src
);
1161 // Display statistics
1162 unsigned long FetchBytes
= Fetcher
.FetchNeeded();
1163 unsigned long FetchPBytes
= Fetcher
.PartialPresent();
1164 unsigned long DebBytes
= Fetcher
.TotalNeeded();
1166 // Check for enough free space
1168 string OutputDir
= ".";
1169 if (statfs(OutputDir
.c_str(),&Buf
) != 0)
1170 return _error
->Errno("statfs","Couldn't determine free space in %s",
1172 if (unsigned(Buf
.f_bfree
) < (FetchBytes
- FetchPBytes
)/Buf
.f_bsize
)
1173 return _error
->Error("Sorry, you don't have enough free space in %s",
1177 c1out
<< "Need to get ";
1178 if (DebBytes
!= FetchBytes
)
1179 c1out
<< SizeToStr(FetchBytes
) << "b/" << SizeToStr(DebBytes
) << 'b';
1181 c1out
<< SizeToStr(DebBytes
) << 'b';
1182 c1out
<< " of source archives." << endl
;
1184 // Just print out the uris an exit if the --print-uris flag was used
1185 if (_config
->FindB("APT::Get::Print-URIs") == true)
1187 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
1188 for (; I
!= Fetcher
.UriEnd(); I
++)
1189 cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
1190 I
->Owner
->FileSize
<< ' ' << I
->Owner
->MD5Sum() << endl
;
1195 if (Fetcher
.Run() == false)
1198 // Print error messages
1199 bool Failed
= false;
1200 for (pkgAcquire::Item
**I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); I
++)
1202 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
1203 (*I
)->Complete
== true)
1206 cerr
<< "Failed to fetch " << (*I
)->DescURI() << endl
;
1207 cerr
<< " " << (*I
)->ErrorText
<< endl
;
1211 return _error
->Error("Failed to fetch some archives.");
1213 if (_config
->FindB("APT::Get::Download-only",false) == true)
1216 // Unpack the sources
1217 for (unsigned I
= 0; I
!= J
; I
++)
1219 string Dir
= Dsc
[I
].Package
+ '-' + pkgBaseVersion(Dsc
[I
].Version
.c_str());
1221 // See if the package is already unpacked
1223 if (stat(Dir
.c_str(),&Stat
) == 0 &&
1224 S_ISDIR(Stat
.st_mode
) != 0)
1226 c0out
<< "Skipping unpack of already unpacked source in " << Dir
<< endl
;
1232 snprintf(S
,sizeof(S
),"%s -x %s",
1233 _config
->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
1234 Dsc
[I
].Dsc
.c_str());
1236 return _error
->Error("Unpack command '%s' failed.",S
);
1239 // Try to compile it with dpkg-buildpackage
1240 if (_config
->FindB("APT::Get::Compile",false) == true)
1242 // Call dpkg-buildpackage
1244 snprintf(S
,sizeof(S
),"cd %s && %s %s",
1246 _config
->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
1247 _config
->Find("DPkg::Build-Options","-b -uc").c_str());
1250 return _error
->Error("Build command '%s' failed.",S
);
1257 // ShowHelp - Show a help screen /*{{{*/
1258 // ---------------------------------------------------------------------
1260 bool ShowHelp(CommandLine
&CmdL
)
1262 cout
<< PACKAGE
<< ' ' << VERSION
<< " for " << ARCHITECTURE
<<
1263 " compiled on " << __DATE__
<< " " << __TIME__
<< endl
;
1264 if (_config
->FindB("version") == true)
1267 cout
<< "Usage: apt-get [options] command" << endl
;
1268 cout
<< " apt-get [options] install pkg1 [pkg2 ...]" << endl
;
1270 cout
<< "apt-get is a simple command line interface for downloading and" << endl
;
1271 cout
<< "installing packages. The most frequently used commands are update" << endl
;
1272 cout
<< "and install." << endl
;
1274 cout
<< "Commands:" << endl
;
1275 cout
<< " update - Retrieve new lists of packages" << endl
;
1276 cout
<< " upgrade - Perform an upgrade" << endl
;
1277 cout
<< " install - Install new packages (pkg is libc6 not libc6.deb)" << endl
;
1278 cout
<< " remove - Remove packages" << endl
;
1279 cout
<< " source - Download source archives" << endl
;
1280 cout
<< " dist-upgrade - Distribution upgrade, see apt-get(8)" << endl
;
1281 cout
<< " dselect-upgrade - Follow dselect selections" << endl
;
1282 cout
<< " clean - Erase downloaded archive files" << endl
;
1283 cout
<< " autoclean - Erase old downloaded archive files" << endl
;
1284 cout
<< " check - Verify that there are no broken dependencies" << endl
;
1286 cout
<< "Options:" << endl
;
1287 cout
<< " -h This help text." << endl
;
1288 cout
<< " -q Loggable output - no progress indicator" << endl
;
1289 cout
<< " -qq No output except for errors" << endl
;
1290 cout
<< " -d Download only - do NOT install or unpack archives" << endl
;
1291 cout
<< " -s No-act. Perform ordering simulation" << endl
;
1292 cout
<< " -y Assume Yes to all queries and do not prompt" << endl
;
1293 cout
<< " -f Attempt to continue if the integrity check fails" << endl
;
1294 cout
<< " -m Attempt to continue if archives are unlocatable" << endl
;
1295 cout
<< " -u Show a list of upgraded packages as well" << endl
;
1296 cout
<< " -c=? Read this configuration file" << endl
;
1297 cout
<< " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" << endl
;
1298 cout
<< "See the apt-get(8), sources.list(5) and apt.conf(5) manual" << endl
;
1299 cout
<< "pages for more information." << endl
;
1303 // GetInitialize - Initialize things for apt-get /*{{{*/
1304 // ---------------------------------------------------------------------
1306 void GetInitialize()
1308 _config
->Set("quiet",0);
1309 _config
->Set("help",false);
1310 _config
->Set("APT::Get::Download-Only",false);
1311 _config
->Set("APT::Get::Simulate",false);
1312 _config
->Set("APT::Get::Assume-Yes",false);
1313 _config
->Set("APT::Get::Fix-Broken",false);
1314 _config
->Set("APT::Get::Force-Yes",false);
1317 // SigWinch - Window size change signal handler /*{{{*/
1318 // ---------------------------------------------------------------------
1322 // Riped from GNU ls
1326 if (ioctl(1, TIOCGWINSZ
, &ws
) != -1 && ws
.ws_col
>= 5)
1327 ScreenWidth
= ws
.ws_col
- 1;
1332 int main(int argc
,const char *argv
[])
1334 CommandLine::Args Args
[] = {
1335 {'h',"help","help",0},
1336 {'v',"version","version",0},
1337 {'q',"quiet","quiet",CommandLine::IntLevel
},
1338 {'q',"silent","quiet",CommandLine::IntLevel
},
1339 {'d',"download-only","APT::Get::Download-Only",0},
1340 {'b',"compile","APT::Get::Compile",0},
1341 {'b',"build","APT::Get::Compile",0},
1342 {'s',"simulate","APT::Get::Simulate",0},
1343 {'s',"just-print","APT::Get::Simulate",0},
1344 {'s',"recon","APT::Get::Simulate",0},
1345 {'s',"no-act","APT::Get::Simulate",0},
1346 {'y',"yes","APT::Get::Assume-Yes",0},
1347 {'y',"assume-yes","APT::Get::Assume-Yes",0},
1348 {'f',"fix-broken","APT::Get::Fix-Broken",0},
1349 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
1350 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
1351 {0,"fix-missing","APT::Get::Fix-Missing",0},
1352 {0,"ignore-hold","APT::Ingore-Hold",0},
1353 {0,"no-upgrade","APT::Get::no-upgrade",0},
1354 {0,"force-yes","APT::Get::force-yes",0},
1355 {0,"print-uris","APT::Get::Print-URIs",0},
1356 {'c',"config-file",0,CommandLine::ConfigFile
},
1357 {'o',"option",0,CommandLine::ArbItem
},
1359 CommandLine::Dispatch Cmds
[] = {{"update",&DoUpdate
},
1360 {"upgrade",&DoUpgrade
},
1361 {"install",&DoInstall
},
1362 {"remove",&DoInstall
},
1363 {"dist-upgrade",&DoDistUpgrade
},
1364 {"dselect-upgrade",&DoDSelectUpgrade
},
1366 {"autoclean",&DoAutoClean
},
1368 {"source",&DoSource
},
1372 // Parse the command line and initialize the package library
1373 CommandLine
CmdL(Args
,_config
);
1374 if (pkgInitialize(*_config
) == false ||
1375 CmdL
.Parse(argc
,argv
) == false)
1377 _error
->DumpErrors();
1381 // See if the help should be shown
1382 if (_config
->FindB("help") == true ||
1383 _config
->FindB("version") == true ||
1384 CmdL
.FileSize() == 0)
1385 return ShowHelp(CmdL
);
1387 // Deal with stdout not being a tty
1388 if (ttyname(STDOUT_FILENO
) == 0 && _config
->FindI("quiet",0) < 1)
1389 _config
->Set("quiet","1");
1391 // Setup the output streams
1392 c0out
.rdbuf(cout
.rdbuf());
1393 c1out
.rdbuf(cout
.rdbuf());
1394 c2out
.rdbuf(cout
.rdbuf());
1395 if (_config
->FindI("quiet",0) > 0)
1396 c0out
.rdbuf(devnull
.rdbuf());
1397 if (_config
->FindI("quiet",0) > 1)
1398 c1out
.rdbuf(devnull
.rdbuf());
1400 // Setup the signals
1401 signal(SIGPIPE
,SIG_IGN
);
1402 signal(SIGWINCH
,SigWinch
);
1405 // Match the operation
1406 CmdL
.DispatchArg(Cmds
);
1408 // Print any errors or warnings found during parsing
1409 if (_error
->empty() == false)
1411 bool Errors
= _error
->PendingError();
1412 _error
->DumpErrors();
1413 return Errors
== true?100:0;