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