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