]>
git.saurik.com Git - apt.git/blob - cmdline/apt-get.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-get.cc,v 1.44 1999/03/06 02:13:48 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>
43 #include "acqprogress.h"
47 #include <sys/ioctl.h>
58 ofstream
devnull("/dev/null");
59 unsigned int ScreenWidth
= 80;
61 // YnPrompt - Yes No Prompt. /*{{{*/
62 // ---------------------------------------------------------------------
63 /* Returns true on a Yes.*/
66 if (_config
->FindB("APT::Get::Assume-Yes",false) == true)
74 read(STDIN_FILENO
,&C
,1);
75 while (C
!= '\n' && Jnk
!= '\n') read(STDIN_FILENO
,&Jnk
,1);
77 if (!(C
== 'Y' || C
== 'y' || C
== '\n' || C
== '\r'))
82 // AnalPrompt - Annoying Yes No Prompt. /*{{{*/
83 // ---------------------------------------------------------------------
84 /* Returns true on a Yes.*/
85 bool AnalPrompt(const char *Text
)
88 cin
.getline(Buf
,sizeof(Buf
));
89 if (strcmp(Buf
,Text
) == 0)
94 // ShowList - Show a list /*{{{*/
95 // ---------------------------------------------------------------------
96 /* This prints out a string of space seperated words with a title and
97 a two space indent line wraped to the current screen width. */
98 bool ShowList(ostream
&out
,string Title
,string List
)
100 if (List
.empty() == true)
103 // Acount for the leading space
104 int ScreenWidth
= ::ScreenWidth
- 3;
106 out
<< Title
<< endl
;
107 string::size_type Start
= 0;
108 while (Start
< List
.size())
110 string::size_type End
;
111 if (Start
+ ScreenWidth
>= List
.size())
114 End
= List
.rfind(' ',Start
+ScreenWidth
);
116 if (End
== string::npos
|| End
< Start
)
117 End
= Start
+ ScreenWidth
;
118 out
<< " " << string(List
,Start
,End
- Start
) << endl
;
124 // ShowBroken - Debugging aide /*{{{*/
125 // ---------------------------------------------------------------------
126 /* This prints out the names of all the packages that are broken along
127 with the name of each each broken dependency and a quite version
129 void ShowBroken(ostream
&out
,pkgDepCache
&Cache
)
131 out
<< "Sorry, but the following packages have unmet dependencies:" << endl
;
132 pkgCache::PkgIterator I
= Cache
.PkgBegin();
133 for (;I
.end() != true; I
++)
135 if (Cache
[I
].InstBroken() == false)
138 // Print out each package and the failed dependencies
139 out
<<" " << I
.Name() << ":";
140 int Indent
= strlen(I
.Name()) + 3;
142 if (Cache
[I
].InstVerIter(Cache
).end() == true)
148 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
150 // Compute a single dependency element (glob or)
151 pkgCache::DepIterator Start
;
152 pkgCache::DepIterator End
;
155 if (Cache
.IsImportantDep(End
) == false ||
156 (Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
160 for (int J
= 0; J
!= Indent
; J
++)
164 cout
<< ' ' << End
.DepType() << ": " << End
.TargetPkg().Name();
166 // Show a quick summary of the version requirements
167 if (End
.TargetVer() != 0)
168 out
<< " (" << End
.CompType() << " " << End
.TargetVer() <<
171 /* Show a summary of the target package if possible. In the case
172 of virtual packages we show nothing */
174 pkgCache::PkgIterator Targ
= End
.TargetPkg();
175 if (Targ
->ProvidesList
== 0)
178 pkgCache::VerIterator Ver
= Cache
[Targ
].InstVerIter(Cache
);
179 if (Ver
.end() == false)
180 out
<< Ver
.VerStr() << " is installed";
183 if (Cache
[Targ
].CandidateVerIter(Cache
).end() == true)
185 if (Targ
->ProvidesList
== 0)
186 out
<< "it is not installable";
188 out
<< "it is a virtual package";
191 out
<< "it is not installed";
200 // ShowNew - Show packages to newly install /*{{{*/
201 // ---------------------------------------------------------------------
203 void ShowNew(ostream
&out
,pkgDepCache
&Dep
)
205 /* Print out a list of packages that are going to be removed extra
206 to what the user asked */
207 pkgCache::PkgIterator I
= Dep
.PkgBegin();
209 for (;I
.end() != true; I
++)
210 if (Dep
[I
].NewInstall() == true)
211 List
+= string(I
.Name()) + " ";
212 ShowList(out
,"The following NEW packages will be installed:",List
);
215 // ShowDel - Show packages to delete /*{{{*/
216 // ---------------------------------------------------------------------
218 void ShowDel(ostream
&out
,pkgDepCache
&Dep
)
220 /* Print out a list of packages that are going to be removed extra
221 to what the user asked */
222 pkgCache::PkgIterator I
= Dep
.PkgBegin();
224 for (;I
.end() != true; I
++)
225 if (Dep
[I
].Delete() == true)
226 List
+= string(I
.Name()) + " ";
228 ShowList(out
,"The following packages will be REMOVED:",List
);
231 // ShowKept - Show kept packages /*{{{*/
232 // ---------------------------------------------------------------------
234 void ShowKept(ostream
&out
,pkgDepCache
&Dep
)
236 pkgCache::PkgIterator I
= Dep
.PkgBegin();
238 for (;I
.end() != true; I
++)
241 if (Dep
[I
].Upgrade() == true || Dep
[I
].Upgradable() == false ||
242 I
->CurrentVer
== 0 || Dep
[I
].Delete() == true)
245 List
+= string(I
.Name()) + " ";
247 ShowList(out
,"The following packages have been kept back",List
);
250 // ShowUpgraded - Show upgraded packages /*{{{*/
251 // ---------------------------------------------------------------------
253 void ShowUpgraded(ostream
&out
,pkgDepCache
&Dep
)
255 pkgCache::PkgIterator I
= Dep
.PkgBegin();
257 for (;I
.end() != true; I
++)
260 if (Dep
[I
].Upgrade() == false || Dep
[I
].NewInstall() == true)
263 List
+= string(I
.Name()) + " ";
265 ShowList(out
,"The following packages will be upgraded",List
);
268 // ShowHold - Show held but changed packages /*{{{*/
269 // ---------------------------------------------------------------------
271 bool ShowHold(ostream
&out
,pkgDepCache
&Dep
)
273 pkgCache::PkgIterator I
= Dep
.PkgBegin();
275 for (;I
.end() != true; I
++)
277 if (Dep
[I
].InstallVer
!= (pkgCache::Version
*)I
.CurrentVer() &&
278 I
->SelectedState
== pkgCache::State::Hold
)
279 List
+= string(I
.Name()) + " ";
282 return ShowList(out
,"The following held packages will be changed:",List
);
285 // ShowEssential - Show an essential package warning /*{{{*/
286 // ---------------------------------------------------------------------
287 /* This prints out a warning message that is not to be ignored. It shows
288 all essential packages and their dependents that are to be removed.
289 It is insanely risky to remove the dependents of an essential package! */
290 bool ShowEssential(ostream
&out
,pkgDepCache
&Dep
)
292 pkgCache::PkgIterator I
= Dep
.PkgBegin();
294 bool *Added
= new bool[Dep
.HeaderP
->PackageCount
];
295 for (unsigned int I
= 0; I
!= Dep
.HeaderP
->PackageCount
; I
++)
298 for (;I
.end() != true; I
++)
300 if ((I
->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
303 // The essential package is being removed
304 if (Dep
[I
].Delete() == true)
306 if (Added
[I
->ID
] == false)
309 List
+= string(I
.Name()) + " ";
313 if (I
->CurrentVer
== 0)
316 // Print out any essential package depenendents that are to be removed
317 for (pkgDepCache::DepIterator D
= I
.CurrentVer().DependsList(); D
.end() == false; D
++)
319 // Skip everything but depends
320 if (D
->Type
!= pkgCache::Dep::PreDepends
&&
321 D
->Type
!= pkgCache::Dep::Depends
)
324 pkgCache::PkgIterator P
= D
.SmartTargetPkg();
325 if (Dep
[P
].Delete() == true)
327 if (Added
[P
->ID
] == true)
332 sprintf(S
,"%s (due to %s) ",P
.Name(),I
.Name());
339 if (List
.empty() == false)
340 out
<< "WARNING: The following essential packages will be removed" << endl
;
341 return ShowList(out
,"This should NOT be done unless you know exactly what you are doing!",List
);
344 // Stats - Show some statistics /*{{{*/
345 // ---------------------------------------------------------------------
347 void Stats(ostream
&out
,pkgDepCache
&Dep
)
349 unsigned long Upgrade
= 0;
350 unsigned long Install
= 0;
351 for (pkgCache::PkgIterator I
= Dep
.PkgBegin(); I
.end() == false; I
++)
353 if (Dep
[I
].NewInstall() == true)
356 if (Dep
[I
].Upgrade() == true)
360 out
<< Upgrade
<< " packages upgraded, " <<
361 Install
<< " newly installed, " <<
362 Dep
.DelCount() << " to remove and " <<
363 Dep
.KeepCount() << " not upgraded." << endl
;
365 if (Dep
.BadCount() != 0)
366 out
<< Dep
.BadCount() << " packages not fully installed or removed." << endl
;
370 // class CacheFile - Cover class for some dependency cache functions /*{{{*/
371 // ---------------------------------------------------------------------
382 inline operator pkgDepCache
&() {return *Cache
;};
383 inline pkgDepCache
*operator ->() {return Cache
;};
384 inline pkgDepCache
&operator *() {return *Cache
;};
386 bool Open(bool AllowBroken
= false);
387 CacheFile() : File(0), Map(0), Cache(0) {};
396 // CacheFile::Open - Open the cache file /*{{{*/
397 // ---------------------------------------------------------------------
398 /* This routine generates the caches and then opens the dependency cache
399 and verifies that the system is OK. */
400 bool CacheFile::Open(bool AllowBroken
)
402 if (_error
->PendingError() == true)
405 // Create a progress class
406 OpTextProgress
Progress(*_config
);
408 // Read the source list
410 if (List
.ReadMainList() == false)
411 return _error
->Error("The list of sources could not be read.");
413 // Build all of the caches
414 pkgMakeStatusCache(List
,Progress
);
415 if (_error
->PendingError() == true)
416 return _error
->Error("The package lists or status file could not be parsed or opened.");
417 if (_error
->empty() == false)
418 _error
->Warning("You may want to run apt-get update to correct theses missing files");
422 // Open the cache file
423 File
= new FileFd(_config
->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly
);
424 if (_error
->PendingError() == true)
427 Map
= new MMap(*File
,MMap::Public
| MMap::ReadOnly
);
428 if (_error
->PendingError() == true)
431 Cache
= new pkgDepCache(*Map
,Progress
);
432 if (_error
->PendingError() == true)
437 // Check that the system is OK
438 if (Cache
->DelCount() != 0 || Cache
->InstCount() != 0)
439 return _error
->Error("Internal Error, non-zero counts");
441 // Apply corrections for half-installed packages
442 if (pkgApplyStatus(*Cache
) == false)
446 if (Cache
->BrokenCount() == 0 || AllowBroken
== true)
449 // Attempt to fix broken things
450 if (_config
->FindB("APT::Get::Fix-Broken",false) == true)
452 c1out
<< "Correcting dependencies..." << flush
;
453 if (pkgFixBroken(*Cache
) == false || Cache
->BrokenCount() != 0)
455 c1out
<< " failed." << endl
;
456 ShowBroken(c1out
,*this);
458 return _error
->Error("Unable to correct dependencies");
460 if (pkgMinimizeUpgrade(*Cache
) == false)
461 return _error
->Error("Unable to minimize the upgrade set");
463 c1out
<< " Done" << endl
;
467 c1out
<< "You might want to run `apt-get -f install' to correct these." << endl
;
468 ShowBroken(c1out
,*this);
470 return _error
->Error("Unmet dependencies. Try using -f.");
477 // InstallPackages - Actually download and install the packages /*{{{*/
478 // ---------------------------------------------------------------------
479 /* This displays the informative messages describing what is going to
480 happen and then calls the download routines */
481 bool InstallPackages(CacheFile
&Cache
,bool ShwKept
,bool Ask
= true,bool Saftey
= true)
484 bool Essential
= false;
486 // Show all the various warning indicators
487 ShowDel(c1out
,Cache
);
488 ShowNew(c1out
,Cache
);
490 ShowKept(c1out
,Cache
);
491 Fail
|= !ShowHold(c1out
,Cache
);
492 if (_config
->FindB("APT::Get::Show-Upgraded",false) == true)
493 ShowUpgraded(c1out
,Cache
);
494 Essential
= !ShowEssential(c1out
,Cache
);
499 if (Cache
->BrokenCount() != 0)
501 ShowBroken(c1out
,Cache
);
502 return _error
->Error("Internal Error, InstallPackages was called with broken packages!");
505 if (Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
506 Cache
->BadCount() == 0)
509 // Run the simulator ..
510 if (_config
->FindB("APT::Get::Simulate") == true)
512 pkgSimulate
PM(Cache
);
513 return PM
.DoInstall();
516 // Create the text record parser
517 pkgRecords
Recs(Cache
);
518 if (_error
->PendingError() == true)
521 // Lock the archive directory
522 if (_config
->FindB("Debug::NoLocking",false) == false)
524 FileFd
Lock(GetLock(_config
->FindDir("Dir::Cache::Archives") + "lock"));
525 if (_error
->PendingError() == true)
526 return _error
->Error("Unable to lock the download directory");
529 // Create the download object
530 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
531 pkgAcquire
Fetcher(&Stat
);
533 // Read the source list
535 if (List
.ReadMainList() == false)
536 return _error
->Error("The list of sources could not be read.");
538 // Create the package manager and prepare to download
540 if (PM
.GetArchives(&Fetcher
,&List
,&Recs
) == false ||
541 _error
->PendingError() == true)
544 // Display statistics
545 unsigned long FetchBytes
= Fetcher
.FetchNeeded();
546 unsigned long DebBytes
= Fetcher
.TotalNeeded();
547 if (DebBytes
!= Cache
->DebSize())
549 c0out
<< DebBytes
<< ',' << Cache
->DebSize() << endl
;
550 c0out
<< "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl
;
553 // Check for enough free space
555 string OutputDir
= _config
->FindDir("Dir::Cache::Archives");
556 if (statfs(OutputDir
.c_str(),&Buf
) != 0)
557 return _error
->Errno("statfs","Couldn't determine free space in %s",
559 if (unsigned(Buf
.f_bfree
) < FetchBytes
/Buf
.f_bsize
)
560 return _error
->Error("Sorry, you don't have enough free space in %s",
564 c1out
<< "Need to get ";
565 if (DebBytes
!= FetchBytes
)
566 c1out
<< SizeToStr(FetchBytes
) << "b/" << SizeToStr(DebBytes
) << 'b';
568 c1out
<< SizeToStr(DebBytes
) << 'b';
570 c1out
<< " of archives. After unpacking ";
573 if (Cache
->UsrSize() >= 0)
574 c1out
<< SizeToStr(Cache
->UsrSize()) << "b will be used." << endl
;
576 c1out
<< SizeToStr(-1*Cache
->UsrSize()) << "b will be freed." << endl
;
578 if (_error
->PendingError() == true)
582 if (_config
->FindB("APT::Get::Assume-Yes",false) == true)
584 if (Fail
== true && _config
->FindB("APT::Get::Force-Yes",false) == false)
585 return _error
->Error("There are problems and -y was used without --force-yes");
588 if (Essential
== true && Saftey
== true)
590 c2out
<< "You are about to do something potentially harmful" << endl
;
591 c2out
<< "To continue type in the phrase 'Yes, I understand this is bad'" << endl
;
592 c2out
<< " ?] " << flush
;
593 if (AnalPrompt("Yes, I understand this is bad") == false)
595 c2out
<< "Abort." << endl
;
601 // Prompt to continue
604 if (_config
->FindI("quiet",0) < 2 ||
605 _config
->FindB("APT::Get::Assume-Yes",false) == false)
606 c2out
<< "Do you want to continue? [Y/n] " << flush
;
608 if (YnPrompt() == false)
610 c2out
<< "Abort." << endl
;
616 if (_config
->FindB("APT::Get::Print-URIs") == true)
618 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
619 for (; I
!= Fetcher
.UriEnd(); I
++)
620 cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
621 I
->Owner
->FileSize
<< ' ' << I
->Owner
->MD5Sum() << endl
;
626 if (Fetcher
.Run() == false)
631 bool Transient
= false;
632 for (pkgAcquire::Item
**I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); I
++)
634 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
635 (*I
)->Complete
== true)
638 if ((*I
)->Status
== pkgAcquire::Item::StatIdle
)
645 cerr
<< "Failed to fetch " << (*I
)->Describe() << endl
;
646 cerr
<< " " << (*I
)->ErrorText
<< endl
;
650 if (_config
->FindB("APT::Get::Download-Only",false) == true)
653 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
655 if (Transient
== true)
657 c2out
<< "Upgrading with disk swapping is not supported in this version." << endl
;
658 c2out
<< "Try running multiple times with --fix-missing" << endl
;
661 return _error
->Error("Unable to fetch some archives, maybe try with --fix-missing?");
664 // Try to deal with missing package files
665 if (PM
.FixMissing() == false)
667 cerr
<< "Unable to correct missing packages." << endl
;
668 return _error
->Error("Aborting Install.");
672 return PM
.DoInstall();
676 // DoUpdate - Update the package lists /*{{{*/
677 // ---------------------------------------------------------------------
679 bool DoUpdate(CommandLine
&)
681 // Get the source list
683 if (List
.ReadMainList() == false)
686 // Lock the list directory
687 if (_config
->FindB("Debug::NoLocking",false) == false)
689 FileFd
Lock(GetLock(_config
->FindDir("Dir::State::Lists") + "lock"));
690 if (_error
->PendingError() == true)
691 return _error
->Error("Unable to lock the list directory");
694 // Create the download object
695 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
696 pkgAcquire
Fetcher(&Stat
);
698 // Populate it with the source selection
699 pkgSourceList::const_iterator I
;
700 for (I
= List
.begin(); I
!= List
.end(); I
++)
702 new pkgAcqIndex(&Fetcher
,I
);
703 if (_error
->PendingError() == true)
708 if (Fetcher
.Run() == false)
711 // Clean out any old list files
712 if (Fetcher
.Clean(_config
->FindDir("Dir::State::lists")) == false ||
713 Fetcher
.Clean(_config
->FindDir("Dir::State::lists") + "partial/") == false)
716 // Prepare the cache.
718 if (Cache
.Open() == false)
724 // DoUpgrade - Upgrade all packages /*{{{*/
725 // ---------------------------------------------------------------------
726 /* Upgrade all packages without installing new packages or erasing old
728 bool DoUpgrade(CommandLine
&CmdL
)
731 if (Cache
.Open() == false)
735 if (pkgAllUpgrade(Cache
) == false)
737 ShowBroken(c1out
,Cache
);
738 return _error
->Error("Internal Error, AllUpgrade broke stuff");
741 return InstallPackages(Cache
,true);
744 // DoInstall - Install packages from the command line /*{{{*/
745 // ---------------------------------------------------------------------
746 /* Install named packages */
747 bool DoInstall(CommandLine
&CmdL
)
750 if (Cache
.Open(CmdL
.FileSize() != 1) == false)
753 // Enter the special broken fixing mode if the user specified arguments
754 bool BrokenFix
= false;
755 if (Cache
->BrokenCount() != 0)
758 unsigned int ExpectedInst
= 0;
759 unsigned int Packages
= 0;
760 pkgProblemResolver
Fix(Cache
);
762 bool DefRemove
= false;
763 if (strcasecmp(CmdL
.FileList
[0],"remove") == 0)
766 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
768 // Duplicate the string
769 unsigned int Length
= strlen(*I
);
771 if (Length
>= sizeof(S
))
775 // See if we are removing the package
776 bool Remove
= DefRemove
;
777 if (Cache
->FindPkg(S
).end() == true)
779 // Handle an optional end tag indicating what to do
780 if (S
[Length
- 1] == '-')
785 if (S
[Length
- 1] == '+')
792 // Locate the package
793 pkgCache::PkgIterator Pkg
= Cache
->FindPkg(S
);
795 if (Pkg
.end() == true)
796 return _error
->Error("Couldn't find package %s",S
);
798 // Handle the no-upgrade case
799 if (_config
->FindB("APT::Get::no-upgrade",false) == true &&
800 Pkg
->CurrentVer
!= 0)
802 c1out
<< "Skipping " << Pkg
.Name() << ", it is already installed and no-upgrade is set." << endl
;
806 // Check if there is something new to install
807 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
808 if (State
.CandidateVer
== 0)
810 if (Pkg
->ProvidesList
!= 0)
812 c1out
<< "Package " << S
<< " is a virtual package provided by:" << endl
;
814 pkgCache::PrvIterator I
= Pkg
.ProvidesList();
815 for (; I
.end() == false; I
++)
817 pkgCache::PkgIterator Pkg
= I
.OwnerPkg();
819 if ((*Cache
)[Pkg
].CandidateVerIter(*Cache
) == I
.OwnerVer())
821 if ((*Cache
)[Pkg
].Install() == true && (*Cache
)[Pkg
].NewInstall() == false)
822 c1out
<< " " << Pkg
.Name() << " " << I
.OwnerVer().VerStr() <<
823 " [Installed]"<< endl
;
825 c1out
<< " " << Pkg
.Name() << " " << I
.OwnerVer().VerStr() << endl
;
828 c1out
<< "You should explicly select one to install." << endl
;
832 c1out
<< "Package " << S
<< " has no available version, but exists in the database." << endl
;
833 c1out
<< "This typically means that the package was mentioned in a dependency and " << endl
;
834 c1out
<< "never uploaded, or that it is an obsolete package." << endl
;
837 pkgCache::DepIterator Dep
= Pkg
.RevDependsList();
838 for (; Dep
.end() == false; Dep
++)
840 if (Dep
->Type
!= pkgCache::Dep::Replaces
)
842 List
+= string(Dep
.ParentPkg().Name()) + " ";
844 ShowList(c1out
,"However the following packages replace it:",List
);
847 return _error
->Error("Package %s has no installation candidate",S
);
854 Cache
->MarkDelete(Pkg
);
859 Cache
->MarkInstall(Pkg
,false);
860 if (State
.Install() == false)
861 c1out
<< "Sorry, " << S
<< " is already the newest version" << endl
;
865 // Install it with autoinstalling enabled.
866 if (State
.InstBroken() == true && BrokenFix
== false)
867 Cache
->MarkInstall(Pkg
,true);
870 /* If we are in the Broken fixing mode we do not attempt to fix the
871 problems. This is if the user invoked install without -f and gave
873 if (BrokenFix
== true && Cache
->BrokenCount() != 0)
875 c1out
<< "You might want to run `apt-get -f install' to correct these." << endl
;
876 ShowBroken(c1out
,Cache
);
878 return _error
->Error("Unmet dependencies. Try using -f.");
881 // Call the scored problem resolver
882 Fix
.InstallProtect();
883 if (Fix
.Resolve(true) == false)
886 // Now we check the state of the packages,
887 if (Cache
->BrokenCount() != 0)
889 c1out
<< "Some packages could not be installed. This may mean that you have" << endl
;
890 c1out
<< "requested an impossible situation or if you are using the unstable" << endl
;
891 c1out
<< "distribution that some required packages have not yet been created" << endl
;
892 c1out
<< "or been moved out of Incoming." << endl
;
896 c1out
<< "Since you only requested a single operation it is extremely likely that" << endl
;
897 c1out
<< "the package is simply not installable and a bug report against" << endl
;
898 c1out
<< "that package should be filed." << endl
;
901 c1out
<< "The following information may help to resolve the situation:" << endl
;
903 ShowBroken(c1out
,Cache
);
904 return _error
->Error("Sorry, broken packages");
907 /* Print out a list of packages that are going to be installed extra
908 to what the user asked */
909 if (Cache
->InstCount() != ExpectedInst
)
912 pkgCache::PkgIterator I
= Cache
->PkgBegin();
913 for (;I
.end() != true; I
++)
915 if ((*Cache
)[I
].Install() == false)
919 for (J
= CmdL
.FileList
+ 1; *J
!= 0; J
++)
920 if (strcmp(*J
,I
.Name()) == 0)
924 List
+= string(I
.Name()) + " ";
927 ShowList(c1out
,"The following extra packages will be installed:",List
);
930 // See if we need to prompt
931 if (Cache
->InstCount() == ExpectedInst
&& Cache
->DelCount() == 0)
932 return InstallPackages(Cache
,false,false);
934 return InstallPackages(Cache
,false);
937 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
938 // ---------------------------------------------------------------------
939 /* Intelligent upgrader that will install and remove packages at will */
940 bool DoDistUpgrade(CommandLine
&CmdL
)
943 if (Cache
.Open() == false)
946 c0out
<< "Calculating Upgrade... " << flush
;
947 if (pkgDistUpgrade(*Cache
) == false)
949 c0out
<< "Failed" << endl
;
950 ShowBroken(c1out
,Cache
);
954 c0out
<< "Done" << endl
;
956 return InstallPackages(Cache
,true);
959 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
960 // ---------------------------------------------------------------------
961 /* Follows dselect's selections */
962 bool DoDSelectUpgrade(CommandLine
&CmdL
)
965 if (Cache
.Open() == false)
968 // Install everything with the install flag set
969 pkgCache::PkgIterator I
= Cache
->PkgBegin();
970 for (;I
.end() != true; I
++)
972 /* Install the package only if it is a new install, the autoupgrader
973 will deal with the rest */
974 if (I
->SelectedState
== pkgCache::State::Install
)
975 Cache
->MarkInstall(I
,false);
978 /* Now install their deps too, if we do this above then order of
979 the status file is significant for | groups */
980 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
982 /* Install the package only if it is a new install, the autoupgrader
983 will deal with the rest */
984 if (I
->SelectedState
== pkgCache::State::Install
)
985 Cache
->MarkInstall(I
,true);
988 // Apply erasures now, they override everything else.
989 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
992 if (I
->SelectedState
== pkgCache::State::DeInstall
||
993 I
->SelectedState
== pkgCache::State::Purge
)
994 Cache
->MarkDelete(I
);
997 /* Resolve any problems that dselect created, allupgrade cannot handle
998 such things. We do so quite agressively too.. */
999 if (Cache
->BrokenCount() != 0)
1001 pkgProblemResolver
Fix(Cache
);
1003 // Hold back held packages.
1004 if (_config
->FindB("APT::Ingore-Hold",false) == false)
1006 for (pkgCache::PkgIterator I
= Cache
->PkgBegin(); I
.end() == false; I
++)
1008 if (I
->SelectedState
== pkgCache::State::Hold
)
1016 if (Fix
.Resolve() == false)
1018 ShowBroken(c1out
,Cache
);
1019 return _error
->Error("Internal Error, problem resolver broke stuff");
1023 // Now upgrade everything
1024 if (pkgAllUpgrade(Cache
) == false)
1026 ShowBroken(c1out
,Cache
);
1027 return _error
->Error("Internal Error, problem resolver broke stuff");
1030 return InstallPackages(Cache
,false);
1033 // DoClean - Remove download archives /*{{{*/
1034 // ---------------------------------------------------------------------
1036 bool DoClean(CommandLine
&CmdL
)
1039 Fetcher
.Clean(_config
->FindDir("Dir::Cache::archives"));
1040 Fetcher
.Clean(_config
->FindDir("Dir::Cache::archives") + "partial/");
1044 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
1045 // ---------------------------------------------------------------------
1046 /* This is similar to clean but it only purges things that cannot be
1047 downloaded, that is old versions of cached packages. */
1048 class LogCleaner
: public pkgArchiveCleaner
1051 virtual void Erase(const char *File
,string Pkg
,string Ver
,struct stat
&St
)
1053 cout
<< "Del " << Pkg
<< " " << Ver
<< " [" << SizeToStr(St
.st_size
) << "b]" << endl
;
1057 bool DoAutoClean(CommandLine
&CmdL
)
1060 if (Cache
.Open(true) == false)
1065 return Cleaner
.Go(_config
->FindDir("Dir::Cache::archives"),*Cache
) &&
1066 Cleaner
.Go(_config
->FindDir("Dir::Cache::archives") + "partial/",*Cache
);
1069 // DoCheck - Perform the check operation /*{{{*/
1070 // ---------------------------------------------------------------------
1071 /* Opening automatically checks the system, this command is mostly used
1073 bool DoCheck(CommandLine
&CmdL
)
1082 // ShowHelp - Show a help screen /*{{{*/
1083 // ---------------------------------------------------------------------
1085 bool ShowHelp(CommandLine
&CmdL
)
1087 cout
<< PACKAGE
<< ' ' << VERSION
<< " for " << ARCHITECTURE
<<
1088 " compiled on " << __DATE__
<< " " << __TIME__
<< endl
;
1089 if (_config
->FindB("version") == true)
1092 cout
<< "Usage: apt-get [options] command" << endl
;
1093 cout
<< " apt-get [options] install pkg1 [pkg2 ...]" << endl
;
1095 cout
<< "apt-get is a simple command line interface for downloading and" << endl
;
1096 cout
<< "installing packages. The most frequently used commands are update" << endl
;
1097 cout
<< "and install." << endl
;
1099 cout
<< "Commands:" << endl
;
1100 cout
<< " update - Retrieve new lists of packages" << endl
;
1101 cout
<< " upgrade - Perform an upgrade" << endl
;
1102 cout
<< " install - Install new packages (pkg is libc6 not libc6.deb)" << endl
;
1103 cout
<< " remove - Remove packages" << endl
;
1104 cout
<< " dist-upgrade - Distribution upgrade, see apt-get(8)" << endl
;
1105 cout
<< " dselect-upgrade - Follow dselect selections" << endl
;
1106 cout
<< " clean - Erase downloaded archive files" << endl
;
1107 cout
<< " autoclean - Erase old downloaded archive files" << endl
;
1108 cout
<< " check - Verify that there are no broken dependencies" << endl
;
1110 cout
<< "Options:" << endl
;
1111 cout
<< " -h This help text." << endl
;
1112 cout
<< " -q Loggable output - no progress indicator" << endl
;
1113 cout
<< " -qq No output except for errors" << endl
;
1114 cout
<< " -d Download only - do NOT install or unpack archives" << endl
;
1115 cout
<< " -s No-act. Perform ordering simulation" << endl
;
1116 cout
<< " -y Assume Yes to all queries and do not prompt" << endl
;
1117 cout
<< " -f Attempt to continue if the integrity check fails" << endl
;
1118 cout
<< " -m Attempt to continue if archives are unlocatable" << endl
;
1119 cout
<< " -u Show a list of upgraded packages as well" << endl
;
1120 cout
<< " -c=? Read this configuration file" << endl
;
1121 cout
<< " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl
;
1122 cout
<< "See the apt-get(8), sources.list(5) and apt.conf(5) manual" << endl
;
1123 cout
<< "pages for more information." << endl
;
1127 // GetInitialize - Initialize things for apt-get /*{{{*/
1128 // ---------------------------------------------------------------------
1130 void GetInitialize()
1132 _config
->Set("quiet",0);
1133 _config
->Set("help",false);
1134 _config
->Set("APT::Get::Download-Only",false);
1135 _config
->Set("APT::Get::Simulate",false);
1136 _config
->Set("APT::Get::Assume-Yes",false);
1137 _config
->Set("APT::Get::Fix-Broken",false);
1138 _config
->Set("APT::Get::Force-Yes",false);
1141 // SigWinch - Window size change signal handler /*{{{*/
1142 // ---------------------------------------------------------------------
1146 // Riped from GNU ls
1150 if (ioctl(1, TIOCGWINSZ
, &ws
) != -1 && ws
.ws_col
>= 5)
1151 ScreenWidth
= ws
.ws_col
- 1;
1156 int main(int argc
,const char *argv
[])
1158 CommandLine::Args Args
[] = {
1159 {'h',"help","help",0},
1160 {'v',"version","version",0},
1161 {'q',"quiet","quiet",CommandLine::IntLevel
},
1162 {'q',"silent","quiet",CommandLine::IntLevel
},
1163 {'d',"download-only","APT::Get::Download-Only",0},
1164 {'s',"simulate","APT::Get::Simulate",0},
1165 {'s',"just-print","APT::Get::Simulate",0},
1166 {'s',"recon","APT::Get::Simulate",0},
1167 {'s',"no-act","APT::Get::Simulate",0},
1168 {'y',"yes","APT::Get::Assume-Yes",0},
1169 {'y',"assume-yes","APT::Get::Assume-Yes",0},
1170 {'f',"fix-broken","APT::Get::Fix-Broken",0},
1171 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
1172 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
1173 {0,"fix-missing","APT::Get::Fix-Missing",0},
1174 {0,"ignore-hold","APT::Ingore-Hold",0},
1175 {0,"no-upgrade","APT::Get::no-upgrade",0},
1176 {0,"force-yes","APT::Get::force-yes",0},
1177 {0,"print-uris","APT::Get::Print-URIs",0},
1178 {'c',"config-file",0,CommandLine::ConfigFile
},
1179 {'o',"option",0,CommandLine::ArbItem
},
1181 CommandLine::Dispatch Cmds
[] = {{"update",&DoUpdate
},
1182 {"upgrade",&DoUpgrade
},
1183 {"install",&DoInstall
},
1184 {"remove",&DoInstall
},
1185 {"dist-upgrade",&DoDistUpgrade
},
1186 {"dselect-upgrade",&DoDSelectUpgrade
},
1188 {"autoclean",&DoAutoClean
},
1193 // Parse the command line and initialize the package library
1194 CommandLine
CmdL(Args
,_config
);
1195 if (pkgInitialize(*_config
) == false ||
1196 CmdL
.Parse(argc
,argv
) == false)
1198 _error
->DumpErrors();
1202 // See if the help should be shown
1203 if (_config
->FindB("help") == true ||
1204 _config
->FindB("version") == true ||
1205 CmdL
.FileSize() == 0)
1206 return ShowHelp(CmdL
);
1208 // Setup the output streams
1209 c0out
.rdbuf(cout
.rdbuf());
1210 c1out
.rdbuf(cout
.rdbuf());
1211 c2out
.rdbuf(cout
.rdbuf());
1212 if (_config
->FindI("quiet",0) > 0)
1213 c0out
.rdbuf(devnull
.rdbuf());
1214 if (_config
->FindI("quiet",0) > 1)
1215 c1out
.rdbuf(devnull
.rdbuf());
1217 // Setup the signals
1218 signal(SIGPIPE
,SIG_IGN
);
1219 signal(SIGWINCH
,SigWinch
);
1222 // Match the operation
1223 CmdL
.DispatchArg(Cmds
);
1225 // Print any errors or warnings found during parsing
1226 if (_error
->empty() == false)
1228 bool Errors
= _error
->PendingError();
1229 _error
->DumpErrors();
1230 return Errors
== true?100:0;