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