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