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