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