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