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