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