Fixed up the docs a bit
[ntk/apt.git] / cmdline / apt-get.cc
CommitLineData
0a8e3465
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
c217f42a 3// $Id: apt-get.cc,v 1.17 1998/11/23 01:45:59 jgg Exp $
0a8e3465
AL
4/* ######################################################################
5
6 apt-get - Cover for dpkg
7
8 This is an allout cover for dpkg implementing a safer front end. It is
9 based largely on libapt-pkg.
10
11 The syntax is different,
12 apt-get [opt] command [things]
13 Where command is:
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
19 a new distribution.
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
23 the partial dir too
24
25 ##################################################################### */
26 /*}}}*/
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>
0919e3f9 35#include <apt-pkg/acquire-item.h>
03e39e59 36#include <apt-pkg/dpkgpm.h>
a6568219 37#include <strutl.h>
0a8e3465
AL
38
39#include <config.h>
40
0919e3f9
AL
41#include "acqprogress.h"
42
0a8e3465 43#include <fstream.h>
d7827aca
AL
44#include <termios.h>
45#include <sys/ioctl.h>
46#include <signal.h>
3e3221ba 47#include <stdio.h>
0a8e3465
AL
48 /*}}}*/
49
50ostream c0out;
51ostream c1out;
52ostream c2out;
53ofstream devnull("/dev/null");
54unsigned int ScreenWidth = 80;
55
a6568219
AL
56// YnPrompt - Yes No Prompt. /*{{{*/
57// ---------------------------------------------------------------------
58/* Returns true on a Yes.*/
59bool YnPrompt()
60{
61 if (_config->FindB("APT::Get::Assume-Yes",false) == true)
62 {
63 c2out << 'Y' << endl;
64 return true;
65 }
66
67 char C = 0;
68 char Jnk = 0;
69 read(STDIN_FILENO,&C,1);
70 while (C != '\n' && Jnk != '\n') read(STDIN_FILENO,&Jnk,1);
71
72 if (!(C == 'Y' || C == 'y' || C == '\n' || C == '\r'))
73 return false;
74 return true;
75}
76 /*}}}*/
0a8e3465
AL
77// ShowList - Show a list /*{{{*/
78// ---------------------------------------------------------------------
79/* This prints out a string of space seperated words with a title and
80 a two space indent line wraped to the current screen width. */
81void ShowList(ostream &out,string Title,string List)
82{
83 if (List.empty() == true)
84 return;
85
86 // Acount for the leading space
87 int ScreenWidth = ::ScreenWidth - 3;
88
89 out << Title << endl;
90 string::size_type Start = 0;
91 while (Start < List.size())
92 {
93 string::size_type End;
94 if (Start + ScreenWidth >= List.size())
95 End = List.size();
96 else
97 End = List.rfind(' ',Start+ScreenWidth);
98
99 if (End == string::npos || End < Start)
100 End = Start + ScreenWidth;
101 out << " " << string(List,Start,End - Start) << endl;
102 Start = End + 1;
103 }
104}
105 /*}}}*/
106// ShowBroken - Debugging aide /*{{{*/
107// ---------------------------------------------------------------------
108/* This prints out the names of all the packages that are broken along
109 with the name of each each broken dependency and a quite version
110 description. */
111void ShowBroken(ostream &out,pkgDepCache &Cache)
112{
30e1eab5 113 out << "Sorry, but the following packages have unmet dependencies:" << endl;
0a8e3465
AL
114 pkgCache::PkgIterator I = Cache.PkgBegin();
115 for (;I.end() != true; I++)
116 {
303a1703
AL
117 if (Cache[I].InstBroken() == false)
118 continue;
119
120 // Print out each package and the failed dependencies
121 out <<" " << I.Name() << ":";
122 int Indent = strlen(I.Name()) + 3;
123 bool First = true;
124 if (Cache[I].InstVerIter(Cache).end() == true)
0a8e3465 125 {
303a1703
AL
126 cout << endl;
127 continue;
128 }
129
30e1eab5 130 for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false;)
303a1703 131 {
30e1eab5
AL
132 // Compute a single dependency element (glob or)
133 pkgCache::DepIterator Start;
134 pkgCache::DepIterator End;
135 D.GlobOr(Start,End);
136
137 if (Cache.IsImportantDep(End) == false ||
138 (Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
303a1703
AL
139 continue;
140
141 if (First == false)
142 for (int J = 0; J != Indent; J++)
143 out << ' ';
144 First = false;
cc718e9a 145
30e1eab5 146 cout << ' ' << End.DepType() << ": " << End.TargetPkg().Name();
303a1703
AL
147
148 // Show a quick summary of the version requirements
30e1eab5
AL
149 if (End.TargetVer() != 0)
150 out << " (" << End.CompType() << " " << End.TargetVer() <<
303a1703
AL
151 ")";
152
153 /* Show a summary of the target package if possible. In the case
154 of virtual packages we show nothing */
155
30e1eab5 156 pkgCache::PkgIterator Targ = End.TargetPkg();
303a1703 157 if (Targ->ProvidesList == 0)
0a8e3465 158 {
303a1703
AL
159 out << " but ";
160 pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
161 if (Ver.end() == false)
162 out << Ver.VerStr() << " is installed";
0a8e3465 163 else
7e798dd7 164 {
303a1703
AL
165 if (Cache[Targ].CandidateVerIter(Cache).end() == true)
166 {
167 if (Targ->ProvidesList == 0)
168 out << "it is not installable";
169 else
170 out << "it is a virtual package";
171 }
7e798dd7
AL
172 else
173 out << "it is not installed";
303a1703
AL
174 }
175 }
176
177 out << endl;
178 }
0a8e3465
AL
179 }
180}
181 /*}}}*/
182// ShowNew - Show packages to newly install /*{{{*/
183// ---------------------------------------------------------------------
184/* */
185void ShowNew(ostream &out,pkgDepCache &Dep)
186{
187 /* Print out a list of packages that are going to be removed extra
188 to what the user asked */
189 pkgCache::PkgIterator I = Dep.PkgBegin();
190 string List;
191 for (;I.end() != true; I++)
192 if (Dep[I].NewInstall() == true)
193 List += string(I.Name()) + " ";
194 ShowList(out,"The following NEW packages will be installed:",List);
195}
196 /*}}}*/
197// ShowDel - Show packages to delete /*{{{*/
198// ---------------------------------------------------------------------
199/* */
200void ShowDel(ostream &out,pkgDepCache &Dep)
201{
202 /* Print out a list of packages that are going to be removed extra
203 to what the user asked */
204 pkgCache::PkgIterator I = Dep.PkgBegin();
205 string List;
206 for (;I.end() != true; I++)
207 if (Dep[I].Delete() == true)
208 List += string(I.Name()) + " ";
209 ShowList(out,"The following packages will be REMOVED:",List);
210}
211 /*}}}*/
212// ShowKept - Show kept packages /*{{{*/
213// ---------------------------------------------------------------------
214/* */
215void ShowKept(ostream &out,pkgDepCache &Dep)
216{
217 pkgCache::PkgIterator I = Dep.PkgBegin();
218 string List;
219 for (;I.end() != true; I++)
220 {
221 // Not interesting
222 if (Dep[I].Upgrade() == true || Dep[I].Upgradable() == false ||
223 I->CurrentVer == 0 || Dep[I].Delete() == true)
224 continue;
225
226 List += string(I.Name()) + " ";
227 }
228 ShowList(out,"The following packages have been kept back",List);
229}
230 /*}}}*/
231// ShowUpgraded - Show upgraded packages /*{{{*/
232// ---------------------------------------------------------------------
233/* */
234void ShowUpgraded(ostream &out,pkgDepCache &Dep)
235{
236 pkgCache::PkgIterator I = Dep.PkgBegin();
237 string List;
238 for (;I.end() != true; I++)
239 {
240 // Not interesting
241 if (Dep[I].Upgrade() == false || Dep[I].NewInstall() == true)
242 continue;
243
244 List += string(I.Name()) + " ";
245 }
246 ShowList(out,"The following packages will be upgraded",List);
247}
248 /*}}}*/
249// ShowHold - Show held but changed packages /*{{{*/
250// ---------------------------------------------------------------------
251/* */
252void ShowHold(ostream &out,pkgDepCache &Dep)
253{
254 pkgCache::PkgIterator I = Dep.PkgBegin();
255 string List;
256 for (;I.end() != true; I++)
257 {
258 if (Dep[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
259 I->SelectedState == pkgCache::State::Hold)
260 List += string(I.Name()) + " ";
261 }
262
263 ShowList(out,"The following held packages will be changed:",List);
264}
265 /*}}}*/
266// ShowEssential - Show an essential package warning /*{{{*/
267// ---------------------------------------------------------------------
268/* This prints out a warning message that is not to be ignored. It shows
269 all essential packages and their dependents that are to be removed.
270 It is insanely risky to remove the dependents of an essential package! */
271void ShowEssential(ostream &out,pkgDepCache &Dep)
272{
273 pkgCache::PkgIterator I = Dep.PkgBegin();
274 string List;
275 bool *Added = new bool[Dep.HeaderP->PackageCount];
93641593 276 for (unsigned int I = 0; I != Dep.HeaderP->PackageCount; I++)
0a8e3465
AL
277 Added[I] = false;
278
279 for (;I.end() != true; I++)
280 {
281 if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential)
282 continue;
283
284 // The essential package is being removed
285 if (Dep[I].Delete() == true)
286 {
287 if (Added[I->ID] == false)
288 {
289 Added[I->ID] = true;
290 List += string(I.Name()) + " ";
291 }
292 }
293
294 if (I->CurrentVer == 0)
295 continue;
296
297 // Print out any essential package depenendents that are to be removed
298 for (pkgDepCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; D++)
299 {
3e3221ba
AL
300 // Skip everything but depends
301 if (D->Type != pkgCache::Dep::PreDepends &&
302 D->Type != pkgCache::Dep::Depends)
303 continue;
304
0a8e3465
AL
305 pkgCache::PkgIterator P = D.SmartTargetPkg();
306 if (Dep[P].Delete() == true)
307 {
308 if (Added[P->ID] == true)
309 continue;
310 Added[P->ID] = true;
3e3221ba
AL
311
312 char S[300];
313 sprintf(S,"%s (due to %s) ",P.Name(),I.Name());
314 List += S;
0a8e3465
AL
315 }
316 }
317 }
318
319 if (List.empty() == false)
320 out << "WARNING: The following essential packages will be removed" << endl;
321 ShowList(out,"This should NOT be done unless you know exactly what you are doing!",List);
322
323 delete [] Added;
324}
325 /*}}}*/
326// Stats - Show some statistics /*{{{*/
327// ---------------------------------------------------------------------
328/* */
329void Stats(ostream &out,pkgDepCache &Dep)
330{
331 unsigned long Upgrade = 0;
332 unsigned long Install = 0;
333 for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++)
334 {
335 if (Dep[I].NewInstall() == true)
336 Install++;
337 else
338 if (Dep[I].Upgrade() == true)
339 Upgrade++;
340 }
341
342 out << Upgrade << " packages upgraded, " <<
343 Install << " newly installed, " <<
344 Dep.DelCount() << " to remove and " <<
345 Dep.KeepCount() << " not upgraded." << endl;
346
347 if (Dep.BadCount() != 0)
348 out << Dep.BadCount() << " packages not fully installed or removed." << endl;
349}
350 /*}}}*/
351
352// class CacheFile - Cover class for some dependency cache functions /*{{{*/
353// ---------------------------------------------------------------------
354/* */
355class CacheFile
356{
357 public:
358
359 FileFd *File;
360 MMap *Map;
361 pkgDepCache *Cache;
362
363 inline operator pkgDepCache &() {return *Cache;};
364 inline pkgDepCache *operator ->() {return Cache;};
365 inline pkgDepCache &operator *() {return *Cache;};
366
367 bool Open();
368 CacheFile() : File(0), Map(0), Cache(0) {};
369 ~CacheFile()
370 {
371 delete Cache;
372 delete Map;
373 delete File;
374 }
375};
376 /*}}}*/
377// CacheFile::Open - Open the cache file /*{{{*/
378// ---------------------------------------------------------------------
379/* This routine generates the caches and then opens the dependency cache
380 and verifies that the system is OK. */
381bool CacheFile::Open()
382{
383 // Create a progress class
384 OpTextProgress Progress(*_config);
385
386 // Read the source list
387 pkgSourceList List;
388 if (List.ReadMainList() == false)
389 return _error->Error("The list of sources could not be read.");
390
391 // Build all of the caches
392 pkgMakeStatusCache(List,Progress);
393 if (_error->PendingError() == true)
394 return _error->Error("The package lists or status file could not be parsed or opened.");
395
396 Progress.Done();
397
398 // Open the cache file
303a1703 399 File = new FileFd(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly);
0a8e3465
AL
400 if (_error->PendingError() == true)
401 return false;
402
403 Map = new MMap(*File,MMap::Public | MMap::ReadOnly);
404 if (_error->PendingError() == true)
405 return false;
406
407 Cache = new pkgDepCache(*Map,Progress);
408 if (_error->PendingError() == true)
409 return false;
410
411 Progress.Done();
412
413 // Check that the system is OK
414 if (Cache->DelCount() != 0 || Cache->InstCount() != 0)
415 return _error->Error("Internal Error, non-zero counts");
416
417 // Apply corrections for half-installed packages
418 if (pkgApplyStatus(*Cache) == false)
419 return false;
420
421 // Nothing is broken
422 if (Cache->BrokenCount() == 0)
423 return true;
424
425 // Attempt to fix broken things
426 if (_config->FindB("APT::Get::Fix-Broken",false) == true)
427 {
428 c1out << "Correcting dependencies..." << flush;
429 if (pkgFixBroken(*Cache) == false || Cache->BrokenCount() != 0)
430 {
431 c1out << " failed." << endl;
432 ShowBroken(c1out,*this);
433
434 return _error->Error("Unable to correct dependencies");
435 }
7e798dd7
AL
436 if (pkgMinimizeUpgrade(*Cache) == false)
437 return _error->Error("Unable to minimize the upgrade set");
0a8e3465
AL
438
439 c1out << " Done" << endl;
440 }
441 else
442 {
443 c1out << "You might want to run `apt-get -f install' to correct these." << endl;
444 ShowBroken(c1out,*this);
445
446 return _error->Error("Unmet dependencies. Try using -f.");
447 }
448
449 return true;
450}
451 /*}}}*/
452
453// InstallPackages - Actually download and install the packages /*{{{*/
454// ---------------------------------------------------------------------
455/* This displays the informative messages describing what is going to
456 happen and then calls the download routines */
03e39e59 457bool InstallPackages(pkgDepCache &Cache,bool ShwKept,bool Ask = true)
0a8e3465 458{
a6568219 459 // Show all the various warning indicators
0a8e3465
AL
460 ShowDel(c1out,Cache);
461 ShowNew(c1out,Cache);
462 if (ShwKept == true)
463 ShowKept(c1out,Cache);
464 ShowHold(c1out,Cache);
465 if (_config->FindB("APT::Get::Show-Upgraded",false) == true)
466 ShowUpgraded(c1out,Cache);
467 ShowEssential(c1out,Cache);
468 Stats(c1out,Cache);
469
470 // Sanity check
471 if (Cache.BrokenCount() != 0)
472 {
473 ShowBroken(c1out,Cache);
474 return _error->Error("Internal Error, InstallPackages was called with broken packages!");
475 }
476
477 if (Cache.DelCount() == 0 && Cache.InstCount() == 0 &&
478 Cache.BadCount() == 0)
479 return true;
03e39e59
AL
480
481 // Run the simulator ..
482 if (_config->FindB("APT::Get::Simulate") == true)
483 {
484 pkgSimulate PM(Cache);
485 return PM.DoInstall();
486 }
487
488 // Create the text record parser
489 pkgRecords Recs(Cache);
490
491 // Create the download object
492 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
493 pkgAcquire Fetcher(&Stat);
494
495 // Read the source list
496 pkgSourceList List;
497 if (List.ReadMainList() == false)
498 return _error->Error("The list of sources could not be read.");
499
500 // Create the package manager and prepare to download
30e1eab5 501 pkgDPkgPM PM(Cache);
03e39e59
AL
502 if (PM.GetArchives(&Fetcher,&List,&Recs) == false)
503 return false;
504
7a1b1f8b 505 // Display statistics
a6568219
AL
506 unsigned long FetchBytes = Fetcher.FetchNeeded();
507 unsigned long DebBytes = Fetcher.TotalNeeded();
508 if (DebBytes != Cache.DebSize())
509 c0out << "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl;
510
7a1b1f8b 511 // Number of bytes
a6568219
AL
512 c1out << "Need to get ";
513 if (DebBytes != FetchBytes)
514 c1out << SizeToStr(FetchBytes) << '/' << SizeToStr(DebBytes);
515 else
516 c1out << SizeToStr(DebBytes);
517
518 c1out << " of archives. After unpacking ";
519
7a1b1f8b 520 // Size delta
a6568219
AL
521 if (Cache.UsrSize() >= 0)
522 c1out << SizeToStr(Cache.UsrSize()) << " will be used." << endl;
523 else
524 c1out << SizeToStr(-1*Cache.UsrSize()) << " will be freed." << endl;
525
526 if (_error->PendingError() == true)
527 return false;
528
7a1b1f8b 529 // Prompt to continue
a6568219 530 if (Ask == true)
e331f6ed 531 {
a6568219
AL
532 if (_config->FindI("quiet",0) < 2 ||
533 _config->FindB("APT::Get::Assume-Yes",false) == false)
534 c2out << "Do you want to continue? [Y/n] " << flush;
535 if (YnPrompt() == false)
536 exit(1);
537 }
538
03e39e59
AL
539 // Run it
540 if (Fetcher.Run() == false)
541 return false;
30e1eab5
AL
542
543 // Print out errors
544 bool Failed = false;
545 for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
546 {
547 if ((*I)->Status == pkgAcquire::Item::StatDone &&
548 (*I)->Complete == true)
549 continue;
550
551 cerr << "Failed to fetch " << (*I)->Describe() << endl;
552 cerr << " " << (*I)->ErrorText << endl;
553 Failed = true;
554 }
03e39e59 555
30e1eab5
AL
556 if (Failed == true && _config->FindB("APT::Fix-Missing",false) == false)
557 return _error->Error("Unable to fetch some archives, maybe try with --fix-missing?");
558
559 // Try to deal with missing package files
560/* if (PM.FixMissing() == false)
561 {
562 cerr << "Unable to correct missing packages." << endl;
563 return _error->Error("Aborting Install.");
564 }*/
565
566 return PM.DoInstall();
0a8e3465
AL
567}
568 /*}}}*/
569
570// DoUpdate - Update the package lists /*{{{*/
571// ---------------------------------------------------------------------
572/* */
0919e3f9 573bool DoUpdate(CommandLine &)
0a8e3465 574{
0919e3f9
AL
575 // Get the source list
576 pkgSourceList List;
577 if (List.ReadMainList() == false)
578 return false;
579
580 // Create the download object
581 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
582 pkgAcquire Fetcher(&Stat);
583
584 // Populate it with the source selection
585 pkgSourceList::const_iterator I;
586 for (I = List.begin(); I != List.end(); I++)
587 {
588 new pkgAcqIndex(&Fetcher,I);
589 if (_error->PendingError() == true)
590 return false;
591 }
592
593 // Run it
594 if (Fetcher.Run() == false)
595 return false;
596
7a7fa5f0
AL
597 // Clean out any old list files
598 if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
599 Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
600 return false;
601
0919e3f9
AL
602 // Prepare the cache.
603 CacheFile Cache;
604 if (Cache.Open() == false)
605 return false;
606
607 return true;
0a8e3465
AL
608}
609 /*}}}*/
610// DoUpgrade - Upgrade all packages /*{{{*/
611// ---------------------------------------------------------------------
612/* Upgrade all packages without installing new packages or erasing old
613 packages */
614bool DoUpgrade(CommandLine &CmdL)
615{
616 CacheFile Cache;
617 if (Cache.Open() == false)
618 return false;
619
620 // Do the upgrade
0a8e3465
AL
621 if (pkgAllUpgrade(Cache) == false)
622 {
623 ShowBroken(c1out,Cache);
624 return _error->Error("Internal Error, AllUpgrade broke stuff");
625 }
626
627 return InstallPackages(Cache,true);
628}
629 /*}}}*/
630// DoInstall - Install packages from the command line /*{{{*/
631// ---------------------------------------------------------------------
632/* Install named packages */
633bool DoInstall(CommandLine &CmdL)
634{
635 CacheFile Cache;
636 if (Cache.Open() == false)
637 return false;
638
a6568219
AL
639 unsigned int ExpectedInst = 0;
640 unsigned int Packages = 0;
0a8e3465
AL
641 pkgProblemResolver Fix(Cache);
642
303a1703
AL
643 bool DefRemove = false;
644 if (strcasecmp(CmdL.FileList[0],"remove") == 0)
645 DefRemove = true;
646
0a8e3465
AL
647 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
648 {
649 // Duplicate the string
650 unsigned int Length = strlen(*I);
651 char S[300];
652 if (Length >= sizeof(S))
653 continue;
654 strcpy(S,*I);
655
656 // See if we are removing the package
303a1703 657 bool Remove = DefRemove;
2c3bc8bb 658 if (Cache->FindPkg(S).end() == true)
0a8e3465 659 {
2c3bc8bb
AL
660 // Handle an optional end tag indicating what to do
661 if (S[Length - 1] == '-')
662 {
663 Remove = true;
664 S[--Length] = 0;
665 }
666 if (S[Length - 1] == '+')
667 {
668 Remove = false;
669 S[--Length] = 0;
670 }
303a1703 671 }
0a8e3465
AL
672
673 // Locate the package
674 pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
303a1703 675 Packages++;
0a8e3465
AL
676 if (Pkg.end() == true)
677 return _error->Error("Couldn't find package %s",S);
678
2c3bc8bb
AL
679 // Handle the no-upgrade case
680 if (_config->FindB("APT::Get::no-upgrade",false) == true &&
681 Pkg->CurrentVer != 0)
682 {
683 c1out << "Skipping " << Pkg.Name() << ", it is already installed and no-upgrade is set." << endl;
684 continue;
685 }
686
0a8e3465
AL
687 // Check if there is something new to install
688 pkgDepCache::StateCache &State = (*Cache)[Pkg];
689 if (State.CandidateVer == 0)
303a1703
AL
690 {
691 if (Pkg->ProvidesList != 0)
692 {
693 c1out << "Package " << S << " is a virtual package provided by:" << endl;
694
695 pkgCache::PrvIterator I = Pkg.ProvidesList();
696 for (; I.end() == false; I++)
697 {
698 pkgCache::PkgIterator Pkg = I.OwnerPkg();
699
700 if ((*Cache)[Pkg].CandidateVerIter(*Cache) == I.OwnerVer())
701 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
702
703 if ((*Cache)[Pkg].InstVerIter(*Cache) == I.OwnerVer())
704 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
705 " [Installed]"<< endl;
706 }
707 c1out << "You should explicly select one to install." << endl;
708 }
709 else
710 {
711 c1out << "Package " << S << " has no available version, but exists in the database." << endl;
712 c1out << "This typically means that the package was mentioned in a dependency and " << endl;
713 c1out << "never uploaded, or that it is an obsolete package." << endl;
714 }
715
0a8e3465 716 return _error->Error("Package %s has no installation candidate",S);
303a1703 717 }
0a8e3465
AL
718
719 Fix.Protect(Pkg);
720 if (Remove == true)
721 {
303a1703 722 Fix.Remove(Pkg);
0a8e3465
AL
723 Cache->MarkDelete(Pkg);
724 continue;
725 }
726
727 // Install it
728 Cache->MarkInstall(Pkg,false);
729 if (State.Install() == false)
730 c1out << "Sorry, " << S << " is already the newest version" << endl;
731 else
732 ExpectedInst++;
733
734 // Install it with autoinstalling enabled.
735 if (State.InstBroken() == true)
736 Cache->MarkInstall(Pkg,true);
737 }
738
739 // Call the scored problem resolver
303a1703 740 Fix.InstallProtect();
0a8e3465
AL
741 if (Fix.Resolve(true) == false)
742 _error->Discard();
743
744 // Now we check the state of the packages,
745 if (Cache->BrokenCount() != 0)
746 {
303a1703
AL
747 c1out << "Some packages could not be installed. This may mean that you have" << endl;
748 c1out << "requested an impossible situation or if you are using the unstable" << endl;
749 c1out << "distribution that some required packages have not yet been created" << endl;
750 c1out << "or been moved out of Incoming." << endl;
751 if (Packages == 1)
752 {
753 c1out << endl;
754 c1out << "Since you only requested a single operation it is extremely likely that" << endl;
755 c1out << "the package is simply not installable and a bug report against" << endl;
756 c1out << "that package should be filed." << endl;
757 }
758
759 c1out << "The following information may help to resolve the situation:" << endl;
760 c1out << endl;
0a8e3465
AL
761 ShowBroken(c1out,Cache);
762 return _error->Error("Sorry, broken packages");
763 }
764
765 /* Print out a list of packages that are going to be installed extra
766 to what the user asked */
767 if (Cache->InstCount() != ExpectedInst)
768 {
769 string List;
770 pkgCache::PkgIterator I = Cache->PkgBegin();
771 for (;I.end() != true; I++)
772 {
773 if ((*Cache)[I].Install() == false)
774 continue;
775
776 const char **J;
777 for (J = CmdL.FileList + 1; *J != 0; J++)
778 if (strcmp(*J,I.Name()) == 0)
779 break;
780
781 if (*J == 0)
782 List += string(I.Name()) + " ";
783 }
784
785 ShowList(c1out,"The following extra packages will be installed:",List);
786 }
787
03e39e59 788 // See if we need to prompt
2c3bc8bb 789 if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
2c3bc8bb 790 return InstallPackages(Cache,false,false);
2c3bc8bb 791
03e39e59 792 return InstallPackages(Cache,false);
0a8e3465
AL
793}
794 /*}}}*/
795// DoDistUpgrade - Automatic smart upgrader /*{{{*/
796// ---------------------------------------------------------------------
797/* Intelligent upgrader that will install and remove packages at will */
798bool DoDistUpgrade(CommandLine &CmdL)
799{
800 CacheFile Cache;
801 if (Cache.Open() == false)
802 return false;
803
804 c0out << "Calculating Upgrade... " << flush;
805 if (pkgDistUpgrade(*Cache) == false)
806 {
807 c0out << "Failed" << endl;
808 ShowBroken(c1out,Cache);
809 return false;
810 }
811
812 c0out << "Done" << endl;
813
814 return InstallPackages(Cache,true);
815}
816 /*}}}*/
817// DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
818// ---------------------------------------------------------------------
819/* Follows dselect's selections */
820bool DoDSelectUpgrade(CommandLine &CmdL)
821{
822 CacheFile Cache;
823 if (Cache.Open() == false)
824 return false;
825
826 // Install everything with the install flag set
827 pkgCache::PkgIterator I = Cache->PkgBegin();
828 for (;I.end() != true; I++)
829 {
830 /* Install the package only if it is a new install, the autoupgrader
831 will deal with the rest */
832 if (I->SelectedState == pkgCache::State::Install)
833 Cache->MarkInstall(I,false);
834 }
835
836 /* Now install their deps too, if we do this above then order of
837 the status file is significant for | groups */
838 for (I = Cache->PkgBegin();I.end() != true; I++)
839 {
840 /* Install the package only if it is a new install, the autoupgrader
841 will deal with the rest */
842 if (I->SelectedState == pkgCache::State::Install)
843 Cache->MarkInstall(I);
844 }
845
846 // Apply erasures now, they override everything else.
847 for (I = Cache->PkgBegin();I.end() != true; I++)
848 {
849 // Remove packages
850 if (I->SelectedState == pkgCache::State::DeInstall ||
851 I->SelectedState == pkgCache::State::Purge)
852 Cache->MarkDelete(I);
853 }
854
855 /* Use updates smart upgrade to do the rest, it will automatically
856 ignore held items */
857 if (pkgAllUpgrade(Cache) == false)
858 {
859 ShowBroken(c1out,Cache);
860 return _error->Error("Internal Error, AllUpgrade broke stuff");
861 }
862
863 return InstallPackages(Cache,false);
864}
865 /*}}}*/
866// DoClean - Remove download archives /*{{{*/
867// ---------------------------------------------------------------------
868/* */
869bool DoClean(CommandLine &CmdL)
870{
7a1b1f8b
AL
871 pkgAcquire Fetcher;
872 Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
873 Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
0a8e3465
AL
874 return true;
875}
876 /*}}}*/
877// DoCheck - Perform the check operation /*{{{*/
878// ---------------------------------------------------------------------
879/* Opening automatically checks the system, this command is mostly used
880 for debugging */
881bool DoCheck(CommandLine &CmdL)
882{
883 CacheFile Cache;
884 Cache.Open();
885
886 return true;
887}
888 /*}}}*/
889
890// ShowHelp - Show a help screen /*{{{*/
891// ---------------------------------------------------------------------
892/* */
893int ShowHelp()
894{
895 cout << PACKAGE << ' ' << VERSION << " for " << ARCHITECTURE <<
896 " compiled on " << __DATE__ << " " << __TIME__ << endl;
897
898 cout << "Usage: apt-get [options] command" << endl;
899 cout << " apt-get [options] install pkg1 [pkg2 ...]" << endl;
900 cout << endl;
901 cout << "apt-get is a simple command line interface for downloading and" << endl;
902 cout << "installing packages. The most frequently used commands are update" << endl;
903 cout << "and install." << endl;
904 cout << endl;
905 cout << "Commands:" << endl;
906 cout << " update - Retrieve new lists of packages" << endl;
907 cout << " upgrade - Perform an upgrade" << endl;
908 cout << " install - Install new packages (pkg is libc6 not libc6.deb)" << endl;
303a1703 909 cout << " remove - Remove packages" << endl;
0a8e3465
AL
910 cout << " dist-upgrade - Distribution upgrade, see apt-get(8)" << endl;
911 cout << " dselect-upgrade - Follow dselect selections" << endl;
912 cout << " clean - Erase downloaded archive files" << endl;
913 cout << " check - Verify that there are no broken dependencies" << endl;
914 cout << endl;
915 cout << "Options:" << endl;
c217f42a
AL
916 cout << " -h This help text." << endl;
917 cout << " -q Loggable output - no progress indicator" << endl;
0a8e3465
AL
918 cout << " -qq No output except for errors" << endl;
919 cout << " -d Download only - do NOT install or unpack archives" << endl;
920 cout << " -s No-act. Perform ordering simulation" << endl;
921 cout << " -y Assume Yes to all queries and do not prompt" << endl;
922 cout << " -f Attempt to continue if the integrity check fails" << endl;
923 cout << " -m Attempt to continue if archives are unlocatable" << endl;
924 cout << " -u Show a list of upgraded packages as well" << endl;
925 cout << " -c=? Read this configuration file" << endl;
926 cout << " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl;
927 cout << "See the apt-get(8), sources.list(8) and apt.conf(8) manual" << endl;
928 cout << "pages for more information." << endl;
929 return 100;
930}
931 /*}}}*/
932// GetInitialize - Initialize things for apt-get /*{{{*/
933// ---------------------------------------------------------------------
934/* */
935void GetInitialize()
936{
937 _config->Set("quiet",0);
938 _config->Set("help",false);
939 _config->Set("APT::Get::Download-Only",false);
940 _config->Set("APT::Get::Simulate",false);
941 _config->Set("APT::Get::Assume-Yes",false);
942 _config->Set("APT::Get::Fix-Broken",false);
943}
944 /*}}}*/
d7827aca
AL
945// SigWinch - Window size change signal handler /*{{{*/
946// ---------------------------------------------------------------------
947/* */
948void SigWinch(int)
949{
950 // Riped from GNU ls
951#ifdef TIOCGWINSZ
952 struct winsize ws;
953
954 if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
955 ScreenWidth = ws.ws_col - 1;
956#endif
957}
958 /*}}}*/
0a8e3465
AL
959
960int main(int argc,const char *argv[])
961{
962 CommandLine::Args Args[] = {
963 {'h',"help","help",0},
964 {'q',"quiet","quiet",CommandLine::IntLevel},
965 {'q',"silent","quiet",CommandLine::IntLevel},
966 {'d',"download-only","APT::Get::Download-Only",0},
967 {'s',"simulate","APT::Get::Simulate",0},
968 {'s',"just-print","APT::Get::Simulate",0},
969 {'s',"recon","APT::Get::Simulate",0},
970 {'s',"no-act","APT::Get::Simulate",0},
971 {'y',"yes","APT::Get::Assume-Yes",0},
972 {'y',"assume-yes","APT::Get::Assume-Yes",0},
973 {'f',"fix-broken","APT::Get::Fix-Broken",0},
974 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
30e1eab5
AL
975 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
976 {0,"fix-missing","APT::Get::Fix-Missing",0},
c88edf1d 977 {0,"ignore-hold","APT::Ingore-Hold",0},
2c3bc8bb 978 {0,"no-upgrade","APT::Get::no-upgrade",0},
0a8e3465
AL
979 {'c',"config-file",0,CommandLine::ConfigFile},
980 {'o',"option",0,CommandLine::ArbItem},
981 {0,0,0,0}};
982
983 // Parse the command line and initialize the package library
984 CommandLine CmdL(Args,_config);
985 if (pkgInitialize(*_config) == false ||
986 CmdL.Parse(argc,argv) == false)
987 {
988 _error->DumpErrors();
989 return 100;
990 }
991
992 // See if the help should be shown
993 if (_config->FindB("help") == true ||
994 CmdL.FileSize() == 0)
995 return ShowHelp();
996
997 // Setup the output streams
998 c0out.rdbuf(cout.rdbuf());
999 c1out.rdbuf(cout.rdbuf());
1000 c2out.rdbuf(cout.rdbuf());
1001 if (_config->FindI("quiet",0) > 0)
1002 c0out.rdbuf(devnull.rdbuf());
1003 if (_config->FindI("quiet",0) > 1)
1004 c1out.rdbuf(devnull.rdbuf());
d7827aca
AL
1005
1006 // Setup the signals
1007 signal(SIGPIPE,SIG_IGN);
1008 signal(SIGWINCH,SigWinch);
1009 SigWinch(0);
0a8e3465
AL
1010
1011 // Match the operation
1012 struct
1013 {
1014 const char *Match;
1015 bool (*Handler)(CommandLine &);
1016 } Map[] = {{"update",&DoUpdate},
1017 {"upgrade",&DoUpgrade},
1018 {"install",&DoInstall},
303a1703 1019 {"remove",&DoInstall},
0a8e3465
AL
1020 {"dist-upgrade",&DoDistUpgrade},
1021 {"dselect-upgrade",&DoDSelectUpgrade},
1022 {"clean",&DoClean},
1023 {"check",&DoCheck},
1024 {0,0}};
1025 int I;
1026 for (I = 0; Map[I].Match != 0; I++)
1027 {
1028 if (strcmp(CmdL.FileList[0],Map[I].Match) == 0)
1029 {
0919e3f9
AL
1030 if (Map[I].Handler(CmdL) == false && _error->PendingError() == false)
1031 _error->Error("Handler silently failed");
0a8e3465
AL
1032 break;
1033 }
1034 }
1035
1036 // No matching name
1037 if (Map[I].Match == 0)
1038 _error->Error("Invalid operation %s", CmdL.FileList[0]);
1039
1040 // Print any errors or warnings found during parsing
1041 if (_error->empty() == false)
1042 {
1043 bool Errors = _error->PendingError();
1044 _error->DumpErrors();
1045 if (Errors == true)
1046 cout << "Returning 100." << endl;
1047 return Errors == true?100:0;
1048 }
1049
1050 return 0;
1051}