]>
git.saurik.com Git - apt.git/blob - cmdline/apt-get.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-get.cc,v 1.55 1999/04/20 05:02: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>
60 ofstream
devnull("/dev/null");
61 unsigned int ScreenWidth
= 80;
63 // YnPrompt - Yes No Prompt. /*{{{*/
64 // ---------------------------------------------------------------------
65 /* Returns true on a Yes.*/
68 if (_config
->FindB("APT::Get::Assume-Yes",false) == true)
76 read(STDIN_FILENO
,&C
,1);
77 while (C
!= '\n' && Jnk
!= '\n') read(STDIN_FILENO
,&Jnk
,1);
79 if (!(C
== 'Y' || C
== 'y' || C
== '\n' || C
== '\r'))
84 // AnalPrompt - Annoying Yes No Prompt. /*{{{*/
85 // ---------------------------------------------------------------------
86 /* Returns true on a Yes.*/
87 bool AnalPrompt(const char *Text
)
90 cin
.getline(Buf
,sizeof(Buf
));
91 if (strcmp(Buf
,Text
) == 0)
96 // ShowList - Show a list /*{{{*/
97 // ---------------------------------------------------------------------
98 /* This prints out a string of space seperated words with a title and
99 a two space indent line wraped to the current screen width. */
100 bool ShowList(ostream
&out
,string Title
,string List
)
102 if (List
.empty() == true)
105 // Acount for the leading space
106 int ScreenWidth
= ::ScreenWidth
- 3;
108 out
<< Title
<< endl
;
109 string::size_type Start
= 0;
110 while (Start
< List
.size())
112 string::size_type End
;
113 if (Start
+ ScreenWidth
>= List
.size())
116 End
= List
.rfind(' ',Start
+ScreenWidth
);
118 if (End
== string::npos
|| End
< Start
)
119 End
= Start
+ ScreenWidth
;
120 out
<< " " << string(List
,Start
,End
- Start
) << endl
;
126 // ShowBroken - Debugging aide /*{{{*/
127 // ---------------------------------------------------------------------
128 /* This prints out the names of all the packages that are broken along
129 with the name of each each broken dependency and a quite version
131 void ShowBroken(ostream
&out
,pkgDepCache
&Cache
)
133 out
<< "Sorry, but the following packages have unmet dependencies:" << endl
;
134 pkgCache::PkgIterator I
= Cache
.PkgBegin();
135 for (;I
.end() != true; I
++)
137 if (Cache
[I
].InstBroken() == false)
140 // Print out each package and the failed dependencies
141 out
<<" " << I
.Name() << ":";
142 int Indent
= strlen(I
.Name()) + 3;
144 if (Cache
[I
].InstVerIter(Cache
).end() == true)
150 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
152 // Compute a single dependency element (glob or)
153 pkgCache::DepIterator Start
;
154 pkgCache::DepIterator End
;
157 if (Cache
.IsImportantDep(End
) == false ||
158 (Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
162 for (int J
= 0; J
!= Indent
; J
++)
166 out
<< ' ' << End
.DepType() << ": " << End
.TargetPkg().Name();
168 // Show a quick summary of the version requirements
169 if (End
.TargetVer() != 0)
170 out
<< " (" << End
.CompType() << " " << End
.TargetVer() <<
173 /* Show a summary of the target package if possible. In the case
174 of virtual packages we show nothing */
176 pkgCache::PkgIterator Targ
= End
.TargetPkg();
177 if (Targ
->ProvidesList
== 0)
180 pkgCache::VerIterator Ver
= Cache
[Targ
].InstVerIter(Cache
);
181 if (Ver
.end() == false)
182 out
<< Ver
.VerStr() << " is installed";
185 if (Cache
[Targ
].CandidateVerIter(Cache
).end() == true)
187 if (Targ
->ProvidesList
== 0)
188 out
<< "it is not installable";
190 out
<< "it is a virtual package";
193 out
<< "it is not installed";
202 // ShowNew - Show packages to newly install /*{{{*/
203 // ---------------------------------------------------------------------
205 void ShowNew(ostream
&out
,pkgDepCache
&Dep
)
207 /* Print out a list of packages that are going to be removed extra
208 to what the user asked */
209 pkgCache::PkgIterator I
= Dep
.PkgBegin();
211 for (;I
.end() != true; I
++)
212 if (Dep
[I
].NewInstall() == true)
213 List
+= string(I
.Name()) + " ";
214 ShowList(out
,"The following NEW packages will be installed:",List
);
217 // ShowDel - Show packages to delete /*{{{*/
218 // ---------------------------------------------------------------------
220 void ShowDel(ostream
&out
,pkgDepCache
&Dep
)
222 /* Print out a list of packages that are going to be removed extra
223 to what the user asked */
224 pkgCache::PkgIterator I
= Dep
.PkgBegin();
226 for (;I
.end() != true; I
++)
227 if (Dep
[I
].Delete() == true)
228 List
+= string(I
.Name()) + " ";
230 ShowList(out
,"The following packages will be REMOVED:",List
);
233 // ShowKept - Show kept packages /*{{{*/
234 // ---------------------------------------------------------------------
236 void ShowKept(ostream
&out
,pkgDepCache
&Dep
)
238 pkgCache::PkgIterator I
= Dep
.PkgBegin();
240 for (;I
.end() != true; I
++)
243 if (Dep
[I
].Upgrade() == true || Dep
[I
].Upgradable() == false ||
244 I
->CurrentVer
== 0 || Dep
[I
].Delete() == true)
247 List
+= string(I
.Name()) + " ";
249 ShowList(out
,"The following packages have been kept back",List
);
252 // ShowUpgraded - Show upgraded packages /*{{{*/
253 // ---------------------------------------------------------------------
255 void ShowUpgraded(ostream
&out
,pkgDepCache
&Dep
)
257 pkgCache::PkgIterator I
= Dep
.PkgBegin();
259 for (;I
.end() != true; I
++)
262 if (Dep
[I
].Upgrade() == false || Dep
[I
].NewInstall() == true)
265 List
+= string(I
.Name()) + " ";
267 ShowList(out
,"The following packages will be upgraded",List
);
270 // ShowHold - Show held but changed packages /*{{{*/
271 // ---------------------------------------------------------------------
273 bool ShowHold(ostream
&out
,pkgDepCache
&Dep
)
275 pkgCache::PkgIterator I
= Dep
.PkgBegin();
277 for (;I
.end() != true; I
++)
279 if (Dep
[I
].InstallVer
!= (pkgCache::Version
*)I
.CurrentVer() &&
280 I
->SelectedState
== pkgCache::State::Hold
)
281 List
+= string(I
.Name()) + " ";
284 return ShowList(out
,"The following held packages will be changed:",List
);
287 // ShowEssential - Show an essential package warning /*{{{*/
288 // ---------------------------------------------------------------------
289 /* This prints out a warning message that is not to be ignored. It shows
290 all essential packages and their dependents that are to be removed.
291 It is insanely risky to remove the dependents of an essential package! */
292 bool ShowEssential(ostream
&out
,pkgDepCache
&Dep
)
294 pkgCache::PkgIterator I
= Dep
.PkgBegin();
296 bool *Added
= new bool[Dep
.HeaderP
->PackageCount
];
297 for (unsigned int I
= 0; I
!= Dep
.HeaderP
->PackageCount
; I
++)
300 for (;I
.end() != true; I
++)
302 if ((I
->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
305 // The essential package is being removed
306 if (Dep
[I
].Delete() == true)
308 if (Added
[I
->ID
] == false)
311 List
+= string(I
.Name()) + " ";
315 if (I
->CurrentVer
== 0)
318 // Print out any essential package depenendents that are to be removed
319 for (pkgDepCache::DepIterator D
= I
.CurrentVer().DependsList(); D
.end() == false; D
++)
321 // Skip everything but depends
322 if (D
->Type
!= pkgCache::Dep::PreDepends
&&
323 D
->Type
!= pkgCache::Dep::Depends
)
326 pkgCache::PkgIterator P
= D
.SmartTargetPkg();
327 if (Dep
[P
].Delete() == true)
329 if (Added
[P
->ID
] == true)
334 sprintf(S
,"%s (due to %s) ",P
.Name(),I
.Name());
341 if (List
.empty() == false)
342 out
<< "WARNING: The following essential packages will be removed" << endl
;
343 return ShowList(out
,"This should NOT be done unless you know exactly what you are doing!",List
);
346 // Stats - Show some statistics /*{{{*/
347 // ---------------------------------------------------------------------
349 void Stats(ostream
&out
,pkgDepCache
&Dep
)
351 unsigned long Upgrade
= 0;
352 unsigned long Install
= 0;
353 for (pkgCache::PkgIterator I
= Dep
.PkgBegin(); I
.end() == false; I
++)
355 if (Dep
[I
].NewInstall() == true)
358 if (Dep
[I
].Upgrade() == true)
362 out
<< Upgrade
<< " packages upgraded, " <<
363 Install
<< " newly installed, " <<
364 Dep
.DelCount() << " to remove and " <<
365 Dep
.KeepCount() << " not upgraded." << endl
;
367 if (Dep
.BadCount() != 0)
368 out
<< Dep
.BadCount() << " packages not fully installed or removed." << endl
;
372 // class CacheFile - Cover class for some dependency cache functions /*{{{*/
373 // ---------------------------------------------------------------------
375 class CacheFile
: public pkgCacheFile
379 bool CheckDeps(bool AllowBroken
= false);
380 bool Open(bool WithLock
= true)
382 OpTextProgress
Prog(*_config
);
383 return pkgCacheFile::Open(Prog
,WithLock
);
387 // CacheFile::Open - Open the cache file /*{{{*/
388 // ---------------------------------------------------------------------
389 /* This routine generates the caches and then opens the dependency cache
390 and verifies that the system is OK. */
391 bool CacheFile::CheckDeps(bool AllowBroken
)
393 if (_error
->PendingError() == true)
396 // Check that the system is OK
397 if (Cache
->DelCount() != 0 || Cache
->InstCount() != 0)
398 return _error
->Error("Internal Error, non-zero counts");
400 // Apply corrections for half-installed packages
401 if (pkgApplyStatus(*Cache
) == false)
405 if (Cache
->BrokenCount() == 0 || AllowBroken
== true)
408 // Attempt to fix broken things
409 if (_config
->FindB("APT::Get::Fix-Broken",false) == true)
411 c1out
<< "Correcting dependencies..." << flush
;
412 if (pkgFixBroken(*Cache
) == false || Cache
->BrokenCount() != 0)
414 c1out
<< " failed." << endl
;
415 ShowBroken(c1out
,*this);
417 return _error
->Error("Unable to correct dependencies");
419 if (pkgMinimizeUpgrade(*Cache
) == false)
420 return _error
->Error("Unable to minimize the upgrade set");
422 c1out
<< " Done" << endl
;
426 c1out
<< "You might want to run `apt-get -f install' to correct these." << endl
;
427 ShowBroken(c1out
,*this);
429 return _error
->Error("Unmet dependencies. Try using -f.");
436 // InstallPackages - Actually download and install the packages /*{{{*/
437 // ---------------------------------------------------------------------
438 /* This displays the informative messages describing what is going to
439 happen and then calls the download routines */
440 bool InstallPackages(CacheFile
&Cache
,bool ShwKept
,bool Ask
= true,bool Saftey
= true)
443 bool Essential
= false;
445 // Show all the various warning indicators
446 ShowDel(c1out
,Cache
);
447 ShowNew(c1out
,Cache
);
449 ShowKept(c1out
,Cache
);
450 Fail
|= !ShowHold(c1out
,Cache
);
451 if (_config
->FindB("APT::Get::Show-Upgraded",false) == true)
452 ShowUpgraded(c1out
,Cache
);
453 Essential
= !ShowEssential(c1out
,Cache
);
458 if (Cache
->BrokenCount() != 0)
460 ShowBroken(c1out
,Cache
);
461 return _error
->Error("Internal Error, InstallPackages was called with broken packages!");
464 if (Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
465 Cache
->BadCount() == 0)
468 // Run the simulator ..
469 if (_config
->FindB("APT::Get::Simulate") == true)
471 pkgSimulate
PM(Cache
);
472 return PM
.DoInstall();
475 // Create the text record parser
476 pkgRecords
Recs(Cache
);
477 if (_error
->PendingError() == true)
480 // Lock the archive directory
482 if (_config
->FindB("Debug::NoLocking",false) == false)
484 Lock
.Fd(GetLock(_config
->FindDir("Dir::Cache::Archives") + "lock"));
485 if (_error
->PendingError() == true)
486 return _error
->Error("Unable to lock the download directory");
489 // Create the download object
490 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
491 pkgAcquire
Fetcher(&Stat
);
493 // Read the source list
495 if (List
.ReadMainList() == false)
496 return _error
->Error("The list of sources could not be read.");
498 // Create the package manager and prepare to download
500 if (PM
.GetArchives(&Fetcher
,&List
,&Recs
) == false ||
501 _error
->PendingError() == true)
504 // Display statistics
505 unsigned long FetchBytes
= Fetcher
.FetchNeeded();
506 unsigned long FetchPBytes
= Fetcher
.PartialPresent();
507 unsigned long DebBytes
= Fetcher
.TotalNeeded();
508 if (DebBytes
!= Cache
->DebSize())
510 c0out
<< DebBytes
<< ',' << Cache
->DebSize() << endl
;
511 c0out
<< "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl
;
514 // Check for enough free space
516 string OutputDir
= _config
->FindDir("Dir::Cache::Archives");
517 if (statfs(OutputDir
.c_str(),&Buf
) != 0)
518 return _error
->Errno("statfs","Couldn't determine free space in %s",
520 if (unsigned(Buf
.f_bfree
) < (FetchBytes
- FetchPBytes
)/Buf
.f_bsize
)
521 return _error
->Error("Sorry, you don't have enough free space in %s",
525 c1out
<< "Need to get ";
526 if (DebBytes
!= FetchBytes
)
527 c1out
<< SizeToStr(FetchBytes
) << "b/" << SizeToStr(DebBytes
) << 'b';
529 c1out
<< SizeToStr(DebBytes
) << 'b';
531 c1out
<< " of archives. After unpacking ";
534 if (Cache
->UsrSize() >= 0)
535 c1out
<< SizeToStr(Cache
->UsrSize()) << "b will be used." << endl
;
537 c1out
<< SizeToStr(-1*Cache
->UsrSize()) << "b will be freed." << endl
;
539 if (_error
->PendingError() == true)
543 if (_config
->FindI("quiet",0) >= 2 ||
544 _config
->FindB("APT::Get::Assume-Yes",false) == true)
546 if (Fail
== true && _config
->FindB("APT::Get::Force-Yes",false) == false)
547 return _error
->Error("There are problems and -y was used without --force-yes");
550 if (Essential
== true && Saftey
== true)
552 c2out
<< "You are about to do something potentially harmful" << endl
;
553 c2out
<< "To continue type in the phrase 'Yes, I understand this may be bad'" << endl
;
554 c2out
<< " ?] " << flush
;
555 if (AnalPrompt("Yes, I understand this may be bad") == false)
557 c2out
<< "Abort." << endl
;
563 // Prompt to continue
564 if (Ask
== true || Fail
== true)
566 if (_config
->FindI("quiet",0) < 2 &&
567 _config
->FindB("APT::Get::Assume-Yes",false) == false)
569 c2out
<< "Do you want to continue? [Y/n] " << flush
;
571 if (YnPrompt() == false)
573 c2out
<< "Abort." << endl
;
580 // Just print out the uris an exit if the --print-uris flag was used
581 if (_config
->FindB("APT::Get::Print-URIs") == true)
583 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
584 for (; I
!= Fetcher
.UriEnd(); I
++)
585 cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
586 I
->Owner
->FileSize
<< ' ' << I
->Owner
->MD5Sum() << endl
;
591 if (Fetcher
.Run() == false)
596 bool Transient
= false;
597 for (pkgAcquire::Item
**I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); I
++)
599 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
600 (*I
)->Complete
== true)
603 if ((*I
)->Status
== pkgAcquire::Item::StatIdle
)
610 cerr
<< "Failed to fetch " << (*I
)->DescURI() << endl
;
611 cerr
<< " " << (*I
)->ErrorText
<< endl
;
615 if (_config
->FindB("APT::Get::Download-Only",false) == true)
618 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
620 if (Transient
== true)
622 c2out
<< "Upgrading with disk swapping is not supported in this version." << endl
;
623 c2out
<< "Try running multiple times with --fix-missing" << endl
;
626 return _error
->Error("Unable to fetch some archives, maybe try with --fix-missing?");
629 // Try to deal with missing package files
630 if (PM
.FixMissing() == false)
632 cerr
<< "Unable to correct missing packages." << endl
;
633 return _error
->Error("Aborting Install.");
637 return PM
.DoInstall();
641 // DoUpdate - Update the package lists /*{{{*/
642 // ---------------------------------------------------------------------
644 bool DoUpdate(CommandLine
&)
646 // Get the source list
648 if (List
.ReadMainList() == false)
651 // Lock the list directory
653 if (_config
->FindB("Debug::NoLocking",false) == false)
655 Lock
.Fd(GetLock(_config
->FindDir("Dir::State::Lists") + "lock"));
656 if (_error
->PendingError() == true)
657 return _error
->Error("Unable to lock the list directory");
660 // Create the download object
661 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
662 pkgAcquire
Fetcher(&Stat
);
664 // Populate it with the source selection
665 pkgSourceList::const_iterator I
;
666 for (I
= List
.begin(); I
!= List
.end(); I
++)
668 new pkgAcqIndex(&Fetcher
,I
);
669 if (_error
->PendingError() == true)
674 if (Fetcher
.Run() == false)
677 // Clean out any old list files
678 if (Fetcher
.Clean(_config
->FindDir("Dir::State::lists")) == false ||
679 Fetcher
.Clean(_config
->FindDir("Dir::State::lists") + "partial/") == false)
682 // Prepare the cache.
684 if (Cache
.Open() == false)
690 // DoUpgrade - Upgrade all packages /*{{{*/
691 // ---------------------------------------------------------------------
692 /* Upgrade all packages without installing new packages or erasing old
694 bool DoUpgrade(CommandLine
&CmdL
)
697 if (Cache
.Open() == false || Cache
.CheckDeps() == false)
701 if (pkgAllUpgrade(Cache
) == false)
703 ShowBroken(c1out
,Cache
);
704 return _error
->Error("Internal Error, AllUpgrade broke stuff");
707 return InstallPackages(Cache
,true);
710 // DoInstall - Install packages from the command line /*{{{*/
711 // ---------------------------------------------------------------------
712 /* Install named packages */
713 bool DoInstall(CommandLine
&CmdL
)
716 if (Cache
.Open() == false || Cache
.CheckDeps(CmdL
.FileSize() != 1) == false)
719 // Enter the special broken fixing mode if the user specified arguments
720 bool BrokenFix
= false;
721 if (Cache
->BrokenCount() != 0)
724 unsigned int ExpectedInst
= 0;
725 unsigned int Packages
= 0;
726 pkgProblemResolver
Fix(Cache
);
728 bool DefRemove
= false;
729 if (strcasecmp(CmdL
.FileList
[0],"remove") == 0)
732 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
734 // Duplicate the string
735 unsigned int Length
= strlen(*I
);
737 if (Length
>= sizeof(S
))
741 // See if we are removing the package
742 bool Remove
= DefRemove
;
743 if (Cache
->FindPkg(S
).end() == true)
745 // Handle an optional end tag indicating what to do
746 if (S
[Length
- 1] == '-')
751 if (S
[Length
- 1] == '+')
758 // Locate the package
759 pkgCache::PkgIterator Pkg
= Cache
->FindPkg(S
);
761 if (Pkg
.end() == true)
762 return _error
->Error("Couldn't find package %s",S
);
764 // Handle the no-upgrade case
765 if (_config
->FindB("APT::Get::no-upgrade",false) == true &&
766 Pkg
->CurrentVer
!= 0)
768 c1out
<< "Skipping " << Pkg
.Name() << ", it is already installed and no-upgrade is set." << endl
;
772 // Check if there is something new to install
773 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
774 if (State
.CandidateVer
== 0)
776 if (Pkg
->ProvidesList
!= 0)
778 c1out
<< "Package " << S
<< " is a virtual package provided by:" << endl
;
780 pkgCache::PrvIterator I
= Pkg
.ProvidesList();
781 for (; I
.end() == false; I
++)
783 pkgCache::PkgIterator Pkg
= I
.OwnerPkg();
785 if ((*Cache
)[Pkg
].CandidateVerIter(*Cache
) == I
.OwnerVer())
787 if ((*Cache
)[Pkg
].Install() == true && (*Cache
)[Pkg
].NewInstall() == false)
788 c1out
<< " " << Pkg
.Name() << " " << I
.OwnerVer().VerStr() <<
789 " [Installed]"<< endl
;
791 c1out
<< " " << Pkg
.Name() << " " << I
.OwnerVer().VerStr() << endl
;
794 c1out
<< "You should explicly select one to install." << endl
;
798 c1out
<< "Package " << S
<< " has no available version, but exists in the database." << endl
;
799 c1out
<< "This typically means that the package was mentioned in a dependency and " << endl
;
800 c1out
<< "never uploaded, or that it is an obsolete package." << endl
;
803 pkgCache::DepIterator Dep
= Pkg
.RevDependsList();
804 for (; Dep
.end() == false; Dep
++)
806 if (Dep
->Type
!= pkgCache::Dep::Replaces
)
808 List
+= string(Dep
.ParentPkg().Name()) + " ";
810 ShowList(c1out
,"However the following packages replace it:",List
);
813 return _error
->Error("Package %s has no installation candidate",S
);
820 Cache
->MarkDelete(Pkg
);
825 Cache
->MarkInstall(Pkg
,false);
826 if (State
.Install() == false)
827 c1out
<< "Sorry, " << S
<< " is already the newest version" << endl
;
831 // Install it with autoinstalling enabled.
832 if (State
.InstBroken() == true && BrokenFix
== false)
833 Cache
->MarkInstall(Pkg
,true);
836 /* If we are in the Broken fixing mode we do not attempt to fix the
837 problems. This is if the user invoked install without -f and gave
839 if (BrokenFix
== true && Cache
->BrokenCount() != 0)
841 c1out
<< "You might want to run `apt-get -f install' to correct these." << endl
;
842 ShowBroken(c1out
,Cache
);
844 return _error
->Error("Unmet dependencies. Try using -f.");
847 // Call the scored problem resolver
848 Fix
.InstallProtect();
849 if (Fix
.Resolve(true) == false)
852 // Now we check the state of the packages,
853 if (Cache
->BrokenCount() != 0)
855 c1out
<< "Some packages could not be installed. This may mean that you have" << endl
;
856 c1out
<< "requested an impossible situation or if you are using the unstable" << endl
;
857 c1out
<< "distribution that some required packages have not yet been created" << endl
;
858 c1out
<< "or been moved out of Incoming." << endl
;
862 c1out
<< "Since you only requested a single operation it is extremely likely that" << endl
;
863 c1out
<< "the package is simply not installable and a bug report against" << endl
;
864 c1out
<< "that package should be filed." << endl
;
867 c1out
<< "The following information may help to resolve the situation:" << endl
;
869 ShowBroken(c1out
,Cache
);
870 return _error
->Error("Sorry, broken packages");
873 /* Print out a list of packages that are going to be installed extra
874 to what the user asked */
875 if (Cache
->InstCount() != ExpectedInst
)
878 pkgCache::PkgIterator I
= Cache
->PkgBegin();
879 for (;I
.end() != true; I
++)
881 if ((*Cache
)[I
].Install() == false)
885 for (J
= CmdL
.FileList
+ 1; *J
!= 0; J
++)
886 if (strcmp(*J
,I
.Name()) == 0)
890 List
+= string(I
.Name()) + " ";
893 ShowList(c1out
,"The following extra packages will be installed:",List
);
896 // See if we need to prompt
897 if (Cache
->InstCount() == ExpectedInst
&& Cache
->DelCount() == 0)
898 return InstallPackages(Cache
,false,false);
900 return InstallPackages(Cache
,false);
903 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
904 // ---------------------------------------------------------------------
905 /* Intelligent upgrader that will install and remove packages at will */
906 bool DoDistUpgrade(CommandLine
&CmdL
)
909 if (Cache
.Open() == false || Cache
.CheckDeps() == false)
912 c0out
<< "Calculating Upgrade... " << flush
;
913 if (pkgDistUpgrade(*Cache
) == false)
915 c0out
<< "Failed" << endl
;
916 ShowBroken(c1out
,Cache
);
920 c0out
<< "Done" << endl
;
922 return InstallPackages(Cache
,true);
925 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
926 // ---------------------------------------------------------------------
927 /* Follows dselect's selections */
928 bool DoDSelectUpgrade(CommandLine
&CmdL
)
931 if (Cache
.Open() == false || Cache
.CheckDeps() == false)
934 // Install everything with the install flag set
935 pkgCache::PkgIterator I
= Cache
->PkgBegin();
936 for (;I
.end() != true; I
++)
938 /* Install the package only if it is a new install, the autoupgrader
939 will deal with the rest */
940 if (I
->SelectedState
== pkgCache::State::Install
)
941 Cache
->MarkInstall(I
,false);
944 /* Now install their deps too, if we do this above then order of
945 the status file is significant for | groups */
946 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
948 /* Install the package only if it is a new install, the autoupgrader
949 will deal with the rest */
950 if (I
->SelectedState
== pkgCache::State::Install
)
951 Cache
->MarkInstall(I
,true);
954 // Apply erasures now, they override everything else.
955 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
958 if (I
->SelectedState
== pkgCache::State::DeInstall
||
959 I
->SelectedState
== pkgCache::State::Purge
)
960 Cache
->MarkDelete(I
);
963 /* Resolve any problems that dselect created, allupgrade cannot handle
964 such things. We do so quite agressively too.. */
965 if (Cache
->BrokenCount() != 0)
967 pkgProblemResolver
Fix(Cache
);
969 // Hold back held packages.
970 if (_config
->FindB("APT::Ingore-Hold",false) == false)
972 for (pkgCache::PkgIterator I
= Cache
->PkgBegin(); I
.end() == false; I
++)
974 if (I
->SelectedState
== pkgCache::State::Hold
)
982 if (Fix
.Resolve() == false)
984 ShowBroken(c1out
,Cache
);
985 return _error
->Error("Internal Error, problem resolver broke stuff");
989 // Now upgrade everything
990 if (pkgAllUpgrade(Cache
) == false)
992 ShowBroken(c1out
,Cache
);
993 return _error
->Error("Internal Error, problem resolver broke stuff");
996 return InstallPackages(Cache
,false);
999 // DoClean - Remove download archives /*{{{*/
1000 // ---------------------------------------------------------------------
1002 bool DoClean(CommandLine
&CmdL
)
1005 Fetcher
.Clean(_config
->FindDir("Dir::Cache::archives"));
1006 Fetcher
.Clean(_config
->FindDir("Dir::Cache::archives") + "partial/");
1010 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
1011 // ---------------------------------------------------------------------
1012 /* This is similar to clean but it only purges things that cannot be
1013 downloaded, that is old versions of cached packages. */
1014 class LogCleaner
: public pkgArchiveCleaner
1017 virtual void Erase(const char *File
,string Pkg
,string Ver
,struct stat
&St
)
1019 cout
<< "Del " << Pkg
<< " " << Ver
<< " [" << SizeToStr(St
.st_size
) << "b]" << endl
;
1023 bool DoAutoClean(CommandLine
&CmdL
)
1026 if (Cache
.Open() == false)
1031 return Cleaner
.Go(_config
->FindDir("Dir::Cache::archives"),*Cache
) &&
1032 Cleaner
.Go(_config
->FindDir("Dir::Cache::archives") + "partial/",*Cache
);
1035 // DoCheck - Perform the check operation /*{{{*/
1036 // ---------------------------------------------------------------------
1037 /* Opening automatically checks the system, this command is mostly used
1039 bool DoCheck(CommandLine
&CmdL
)
1048 // DoSource - Fetch a source archive /*{{{*/
1049 // ---------------------------------------------------------------------
1050 /* Fetch souce packages */
1058 bool DoSource(CommandLine
&CmdL
)
1061 if (Cache
.Open(false) == false)
1064 if (CmdL
.FileSize() <= 1)
1065 return _error
->Error("Must specify at least one package to fetch source for");
1067 // Read the source list
1069 if (List
.ReadMainList() == false)
1070 return _error
->Error("The list of sources could not be read.");
1072 // Create the text record parsers
1073 pkgRecords
Recs(Cache
);
1074 pkgSrcRecords
SrcRecs(List
);
1075 if (_error
->PendingError() == true)
1078 // Create the download object
1079 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
1080 pkgAcquire
Fetcher(&Stat
);
1082 DscFile
*Dsc
= new DscFile
[CmdL
.FileSize()];
1084 // Load the requestd sources into the fetcher
1086 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++, J
++)
1090 /* Lookup the version of the package we would install if we were to
1091 install a version and determine the source package name, then look
1092 in the archive for a source package of the same name. In theory
1093 we could stash the version string as well and match that too but
1094 today there aren't multi source versions in the archive. */
1095 pkgCache::PkgIterator Pkg
= Cache
->FindPkg(*I
);
1096 if (Pkg
.end() == false)
1098 pkgCache::VerIterator Ver
= Cache
->GetCandidateVer(Pkg
);
1099 if (Ver
.end() == false)
1101 pkgRecords::Parser
&Parse
= Recs
.Lookup(Ver
.FileList());
1102 Src
= Parse
.SourcePkg();
1106 // No source package name..
1107 if (Src
.empty() == true)
1111 pkgSrcRecords::Parser
*Last
= 0;
1112 unsigned long Offset
= 0;
1115 // Iterate over all of the hits
1116 pkgSrcRecords::Parser
*Parse
;
1118 while ((Parse
= SrcRecs
.Find(Src
.c_str(),false)) != 0)
1120 string Ver
= Parse
->Version();
1121 if (Last
== 0 || pkgVersionCompare(Version
,Ver
) < 0)
1124 Offset
= Parse
->Offset();
1130 return _error
->Error("Unable to find a source package for %s",Src
.c_str());
1133 vector
<pkgSrcRecords::File
> Lst
;
1134 if (Last
->Jump(Offset
) == false || Last
->Files(Lst
) == false)
1137 // Load them into the fetcher
1138 for (vector
<pkgSrcRecords::File
>::const_iterator I
= Lst
.begin();
1139 I
!= Lst
.end(); I
++)
1141 // Try to guess what sort of file it is we are getting.
1143 if (I
->Path
.find(".dsc") != string::npos
)
1146 Dsc
[J
].Package
= Last
->Package();
1147 Dsc
[J
].Version
= Last
->Version();
1148 Dsc
[J
].Dsc
= flNotDir(I
->Path
);
1151 if (I
->Path
.find(".tar.gz") != string::npos
)
1153 if (I
->Path
.find(".diff.gz") != string::npos
)
1156 new pkgAcqFile(&Fetcher
,Last
->Source()->ArchiveURI(I
->Path
),
1157 I
->MD5Hash
,I
->Size
,Last
->Source()->SourceInfo(Src
,
1158 Last
->Version(),Comp
),Src
);
1162 // Display statistics
1163 unsigned long FetchBytes
= Fetcher
.FetchNeeded();
1164 unsigned long FetchPBytes
= Fetcher
.PartialPresent();
1165 unsigned long DebBytes
= Fetcher
.TotalNeeded();
1167 // Check for enough free space
1169 string OutputDir
= ".";
1170 if (statfs(OutputDir
.c_str(),&Buf
) != 0)
1171 return _error
->Errno("statfs","Couldn't determine free space in %s",
1173 if (unsigned(Buf
.f_bfree
) < (FetchBytes
- FetchPBytes
)/Buf
.f_bsize
)
1174 return _error
->Error("Sorry, you don't have enough free space in %s",
1178 c1out
<< "Need to get ";
1179 if (DebBytes
!= FetchBytes
)
1180 c1out
<< SizeToStr(FetchBytes
) << "b/" << SizeToStr(DebBytes
) << 'b';
1182 c1out
<< SizeToStr(DebBytes
) << 'b';
1183 c1out
<< " of source archives." << endl
;
1185 // Just print out the uris an exit if the --print-uris flag was used
1186 if (_config
->FindB("APT::Get::Print-URIs") == true)
1188 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
1189 for (; I
!= Fetcher
.UriEnd(); I
++)
1190 cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
1191 I
->Owner
->FileSize
<< ' ' << I
->Owner
->MD5Sum() << endl
;
1196 if (Fetcher
.Run() == false)
1199 // Print error messages
1200 bool Failed
= false;
1201 for (pkgAcquire::Item
**I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); I
++)
1203 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
1204 (*I
)->Complete
== true)
1207 cerr
<< "Failed to fetch " << (*I
)->DescURI() << endl
;
1208 cerr
<< " " << (*I
)->ErrorText
<< endl
;
1212 return _error
->Error("Failed to fetch some archives.");
1214 if (_config
->FindB("APT::Get::Download-only",false) == true)
1217 // Unpack the sources
1218 pid_t Process
= ExecFork();
1222 for (unsigned I
= 0; I
!= J
; I
++)
1224 string Dir
= Dsc
[I
].Package
+ '-' + pkgBaseVersion(Dsc
[I
].Version
.c_str());
1226 // See if the package is already unpacked
1228 if (stat(Dir
.c_str(),&Stat
) == 0 &&
1229 S_ISDIR(Stat
.st_mode
) != 0)
1231 c0out
<< "Skipping unpack of already unpacked source in " << Dir
<< endl
;
1237 snprintf(S
,sizeof(S
),"%s -x %s",
1238 _config
->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
1239 Dsc
[I
].Dsc
.c_str());
1242 cerr
<< "Unpack command '" << S
<< "' failed." << endl
;
1247 // Try to compile it with dpkg-buildpackage
1248 if (_config
->FindB("APT::Get::Compile",false) == true)
1250 // Call dpkg-buildpackage
1252 snprintf(S
,sizeof(S
),"cd %s && %s %s",
1254 _config
->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
1255 _config
->Find("DPkg::Build-Options","-b -uc").c_str());
1259 cerr
<< "Build command '" << S
<< "' failed." << endl
;
1268 // Wait for the subprocess
1270 while (waitpid(Process
,&Status
,0) != Process
)
1274 return _error
->Errno("waitpid","Couldn't wait for subprocess");
1277 if (WIFEXITED(Status
) == 0 || WEXITSTATUS(Status
) != 0)
1278 return _error
->Error("Child process failed");
1284 // ShowHelp - Show a help screen /*{{{*/
1285 // ---------------------------------------------------------------------
1287 bool ShowHelp(CommandLine
&CmdL
)
1289 cout
<< PACKAGE
<< ' ' << VERSION
<< " for " << ARCHITECTURE
<<
1290 " compiled on " << __DATE__
<< " " << __TIME__
<< endl
;
1291 if (_config
->FindB("version") == true)
1294 cout
<< "Usage: apt-get [options] command" << endl
;
1295 cout
<< " apt-get [options] install pkg1 [pkg2 ...]" << endl
;
1297 cout
<< "apt-get is a simple command line interface for downloading and" << endl
;
1298 cout
<< "installing packages. The most frequently used commands are update" << endl
;
1299 cout
<< "and install." << endl
;
1301 cout
<< "Commands:" << endl
;
1302 cout
<< " update - Retrieve new lists of packages" << endl
;
1303 cout
<< " upgrade - Perform an upgrade" << endl
;
1304 cout
<< " install - Install new packages (pkg is libc6 not libc6.deb)" << endl
;
1305 cout
<< " remove - Remove packages" << endl
;
1306 cout
<< " source - Download source archives" << endl
;
1307 cout
<< " dist-upgrade - Distribution upgrade, see apt-get(8)" << endl
;
1308 cout
<< " dselect-upgrade - Follow dselect selections" << endl
;
1309 cout
<< " clean - Erase downloaded archive files" << endl
;
1310 cout
<< " autoclean - Erase old downloaded archive files" << endl
;
1311 cout
<< " check - Verify that there are no broken dependencies" << endl
;
1313 cout
<< "Options:" << endl
;
1314 cout
<< " -h This help text." << endl
;
1315 cout
<< " -q Loggable output - no progress indicator" << endl
;
1316 cout
<< " -qq No output except for errors" << endl
;
1317 cout
<< " -d Download only - do NOT install or unpack archives" << endl
;
1318 cout
<< " -s No-act. Perform ordering simulation" << endl
;
1319 cout
<< " -y Assume Yes to all queries and do not prompt" << endl
;
1320 cout
<< " -f Attempt to continue if the integrity check fails" << endl
;
1321 cout
<< " -m Attempt to continue if archives are unlocatable" << endl
;
1322 cout
<< " -u Show a list of upgraded packages as well" << endl
;
1323 cout
<< " -c=? Read this configuration file" << endl
;
1324 cout
<< " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" << endl
;
1325 cout
<< "See the apt-get(8), sources.list(5) and apt.conf(5) manual" << endl
;
1326 cout
<< "pages for more information." << endl
;
1330 // GetInitialize - Initialize things for apt-get /*{{{*/
1331 // ---------------------------------------------------------------------
1333 void GetInitialize()
1335 _config
->Set("quiet",0);
1336 _config
->Set("help",false);
1337 _config
->Set("APT::Get::Download-Only",false);
1338 _config
->Set("APT::Get::Simulate",false);
1339 _config
->Set("APT::Get::Assume-Yes",false);
1340 _config
->Set("APT::Get::Fix-Broken",false);
1341 _config
->Set("APT::Get::Force-Yes",false);
1344 // SigWinch - Window size change signal handler /*{{{*/
1345 // ---------------------------------------------------------------------
1349 // Riped from GNU ls
1353 if (ioctl(1, TIOCGWINSZ
, &ws
) != -1 && ws
.ws_col
>= 5)
1354 ScreenWidth
= ws
.ws_col
- 1;
1359 int main(int argc
,const char *argv
[])
1361 CommandLine::Args Args
[] = {
1362 {'h',"help","help",0},
1363 {'v',"version","version",0},
1364 {'q',"quiet","quiet",CommandLine::IntLevel
},
1365 {'q',"silent","quiet",CommandLine::IntLevel
},
1366 {'d',"download-only","APT::Get::Download-Only",0},
1367 {'b',"compile","APT::Get::Compile",0},
1368 {'b',"build","APT::Get::Compile",0},
1369 {'s',"simulate","APT::Get::Simulate",0},
1370 {'s',"just-print","APT::Get::Simulate",0},
1371 {'s',"recon","APT::Get::Simulate",0},
1372 {'s',"no-act","APT::Get::Simulate",0},
1373 {'y',"yes","APT::Get::Assume-Yes",0},
1374 {'y',"assume-yes","APT::Get::Assume-Yes",0},
1375 {'f',"fix-broken","APT::Get::Fix-Broken",0},
1376 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
1377 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
1378 {0,"fix-missing","APT::Get::Fix-Missing",0},
1379 {0,"ignore-hold","APT::Ingore-Hold",0},
1380 {0,"no-upgrade","APT::Get::no-upgrade",0},
1381 {0,"force-yes","APT::Get::force-yes",0},
1382 {0,"print-uris","APT::Get::Print-URIs",0},
1383 {'c',"config-file",0,CommandLine::ConfigFile
},
1384 {'o',"option",0,CommandLine::ArbItem
},
1386 CommandLine::Dispatch Cmds
[] = {{"update",&DoUpdate
},
1387 {"upgrade",&DoUpgrade
},
1388 {"install",&DoInstall
},
1389 {"remove",&DoInstall
},
1390 {"dist-upgrade",&DoDistUpgrade
},
1391 {"dselect-upgrade",&DoDSelectUpgrade
},
1393 {"autoclean",&DoAutoClean
},
1395 {"source",&DoSource
},
1399 // Parse the command line and initialize the package library
1400 CommandLine
CmdL(Args
,_config
);
1401 if (pkgInitialize(*_config
) == false ||
1402 CmdL
.Parse(argc
,argv
) == false)
1404 _error
->DumpErrors();
1408 // See if the help should be shown
1409 if (_config
->FindB("help") == true ||
1410 _config
->FindB("version") == true ||
1411 CmdL
.FileSize() == 0)
1412 return ShowHelp(CmdL
);
1414 // Deal with stdout not being a tty
1415 if (ttyname(STDOUT_FILENO
) == 0 && _config
->FindI("quiet",0) < 1)
1416 _config
->Set("quiet","1");
1418 // Setup the output streams
1419 c0out
.rdbuf(cout
.rdbuf());
1420 c1out
.rdbuf(cout
.rdbuf());
1421 c2out
.rdbuf(cout
.rdbuf());
1422 if (_config
->FindI("quiet",0) > 0)
1423 c0out
.rdbuf(devnull
.rdbuf());
1424 if (_config
->FindI("quiet",0) > 1)
1425 c1out
.rdbuf(devnull
.rdbuf());
1427 // Setup the signals
1428 signal(SIGPIPE
,SIG_IGN
);
1429 signal(SIGWINCH
,SigWinch
);
1432 // Match the operation
1433 CmdL
.DispatchArg(Cmds
);
1435 // Print any errors or warnings found during parsing
1436 if (_error
->empty() == false)
1438 bool Errors
= _error
->PendingError();
1439 _error
->DumpErrors();
1440 return Errors
== true?100:0;