]> git.saurik.com Git - apt.git/blob - cmdline/apt-get.cc
31dfe97c16d7018f300e128c9a4523dd6b9624fc
[apt.git] / cmdline / apt-get.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: apt-get.cc,v 1.21 1998/12/05 02:56:45 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 <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 c2out << '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 ShowList(out,"The following packages will be REMOVED:",List);
212 }
213 /*}}}*/
214 // ShowKept - Show kept packages /*{{{*/
215 // ---------------------------------------------------------------------
216 /* */
217 void 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 /* */
236 void 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 /* */
254 bool ShowHold(ostream &out,pkgDepCache &Dep)
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
265 return ShowList(out,"The following held packages will be changed:",List);
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! */
273 bool ShowEssential(ostream &out,pkgDepCache &Dep)
274 {
275 pkgCache::PkgIterator I = Dep.PkgBegin();
276 string List;
277 bool *Added = new bool[Dep.HeaderP->PackageCount];
278 for (unsigned int I = 0; I != Dep.HeaderP->PackageCount; I++)
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 {
302 // Skip everything but depends
303 if (D->Type != pkgCache::Dep::PreDepends &&
304 D->Type != pkgCache::Dep::Depends)
305 continue;
306
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;
313
314 char S[300];
315 sprintf(S,"%s (due to %s) ",P.Name(),I.Name());
316 List += S;
317 }
318 }
319 }
320
321 delete [] Added;
322 if (List.empty() == false)
323 out << "WARNING: The following essential packages will be removed" << endl;
324 return ShowList(out,"This should NOT be done unless you know exactly what you are doing!",List);
325 }
326 /*}}}*/
327 // Stats - Show some statistics /*{{{*/
328 // ---------------------------------------------------------------------
329 /* */
330 void 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 /* */
356 class CacheFile
357 {
358 public:
359
360 FileFd *File;
361 MMap *Map;
362 pkgDepCache *Cache;
363 pkgDpkgLock Lock;
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. */
383 bool CacheFile::Open()
384 {
385 if (_error->PendingError() == true)
386 return false;
387
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
404 File = new FileFd(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly);
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 }
441 if (pkgMinimizeUpgrade(*Cache) == false)
442 return _error->Error("Unable to minimize the upgrade set");
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 */
462 bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true)
463 {
464 bool Fail = false;
465
466 // Show all the various warning indicators
467 ShowDel(c1out,Cache);
468 ShowNew(c1out,Cache);
469 if (ShwKept == true)
470 ShowKept(c1out,Cache);
471 Fail |= ShowHold(c1out,Cache);
472 if (_config->FindB("APT::Get::Show-Upgraded",false) == true)
473 ShowUpgraded(c1out,Cache);
474 Fail |= ShowEssential(c1out,Cache);
475 Stats(c1out,Cache);
476
477 // Sanity check
478 if (Cache->BrokenCount() != 0)
479 {
480 ShowBroken(c1out,Cache);
481 return _error->Error("Internal Error, InstallPackages was called with broken packages!");
482 }
483
484 if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
485 Cache->BadCount() == 0)
486 return true;
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);
497 if (_error->PendingError() == true)
498 return false;
499
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 }
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
518 pkgDPkgPM PM(Cache);
519 if (PM.GetArchives(&Fetcher,&List,&Recs) == false)
520 return false;
521
522 // Display statistics
523 unsigned long FetchBytes = Fetcher.FetchNeeded();
524 unsigned long DebBytes = Fetcher.TotalNeeded();
525 if (DebBytes != Cache->DebSize())
526 {
527 c0out << DebBytes << ',' << Cache->DebSize() << endl;
528 c0out << "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl;
529 }
530
531 // Number of bytes
532 c1out << "Need to get ";
533 if (DebBytes != FetchBytes)
534 c1out << SizeToStr(FetchBytes) << '/' << SizeToStr(DebBytes);
535 else
536 c1out << SizeToStr(DebBytes);
537
538 c1out << " of archives. After unpacking ";
539
540 // Size delta
541 if (Cache->UsrSize() >= 0)
542 c1out << SizeToStr(Cache->UsrSize()) << " will be used." << endl;
543 else
544 c1out << SizeToStr(-1*Cache->UsrSize()) << " will be freed." << endl;
545
546 if (_error->PendingError() == true)
547 return false;
548
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
556 // Prompt to continue
557 if (Ask == true)
558 {
559 if (_config->FindI("quiet",0) < 2 ||
560 _config->FindB("APT::Get::Assume-Yes",false) == false)
561 c2out << "Do you want to continue? [Y/n] " << flush;
562
563 if (YnPrompt() == false)
564 exit(1);
565 }
566
567 // Run it
568 if (Fetcher.Run() == false)
569 return false;
570
571 // Print out errors
572 bool Failed = false;
573 bool Transient = false;
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
580 if ((*I)->Status == pkgAcquire::Item::StatIdle)
581 {
582 Transient = true;
583 Failed = true;
584 continue;
585 }
586
587 cerr << "Failed to fetch " << (*I)->Describe() << endl;
588 cerr << " " << (*I)->ErrorText << endl;
589 Failed = true;
590 }
591
592 if (Failed == true && _config->FindB("APT::Fix-Missing",false) == false)
593 {
594 if (Transient == true)
595 {
596 c2out << "Upgrading with disk swapping is not supported in this version." << endl;
597 c2out << "Try running multiple times with --fix-missing" << endl;
598 }
599
600 return _error->Error("Unable to fetch some archives, maybe try with --fix-missing?");
601 }
602
603 // Try to deal with missing package files
604 if (PM.FixMissing() == false)
605 {
606 cerr << "Unable to correct missing packages." << endl;
607 return _error->Error("Aborting Install.");
608 }
609
610 Cache.Lock.Close();
611 return PM.DoInstall();
612 }
613 /*}}}*/
614
615 // DoUpdate - Update the package lists /*{{{*/
616 // ---------------------------------------------------------------------
617 /* */
618 bool DoUpdate(CommandLine &)
619 {
620 // Get the source list
621 pkgSourceList List;
622 if (List.ReadMainList() == false)
623 return false;
624
625 // Lock the list directory
626 if (_config->FindB("Debug::NoLocking",false) == false)
627 {
628 FileFd Lock(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
629 if (_error->PendingError() == true)
630 return _error->Error("Unable to lock the list directory");
631 }
632
633 // Create the download object
634 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
635 pkgAcquire Fetcher(&Stat);
636
637 // Populate it with the source selection
638 pkgSourceList::const_iterator I;
639 for (I = List.begin(); I != List.end(); I++)
640 {
641 new pkgAcqIndex(&Fetcher,I);
642 if (_error->PendingError() == true)
643 return false;
644 }
645
646 // Run it
647 if (Fetcher.Run() == false)
648 return false;
649
650 // Clean out any old list files
651 if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
652 Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
653 return false;
654
655 // Prepare the cache.
656 CacheFile Cache;
657 if (Cache.Open() == false)
658 return false;
659
660 return true;
661 }
662 /*}}}*/
663 // DoUpgrade - Upgrade all packages /*{{{*/
664 // ---------------------------------------------------------------------
665 /* Upgrade all packages without installing new packages or erasing old
666 packages */
667 bool DoUpgrade(CommandLine &CmdL)
668 {
669 CacheFile Cache;
670 if (Cache.Open() == false)
671 return false;
672
673 // Do the upgrade
674 if (pkgAllUpgrade(Cache) == false)
675 {
676 ShowBroken(c1out,Cache);
677 return _error->Error("Internal Error, AllUpgrade broke stuff");
678 }
679
680 return InstallPackages(Cache,true);
681 }
682 /*}}}*/
683 // DoInstall - Install packages from the command line /*{{{*/
684 // ---------------------------------------------------------------------
685 /* Install named packages */
686 bool DoInstall(CommandLine &CmdL)
687 {
688 CacheFile Cache;
689 if (Cache.Open() == false)
690 return false;
691
692 unsigned int ExpectedInst = 0;
693 unsigned int Packages = 0;
694 pkgProblemResolver Fix(Cache);
695
696 bool DefRemove = false;
697 if (strcasecmp(CmdL.FileList[0],"remove") == 0)
698 DefRemove = true;
699
700 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
701 {
702 // Duplicate the string
703 unsigned int Length = strlen(*I);
704 char S[300];
705 if (Length >= sizeof(S))
706 continue;
707 strcpy(S,*I);
708
709 // See if we are removing the package
710 bool Remove = DefRemove;
711 if (Cache->FindPkg(S).end() == true)
712 {
713 // Handle an optional end tag indicating what to do
714 if (S[Length - 1] == '-')
715 {
716 Remove = true;
717 S[--Length] = 0;
718 }
719 if (S[Length - 1] == '+')
720 {
721 Remove = false;
722 S[--Length] = 0;
723 }
724 }
725
726 // Locate the package
727 pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
728 Packages++;
729 if (Pkg.end() == true)
730 return _error->Error("Couldn't find package %s",S);
731
732 // Handle the no-upgrade case
733 if (_config->FindB("APT::Get::no-upgrade",false) == true &&
734 Pkg->CurrentVer != 0)
735 {
736 c1out << "Skipping " << Pkg.Name() << ", it is already installed and no-upgrade is set." << endl;
737 continue;
738 }
739
740 // Check if there is something new to install
741 pkgDepCache::StateCache &State = (*Cache)[Pkg];
742 if (State.CandidateVer == 0)
743 {
744 if (Pkg->ProvidesList != 0)
745 {
746 c1out << "Package " << S << " is a virtual package provided by:" << endl;
747
748 pkgCache::PrvIterator I = Pkg.ProvidesList();
749 for (; I.end() == false; I++)
750 {
751 pkgCache::PkgIterator Pkg = I.OwnerPkg();
752
753 if ((*Cache)[Pkg].CandidateVerIter(*Cache) == I.OwnerVer())
754 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
755
756 if ((*Cache)[Pkg].InstVerIter(*Cache) == I.OwnerVer())
757 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
758 " [Installed]"<< endl;
759 }
760 c1out << "You should explicly select one to install." << endl;
761 }
762 else
763 {
764 c1out << "Package " << S << " has no available version, but exists in the database." << endl;
765 c1out << "This typically means that the package was mentioned in a dependency and " << endl;
766 c1out << "never uploaded, or that it is an obsolete package." << endl;
767
768 string List;
769 pkgCache::DepIterator Dep = Pkg.RevDependsList();
770 for (; Dep.end() == false; Dep++)
771 {
772 if (Dep->Type != pkgCache::Dep::Replaces)
773 continue;
774 List += string(Dep.ParentPkg().Name()) + " ";
775 }
776 ShowList(c1out,"However the following packages replace it:",List);
777 }
778
779 return _error->Error("Package %s has no installation candidate",S);
780 }
781
782 Fix.Protect(Pkg);
783 if (Remove == true)
784 {
785 Fix.Remove(Pkg);
786 Cache->MarkDelete(Pkg);
787 continue;
788 }
789
790 // Install it
791 Cache->MarkInstall(Pkg,false);
792 if (State.Install() == false)
793 c1out << "Sorry, " << S << " is already the newest version" << endl;
794 else
795 ExpectedInst++;
796
797 // Install it with autoinstalling enabled.
798 if (State.InstBroken() == true)
799 Cache->MarkInstall(Pkg,true);
800 }
801
802 // Call the scored problem resolver
803 Fix.InstallProtect();
804 if (Fix.Resolve(true) == false)
805 _error->Discard();
806
807 // Now we check the state of the packages,
808 if (Cache->BrokenCount() != 0)
809 {
810 c1out << "Some packages could not be installed. This may mean that you have" << endl;
811 c1out << "requested an impossible situation or if you are using the unstable" << endl;
812 c1out << "distribution that some required packages have not yet been created" << endl;
813 c1out << "or been moved out of Incoming." << endl;
814 if (Packages == 1)
815 {
816 c1out << endl;
817 c1out << "Since you only requested a single operation it is extremely likely that" << endl;
818 c1out << "the package is simply not installable and a bug report against" << endl;
819 c1out << "that package should be filed." << endl;
820 }
821
822 c1out << "The following information may help to resolve the situation:" << endl;
823 c1out << endl;
824 ShowBroken(c1out,Cache);
825 return _error->Error("Sorry, broken packages");
826 }
827
828 /* Print out a list of packages that are going to be installed extra
829 to what the user asked */
830 if (Cache->InstCount() != ExpectedInst)
831 {
832 string List;
833 pkgCache::PkgIterator I = Cache->PkgBegin();
834 for (;I.end() != true; I++)
835 {
836 if ((*Cache)[I].Install() == false)
837 continue;
838
839 const char **J;
840 for (J = CmdL.FileList + 1; *J != 0; J++)
841 if (strcmp(*J,I.Name()) == 0)
842 break;
843
844 if (*J == 0)
845 List += string(I.Name()) + " ";
846 }
847
848 ShowList(c1out,"The following extra packages will be installed:",List);
849 }
850
851 // See if we need to prompt
852 if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
853 return InstallPackages(Cache,false,false);
854
855 return InstallPackages(Cache,false);
856 }
857 /*}}}*/
858 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
859 // ---------------------------------------------------------------------
860 /* Intelligent upgrader that will install and remove packages at will */
861 bool DoDistUpgrade(CommandLine &CmdL)
862 {
863 CacheFile Cache;
864 if (Cache.Open() == false)
865 return false;
866
867 c0out << "Calculating Upgrade... " << flush;
868 if (pkgDistUpgrade(*Cache) == false)
869 {
870 c0out << "Failed" << endl;
871 ShowBroken(c1out,Cache);
872 return false;
873 }
874
875 c0out << "Done" << endl;
876
877 return InstallPackages(Cache,true);
878 }
879 /*}}}*/
880 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
881 // ---------------------------------------------------------------------
882 /* Follows dselect's selections */
883 bool DoDSelectUpgrade(CommandLine &CmdL)
884 {
885 CacheFile Cache;
886 if (Cache.Open() == false)
887 return false;
888
889 // Install everything with the install flag set
890 pkgCache::PkgIterator I = Cache->PkgBegin();
891 for (;I.end() != true; I++)
892 {
893 /* Install the package only if it is a new install, the autoupgrader
894 will deal with the rest */
895 if (I->SelectedState == pkgCache::State::Install)
896 Cache->MarkInstall(I,false);
897 }
898
899 /* Now install their deps too, if we do this above then order of
900 the status file is significant for | groups */
901 for (I = Cache->PkgBegin();I.end() != true; I++)
902 {
903 /* Install the package only if it is a new install, the autoupgrader
904 will deal with the rest */
905 if (I->SelectedState == pkgCache::State::Install)
906 Cache->MarkInstall(I);
907 }
908
909 // Apply erasures now, they override everything else.
910 for (I = Cache->PkgBegin();I.end() != true; I++)
911 {
912 // Remove packages
913 if (I->SelectedState == pkgCache::State::DeInstall ||
914 I->SelectedState == pkgCache::State::Purge)
915 Cache->MarkDelete(I);
916 }
917
918 /* Use updates smart upgrade to do the rest, it will automatically
919 ignore held items */
920 if (pkgAllUpgrade(Cache) == false)
921 {
922 ShowBroken(c1out,Cache);
923 return _error->Error("Internal Error, AllUpgrade broke stuff");
924 }
925
926 return InstallPackages(Cache,false);
927 }
928 /*}}}*/
929 // DoClean - Remove download archives /*{{{*/
930 // ---------------------------------------------------------------------
931 /* */
932 bool DoClean(CommandLine &CmdL)
933 {
934 pkgAcquire Fetcher;
935 Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
936 Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
937 return true;
938 }
939 /*}}}*/
940 // DoCheck - Perform the check operation /*{{{*/
941 // ---------------------------------------------------------------------
942 /* Opening automatically checks the system, this command is mostly used
943 for debugging */
944 bool DoCheck(CommandLine &CmdL)
945 {
946 CacheFile Cache;
947 Cache.Open();
948
949 return true;
950 }
951 /*}}}*/
952
953 // ShowHelp - Show a help screen /*{{{*/
954 // ---------------------------------------------------------------------
955 /* */
956 int ShowHelp()
957 {
958 cout << PACKAGE << ' ' << VERSION << " for " << ARCHITECTURE <<
959 " compiled on " << __DATE__ << " " << __TIME__ << endl;
960
961 cout << "Usage: apt-get [options] command" << endl;
962 cout << " apt-get [options] install pkg1 [pkg2 ...]" << endl;
963 cout << endl;
964 cout << "apt-get is a simple command line interface for downloading and" << endl;
965 cout << "installing packages. The most frequently used commands are update" << endl;
966 cout << "and install." << endl;
967 cout << endl;
968 cout << "Commands:" << endl;
969 cout << " update - Retrieve new lists of packages" << endl;
970 cout << " upgrade - Perform an upgrade" << endl;
971 cout << " install - Install new packages (pkg is libc6 not libc6.deb)" << endl;
972 cout << " remove - Remove packages" << endl;
973 cout << " dist-upgrade - Distribution upgrade, see apt-get(8)" << endl;
974 cout << " dselect-upgrade - Follow dselect selections" << endl;
975 cout << " clean - Erase downloaded archive files" << endl;
976 cout << " check - Verify that there are no broken dependencies" << endl;
977 cout << endl;
978 cout << "Options:" << endl;
979 cout << " -h This help text." << endl;
980 cout << " -q Loggable output - no progress indicator" << endl;
981 cout << " -qq No output except for errors" << endl;
982 cout << " -d Download only - do NOT install or unpack archives" << endl;
983 cout << " -s No-act. Perform ordering simulation" << endl;
984 cout << " -y Assume Yes to all queries and do not prompt" << endl;
985 cout << " -f Attempt to continue if the integrity check fails" << endl;
986 cout << " -m Attempt to continue if archives are unlocatable" << endl;
987 cout << " -u Show a list of upgraded packages as well" << endl;
988 cout << " -c=? Read this configuration file" << endl;
989 cout << " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl;
990 cout << "See the apt-get(8), sources.list(8) and apt.conf(8) manual" << endl;
991 cout << "pages for more information." << endl;
992 return 100;
993 }
994 /*}}}*/
995 // GetInitialize - Initialize things for apt-get /*{{{*/
996 // ---------------------------------------------------------------------
997 /* */
998 void GetInitialize()
999 {
1000 _config->Set("quiet",0);
1001 _config->Set("help",false);
1002 _config->Set("APT::Get::Download-Only",false);
1003 _config->Set("APT::Get::Simulate",false);
1004 _config->Set("APT::Get::Assume-Yes",false);
1005 _config->Set("APT::Get::Fix-Broken",false);
1006 _config->Set("APT::Get::Force-Yes",false);
1007 }
1008 /*}}}*/
1009 // SigWinch - Window size change signal handler /*{{{*/
1010 // ---------------------------------------------------------------------
1011 /* */
1012 void SigWinch(int)
1013 {
1014 // Riped from GNU ls
1015 #ifdef TIOCGWINSZ
1016 struct winsize ws;
1017
1018 if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
1019 ScreenWidth = ws.ws_col - 1;
1020 #endif
1021 }
1022 /*}}}*/
1023
1024 int main(int argc,const char *argv[])
1025 {
1026 CommandLine::Args Args[] = {
1027 {'h',"help","help",0},
1028 {'q',"quiet","quiet",CommandLine::IntLevel},
1029 {'q',"silent","quiet",CommandLine::IntLevel},
1030 {'d',"download-only","APT::Get::Download-Only",0},
1031 {'s',"simulate","APT::Get::Simulate",0},
1032 {'s',"just-print","APT::Get::Simulate",0},
1033 {'s',"recon","APT::Get::Simulate",0},
1034 {'s',"no-act","APT::Get::Simulate",0},
1035 {'y',"yes","APT::Get::Assume-Yes",0},
1036 {'y',"assume-yes","APT::Get::Assume-Yes",0},
1037 {'f',"fix-broken","APT::Get::Fix-Broken",0},
1038 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
1039 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
1040 {0,"fix-missing","APT::Get::Fix-Missing",0},
1041 {0,"ignore-hold","APT::Ingore-Hold",0},
1042 {0,"no-upgrade","APT::Get::no-upgrade",0},
1043 {0,"force-yes","APT::Get::force-yes",0},
1044 {'c',"config-file",0,CommandLine::ConfigFile},
1045 {'o',"option",0,CommandLine::ArbItem},
1046 {0,0,0,0}};
1047 CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
1048 {"upgrade",&DoUpgrade},
1049 {"install",&DoInstall},
1050 {"remove",&DoInstall},
1051 {"dist-upgrade",&DoDistUpgrade},
1052 {"dselect-upgrade",&DoDSelectUpgrade},
1053 {"clean",&DoClean},
1054 {"check",&DoCheck},
1055 {0,0}};
1056
1057 // Parse the command line and initialize the package library
1058 CommandLine CmdL(Args,_config);
1059 if (pkgInitialize(*_config) == false ||
1060 CmdL.Parse(argc,argv) == false)
1061 {
1062 _error->DumpErrors();
1063 return 100;
1064 }
1065
1066 // See if the help should be shown
1067 if (_config->FindB("help") == true ||
1068 CmdL.FileSize() == 0)
1069 return ShowHelp();
1070
1071 // Setup the output streams
1072 c0out.rdbuf(cout.rdbuf());
1073 c1out.rdbuf(cout.rdbuf());
1074 c2out.rdbuf(cout.rdbuf());
1075 if (_config->FindI("quiet",0) > 0)
1076 c0out.rdbuf(devnull.rdbuf());
1077 if (_config->FindI("quiet",0) > 1)
1078 c1out.rdbuf(devnull.rdbuf());
1079
1080 // Setup the signals
1081 signal(SIGPIPE,SIG_IGN);
1082 signal(SIGWINCH,SigWinch);
1083 SigWinch(0);
1084
1085 // Match the operation
1086 CmdL.DispatchArg(Cmds);
1087
1088 // Print any errors or warnings found during parsing
1089 if (_error->empty() == false)
1090 {
1091 bool Errors = _error->PendingError();
1092 _error->DumpErrors();
1093 if (Errors == true)
1094 cout << "Returning 100." << endl;
1095 return Errors == true?100:0;
1096 }
1097
1098 return 0;
1099 }