]>
git.saurik.com Git - apt.git/blob - cmdline/apt-get.cc
f3dd4205a17a152e189e3d35baf5665c73dfec55
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-get.cc,v 1.1 1998/10/02 04:39:56 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() <<
121 // ShowNew - Show packages to newly install /*{{{*/
122 // ---------------------------------------------------------------------
124 void ShowNew(ostream
&out
,pkgDepCache
&Dep
)
126 /* Print out a list of packages that are going to be removed extra
127 to what the user asked */
128 pkgCache::PkgIterator I
= Dep
.PkgBegin();
130 for (;I
.end() != true; I
++)
131 if (Dep
[I
].NewInstall() == true)
132 List
+= string(I
.Name()) + " ";
133 ShowList(out
,"The following NEW packages will be installed:",List
);
136 // ShowDel - Show packages to delete /*{{{*/
137 // ---------------------------------------------------------------------
139 void ShowDel(ostream
&out
,pkgDepCache
&Dep
)
141 /* Print out a list of packages that are going to be removed extra
142 to what the user asked */
143 pkgCache::PkgIterator I
= Dep
.PkgBegin();
145 for (;I
.end() != true; I
++)
146 if (Dep
[I
].Delete() == true)
147 List
+= string(I
.Name()) + " ";
148 ShowList(out
,"The following packages will be REMOVED:",List
);
151 // ShowKept - Show kept packages /*{{{*/
152 // ---------------------------------------------------------------------
154 void ShowKept(ostream
&out
,pkgDepCache
&Dep
)
156 pkgCache::PkgIterator I
= Dep
.PkgBegin();
158 for (;I
.end() != true; I
++)
161 if (Dep
[I
].Upgrade() == true || Dep
[I
].Upgradable() == false ||
162 I
->CurrentVer
== 0 || Dep
[I
].Delete() == true)
165 List
+= string(I
.Name()) + " ";
167 ShowList(out
,"The following packages have been kept back",List
);
170 // ShowUpgraded - Show upgraded packages /*{{{*/
171 // ---------------------------------------------------------------------
173 void ShowUpgraded(ostream
&out
,pkgDepCache
&Dep
)
175 pkgCache::PkgIterator I
= Dep
.PkgBegin();
177 for (;I
.end() != true; I
++)
180 if (Dep
[I
].Upgrade() == false || Dep
[I
].NewInstall() == true)
183 List
+= string(I
.Name()) + " ";
185 ShowList(out
,"The following packages will be upgraded",List
);
188 // ShowHold - Show held but changed packages /*{{{*/
189 // ---------------------------------------------------------------------
191 void ShowHold(ostream
&out
,pkgDepCache
&Dep
)
193 pkgCache::PkgIterator I
= Dep
.PkgBegin();
195 for (;I
.end() != true; I
++)
197 if (Dep
[I
].InstallVer
!= (pkgCache::Version
*)I
.CurrentVer() &&
198 I
->SelectedState
== pkgCache::State::Hold
)
199 List
+= string(I
.Name()) + " ";
202 ShowList(out
,"The following held packages will be changed:",List
);
205 // ShowEssential - Show an essential package warning /*{{{*/
206 // ---------------------------------------------------------------------
207 /* This prints out a warning message that is not to be ignored. It shows
208 all essential packages and their dependents that are to be removed.
209 It is insanely risky to remove the dependents of an essential package! */
210 void ShowEssential(ostream
&out
,pkgDepCache
&Dep
)
212 pkgCache::PkgIterator I
= Dep
.PkgBegin();
214 bool *Added
= new bool[Dep
.HeaderP
->PackageCount
];
215 for (int I
= 0; I
!= Dep
.HeaderP
->PackageCount
; I
++)
218 for (;I
.end() != true; I
++)
220 if ((I
->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
223 // The essential package is being removed
224 if (Dep
[I
].Delete() == true)
226 if (Added
[I
->ID
] == false)
229 List
+= string(I
.Name()) + " ";
233 if (I
->CurrentVer
== 0)
236 // Print out any essential package depenendents that are to be removed
237 for (pkgDepCache::DepIterator D
= I
.CurrentVer().DependsList(); D
.end() == false; D
++)
239 pkgCache::PkgIterator P
= D
.SmartTargetPkg();
240 if (Dep
[P
].Delete() == true)
242 if (Added
[P
->ID
] == true)
245 List
+= string(P
.Name()) + " ";
250 if (List
.empty() == false)
251 out
<< "WARNING: The following essential packages will be removed" << endl
;
252 ShowList(out
,"This should NOT be done unless you know exactly what you are doing!",List
);
257 // Stats - Show some statistics /*{{{*/
258 // ---------------------------------------------------------------------
260 void Stats(ostream
&out
,pkgDepCache
&Dep
)
262 unsigned long Upgrade
= 0;
263 unsigned long Install
= 0;
264 for (pkgCache::PkgIterator I
= Dep
.PkgBegin(); I
.end() == false; I
++)
266 if (Dep
[I
].NewInstall() == true)
269 if (Dep
[I
].Upgrade() == true)
273 out
<< Upgrade
<< " packages upgraded, " <<
274 Install
<< " newly installed, " <<
275 Dep
.DelCount() << " to remove and " <<
276 Dep
.KeepCount() << " not upgraded." << endl
;
278 if (Dep
.BadCount() != 0)
279 out
<< Dep
.BadCount() << " packages not fully installed or removed." << endl
;
283 // class CacheFile - Cover class for some dependency cache functions /*{{{*/
284 // ---------------------------------------------------------------------
294 inline operator pkgDepCache
&() {return *Cache
;};
295 inline pkgDepCache
*operator ->() {return Cache
;};
296 inline pkgDepCache
&operator *() {return *Cache
;};
299 CacheFile() : File(0), Map(0), Cache(0) {};
308 // CacheFile::Open - Open the cache file /*{{{*/
309 // ---------------------------------------------------------------------
310 /* This routine generates the caches and then opens the dependency cache
311 and verifies that the system is OK. */
312 bool CacheFile::Open()
314 // Create a progress class
315 OpTextProgress
Progress(*_config
);
317 // Read the source list
319 if (List
.ReadMainList() == false)
320 return _error
->Error("The list of sources could not be read.");
322 // Build all of the caches
323 pkgMakeStatusCache(List
,Progress
);
324 if (_error
->PendingError() == true)
325 return _error
->Error("The package lists or status file could not be parsed or opened.");
329 // Open the cache file
330 File
= new FileFd(_config
->FindDir("Dir::Cache::pkgcache"),FileFd::ReadOnly
);
331 if (_error
->PendingError() == true)
334 Map
= new MMap(*File
,MMap::Public
| MMap::ReadOnly
);
335 if (_error
->PendingError() == true)
338 Cache
= new pkgDepCache(*Map
,Progress
);
339 if (_error
->PendingError() == true)
344 // Check that the system is OK
345 if (Cache
->DelCount() != 0 || Cache
->InstCount() != 0)
346 return _error
->Error("Internal Error, non-zero counts");
348 // Apply corrections for half-installed packages
349 if (pkgApplyStatus(*Cache
) == false)
353 if (Cache
->BrokenCount() == 0)
356 // Attempt to fix broken things
357 if (_config
->FindB("APT::Get::Fix-Broken",false) == true)
359 c1out
<< "Correcting dependencies..." << flush
;
360 if (pkgFixBroken(*Cache
) == false || Cache
->BrokenCount() != 0)
362 c1out
<< " failed." << endl
;
363 ShowBroken(c1out
,*this);
365 return _error
->Error("Unable to correct dependencies");
368 c1out
<< " Done" << endl
;
372 c1out
<< "You might want to run `apt-get -f install' to correct these." << endl
;
373 ShowBroken(c1out
,*this);
375 return _error
->Error("Unmet dependencies. Try using -f.");
382 // InstallPackages - Actually download and install the packages /*{{{*/
383 // ---------------------------------------------------------------------
384 /* This displays the informative messages describing what is going to
385 happen and then calls the download routines */
386 bool InstallPackages(pkgDepCache
&Cache
,bool ShwKept
)
388 ShowDel(c1out
,Cache
);
389 ShowNew(c1out
,Cache
);
391 ShowKept(c1out
,Cache
);
392 ShowHold(c1out
,Cache
);
393 if (_config
->FindB("APT::Get::Show-Upgraded",false) == true)
394 ShowUpgraded(c1out
,Cache
);
395 ShowEssential(c1out
,Cache
);
399 if (Cache
.BrokenCount() != 0)
401 ShowBroken(c1out
,Cache
);
402 return _error
->Error("Internal Error, InstallPackages was called with broken packages!");
405 if (Cache
.DelCount() == 0 && Cache
.InstCount() == 0 &&
406 Cache
.BadCount() == 0)
413 // DoUpdate - Update the package lists /*{{{*/
414 // ---------------------------------------------------------------------
416 bool DoUpdate(CommandLine
&CmdL
)
420 // DoUpgrade - Upgrade all packages /*{{{*/
421 // ---------------------------------------------------------------------
422 /* Upgrade all packages without installing new packages or erasing old
424 bool DoUpgrade(CommandLine
&CmdL
)
427 if (Cache
.Open() == false)
431 pkgProblemResolver
Resolve(Cache
);
432 if (pkgAllUpgrade(Cache
) == false)
434 ShowBroken(c1out
,Cache
);
435 return _error
->Error("Internal Error, AllUpgrade broke stuff");
438 return InstallPackages(Cache
,true);
441 // DoInstall - Install packages from the command line /*{{{*/
442 // ---------------------------------------------------------------------
443 /* Install named packages */
444 bool DoInstall(CommandLine
&CmdL
)
447 if (Cache
.Open() == false)
450 int ExpectedInst
= 0;
451 pkgProblemResolver
Fix(Cache
);
453 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
455 // Duplicate the string
456 unsigned int Length
= strlen(*I
);
458 if (Length
>= sizeof(S
))
462 // See if we are removing the package
464 if (S
[Length
- 1] == '-')
470 // Locate the package
471 pkgCache::PkgIterator Pkg
= Cache
->FindPkg(S
);
472 if (Pkg
.end() == true)
473 return _error
->Error("Couldn't find package %s",S
);
475 // Check if there is something new to install
476 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
477 if (State
.CandidateVer
== 0)
478 return _error
->Error("Package %s has no installation candidate",S
);
483 Cache
->MarkDelete(Pkg
);
488 Cache
->MarkInstall(Pkg
,false);
489 if (State
.Install() == false)
490 c1out
<< "Sorry, " << S
<< " is already the newest version" << endl
;
494 // Install it with autoinstalling enabled.
495 if (State
.InstBroken() == true)
496 Cache
->MarkInstall(Pkg
,true);
499 // Call the scored problem resolver
500 if (Fix
.Resolve(true) == false)
503 // Now we check the state of the packages,
504 if (Cache
->BrokenCount() != 0)
506 ShowBroken(c1out
,Cache
);
507 return _error
->Error("Sorry, broken packages");
510 /* Print out a list of packages that are going to be installed extra
511 to what the user asked */
512 if (Cache
->InstCount() != ExpectedInst
)
515 pkgCache::PkgIterator I
= Cache
->PkgBegin();
516 for (;I
.end() != true; I
++)
518 if ((*Cache
)[I
].Install() == false)
522 for (J
= CmdL
.FileList
+ 1; *J
!= 0; J
++)
523 if (strcmp(*J
,I
.Name()) == 0)
527 List
+= string(I
.Name()) + " ";
530 ShowList(c1out
,"The following extra packages will be installed:",List
);
533 return InstallPackages(Cache
,false);
536 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
537 // ---------------------------------------------------------------------
538 /* Intelligent upgrader that will install and remove packages at will */
539 bool DoDistUpgrade(CommandLine
&CmdL
)
542 if (Cache
.Open() == false)
545 c0out
<< "Calculating Upgrade... " << flush
;
546 if (pkgDistUpgrade(*Cache
) == false)
548 c0out
<< "Failed" << endl
;
549 ShowBroken(c1out
,Cache
);
553 c0out
<< "Done" << endl
;
555 return InstallPackages(Cache
,true);
558 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
559 // ---------------------------------------------------------------------
560 /* Follows dselect's selections */
561 bool DoDSelectUpgrade(CommandLine
&CmdL
)
564 if (Cache
.Open() == false)
567 // Install everything with the install flag set
568 pkgCache::PkgIterator I
= Cache
->PkgBegin();
569 for (;I
.end() != true; I
++)
571 /* Install the package only if it is a new install, the autoupgrader
572 will deal with the rest */
573 if (I
->SelectedState
== pkgCache::State::Install
)
574 Cache
->MarkInstall(I
,false);
577 /* Now install their deps too, if we do this above then order of
578 the status file is significant for | groups */
579 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
581 /* Install the package only if it is a new install, the autoupgrader
582 will deal with the rest */
583 if (I
->SelectedState
== pkgCache::State::Install
)
584 Cache
->MarkInstall(I
);
587 // Apply erasures now, they override everything else.
588 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
591 if (I
->SelectedState
== pkgCache::State::DeInstall
||
592 I
->SelectedState
== pkgCache::State::Purge
)
593 Cache
->MarkDelete(I
);
596 /* Use updates smart upgrade to do the rest, it will automatically
598 if (pkgAllUpgrade(Cache
) == false)
600 ShowBroken(c1out
,Cache
);
601 return _error
->Error("Internal Error, AllUpgrade broke stuff");
604 return InstallPackages(Cache
,false);
607 // DoClean - Remove download archives /*{{{*/
608 // ---------------------------------------------------------------------
610 bool DoClean(CommandLine
&CmdL
)
615 // DoCheck - Perform the check operation /*{{{*/
616 // ---------------------------------------------------------------------
617 /* Opening automatically checks the system, this command is mostly used
619 bool DoCheck(CommandLine
&CmdL
)
628 // ShowHelp - Show a help screen /*{{{*/
629 // ---------------------------------------------------------------------
633 cout
<< PACKAGE
<< ' ' << VERSION
<< " for " << ARCHITECTURE
<<
634 " compiled on " << __DATE__
<< " " << __TIME__
<< endl
;
636 cout
<< "Usage: apt-get [options] command" << endl
;
637 cout
<< " apt-get [options] install pkg1 [pkg2 ...]" << endl
;
639 cout
<< "apt-get is a simple command line interface for downloading and" << endl
;
640 cout
<< "installing packages. The most frequently used commands are update" << endl
;
641 cout
<< "and install." << endl
;
643 cout
<< "Commands:" << endl
;
644 cout
<< " update - Retrieve new lists of packages" << endl
;
645 cout
<< " upgrade - Perform an upgrade" << endl
;
646 cout
<< " install - Install new packages (pkg is libc6 not libc6.deb)" << endl
;
647 cout
<< " dist-upgrade - Distribution upgrade, see apt-get(8)" << endl
;
648 cout
<< " dselect-upgrade - Follow dselect selections" << endl
;
649 cout
<< " clean - Erase downloaded archive files" << endl
;
650 cout
<< " check - Verify that there are no broken dependencies" << endl
;
652 cout
<< "Options:" << endl
;
653 cout
<< " -h This help text." << endl
;
654 cout
<< " -q Loggable output - no progress indicator" << endl
;
655 cout
<< " -qq No output except for errors" << endl
;
656 cout
<< " -d Download only - do NOT install or unpack archives" << endl
;
657 cout
<< " -s No-act. Perform ordering simulation" << endl
;
658 cout
<< " -y Assume Yes to all queries and do not prompt" << endl
;
659 cout
<< " -f Attempt to continue if the integrity check fails" << endl
;
660 cout
<< " -m Attempt to continue if archives are unlocatable" << endl
;
661 cout
<< " -u Show a list of upgraded packages as well" << endl
;
662 cout
<< " -c=? Read this configuration file" << endl
;
663 cout
<< " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl
;
664 cout
<< "See the apt-get(8), sources.list(8) and apt.conf(8) manual" << endl
;
665 cout
<< "pages for more information." << endl
;
669 // GetInitialize - Initialize things for apt-get /*{{{*/
670 // ---------------------------------------------------------------------
674 _config
->Set("quiet",0);
675 _config
->Set("help",false);
676 _config
->Set("APT::Get::Download-Only",false);
677 _config
->Set("APT::Get::Simulate",false);
678 _config
->Set("APT::Get::Assume-Yes",false);
679 _config
->Set("APT::Get::Fix-Broken",false);
683 int main(int argc
,const char *argv
[])
685 CommandLine::Args Args
[] = {
686 {'h',"help","help",0},
687 {'q',"quiet","quiet",CommandLine::IntLevel
},
688 {'q',"silent","quiet",CommandLine::IntLevel
},
689 {'d',"download-only","APT::Get::Download-Only",0},
690 {'s',"simulate","APT::Get::Simulate",0},
691 {'s',"just-print","APT::Get::Simulate",0},
692 {'s',"recon","APT::Get::Simulate",0},
693 {'s',"no-act","APT::Get::Simulate",0},
694 {'y',"yes","APT::Get::Assume-Yes",0},
695 {'y',"assume-yes","APT::Get::Assume-Yes",0},
696 {'f',"fix-broken","APT::Get::Fix-Broken",0},
697 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
698 {'m',"ignore-missing","APT::Get::Fix-Broken",0},
699 {'c',"config-file",0,CommandLine::ConfigFile
},
700 {'o',"option",0,CommandLine::ArbItem
},
703 // Parse the command line and initialize the package library
704 CommandLine
CmdL(Args
,_config
);
705 if (pkgInitialize(*_config
) == false ||
706 CmdL
.Parse(argc
,argv
) == false)
708 _error
->DumpErrors();
712 // See if the help should be shown
713 if (_config
->FindB("help") == true ||
714 CmdL
.FileSize() == 0)
717 // Setup the output streams
718 c0out
.rdbuf(cout
.rdbuf());
719 c1out
.rdbuf(cout
.rdbuf());
720 c2out
.rdbuf(cout
.rdbuf());
721 if (_config
->FindI("quiet",0) > 0)
722 c0out
.rdbuf(devnull
.rdbuf());
723 if (_config
->FindI("quiet",0) > 1)
724 c1out
.rdbuf(devnull
.rdbuf());
726 // Match the operation
730 bool (*Handler
)(CommandLine
&);
731 } Map
[] = {{"update",&DoUpdate
},
732 {"upgrade",&DoUpgrade
},
733 {"install",&DoInstall
},
734 {"dist-upgrade",&DoDistUpgrade
},
735 {"dselect-upgrade",&DoDSelectUpgrade
},
740 for (I
= 0; Map
[I
].Match
!= 0; I
++)
742 if (strcmp(CmdL
.FileList
[0],Map
[I
].Match
) == 0)
744 Map
[I
].Handler(CmdL
);
750 if (Map
[I
].Match
== 0)
751 _error
->Error("Invalid operation %s", CmdL
.FileList
[0]);
753 // Print any errors or warnings found during parsing
754 if (_error
->empty() == false)
756 bool Errors
= _error
->PendingError();
757 _error
->DumpErrors();
759 cout
<< "Returning 100." << endl
;
760 return Errors
== true?100:0;