]>
git.saurik.com Git - apt.git/blob - cmdline/apt-get.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-get.cc,v 1.2 1998/10/08 04:55:05 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>
44 ofstream
devnull("/dev/null");
45 unsigned int ScreenWidth
= 80;
47 // ShowList - Show a list /*{{{*/
48 // ---------------------------------------------------------------------
49 /* This prints out a string of space seperated words with a title and
50 a two space indent line wraped to the current screen width. */
51 void ShowList(ostream
&out
,string Title
,string List
)
53 if (List
.empty() == true)
56 // Acount for the leading space
57 int ScreenWidth
= ::ScreenWidth
- 3;
60 string::size_type Start
= 0;
61 while (Start
< List
.size())
63 string::size_type End
;
64 if (Start
+ ScreenWidth
>= List
.size())
67 End
= List
.rfind(' ',Start
+ScreenWidth
);
69 if (End
== string::npos
|| End
< Start
)
70 End
= Start
+ ScreenWidth
;
71 out
<< " " << string(List
,Start
,End
- Start
) << endl
;
76 // ShowBroken - Debugging aide /*{{{*/
77 // ---------------------------------------------------------------------
78 /* This prints out the names of all the packages that are broken along
79 with the name of each each broken dependency and a quite version
81 void ShowBroken(ostream
&out
,pkgDepCache
&Cache
)
83 out
<< "Sorry, but the following packages are broken - this means they have unmet" << endl
;
84 out
<< "dependencies:" << endl
;
85 pkgCache::PkgIterator I
= Cache
.PkgBegin();
86 for (;I
.end() != true; I
++)
88 if (Cache
[I
].InstBroken() == true)
90 // Print out each package and the failed dependencies
91 out
<<" " << I
.Name() << ":";
92 int Indent
= strlen(I
.Name()) + 3;
94 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false; D
++)
96 if (Cache
.IsImportantDep(D
) == false || (Cache
[D
] &
97 pkgDepCache::DepInstall
) != 0)
101 for (int J
= 0; J
!= Indent
; J
++)
105 if (D
->Type
== pkgCache::Dep::Conflicts
)
106 out
<< " Conflicts:" << D
.TargetPkg().Name();
108 out
<< " Depends:" << D
.TargetPkg().Name();
110 // Show a quick summary of the version requirements
111 if (D
.TargetVer() != 0)
112 out
<< " (" << D
.CompType() << " " << D
.TargetVer() <<
115 /* Show a summary of the target package if possible. In the case
116 of virtual packages we show nothing */
117 pkgCache::PkgIterator Targ
= D
.TargetPkg();
118 if (Targ
->ProvidesList
== 0)
121 pkgCache::VerIterator Ver
= Cache
[Targ
].InstVerIter(Cache
);
122 if (Ver
.end() == false)
123 out
<< Ver
.VerStr() << "is installed";
125 out
<< "it is not installed";
134 // ShowNew - Show packages to newly install /*{{{*/
135 // ---------------------------------------------------------------------
137 void ShowNew(ostream
&out
,pkgDepCache
&Dep
)
139 /* Print out a list of packages that are going to be removed extra
140 to what the user asked */
141 pkgCache::PkgIterator I
= Dep
.PkgBegin();
143 for (;I
.end() != true; I
++)
144 if (Dep
[I
].NewInstall() == true)
145 List
+= string(I
.Name()) + " ";
146 ShowList(out
,"The following NEW packages will be installed:",List
);
149 // ShowDel - Show packages to delete /*{{{*/
150 // ---------------------------------------------------------------------
152 void ShowDel(ostream
&out
,pkgDepCache
&Dep
)
154 /* Print out a list of packages that are going to be removed extra
155 to what the user asked */
156 pkgCache::PkgIterator I
= Dep
.PkgBegin();
158 for (;I
.end() != true; I
++)
159 if (Dep
[I
].Delete() == true)
160 List
+= string(I
.Name()) + " ";
161 ShowList(out
,"The following packages will be REMOVED:",List
);
164 // ShowKept - Show kept packages /*{{{*/
165 // ---------------------------------------------------------------------
167 void ShowKept(ostream
&out
,pkgDepCache
&Dep
)
169 pkgCache::PkgIterator I
= Dep
.PkgBegin();
171 for (;I
.end() != true; I
++)
174 if (Dep
[I
].Upgrade() == true || Dep
[I
].Upgradable() == false ||
175 I
->CurrentVer
== 0 || Dep
[I
].Delete() == true)
178 List
+= string(I
.Name()) + " ";
180 ShowList(out
,"The following packages have been kept back",List
);
183 // ShowUpgraded - Show upgraded packages /*{{{*/
184 // ---------------------------------------------------------------------
186 void ShowUpgraded(ostream
&out
,pkgDepCache
&Dep
)
188 pkgCache::PkgIterator I
= Dep
.PkgBegin();
190 for (;I
.end() != true; I
++)
193 if (Dep
[I
].Upgrade() == false || Dep
[I
].NewInstall() == true)
196 List
+= string(I
.Name()) + " ";
198 ShowList(out
,"The following packages will be upgraded",List
);
201 // ShowHold - Show held but changed packages /*{{{*/
202 // ---------------------------------------------------------------------
204 void ShowHold(ostream
&out
,pkgDepCache
&Dep
)
206 pkgCache::PkgIterator I
= Dep
.PkgBegin();
208 for (;I
.end() != true; I
++)
210 if (Dep
[I
].InstallVer
!= (pkgCache::Version
*)I
.CurrentVer() &&
211 I
->SelectedState
== pkgCache::State::Hold
)
212 List
+= string(I
.Name()) + " ";
215 ShowList(out
,"The following held packages will be changed:",List
);
218 // ShowEssential - Show an essential package warning /*{{{*/
219 // ---------------------------------------------------------------------
220 /* This prints out a warning message that is not to be ignored. It shows
221 all essential packages and their dependents that are to be removed.
222 It is insanely risky to remove the dependents of an essential package! */
223 void ShowEssential(ostream
&out
,pkgDepCache
&Dep
)
225 pkgCache::PkgIterator I
= Dep
.PkgBegin();
227 bool *Added
= new bool[Dep
.HeaderP
->PackageCount
];
228 for (int I
= 0; I
!= Dep
.HeaderP
->PackageCount
; I
++)
231 for (;I
.end() != true; I
++)
233 if ((I
->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
236 // The essential package is being removed
237 if (Dep
[I
].Delete() == true)
239 if (Added
[I
->ID
] == false)
242 List
+= string(I
.Name()) + " ";
246 if (I
->CurrentVer
== 0)
249 // Print out any essential package depenendents that are to be removed
250 for (pkgDepCache::DepIterator D
= I
.CurrentVer().DependsList(); D
.end() == false; D
++)
252 pkgCache::PkgIterator P
= D
.SmartTargetPkg();
253 if (Dep
[P
].Delete() == true)
255 if (Added
[P
->ID
] == true)
258 List
+= string(P
.Name()) + " ";
263 if (List
.empty() == false)
264 out
<< "WARNING: The following essential packages will be removed" << endl
;
265 ShowList(out
,"This should NOT be done unless you know exactly what you are doing!",List
);
270 // Stats - Show some statistics /*{{{*/
271 // ---------------------------------------------------------------------
273 void Stats(ostream
&out
,pkgDepCache
&Dep
)
275 unsigned long Upgrade
= 0;
276 unsigned long Install
= 0;
277 for (pkgCache::PkgIterator I
= Dep
.PkgBegin(); I
.end() == false; I
++)
279 if (Dep
[I
].NewInstall() == true)
282 if (Dep
[I
].Upgrade() == true)
286 out
<< Upgrade
<< " packages upgraded, " <<
287 Install
<< " newly installed, " <<
288 Dep
.DelCount() << " to remove and " <<
289 Dep
.KeepCount() << " not upgraded." << endl
;
291 if (Dep
.BadCount() != 0)
292 out
<< Dep
.BadCount() << " packages not fully installed or removed." << endl
;
296 // class CacheFile - Cover class for some dependency cache functions /*{{{*/
297 // ---------------------------------------------------------------------
307 inline operator pkgDepCache
&() {return *Cache
;};
308 inline pkgDepCache
*operator ->() {return Cache
;};
309 inline pkgDepCache
&operator *() {return *Cache
;};
312 CacheFile() : File(0), Map(0), Cache(0) {};
321 // CacheFile::Open - Open the cache file /*{{{*/
322 // ---------------------------------------------------------------------
323 /* This routine generates the caches and then opens the dependency cache
324 and verifies that the system is OK. */
325 bool CacheFile::Open()
327 // Create a progress class
328 OpTextProgress
Progress(*_config
);
330 // Read the source list
332 if (List
.ReadMainList() == false)
333 return _error
->Error("The list of sources could not be read.");
335 // Build all of the caches
336 pkgMakeStatusCache(List
,Progress
);
337 if (_error
->PendingError() == true)
338 return _error
->Error("The package lists or status file could not be parsed or opened.");
342 // Open the cache file
343 File
= new FileFd(_config
->FindDir("Dir::Cache::pkgcache"),FileFd::ReadOnly
);
344 if (_error
->PendingError() == true)
347 Map
= new MMap(*File
,MMap::Public
| MMap::ReadOnly
);
348 if (_error
->PendingError() == true)
351 Cache
= new pkgDepCache(*Map
,Progress
);
352 if (_error
->PendingError() == true)
357 // Check that the system is OK
358 if (Cache
->DelCount() != 0 || Cache
->InstCount() != 0)
359 return _error
->Error("Internal Error, non-zero counts");
361 // Apply corrections for half-installed packages
362 if (pkgApplyStatus(*Cache
) == false)
366 if (Cache
->BrokenCount() == 0)
369 // Attempt to fix broken things
370 if (_config
->FindB("APT::Get::Fix-Broken",false) == true)
372 c1out
<< "Correcting dependencies..." << flush
;
373 if (pkgFixBroken(*Cache
) == false || Cache
->BrokenCount() != 0)
375 c1out
<< " failed." << endl
;
376 ShowBroken(c1out
,*this);
378 return _error
->Error("Unable to correct dependencies");
380 if (pkgMinimizeUpgrade(*Cache
) == false)
381 return _error
->Error("Unable to minimize the upgrade set");
383 c1out
<< " Done" << endl
;
387 c1out
<< "You might want to run `apt-get -f install' to correct these." << endl
;
388 ShowBroken(c1out
,*this);
390 return _error
->Error("Unmet dependencies. Try using -f.");
397 // InstallPackages - Actually download and install the packages /*{{{*/
398 // ---------------------------------------------------------------------
399 /* This displays the informative messages describing what is going to
400 happen and then calls the download routines */
401 bool InstallPackages(pkgDepCache
&Cache
,bool ShwKept
)
403 ShowDel(c1out
,Cache
);
404 ShowNew(c1out
,Cache
);
406 ShowKept(c1out
,Cache
);
407 ShowHold(c1out
,Cache
);
408 if (_config
->FindB("APT::Get::Show-Upgraded",false) == true)
409 ShowUpgraded(c1out
,Cache
);
410 ShowEssential(c1out
,Cache
);
414 if (Cache
.BrokenCount() != 0)
416 ShowBroken(c1out
,Cache
);
417 return _error
->Error("Internal Error, InstallPackages was called with broken packages!");
420 if (Cache
.DelCount() == 0 && Cache
.InstCount() == 0 &&
421 Cache
.BadCount() == 0)
428 // DoUpdate - Update the package lists /*{{{*/
429 // ---------------------------------------------------------------------
431 bool DoUpdate(CommandLine
&CmdL
)
435 // DoUpgrade - Upgrade all packages /*{{{*/
436 // ---------------------------------------------------------------------
437 /* Upgrade all packages without installing new packages or erasing old
439 bool DoUpgrade(CommandLine
&CmdL
)
442 if (Cache
.Open() == false)
446 pkgProblemResolver
Resolve(Cache
);
447 if (pkgAllUpgrade(Cache
) == false)
449 ShowBroken(c1out
,Cache
);
450 return _error
->Error("Internal Error, AllUpgrade broke stuff");
453 return InstallPackages(Cache
,true);
456 // DoInstall - Install packages from the command line /*{{{*/
457 // ---------------------------------------------------------------------
458 /* Install named packages */
459 bool DoInstall(CommandLine
&CmdL
)
462 if (Cache
.Open() == false)
465 int ExpectedInst
= 0;
466 pkgProblemResolver
Fix(Cache
);
468 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
470 // Duplicate the string
471 unsigned int Length
= strlen(*I
);
473 if (Length
>= sizeof(S
))
477 // See if we are removing the package
479 if (S
[Length
- 1] == '-')
485 // Locate the package
486 pkgCache::PkgIterator Pkg
= Cache
->FindPkg(S
);
487 if (Pkg
.end() == true)
488 return _error
->Error("Couldn't find package %s",S
);
490 // Check if there is something new to install
491 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
492 if (State
.CandidateVer
== 0)
493 return _error
->Error("Package %s has no installation candidate",S
);
498 Cache
->MarkDelete(Pkg
);
503 Cache
->MarkInstall(Pkg
,false);
504 if (State
.Install() == false)
505 c1out
<< "Sorry, " << S
<< " is already the newest version" << endl
;
509 // Install it with autoinstalling enabled.
510 if (State
.InstBroken() == true)
511 Cache
->MarkInstall(Pkg
,true);
514 // Call the scored problem resolver
515 if (Fix
.Resolve(true) == false)
518 // Now we check the state of the packages,
519 if (Cache
->BrokenCount() != 0)
521 ShowBroken(c1out
,Cache
);
522 return _error
->Error("Sorry, broken packages");
525 /* Print out a list of packages that are going to be installed extra
526 to what the user asked */
527 if (Cache
->InstCount() != ExpectedInst
)
530 pkgCache::PkgIterator I
= Cache
->PkgBegin();
531 for (;I
.end() != true; I
++)
533 if ((*Cache
)[I
].Install() == false)
537 for (J
= CmdL
.FileList
+ 1; *J
!= 0; J
++)
538 if (strcmp(*J
,I
.Name()) == 0)
542 List
+= string(I
.Name()) + " ";
545 ShowList(c1out
,"The following extra packages will be installed:",List
);
548 return InstallPackages(Cache
,false);
551 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
552 // ---------------------------------------------------------------------
553 /* Intelligent upgrader that will install and remove packages at will */
554 bool DoDistUpgrade(CommandLine
&CmdL
)
557 if (Cache
.Open() == false)
560 c0out
<< "Calculating Upgrade... " << flush
;
561 if (pkgDistUpgrade(*Cache
) == false)
563 c0out
<< "Failed" << endl
;
564 ShowBroken(c1out
,Cache
);
568 c0out
<< "Done" << endl
;
570 return InstallPackages(Cache
,true);
573 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
574 // ---------------------------------------------------------------------
575 /* Follows dselect's selections */
576 bool DoDSelectUpgrade(CommandLine
&CmdL
)
579 if (Cache
.Open() == false)
582 // Install everything with the install flag set
583 pkgCache::PkgIterator I
= Cache
->PkgBegin();
584 for (;I
.end() != true; I
++)
586 /* Install the package only if it is a new install, the autoupgrader
587 will deal with the rest */
588 if (I
->SelectedState
== pkgCache::State::Install
)
589 Cache
->MarkInstall(I
,false);
592 /* Now install their deps too, if we do this above then order of
593 the status file is significant for | groups */
594 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
596 /* Install the package only if it is a new install, the autoupgrader
597 will deal with the rest */
598 if (I
->SelectedState
== pkgCache::State::Install
)
599 Cache
->MarkInstall(I
);
602 // Apply erasures now, they override everything else.
603 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
606 if (I
->SelectedState
== pkgCache::State::DeInstall
||
607 I
->SelectedState
== pkgCache::State::Purge
)
608 Cache
->MarkDelete(I
);
611 /* Use updates smart upgrade to do the rest, it will automatically
613 if (pkgAllUpgrade(Cache
) == false)
615 ShowBroken(c1out
,Cache
);
616 return _error
->Error("Internal Error, AllUpgrade broke stuff");
619 return InstallPackages(Cache
,false);
622 // DoClean - Remove download archives /*{{{*/
623 // ---------------------------------------------------------------------
625 bool DoClean(CommandLine
&CmdL
)
630 // DoCheck - Perform the check operation /*{{{*/
631 // ---------------------------------------------------------------------
632 /* Opening automatically checks the system, this command is mostly used
634 bool DoCheck(CommandLine
&CmdL
)
643 // ShowHelp - Show a help screen /*{{{*/
644 // ---------------------------------------------------------------------
648 cout
<< PACKAGE
<< ' ' << VERSION
<< " for " << ARCHITECTURE
<<
649 " compiled on " << __DATE__
<< " " << __TIME__
<< endl
;
651 cout
<< "Usage: apt-get [options] command" << endl
;
652 cout
<< " apt-get [options] install pkg1 [pkg2 ...]" << endl
;
654 cout
<< "apt-get is a simple command line interface for downloading and" << endl
;
655 cout
<< "installing packages. The most frequently used commands are update" << endl
;
656 cout
<< "and install." << endl
;
658 cout
<< "Commands:" << endl
;
659 cout
<< " update - Retrieve new lists of packages" << endl
;
660 cout
<< " upgrade - Perform an upgrade" << endl
;
661 cout
<< " install - Install new packages (pkg is libc6 not libc6.deb)" << endl
;
662 cout
<< " dist-upgrade - Distribution upgrade, see apt-get(8)" << endl
;
663 cout
<< " dselect-upgrade - Follow dselect selections" << endl
;
664 cout
<< " clean - Erase downloaded archive files" << endl
;
665 cout
<< " check - Verify that there are no broken dependencies" << endl
;
667 cout
<< "Options:" << endl
;
668 cout
<< " -h This help text." << endl
;
669 cout
<< " -q Loggable output - no progress indicator" << endl
;
670 cout
<< " -qq No output except for errors" << endl
;
671 cout
<< " -d Download only - do NOT install or unpack archives" << endl
;
672 cout
<< " -s No-act. Perform ordering simulation" << endl
;
673 cout
<< " -y Assume Yes to all queries and do not prompt" << endl
;
674 cout
<< " -f Attempt to continue if the integrity check fails" << endl
;
675 cout
<< " -m Attempt to continue if archives are unlocatable" << endl
;
676 cout
<< " -u Show a list of upgraded packages as well" << endl
;
677 cout
<< " -c=? Read this configuration file" << endl
;
678 cout
<< " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl
;
679 cout
<< "See the apt-get(8), sources.list(8) and apt.conf(8) manual" << endl
;
680 cout
<< "pages for more information." << endl
;
684 // GetInitialize - Initialize things for apt-get /*{{{*/
685 // ---------------------------------------------------------------------
689 _config
->Set("quiet",0);
690 _config
->Set("help",false);
691 _config
->Set("APT::Get::Download-Only",false);
692 _config
->Set("APT::Get::Simulate",false);
693 _config
->Set("APT::Get::Assume-Yes",false);
694 _config
->Set("APT::Get::Fix-Broken",false);
698 int main(int argc
,const char *argv
[])
700 CommandLine::Args Args
[] = {
701 {'h',"help","help",0},
702 {'q',"quiet","quiet",CommandLine::IntLevel
},
703 {'q',"silent","quiet",CommandLine::IntLevel
},
704 {'d',"download-only","APT::Get::Download-Only",0},
705 {'s',"simulate","APT::Get::Simulate",0},
706 {'s',"just-print","APT::Get::Simulate",0},
707 {'s',"recon","APT::Get::Simulate",0},
708 {'s',"no-act","APT::Get::Simulate",0},
709 {'y',"yes","APT::Get::Assume-Yes",0},
710 {'y',"assume-yes","APT::Get::Assume-Yes",0},
711 {'f',"fix-broken","APT::Get::Fix-Broken",0},
712 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
713 {'m',"ignore-missing","APT::Get::Fix-Broken",0},
714 {'c',"config-file",0,CommandLine::ConfigFile
},
715 {'o',"option",0,CommandLine::ArbItem
},
718 // Parse the command line and initialize the package library
719 CommandLine
CmdL(Args
,_config
);
720 if (pkgInitialize(*_config
) == false ||
721 CmdL
.Parse(argc
,argv
) == false)
723 _error
->DumpErrors();
727 // See if the help should be shown
728 if (_config
->FindB("help") == true ||
729 CmdL
.FileSize() == 0)
732 // Setup the output streams
733 c0out
.rdbuf(cout
.rdbuf());
734 c1out
.rdbuf(cout
.rdbuf());
735 c2out
.rdbuf(cout
.rdbuf());
736 if (_config
->FindI("quiet",0) > 0)
737 c0out
.rdbuf(devnull
.rdbuf());
738 if (_config
->FindI("quiet",0) > 1)
739 c1out
.rdbuf(devnull
.rdbuf());
741 // Match the operation
745 bool (*Handler
)(CommandLine
&);
746 } Map
[] = {{"update",&DoUpdate
},
747 {"upgrade",&DoUpgrade
},
748 {"install",&DoInstall
},
749 {"dist-upgrade",&DoDistUpgrade
},
750 {"dselect-upgrade",&DoDSelectUpgrade
},
755 for (I
= 0; Map
[I
].Match
!= 0; I
++)
757 if (strcmp(CmdL
.FileList
[0],Map
[I
].Match
) == 0)
759 Map
[I
].Handler(CmdL
);
765 if (Map
[I
].Match
== 0)
766 _error
->Error("Invalid operation %s", CmdL
.FileList
[0]);
768 // Print any errors or warnings found during parsing
769 if (_error
->empty() == false)
771 bool Errors
= _error
->PendingError();
772 _error
->DumpErrors();
774 cout
<< "Returning 100." << endl
;
775 return Errors
== true?100:0;