]>
git.saurik.com Git - apt.git/blob - cmdline/apt-get.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-get.cc,v 1.49 1999/04/07 05:30:18 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/pkgcachegen.h>
34 #include <apt-pkg/algorithms.h>
35 #include <apt-pkg/acquire-item.h>
36 #include <apt-pkg/dpkgpm.h>
37 #include <apt-pkg/dpkginit.h>
38 #include <apt-pkg/strutl.h>
39 #include <apt-pkg/clean.h>
40 #include <apt-pkg/srcrecords.h>
41 #include <apt-pkg/version.h>
45 #include "acqprogress.h"
49 #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 cout
<< ' ' << 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 // ---------------------------------------------------------------------
384 inline operator pkgDepCache
&() {return *Cache
;};
385 inline pkgDepCache
*operator ->() {return Cache
;};
386 inline pkgDepCache
&operator *() {return *Cache
;};
388 bool Open(bool AllowBroken
= false);
389 CacheFile() : File(0), Map(0), Cache(0) {};
398 // CacheFile::Open - Open the cache file /*{{{*/
399 // ---------------------------------------------------------------------
400 /* This routine generates the caches and then opens the dependency cache
401 and verifies that the system is OK. */
402 bool CacheFile::Open(bool AllowBroken
)
404 if (_error
->PendingError() == true)
407 // Create a progress class
408 OpTextProgress
Progress(*_config
);
410 // Read the source list
412 if (List
.ReadMainList() == false)
413 return _error
->Error("The list of sources could not be read.");
415 // Build all of the caches
416 pkgMakeStatusCache(List
,Progress
);
417 if (_error
->PendingError() == true)
418 return _error
->Error("The package lists or status file could not be parsed or opened.");
419 if (_error
->empty() == false)
420 _error
->Warning("You may want to run apt-get update to correct theses missing files");
424 // Open the cache file
425 File
= new FileFd(_config
->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly
);
426 if (_error
->PendingError() == true)
429 Map
= new MMap(*File
,MMap::Public
| MMap::ReadOnly
);
430 if (_error
->PendingError() == true)
433 Cache
= new pkgDepCache(*Map
,Progress
);
434 if (_error
->PendingError() == true)
439 // Check that the system is OK
440 if (Cache
->DelCount() != 0 || Cache
->InstCount() != 0)
441 return _error
->Error("Internal Error, non-zero counts");
443 // Apply corrections for half-installed packages
444 if (pkgApplyStatus(*Cache
) == false)
448 if (Cache
->BrokenCount() == 0 || AllowBroken
== true)
451 // Attempt to fix broken things
452 if (_config
->FindB("APT::Get::Fix-Broken",false) == true)
454 c1out
<< "Correcting dependencies..." << flush
;
455 if (pkgFixBroken(*Cache
) == false || Cache
->BrokenCount() != 0)
457 c1out
<< " failed." << endl
;
458 ShowBroken(c1out
,*this);
460 return _error
->Error("Unable to correct dependencies");
462 if (pkgMinimizeUpgrade(*Cache
) == false)
463 return _error
->Error("Unable to minimize the upgrade set");
465 c1out
<< " Done" << endl
;
469 c1out
<< "You might want to run `apt-get -f install' to correct these." << endl
;
470 ShowBroken(c1out
,*this);
472 return _error
->Error("Unmet dependencies. Try using -f.");
479 // InstallPackages - Actually download and install the packages /*{{{*/
480 // ---------------------------------------------------------------------
481 /* This displays the informative messages describing what is going to
482 happen and then calls the download routines */
483 bool InstallPackages(CacheFile
&Cache
,bool ShwKept
,bool Ask
= true,bool Saftey
= true)
486 bool Essential
= false;
488 // Show all the various warning indicators
489 ShowDel(c1out
,Cache
);
490 ShowNew(c1out
,Cache
);
492 ShowKept(c1out
,Cache
);
493 Fail
|= !ShowHold(c1out
,Cache
);
494 if (_config
->FindB("APT::Get::Show-Upgraded",false) == true)
495 ShowUpgraded(c1out
,Cache
);
496 Essential
= !ShowEssential(c1out
,Cache
);
501 if (Cache
->BrokenCount() != 0)
503 ShowBroken(c1out
,Cache
);
504 return _error
->Error("Internal Error, InstallPackages was called with broken packages!");
507 if (Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
508 Cache
->BadCount() == 0)
511 // Run the simulator ..
512 if (_config
->FindB("APT::Get::Simulate") == true)
514 pkgSimulate
PM(Cache
);
515 return PM
.DoInstall();
518 // Create the text record parser
519 pkgRecords
Recs(Cache
);
520 if (_error
->PendingError() == true)
523 // Lock the archive directory
525 if (_config
->FindB("Debug::NoLocking",false) == false)
527 Lock
.Fd(GetLock(_config
->FindDir("Dir::Cache::Archives") + "lock"));
528 if (_error
->PendingError() == true)
529 return _error
->Error("Unable to lock the download directory");
532 // Create the download object
533 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
534 pkgAcquire
Fetcher(&Stat
);
536 // Read the source list
538 if (List
.ReadMainList() == false)
539 return _error
->Error("The list of sources could not be read.");
541 // Create the package manager and prepare to download
543 if (PM
.GetArchives(&Fetcher
,&List
,&Recs
) == false ||
544 _error
->PendingError() == true)
547 // Display statistics
548 unsigned long FetchBytes
= Fetcher
.FetchNeeded();
549 unsigned long FetchPBytes
= Fetcher
.PartialPresent();
550 unsigned long DebBytes
= Fetcher
.TotalNeeded();
551 if (DebBytes
!= Cache
->DebSize())
553 c0out
<< DebBytes
<< ',' << Cache
->DebSize() << endl
;
554 c0out
<< "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl
;
557 // Check for enough free space
559 string OutputDir
= _config
->FindDir("Dir::Cache::Archives");
560 if (statfs(OutputDir
.c_str(),&Buf
) != 0)
561 return _error
->Errno("statfs","Couldn't determine free space in %s",
563 if (unsigned(Buf
.f_bfree
) < (FetchBytes
- FetchPBytes
)/Buf
.f_bsize
)
564 return _error
->Error("Sorry, you don't have enough free space in %s",
568 c1out
<< "Need to get ";
569 if (DebBytes
!= FetchBytes
)
570 c1out
<< SizeToStr(FetchBytes
) << "b/" << SizeToStr(DebBytes
) << 'b';
572 c1out
<< SizeToStr(DebBytes
) << 'b';
574 c1out
<< " of archives. After unpacking ";
577 if (Cache
->UsrSize() >= 0)
578 c1out
<< SizeToStr(Cache
->UsrSize()) << "b will be used." << endl
;
580 c1out
<< SizeToStr(-1*Cache
->UsrSize()) << "b will be freed." << endl
;
582 if (_error
->PendingError() == true)
586 if (_config
->FindI("quiet",0) >= 2 ||
587 _config
->FindB("APT::Get::Assume-Yes",false) == true)
589 if (Fail
== true && _config
->FindB("APT::Get::Force-Yes",false) == false)
590 return _error
->Error("There are problems and -y was used without --force-yes");
593 if (Essential
== true && Saftey
== true)
595 c2out
<< "You are about to do something potentially harmful" << endl
;
596 c2out
<< "To continue type in the phrase 'Yes, I understand this may be bad'" << endl
;
597 c2out
<< " ?] " << flush
;
598 if (AnalPrompt("Yes, I understand this may be bad") == false)
600 c2out
<< "Abort." << endl
;
606 // Prompt to continue
609 if (_config
->FindI("quiet",0) < 2 &&
610 _config
->FindB("APT::Get::Assume-Yes",false) == false)
612 c2out
<< "Do you want to continue? [Y/n] " << flush
;
614 if (YnPrompt() == false)
616 c2out
<< "Abort." << endl
;
623 // Just print out the uris an exit if the --print-uris flag was used
624 if (_config
->FindB("APT::Get::Print-URIs") == true)
626 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
627 for (; I
!= Fetcher
.UriEnd(); I
++)
628 cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
629 I
->Owner
->FileSize
<< ' ' << I
->Owner
->MD5Sum() << endl
;
634 if (Fetcher
.Run() == false)
639 bool Transient
= false;
640 for (pkgAcquire::Item
**I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); I
++)
642 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
643 (*I
)->Complete
== true)
646 if ((*I
)->Status
== pkgAcquire::Item::StatIdle
)
653 cerr
<< "Failed to fetch " << (*I
)->DescURI() << endl
;
654 cerr
<< " " << (*I
)->ErrorText
<< endl
;
658 if (_config
->FindB("APT::Get::Download-Only",false) == true)
661 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
663 if (Transient
== true)
665 c2out
<< "Upgrading with disk swapping is not supported in this version." << endl
;
666 c2out
<< "Try running multiple times with --fix-missing" << endl
;
669 return _error
->Error("Unable to fetch some archives, maybe try with --fix-missing?");
672 // Try to deal with missing package files
673 if (PM
.FixMissing() == false)
675 cerr
<< "Unable to correct missing packages." << endl
;
676 return _error
->Error("Aborting Install.");
680 return PM
.DoInstall();
684 // DoUpdate - Update the package lists /*{{{*/
685 // ---------------------------------------------------------------------
687 bool DoUpdate(CommandLine
&)
689 // Get the source list
691 if (List
.ReadMainList() == false)
694 // Lock the list directory
696 if (_config
->FindB("Debug::NoLocking",false) == false)
698 Lock
.Fd(GetLock(_config
->FindDir("Dir::State::Lists") + "lock"));
699 if (_error
->PendingError() == true)
700 return _error
->Error("Unable to lock the list directory");
703 // Create the download object
704 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
705 pkgAcquire
Fetcher(&Stat
);
707 // Populate it with the source selection
708 pkgSourceList::const_iterator I
;
709 for (I
= List
.begin(); I
!= List
.end(); I
++)
711 new pkgAcqIndex(&Fetcher
,I
);
712 if (_error
->PendingError() == true)
717 if (Fetcher
.Run() == false)
720 // Clean out any old list files
721 if (Fetcher
.Clean(_config
->FindDir("Dir::State::lists")) == false ||
722 Fetcher
.Clean(_config
->FindDir("Dir::State::lists") + "partial/") == false)
725 // Prepare the cache.
727 if (Cache
.Open() == false)
733 // DoUpgrade - Upgrade all packages /*{{{*/
734 // ---------------------------------------------------------------------
735 /* Upgrade all packages without installing new packages or erasing old
737 bool DoUpgrade(CommandLine
&CmdL
)
740 if (Cache
.Open() == false)
744 if (pkgAllUpgrade(Cache
) == false)
746 ShowBroken(c1out
,Cache
);
747 return _error
->Error("Internal Error, AllUpgrade broke stuff");
750 return InstallPackages(Cache
,true);
753 // DoInstall - Install packages from the command line /*{{{*/
754 // ---------------------------------------------------------------------
755 /* Install named packages */
756 bool DoInstall(CommandLine
&CmdL
)
759 if (Cache
.Open(CmdL
.FileSize() != 1) == false)
762 // Enter the special broken fixing mode if the user specified arguments
763 bool BrokenFix
= false;
764 if (Cache
->BrokenCount() != 0)
767 unsigned int ExpectedInst
= 0;
768 unsigned int Packages
= 0;
769 pkgProblemResolver
Fix(Cache
);
771 bool DefRemove
= false;
772 if (strcasecmp(CmdL
.FileList
[0],"remove") == 0)
775 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
777 // Duplicate the string
778 unsigned int Length
= strlen(*I
);
780 if (Length
>= sizeof(S
))
784 // See if we are removing the package
785 bool Remove
= DefRemove
;
786 if (Cache
->FindPkg(S
).end() == true)
788 // Handle an optional end tag indicating what to do
789 if (S
[Length
- 1] == '-')
794 if (S
[Length
- 1] == '+')
801 // Locate the package
802 pkgCache::PkgIterator Pkg
= Cache
->FindPkg(S
);
804 if (Pkg
.end() == true)
805 return _error
->Error("Couldn't find package %s",S
);
807 // Handle the no-upgrade case
808 if (_config
->FindB("APT::Get::no-upgrade",false) == true &&
809 Pkg
->CurrentVer
!= 0)
811 c1out
<< "Skipping " << Pkg
.Name() << ", it is already installed and no-upgrade is set." << endl
;
815 // Check if there is something new to install
816 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
817 if (State
.CandidateVer
== 0)
819 if (Pkg
->ProvidesList
!= 0)
821 c1out
<< "Package " << S
<< " is a virtual package provided by:" << endl
;
823 pkgCache::PrvIterator I
= Pkg
.ProvidesList();
824 for (; I
.end() == false; I
++)
826 pkgCache::PkgIterator Pkg
= I
.OwnerPkg();
828 if ((*Cache
)[Pkg
].CandidateVerIter(*Cache
) == I
.OwnerVer())
830 if ((*Cache
)[Pkg
].Install() == true && (*Cache
)[Pkg
].NewInstall() == false)
831 c1out
<< " " << Pkg
.Name() << " " << I
.OwnerVer().VerStr() <<
832 " [Installed]"<< endl
;
834 c1out
<< " " << Pkg
.Name() << " " << I
.OwnerVer().VerStr() << endl
;
837 c1out
<< "You should explicly select one to install." << endl
;
841 c1out
<< "Package " << S
<< " has no available version, but exists in the database." << endl
;
842 c1out
<< "This typically means that the package was mentioned in a dependency and " << endl
;
843 c1out
<< "never uploaded, or that it is an obsolete package." << endl
;
846 pkgCache::DepIterator Dep
= Pkg
.RevDependsList();
847 for (; Dep
.end() == false; Dep
++)
849 if (Dep
->Type
!= pkgCache::Dep::Replaces
)
851 List
+= string(Dep
.ParentPkg().Name()) + " ";
853 ShowList(c1out
,"However the following packages replace it:",List
);
856 return _error
->Error("Package %s has no installation candidate",S
);
863 Cache
->MarkDelete(Pkg
);
868 Cache
->MarkInstall(Pkg
,false);
869 if (State
.Install() == false)
870 c1out
<< "Sorry, " << S
<< " is already the newest version" << endl
;
874 // Install it with autoinstalling enabled.
875 if (State
.InstBroken() == true && BrokenFix
== false)
876 Cache
->MarkInstall(Pkg
,true);
879 /* If we are in the Broken fixing mode we do not attempt to fix the
880 problems. This is if the user invoked install without -f and gave
882 if (BrokenFix
== true && Cache
->BrokenCount() != 0)
884 c1out
<< "You might want to run `apt-get -f install' to correct these." << endl
;
885 ShowBroken(c1out
,Cache
);
887 return _error
->Error("Unmet dependencies. Try using -f.");
890 // Call the scored problem resolver
891 Fix
.InstallProtect();
892 if (Fix
.Resolve(true) == false)
895 // Now we check the state of the packages,
896 if (Cache
->BrokenCount() != 0)
898 c1out
<< "Some packages could not be installed. This may mean that you have" << endl
;
899 c1out
<< "requested an impossible situation or if you are using the unstable" << endl
;
900 c1out
<< "distribution that some required packages have not yet been created" << endl
;
901 c1out
<< "or been moved out of Incoming." << endl
;
905 c1out
<< "Since you only requested a single operation it is extremely likely that" << endl
;
906 c1out
<< "the package is simply not installable and a bug report against" << endl
;
907 c1out
<< "that package should be filed." << endl
;
910 c1out
<< "The following information may help to resolve the situation:" << endl
;
912 ShowBroken(c1out
,Cache
);
913 return _error
->Error("Sorry, broken packages");
916 /* Print out a list of packages that are going to be installed extra
917 to what the user asked */
918 if (Cache
->InstCount() != ExpectedInst
)
921 pkgCache::PkgIterator I
= Cache
->PkgBegin();
922 for (;I
.end() != true; I
++)
924 if ((*Cache
)[I
].Install() == false)
928 for (J
= CmdL
.FileList
+ 1; *J
!= 0; J
++)
929 if (strcmp(*J
,I
.Name()) == 0)
933 List
+= string(I
.Name()) + " ";
936 ShowList(c1out
,"The following extra packages will be installed:",List
);
939 // See if we need to prompt
940 if (Cache
->InstCount() == ExpectedInst
&& Cache
->DelCount() == 0)
941 return InstallPackages(Cache
,false,false);
943 return InstallPackages(Cache
,false);
946 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
947 // ---------------------------------------------------------------------
948 /* Intelligent upgrader that will install and remove packages at will */
949 bool DoDistUpgrade(CommandLine
&CmdL
)
952 if (Cache
.Open() == false)
955 c0out
<< "Calculating Upgrade... " << flush
;
956 if (pkgDistUpgrade(*Cache
) == false)
958 c0out
<< "Failed" << endl
;
959 ShowBroken(c1out
,Cache
);
963 c0out
<< "Done" << endl
;
965 return InstallPackages(Cache
,true);
968 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
969 // ---------------------------------------------------------------------
970 /* Follows dselect's selections */
971 bool DoDSelectUpgrade(CommandLine
&CmdL
)
974 if (Cache
.Open() == false)
977 // Install everything with the install flag set
978 pkgCache::PkgIterator I
= Cache
->PkgBegin();
979 for (;I
.end() != true; I
++)
981 /* Install the package only if it is a new install, the autoupgrader
982 will deal with the rest */
983 if (I
->SelectedState
== pkgCache::State::Install
)
984 Cache
->MarkInstall(I
,false);
987 /* Now install their deps too, if we do this above then order of
988 the status file is significant for | groups */
989 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
991 /* Install the package only if it is a new install, the autoupgrader
992 will deal with the rest */
993 if (I
->SelectedState
== pkgCache::State::Install
)
994 Cache
->MarkInstall(I
,true);
997 // Apply erasures now, they override everything else.
998 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
1001 if (I
->SelectedState
== pkgCache::State::DeInstall
||
1002 I
->SelectedState
== pkgCache::State::Purge
)
1003 Cache
->MarkDelete(I
);
1006 /* Resolve any problems that dselect created, allupgrade cannot handle
1007 such things. We do so quite agressively too.. */
1008 if (Cache
->BrokenCount() != 0)
1010 pkgProblemResolver
Fix(Cache
);
1012 // Hold back held packages.
1013 if (_config
->FindB("APT::Ingore-Hold",false) == false)
1015 for (pkgCache::PkgIterator I
= Cache
->PkgBegin(); I
.end() == false; I
++)
1017 if (I
->SelectedState
== pkgCache::State::Hold
)
1025 if (Fix
.Resolve() == false)
1027 ShowBroken(c1out
,Cache
);
1028 return _error
->Error("Internal Error, problem resolver broke stuff");
1032 // Now upgrade everything
1033 if (pkgAllUpgrade(Cache
) == false)
1035 ShowBroken(c1out
,Cache
);
1036 return _error
->Error("Internal Error, problem resolver broke stuff");
1039 return InstallPackages(Cache
,false);
1042 // DoClean - Remove download archives /*{{{*/
1043 // ---------------------------------------------------------------------
1045 bool DoClean(CommandLine
&CmdL
)
1048 Fetcher
.Clean(_config
->FindDir("Dir::Cache::archives"));
1049 Fetcher
.Clean(_config
->FindDir("Dir::Cache::archives") + "partial/");
1053 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
1054 // ---------------------------------------------------------------------
1055 /* This is similar to clean but it only purges things that cannot be
1056 downloaded, that is old versions of cached packages. */
1057 class LogCleaner
: public pkgArchiveCleaner
1060 virtual void Erase(const char *File
,string Pkg
,string Ver
,struct stat
&St
)
1062 cout
<< "Del " << Pkg
<< " " << Ver
<< " [" << SizeToStr(St
.st_size
) << "b]" << endl
;
1066 bool DoAutoClean(CommandLine
&CmdL
)
1069 if (Cache
.Open(true) == false)
1074 return Cleaner
.Go(_config
->FindDir("Dir::Cache::archives"),*Cache
) &&
1075 Cleaner
.Go(_config
->FindDir("Dir::Cache::archives") + "partial/",*Cache
);
1078 // DoCheck - Perform the check operation /*{{{*/
1079 // ---------------------------------------------------------------------
1080 /* Opening automatically checks the system, this command is mostly used
1082 bool DoCheck(CommandLine
&CmdL
)
1090 // DoSource - Fetch a source archive /*{{{*/
1091 // ---------------------------------------------------------------------
1093 bool DoSource(CommandLine
&CmdL
)
1096 if (Cache
.Open(true) == false)
1099 // Read the source list
1101 if (List
.ReadMainList() == false)
1102 return _error
->Error("The list of sources could not be read.");
1104 // Create the text record parsers
1105 pkgRecords
Recs(Cache
);
1106 pkgSrcRecords
SrcRecs(List
);
1107 if (_error
->PendingError() == true)
1110 // Create the download object
1111 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
1112 pkgAcquire
Fetcher(&Stat
);
1114 // Load the requestd sources into the fetcher
1115 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
1119 /* Lookup the version of the package we would install if we were to
1120 install a version and determine the source package name, then look
1121 in the archive for a source package of the same name. In theory
1122 we could stash the version string as well and match that too but
1123 today there aren't multi source versions in the archive. */
1124 pkgCache::PkgIterator Pkg
= Cache
->FindPkg(*I
);
1125 if (Pkg
.end() == false)
1127 pkgCache::VerIterator Ver
= Cache
->GetCandidateVer(Pkg
);
1128 if (Ver
.end() == false)
1130 pkgRecords::Parser
&Parse
= Recs
.Lookup(Ver
.FileList());
1131 Src
= Parse
.SourcePkg();
1135 // No source package name..
1136 if (Src
.empty() == true)
1140 pkgSrcRecords::Parser
*Last
= 0;
1141 unsigned long Offset
= 0;
1144 // Iterate over all of the hits
1145 pkgSrcRecords::Parser
*Parse
;
1147 while ((Parse
= SrcRecs
.Find(Src
.c_str(),false)) != 0)
1149 string Ver
= Parse
->Version();
1150 if (Last
== 0 || pkgVersionCompare(Version
,Ver
) < 0)
1153 Offset
= Parse
->Offset();
1159 return _error
->Error("Unable to find a source package for %s",Src
.c_str());
1162 vector
<pkgSrcRecords::File
> Lst
;
1163 if (Last
->Jump(Offset
) == false || Last
->Files(Lst
) == false)
1166 // Load them into the fetcher
1167 for (vector
<pkgSrcRecords::File
>::const_iterator I
= Lst
.begin();
1168 I
!= Lst
.end(); I
++)
1170 // Try to guess what sort of file it is we are getting.
1172 if (I
->Path
.find(".dsc") != string::npos
)
1174 if (I
->Path
.find(".tar.gz") != string::npos
)
1176 if (I
->Path
.find(".diff.gz") != string::npos
)
1179 new pkgAcqFile(&Fetcher
,Last
->Source()->ArchiveURI(I
->Path
),
1180 I
->MD5Hash
,I
->Size
,Last
->Source()->SourceInfo(Src
,
1181 Last
->Version(),Comp
),Src
);
1185 // Display statistics
1186 unsigned long FetchBytes
= Fetcher
.FetchNeeded();
1187 unsigned long FetchPBytes
= Fetcher
.PartialPresent();
1188 unsigned long DebBytes
= Fetcher
.TotalNeeded();
1190 // Check for enough free space
1192 string OutputDir
= ".";
1193 if (statfs(OutputDir
.c_str(),&Buf
) != 0)
1194 return _error
->Errno("statfs","Couldn't determine free space in %s",
1196 if (unsigned(Buf
.f_bfree
) < (FetchBytes
- FetchPBytes
)/Buf
.f_bsize
)
1197 return _error
->Error("Sorry, you don't have enough free space in %s",
1201 c1out
<< "Need to get ";
1202 if (DebBytes
!= FetchBytes
)
1203 c1out
<< SizeToStr(FetchBytes
) << "b/" << SizeToStr(DebBytes
) << 'b';
1205 c1out
<< SizeToStr(DebBytes
) << 'b';
1206 c1out
<< " of source archives." << endl
;
1208 // Just print out the uris an exit if the --print-uris flag was used
1209 if (_config
->FindB("APT::Get::Print-URIs") == true)
1211 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
1212 for (; I
!= Fetcher
.UriEnd(); I
++)
1213 cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
1214 I
->Owner
->FileSize
<< ' ' << I
->Owner
->MD5Sum() << endl
;
1219 if (Fetcher
.Run() == false)
1222 // Print error messages
1223 for (pkgAcquire::Item
**I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); I
++)
1225 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
1226 (*I
)->Complete
== true)
1229 cerr
<< "Failed to fetch " << (*I
)->DescURI() << endl
;
1230 cerr
<< " " << (*I
)->ErrorText
<< endl
;
1237 // ShowHelp - Show a help screen /*{{{*/
1238 // ---------------------------------------------------------------------
1240 bool ShowHelp(CommandLine
&CmdL
)
1242 cout
<< PACKAGE
<< ' ' << VERSION
<< " for " << ARCHITECTURE
<<
1243 " compiled on " << __DATE__
<< " " << __TIME__
<< endl
;
1244 if (_config
->FindB("version") == true)
1247 cout
<< "Usage: apt-get [options] command" << endl
;
1248 cout
<< " apt-get [options] install pkg1 [pkg2 ...]" << endl
;
1250 cout
<< "apt-get is a simple command line interface for downloading and" << endl
;
1251 cout
<< "installing packages. The most frequently used commands are update" << endl
;
1252 cout
<< "and install." << endl
;
1254 cout
<< "Commands:" << endl
;
1255 cout
<< " update - Retrieve new lists of packages" << endl
;
1256 cout
<< " upgrade - Perform an upgrade" << endl
;
1257 cout
<< " install - Install new packages (pkg is libc6 not libc6.deb)" << endl
;
1258 cout
<< " remove - Remove packages" << endl
;
1259 cout
<< " dist-upgrade - Distribution upgrade, see apt-get(8)" << endl
;
1260 cout
<< " dselect-upgrade - Follow dselect selections" << endl
;
1261 cout
<< " clean - Erase downloaded archive files" << endl
;
1262 cout
<< " autoclean - Erase old downloaded archive files" << endl
;
1263 cout
<< " check - Verify that there are no broken dependencies" << endl
;
1265 cout
<< "Options:" << endl
;
1266 cout
<< " -h This help text." << endl
;
1267 cout
<< " -q Loggable output - no progress indicator" << endl
;
1268 cout
<< " -qq No output except for errors" << endl
;
1269 cout
<< " -d Download only - do NOT install or unpack archives" << endl
;
1270 cout
<< " -s No-act. Perform ordering simulation" << endl
;
1271 cout
<< " -y Assume Yes to all queries and do not prompt" << endl
;
1272 cout
<< " -f Attempt to continue if the integrity check fails" << endl
;
1273 cout
<< " -m Attempt to continue if archives are unlocatable" << endl
;
1274 cout
<< " -u Show a list of upgraded packages as well" << endl
;
1275 cout
<< " -c=? Read this configuration file" << endl
;
1276 cout
<< " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" << endl
;
1277 cout
<< "See the apt-get(8), sources.list(5) and apt.conf(5) manual" << endl
;
1278 cout
<< "pages for more information." << endl
;
1282 // GetInitialize - Initialize things for apt-get /*{{{*/
1283 // ---------------------------------------------------------------------
1285 void GetInitialize()
1287 _config
->Set("quiet",0);
1288 _config
->Set("help",false);
1289 _config
->Set("APT::Get::Download-Only",false);
1290 _config
->Set("APT::Get::Simulate",false);
1291 _config
->Set("APT::Get::Assume-Yes",false);
1292 _config
->Set("APT::Get::Fix-Broken",false);
1293 _config
->Set("APT::Get::Force-Yes",false);
1296 // SigWinch - Window size change signal handler /*{{{*/
1297 // ---------------------------------------------------------------------
1301 // Riped from GNU ls
1305 if (ioctl(1, TIOCGWINSZ
, &ws
) != -1 && ws
.ws_col
>= 5)
1306 ScreenWidth
= ws
.ws_col
- 1;
1311 int main(int argc
,const char *argv
[])
1313 CommandLine::Args Args
[] = {
1314 {'h',"help","help",0},
1315 {'v',"version","version",0},
1316 {'q',"quiet","quiet",CommandLine::IntLevel
},
1317 {'q',"silent","quiet",CommandLine::IntLevel
},
1318 {'d',"download-only","APT::Get::Download-Only",0},
1319 {'s',"simulate","APT::Get::Simulate",0},
1320 {'s',"just-print","APT::Get::Simulate",0},
1321 {'s',"recon","APT::Get::Simulate",0},
1322 {'s',"no-act","APT::Get::Simulate",0},
1323 {'y',"yes","APT::Get::Assume-Yes",0},
1324 {'y',"assume-yes","APT::Get::Assume-Yes",0},
1325 {'f',"fix-broken","APT::Get::Fix-Broken",0},
1326 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
1327 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
1328 {0,"fix-missing","APT::Get::Fix-Missing",0},
1329 {0,"ignore-hold","APT::Ingore-Hold",0},
1330 {0,"no-upgrade","APT::Get::no-upgrade",0},
1331 {0,"force-yes","APT::Get::force-yes",0},
1332 {0,"print-uris","APT::Get::Print-URIs",0},
1333 {'c',"config-file",0,CommandLine::ConfigFile
},
1334 {'o',"option",0,CommandLine::ArbItem
},
1336 CommandLine::Dispatch Cmds
[] = {{"update",&DoUpdate
},
1337 {"upgrade",&DoUpgrade
},
1338 {"install",&DoInstall
},
1339 {"remove",&DoInstall
},
1340 {"dist-upgrade",&DoDistUpgrade
},
1341 {"dselect-upgrade",&DoDSelectUpgrade
},
1343 {"autoclean",&DoAutoClean
},
1345 {"source",&DoSource
},
1349 // Parse the command line and initialize the package library
1350 CommandLine
CmdL(Args
,_config
);
1351 if (pkgInitialize(*_config
) == false ||
1352 CmdL
.Parse(argc
,argv
) == false)
1354 _error
->DumpErrors();
1358 // See if the help should be shown
1359 if (_config
->FindB("help") == true ||
1360 _config
->FindB("version") == true ||
1361 CmdL
.FileSize() == 0)
1362 return ShowHelp(CmdL
);
1364 // Deal with stdout not being a tty
1365 if (ttyname(STDOUT_FILENO
) == 0 && _config
->FindI("quiet",0) < 1)
1366 _config
->Set("quiet","1");
1368 // Setup the output streams
1369 c0out
.rdbuf(cout
.rdbuf());
1370 c1out
.rdbuf(cout
.rdbuf());
1371 c2out
.rdbuf(cout
.rdbuf());
1372 if (_config
->FindI("quiet",0) > 0)
1373 c0out
.rdbuf(devnull
.rdbuf());
1374 if (_config
->FindI("quiet",0) > 1)
1375 c1out
.rdbuf(devnull
.rdbuf());
1377 // Setup the signals
1378 signal(SIGPIPE
,SIG_IGN
);
1379 signal(SIGWINCH
,SigWinch
);
1382 // Match the operation
1383 CmdL
.DispatchArg(Cmds
);
1385 // Print any errors or warnings found during parsing
1386 if (_error
->empty() == false)
1388 bool Errors
= _error
->PendingError();
1389 _error
->DumpErrors();
1390 return Errors
== true?100:0;