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