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