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