]> git.saurik.com Git - apt.git/blob - cmdline/apt-get.cc
Doc updates, 133950, 117856
[apt.git] / cmdline / apt-get.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: apt-get.cc,v 1.117 2002/03/27 05:26:24 jgg Exp $
4 /* ######################################################################
5
6 apt-get - Cover for dpkg
7
8 This is an allout cover for dpkg implementing a safer front end. It is
9 based largely on libapt-pkg.
10
11 The syntax is different,
12 apt-get [opt] command [things]
13 Where command is:
14 update - Resyncronize the package files from their sources
15 upgrade - Smart-Download the newest versions of all packages
16 dselect-upgrade - Follows dselect's changes to the Status: field
17 and installes new and removes old packages
18 dist-upgrade - Powerfull upgrader designed to handle the issues with
19 a new distribution.
20 install - Download and install a given package (by name, not by .deb)
21 check - Update the package cache and check for broken packages
22 clean - Erase the .debs downloaded to /var/cache/apt/archives and
23 the partial dir too
24
25 ##################################################################### */
26 /*}}}*/
27 // Include Files /*{{{*/
28 #include <apt-pkg/error.h>
29 #include <apt-pkg/cmndline.h>
30 #include <apt-pkg/init.h>
31 #include <apt-pkg/depcache.h>
32 #include <apt-pkg/sourcelist.h>
33 #include <apt-pkg/algorithms.h>
34 #include <apt-pkg/acquire-item.h>
35 #include <apt-pkg/strutl.h>
36 #include <apt-pkg/clean.h>
37 #include <apt-pkg/srcrecords.h>
38 #include <apt-pkg/version.h>
39 #include <apt-pkg/cachefile.h>
40 #include <apt-pkg/sptr.h>
41 #include <apt-pkg/versionmatch.h>
42
43 #include <config.h>
44 #include <apti18n.h>
45
46 #include "acqprogress.h"
47
48 #include <locale.h>
49 #include <fstream>
50 #include <termios.h>
51 #include <sys/ioctl.h>
52 #include <sys/stat.h>
53 #include <sys/statvfs.h>
54 #include <signal.h>
55 #include <unistd.h>
56 #include <stdio.h>
57 #include <errno.h>
58 #include <regex.h>
59 #include <sys/wait.h>
60 /*}}}*/
61
62 using namespace std;
63
64 ostream c0out(0);
65 ostream c1out(0);
66 ostream c2out(0);
67 ofstream devnull("/dev/null");
68 unsigned int ScreenWidth = 80;
69
70 // class CacheFile - Cover class for some dependency cache functions /*{{{*/
71 // ---------------------------------------------------------------------
72 /* */
73 class CacheFile : public pkgCacheFile
74 {
75 static pkgCache *SortCache;
76 static int NameComp(const void *a,const void *b);
77
78 public:
79 pkgCache::Package **List;
80
81 void Sort();
82 bool CheckDeps(bool AllowBroken = false);
83 bool Open(bool WithLock = true)
84 {
85 OpTextProgress Prog(*_config);
86 if (pkgCacheFile::Open(Prog,WithLock) == false)
87 return false;
88 Sort();
89
90 return true;
91 };
92 bool OpenForInstall()
93 {
94 if (_config->FindB("APT::Get::Print-URIs") == true)
95 return Open(false);
96 else
97 return Open(true);
98 }
99 CacheFile() : List(0) {};
100 };
101 /*}}}*/
102
103 // YnPrompt - Yes No Prompt. /*{{{*/
104 // ---------------------------------------------------------------------
105 /* Returns true on a Yes.*/
106 bool YnPrompt()
107 {
108 // This needs to be a capital
109 const char *Yes = _("Y");
110
111 if (_config->FindB("APT::Get::Assume-Yes",false) == true)
112 {
113 c1out << Yes << endl;
114 return true;
115 }
116
117 char C = 0;
118 char Jnk = 0;
119 if (read(STDIN_FILENO,&C,1) != 1)
120 return false;
121 while (C != '\n' && Jnk != '\n')
122 if (read(STDIN_FILENO,&Jnk,1) != 1)
123 return false;
124
125 if (!(toupper(C) == *Yes || C == '\n' || C == '\r'))
126 return false;
127 return true;
128 }
129 /*}}}*/
130 // AnalPrompt - Annoying Yes No Prompt. /*{{{*/
131 // ---------------------------------------------------------------------
132 /* Returns true on a Yes.*/
133 bool AnalPrompt(const char *Text)
134 {
135 char Buf[1024];
136 cin.getline(Buf,sizeof(Buf));
137 if (strcmp(Buf,Text) == 0)
138 return true;
139 return false;
140 }
141 /*}}}*/
142 // ShowList - Show a list /*{{{*/
143 // ---------------------------------------------------------------------
144 /* This prints out a string of space separated words with a title and
145 a two space indent line wraped to the current screen width. */
146 bool ShowList(ostream &out,string Title,string List)
147 {
148 if (List.empty() == true)
149 return true;
150
151 // Acount for the leading space
152 int ScreenWidth = ::ScreenWidth - 3;
153
154 out << Title << endl;
155 string::size_type Start = 0;
156 while (Start < List.size())
157 {
158 string::size_type End;
159 if (Start + ScreenWidth >= List.size())
160 End = List.size();
161 else
162 End = List.rfind(' ',Start+ScreenWidth);
163
164 if (End == string::npos || End < Start)
165 End = Start + ScreenWidth;
166 out << " " << string(List,Start,End - Start) << endl;
167 Start = End + 1;
168 }
169 return false;
170 }
171 /*}}}*/
172 // ShowBroken - Debugging aide /*{{{*/
173 // ---------------------------------------------------------------------
174 /* This prints out the names of all the packages that are broken along
175 with the name of each each broken dependency and a quite version
176 description.
177
178 The output looks like:
179 Sorry, but the following packages have unmet dependencies:
180 exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed
181 Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
182 Depends: libsasl7 but it is not going to be installed
183 */
184 void ShowBroken(ostream &out,CacheFile &Cache,bool Now)
185 {
186 out << _("Sorry, but the following packages have unmet dependencies:") << endl;
187 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
188 {
189 pkgCache::PkgIterator I(Cache,Cache.List[J]);
190
191 if (Now == true)
192 {
193 if (Cache[I].NowBroken() == false)
194 continue;
195 }
196 else
197 {
198 if (Cache[I].InstBroken() == false)
199 continue;
200 }
201
202 // Print out each package and the failed dependencies
203 out <<" " << I.Name() << ":";
204 unsigned Indent = strlen(I.Name()) + 3;
205 bool First = true;
206 pkgCache::VerIterator Ver;
207
208 if (Now == true)
209 Ver = I.CurrentVer();
210 else
211 Ver = Cache[I].InstVerIter(Cache);
212
213 if (Ver.end() == true)
214 {
215 out << endl;
216 continue;
217 }
218
219 for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
220 {
221 // Compute a single dependency element (glob or)
222 pkgCache::DepIterator Start;
223 pkgCache::DepIterator End;
224 D.GlobOr(Start,End);
225
226 if (Cache->IsImportantDep(End) == false)
227 continue;
228
229 if (Now == true)
230 {
231 if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
232 continue;
233 }
234 else
235 {
236 if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
237 continue;
238 }
239
240 bool FirstOr = true;
241 while (1)
242 {
243 if (First == false)
244 for (unsigned J = 0; J != Indent; J++)
245 out << ' ';
246 First = false;
247
248 if (FirstOr == false)
249 {
250 for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
251 out << ' ';
252 }
253 else
254 out << ' ' << End.DepType() << ": ";
255 FirstOr = false;
256
257 out << Start.TargetPkg().Name();
258
259 // Show a quick summary of the version requirements
260 if (Start.TargetVer() != 0)
261 out << " (" << Start.CompType() << " " << Start.TargetVer() << ")";
262
263 /* Show a summary of the target package if possible. In the case
264 of virtual packages we show nothing */
265 pkgCache::PkgIterator Targ = Start.TargetPkg();
266 if (Targ->ProvidesList == 0)
267 {
268 out << ' ';
269 pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
270 if (Now == true)
271 Ver = Targ.CurrentVer();
272
273 if (Ver.end() == false)
274 {
275 if (Now == true)
276 ioprintf(out,_("but %s is installed"),Ver.VerStr());
277 else
278 ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
279 }
280 else
281 {
282 if (Cache[Targ].CandidateVerIter(Cache).end() == true)
283 {
284 if (Targ->ProvidesList == 0)
285 out << _("but it is not installable");
286 else
287 out << _("but it is a virtual package");
288 }
289 else
290 out << (Now?_("but it is not installed"):_("but it is not going to be installed"));
291 }
292 }
293
294 if (Start != End)
295 out << _(" or");
296 out << endl;
297
298 if (Start == End)
299 break;
300 Start++;
301 }
302 }
303 }
304 }
305 /*}}}*/
306 // ShowNew - Show packages to newly install /*{{{*/
307 // ---------------------------------------------------------------------
308 /* */
309 void ShowNew(ostream &out,CacheFile &Cache)
310 {
311 /* Print out a list of packages that are going to be removed extra
312 to what the user asked */
313 string List;
314 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
315 {
316 pkgCache::PkgIterator I(Cache,Cache.List[J]);
317 if (Cache[I].NewInstall() == true)
318 List += string(I.Name()) + " ";
319 }
320
321 ShowList(out,_("The following NEW packages will be installed:"),List);
322 }
323 /*}}}*/
324 // ShowDel - Show packages to delete /*{{{*/
325 // ---------------------------------------------------------------------
326 /* */
327 void ShowDel(ostream &out,CacheFile &Cache)
328 {
329 /* Print out a list of packages that are going to be removed extra
330 to what the user asked */
331 string List;
332 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
333 {
334 pkgCache::PkgIterator I(Cache,Cache.List[J]);
335 if (Cache[I].Delete() == true)
336 {
337 if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
338 List += string(I.Name()) + "* ";
339 else
340 List += string(I.Name()) + " ";
341 }
342 }
343
344 ShowList(out,_("The following packages will be REMOVED:"),List);
345 }
346 /*}}}*/
347 // ShowKept - Show kept packages /*{{{*/
348 // ---------------------------------------------------------------------
349 /* */
350 void ShowKept(ostream &out,CacheFile &Cache)
351 {
352 string List;
353 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
354 {
355 pkgCache::PkgIterator I(Cache,Cache.List[J]);
356
357 // Not interesting
358 if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false ||
359 I->CurrentVer == 0 || Cache[I].Delete() == true)
360 continue;
361
362 List += string(I.Name()) + " ";
363 }
364 ShowList(out,_("The following packages have been kept back"),List);
365 }
366 /*}}}*/
367 // ShowUpgraded - Show upgraded packages /*{{{*/
368 // ---------------------------------------------------------------------
369 /* */
370 void ShowUpgraded(ostream &out,CacheFile &Cache)
371 {
372 string List;
373 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
374 {
375 pkgCache::PkgIterator I(Cache,Cache.List[J]);
376
377 // Not interesting
378 if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
379 continue;
380
381 List += string(I.Name()) + " ";
382 }
383 ShowList(out,_("The following packages will be upgraded"),List);
384 }
385 /*}}}*/
386 // ShowDowngraded - Show downgraded packages /*{{{*/
387 // ---------------------------------------------------------------------
388 /* */
389 bool ShowDowngraded(ostream &out,CacheFile &Cache)
390 {
391 string List;
392 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
393 {
394 pkgCache::PkgIterator I(Cache,Cache.List[J]);
395
396 // Not interesting
397 if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
398 continue;
399
400 List += string(I.Name()) + " ";
401 }
402 return ShowList(out,_("The following packages will be DOWNGRADED"),List);
403 }
404 /*}}}*/
405 // ShowHold - Show held but changed packages /*{{{*/
406 // ---------------------------------------------------------------------
407 /* */
408 bool ShowHold(ostream &out,CacheFile &Cache)
409 {
410 string List;
411 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
412 {
413 pkgCache::PkgIterator I(Cache,Cache.List[J]);
414 if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
415 I->SelectedState == pkgCache::State::Hold)
416 List += string(I.Name()) + " ";
417 }
418
419 return ShowList(out,_("The following held packages will be changed:"),List);
420 }
421 /*}}}*/
422 // ShowEssential - Show an essential package warning /*{{{*/
423 // ---------------------------------------------------------------------
424 /* This prints out a warning message that is not to be ignored. It shows
425 all essential packages and their dependents that are to be removed.
426 It is insanely risky to remove the dependents of an essential package! */
427 bool ShowEssential(ostream &out,CacheFile &Cache)
428 {
429 string List;
430 bool *Added = new bool[Cache->Head().PackageCount];
431 for (unsigned int I = 0; I != Cache->Head().PackageCount; I++)
432 Added[I] = false;
433
434 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
435 {
436 pkgCache::PkgIterator I(Cache,Cache.List[J]);
437 if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
438 (I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
439 continue;
440
441 // The essential package is being removed
442 if (Cache[I].Delete() == true)
443 {
444 if (Added[I->ID] == false)
445 {
446 Added[I->ID] = true;
447 List += string(I.Name()) + " ";
448 }
449 }
450
451 if (I->CurrentVer == 0)
452 continue;
453
454 // Print out any essential package depenendents that are to be removed
455 for (pkgCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; D++)
456 {
457 // Skip everything but depends
458 if (D->Type != pkgCache::Dep::PreDepends &&
459 D->Type != pkgCache::Dep::Depends)
460 continue;
461
462 pkgCache::PkgIterator P = D.SmartTargetPkg();
463 if (Cache[P].Delete() == true)
464 {
465 if (Added[P->ID] == true)
466 continue;
467 Added[P->ID] = true;
468
469 char S[300];
470 snprintf(S,sizeof(S),_("%s (due to %s) "),P.Name(),I.Name());
471 List += S;
472 }
473 }
474 }
475
476 delete [] Added;
477 return ShowList(out,_("WARNING: The following essential packages will be removed\n"
478 "This should NOT be done unless you know exactly what you are doing!"),List);
479 }
480 /*}}}*/
481 // Stats - Show some statistics /*{{{*/
482 // ---------------------------------------------------------------------
483 /* */
484 void Stats(ostream &out,pkgDepCache &Dep)
485 {
486 unsigned long Upgrade = 0;
487 unsigned long Downgrade = 0;
488 unsigned long Install = 0;
489 unsigned long ReInstall = 0;
490 for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++)
491 {
492 if (Dep[I].NewInstall() == true)
493 Install++;
494 else
495 {
496 if (Dep[I].Upgrade() == true)
497 Upgrade++;
498 else
499 if (Dep[I].Downgrade() == true)
500 Downgrade++;
501 }
502
503 if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
504 ReInstall++;
505 }
506
507 ioprintf(out,_("%lu packages upgraded, %lu newly installed, "),
508 Upgrade,Install);
509
510 if (ReInstall != 0)
511 ioprintf(out,_("%lu reinstalled, "),ReInstall);
512 if (Downgrade != 0)
513 ioprintf(out,_("%lu downgraded, "),Downgrade);
514
515 ioprintf(out,_("%lu to remove and %lu not upgraded.\n"),
516 Dep.DelCount(),Dep.KeepCount());
517
518 if (Dep.BadCount() != 0)
519 ioprintf(out,_("%lu packages not fully installed or removed.\n"),
520 Dep.BadCount());
521 }
522 /*}}}*/
523
524 // CacheFile::NameComp - QSort compare by name /*{{{*/
525 // ---------------------------------------------------------------------
526 /* */
527 pkgCache *CacheFile::SortCache = 0;
528 int CacheFile::NameComp(const void *a,const void *b)
529 {
530 if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0)
531 return *(pkgCache::Package **)a - *(pkgCache::Package **)b;
532
533 const pkgCache::Package &A = **(pkgCache::Package **)a;
534 const pkgCache::Package &B = **(pkgCache::Package **)b;
535
536 return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name);
537 }
538 /*}}}*/
539 // CacheFile::Sort - Sort by name /*{{{*/
540 // ---------------------------------------------------------------------
541 /* */
542 void CacheFile::Sort()
543 {
544 delete [] List;
545 List = new pkgCache::Package *[Cache->Head().PackageCount];
546 memset(List,0,sizeof(*List)*Cache->Head().PackageCount);
547 pkgCache::PkgIterator I = Cache->PkgBegin();
548 for (;I.end() != true; I++)
549 List[I->ID] = I;
550
551 SortCache = *this;
552 qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp);
553 }
554 /*}}}*/
555 // CacheFile::CheckDeps - Open the cache file /*{{{*/
556 // ---------------------------------------------------------------------
557 /* This routine generates the caches and then opens the dependency cache
558 and verifies that the system is OK. */
559 bool CacheFile::CheckDeps(bool AllowBroken)
560 {
561 if (_error->PendingError() == true)
562 return false;
563
564 // Check that the system is OK
565 if (DCache->DelCount() != 0 || DCache->InstCount() != 0)
566 return _error->Error("Internal Error, non-zero counts");
567
568 // Apply corrections for half-installed packages
569 if (pkgApplyStatus(*DCache) == false)
570 return false;
571
572 // Nothing is broken
573 if (DCache->BrokenCount() == 0 || AllowBroken == true)
574 return true;
575
576 // Attempt to fix broken things
577 if (_config->FindB("APT::Get::Fix-Broken",false) == true)
578 {
579 c1out << _("Correcting dependencies...") << flush;
580 if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
581 {
582 c1out << _(" failed.") << endl;
583 ShowBroken(c1out,*this,true);
584
585 return _error->Error(_("Unable to correct dependencies"));
586 }
587 if (pkgMinimizeUpgrade(*DCache) == false)
588 return _error->Error(_("Unable to minimize the upgrade set"));
589
590 c1out << _(" Done") << endl;
591 }
592 else
593 {
594 c1out << _("You might want to run `apt-get -f install' to correct these.") << endl;
595 ShowBroken(c1out,*this,true);
596
597 return _error->Error(_("Unmet dependencies. Try using -f."));
598 }
599
600 return true;
601 }
602 /*}}}*/
603
604 // InstallPackages - Actually download and install the packages /*{{{*/
605 // ---------------------------------------------------------------------
606 /* This displays the informative messages describing what is going to
607 happen and then calls the download routines */
608 bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
609 bool Saftey = true)
610 {
611 if (_config->FindB("APT::Get::Purge",false) == true)
612 {
613 pkgCache::PkgIterator I = Cache->PkgBegin();
614 for (; I.end() == false; I++)
615 {
616 if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
617 Cache->MarkDelete(I,true);
618 }
619 }
620
621 bool Fail = false;
622 bool Essential = false;
623
624 // Show all the various warning indicators
625 ShowDel(c1out,Cache);
626 ShowNew(c1out,Cache);
627 if (ShwKept == true)
628 ShowKept(c1out,Cache);
629 Fail |= !ShowHold(c1out,Cache);
630 if (_config->FindB("APT::Get::Show-Upgraded",false) == true)
631 ShowUpgraded(c1out,Cache);
632 Fail |= !ShowDowngraded(c1out,Cache);
633 Essential = !ShowEssential(c1out,Cache);
634 Fail |= Essential;
635 Stats(c1out,Cache);
636
637 // Sanity check
638 if (Cache->BrokenCount() != 0)
639 {
640 ShowBroken(c1out,Cache,false);
641 return _error->Error("Internal Error, InstallPackages was called with broken packages!");
642 }
643
644 if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
645 Cache->BadCount() == 0)
646 return true;
647
648 // No remove flag
649 if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
650 return _error->Error(_("Packages need to be removed but Remove is disabled."));
651
652 // Run the simulator ..
653 if (_config->FindB("APT::Get::Simulate") == true)
654 {
655 pkgSimulate PM(Cache);
656 pkgPackageManager::OrderResult Res = PM.DoInstall();
657 if (Res == pkgPackageManager::Failed)
658 return false;
659 if (Res != pkgPackageManager::Completed)
660 return _error->Error("Internal Error, Ordering didn't finish");
661 return true;
662 }
663
664 // Create the text record parser
665 pkgRecords Recs(Cache);
666 if (_error->PendingError() == true)
667 return false;
668
669 // Lock the archive directory
670 FileFd Lock;
671 if (_config->FindB("Debug::NoLocking",false) == false &&
672 _config->FindB("APT::Get::Print-URIs") == false)
673 {
674 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
675 if (_error->PendingError() == true)
676 return _error->Error(_("Unable to lock the download directory"));
677 }
678
679 // Create the download object
680 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
681 pkgAcquire Fetcher(&Stat);
682
683 // Read the source list
684 pkgSourceList List;
685 if (List.ReadMainList() == false)
686 return _error->Error(_("The list of sources could not be read."));
687
688 // Create the package manager and prepare to download
689 SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
690 if (PM->GetArchives(&Fetcher,&List,&Recs) == false ||
691 _error->PendingError() == true)
692 return false;
693
694 // Display statistics
695 double FetchBytes = Fetcher.FetchNeeded();
696 double FetchPBytes = Fetcher.PartialPresent();
697 double DebBytes = Fetcher.TotalNeeded();
698 if (DebBytes != Cache->DebSize())
699 {
700 c0out << DebBytes << ',' << Cache->DebSize() << endl;
701 c0out << "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl;
702 }
703
704 // Number of bytes
705 if (DebBytes != FetchBytes)
706 ioprintf(c1out,_("Need to get %sB/%sB of archives. "),
707 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
708 else
709 ioprintf(c1out,_("Need to get %sB of archives. "),
710 SizeToStr(DebBytes).c_str());
711
712 // Size delta
713 if (Cache->UsrSize() >= 0)
714 ioprintf(c1out,_("After unpacking %sB will be used.\n"),
715 SizeToStr(Cache->UsrSize()).c_str());
716 else
717 ioprintf(c1out,_("After unpacking %sB will be freed.\n"),
718 SizeToStr(-1*Cache->UsrSize()).c_str());
719
720 if (_error->PendingError() == true)
721 return false;
722
723 /* Check for enough free space, but only if we are actually going to
724 download */
725 if (_config->FindB("APT::Get::Print-URIs") == false &&
726 _config->FindB("APT::Get::Download",true) == true)
727 {
728 struct statvfs Buf;
729 string OutputDir = _config->FindDir("Dir::Cache::Archives");
730 if (statvfs(OutputDir.c_str(),&Buf) != 0)
731 return _error->Errno("statvfs","Couldn't determine free space in %s",
732 OutputDir.c_str());
733 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
734 return _error->Error(_("Sorry, you don't have enough free space in %s to hold all the .debs."),
735 OutputDir.c_str());
736 }
737
738 // Fail safe check
739 if (_config->FindI("quiet",0) >= 2 ||
740 _config->FindB("APT::Get::Assume-Yes",false) == true)
741 {
742 if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
743 return _error->Error(_("There are problems and -y was used without --force-yes"));
744 }
745
746 if (Essential == true && Saftey == true)
747 {
748 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
749 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
750
751 const char *Prompt = _("Yes, do as I say!");
752 ioprintf(c2out,
753 _("You are about to do something potentially harmful\n"
754 "To continue type in the phrase '%s'\n"
755 " ?] "),Prompt);
756 c2out << flush;
757 if (AnalPrompt(Prompt) == false)
758 {
759 c2out << _("Abort.") << endl;
760 exit(1);
761 }
762 }
763 else
764 {
765 // Prompt to continue
766 if (Ask == true || Fail == true)
767 {
768 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
769 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
770
771 if (_config->FindI("quiet",0) < 2 &&
772 _config->FindB("APT::Get::Assume-Yes",false) == false)
773 {
774 c2out << _("Do you want to continue? [Y/n] ") << flush;
775
776 if (YnPrompt() == false)
777 {
778 c2out << _("Abort.") << endl;
779 exit(1);
780 }
781 }
782 }
783 }
784
785 // Just print out the uris an exit if the --print-uris flag was used
786 if (_config->FindB("APT::Get::Print-URIs") == true)
787 {
788 pkgAcquire::UriIterator I = Fetcher.UriBegin();
789 for (; I != Fetcher.UriEnd(); I++)
790 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
791 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
792 return true;
793 }
794
795 /* Unlock the dpkg lock if we are not going to be doing an install
796 after. */
797 if (_config->FindB("APT::Get::Download-Only",false) == true)
798 _system->UnLock();
799
800 // Run it
801 while (1)
802 {
803 bool Transient = false;
804 if (_config->FindB("APT::Get::Download",true) == false)
805 {
806 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
807 {
808 if ((*I)->Local == true)
809 {
810 I++;
811 continue;
812 }
813
814 // Close the item and check if it was found in cache
815 (*I)->Finished();
816 if ((*I)->Complete == false)
817 Transient = true;
818
819 // Clear it out of the fetch list
820 delete *I;
821 I = Fetcher.ItemsBegin();
822 }
823 }
824
825 if (Fetcher.Run() == pkgAcquire::Failed)
826 return false;
827
828 // Print out errors
829 bool Failed = false;
830 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
831 {
832 if ((*I)->Status == pkgAcquire::Item::StatDone &&
833 (*I)->Complete == true)
834 continue;
835
836 if ((*I)->Status == pkgAcquire::Item::StatIdle)
837 {
838 Transient = true;
839 // Failed = true;
840 continue;
841 }
842
843 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
844 (*I)->ErrorText.c_str());
845 Failed = true;
846 }
847
848 /* If we are in no download mode and missing files and there were
849 'failures' then the user must specify -m. Furthermore, there
850 is no such thing as a transient error in no-download mode! */
851 if (Transient == true &&
852 _config->FindB("APT::Get::Download",true) == false)
853 {
854 Transient = false;
855 Failed = true;
856 }
857
858 if (_config->FindB("APT::Get::Download-Only",false) == true)
859 {
860 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
861 return _error->Error(_("Some files failed to download"));
862 c1out << _("Download complete and in download only mode") << endl;
863 return true;
864 }
865
866 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
867 {
868 return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
869 }
870
871 if (Transient == true && Failed == true)
872 return _error->Error(_("--fix-missing and media swapping is not currently supported"));
873
874 // Try to deal with missing package files
875 if (Failed == true && PM->FixMissing() == false)
876 {
877 cerr << _("Unable to correct missing packages.") << endl;
878 return _error->Error(_("Aborting Install."));
879 }
880
881 _system->UnLock();
882 pkgPackageManager::OrderResult Res = PM->DoInstall();
883 if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
884 return false;
885 if (Res == pkgPackageManager::Completed)
886 return true;
887
888 // Reload the fetcher object and loop again for media swapping
889 Fetcher.Shutdown();
890 if (PM->GetArchives(&Fetcher,&List,&Recs) == false)
891 return false;
892
893 _system->Lock();
894 }
895 }
896 /*}}}*/
897 // TryToInstall - Try to install a single package /*{{{*/
898 // ---------------------------------------------------------------------
899 /* This used to be inlined in DoInstall, but with the advent of regex package
900 name matching it was split out.. */
901 bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
902 pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
903 unsigned int &ExpectedInst,bool AllowFail = true)
904 {
905 /* This is a pure virtual package and there is a single available
906 provides */
907 if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0 &&
908 Pkg.ProvidesList()->NextProvides == 0)
909 {
910 pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg();
911 ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
912 Tmp.Name(),Pkg.Name());
913 Pkg = Tmp;
914 }
915
916 // Handle the no-upgrade case
917 if (_config->FindB("APT::Get::upgrade",true) == false &&
918 Pkg->CurrentVer != 0)
919 {
920 if (AllowFail == true)
921 ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
922 Pkg.Name());
923 return true;
924 }
925
926 // Check if there is something at all to install
927 pkgDepCache::StateCache &State = Cache[Pkg];
928 if (Remove == true && Pkg->CurrentVer == 0)
929 {
930 /* We want to continue searching for regex hits, so we return false here
931 otherwise this is not really an error. */
932 if (AllowFail == false)
933 return false;
934 ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.Name());
935 return true;
936 }
937
938 if (State.CandidateVer == 0 && Remove == false)
939 {
940 if (AllowFail == false)
941 return false;
942
943 if (Pkg->ProvidesList != 0)
944 {
945 ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
946 Pkg.Name());
947
948 pkgCache::PrvIterator I = Pkg.ProvidesList();
949 for (; I.end() == false; I++)
950 {
951 pkgCache::PkgIterator Pkg = I.OwnerPkg();
952
953 if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer())
954 {
955 if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
956 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
957 _(" [Installed]") << endl;
958 else
959 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
960 }
961 }
962 c1out << _("You should explicitly select one to install.") << endl;
963 }
964 else
965 {
966 ioprintf(c1out,
967 _("Package %s has no available version, but exists in the database.\n"
968 "This typically means that the package was mentioned in a dependency and\n"
969 "never uploaded, has been obsoleted or is not available with the contents\n"
970 "of sources.list\n"),Pkg.Name());
971
972 string List;
973 SPtrArray<bool> Seen = new bool[Cache.Head().PackageCount];
974 memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen));
975 pkgCache::DepIterator Dep = Pkg.RevDependsList();
976 for (; Dep.end() == false; Dep++)
977 {
978 if (Dep->Type != pkgCache::Dep::Replaces)
979 continue;
980 if (Seen[Dep.ParentPkg()->ID] == true)
981 continue;
982 Seen[Dep.ParentPkg()->ID] = true;
983 List += string(Dep.ParentPkg().Name()) + " ";
984 }
985 ShowList(c1out,_("However the following packages replace it:"),List);
986 }
987
988 _error->Error(_("Package %s has no installation candidate"),Pkg.Name());
989 return false;
990 }
991
992 Fix.Clear(Pkg);
993 Fix.Protect(Pkg);
994 if (Remove == true)
995 {
996 Fix.Remove(Pkg);
997 Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
998 return true;
999 }
1000
1001 // Install it
1002 Cache.MarkInstall(Pkg,false);
1003 if (State.Install() == false)
1004 {
1005 if (_config->FindB("APT::Get::ReInstall",false) == true)
1006 {
1007 if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
1008 ioprintf(c1out,_("Sorry, re-installation of %s is not possible, it cannot be downloaded.\n"),
1009 Pkg.Name());
1010 else
1011 Cache.SetReInstall(Pkg,true);
1012 }
1013 else
1014 {
1015 if (AllowFail == true)
1016 ioprintf(c1out,_("Sorry, %s is already the newest version.\n"),
1017 Pkg.Name());
1018 }
1019 }
1020 else
1021 ExpectedInst++;
1022
1023 // Install it with autoinstalling enabled.
1024 if (State.InstBroken() == true && BrokenFix == false)
1025 Cache.MarkInstall(Pkg,true);
1026 return true;
1027 }
1028 /*}}}*/
1029 // TryToChangeVer - Try to change a candidate version /*{{{*/
1030 // ---------------------------------------------------------------------
1031 /* */
1032 bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
1033 const char *VerTag,bool IsRel)
1034 {
1035 pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release:pkgVersionMatch::Version));
1036
1037 pkgCache::VerIterator Ver = Match.Find(Pkg);
1038
1039 if (Ver.end() == true)
1040 {
1041 if (IsRel == true)
1042 return _error->Error(_("Release '%s' for '%s' was not found"),
1043 VerTag,Pkg.Name());
1044 return _error->Error(_("Version '%s' for '%s' was not found"),
1045 VerTag,Pkg.Name());
1046 }
1047
1048 if (strcmp(VerTag,Ver.VerStr()) != 0)
1049 {
1050 ioprintf(c1out,_("Selected version %s (%s) for %s\n"),
1051 Ver.VerStr(),Ver.RelStr().c_str(),Pkg.Name());
1052 }
1053
1054 Cache.SetCandidateVersion(Ver);
1055 return true;
1056 }
1057 /*}}}*/
1058 // FindSrc - Find a source record /*{{{*/
1059 // ---------------------------------------------------------------------
1060 /* */
1061 pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
1062 pkgSrcRecords &SrcRecs,string &Src,
1063 pkgDepCache &Cache)
1064 {
1065 // We want to pull the version off the package specification..
1066 string VerTag;
1067 string TmpSrc = Name;
1068 string::size_type Slash = TmpSrc.rfind('=');
1069 if (Slash != string::npos)
1070 {
1071 VerTag = string(TmpSrc.begin() + Slash + 1,TmpSrc.end());
1072 TmpSrc = string(TmpSrc.begin(),TmpSrc.begin() + Slash);
1073 }
1074
1075 /* Lookup the version of the package we would install if we were to
1076 install a version and determine the source package name, then look
1077 in the archive for a source package of the same name. In theory
1078 we could stash the version string as well and match that too but
1079 today there aren't multi source versions in the archive. */
1080 if (_config->FindB("APT::Get::Only-Source") == false &&
1081 VerTag.empty() == true)
1082 {
1083 pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc);
1084 if (Pkg.end() == false)
1085 {
1086 pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
1087 if (Ver.end() == false)
1088 {
1089 pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
1090 Src = Parse.SourcePkg();
1091 }
1092 }
1093 }
1094
1095 // No source package name..
1096 if (Src.empty() == true)
1097 Src = TmpSrc;
1098
1099 // The best hit
1100 pkgSrcRecords::Parser *Last = 0;
1101 unsigned long Offset = 0;
1102 string Version;
1103 bool IsMatch = false;
1104
1105 // If we are matching by version then we need exact matches to be happy
1106 if (VerTag.empty() == false)
1107 IsMatch = true;
1108
1109 /* Iterate over all of the hits, which includes the resulting
1110 binary packages in the search */
1111 pkgSrcRecords::Parser *Parse;
1112 SrcRecs.Restart();
1113 while ((Parse = SrcRecs.Find(Src.c_str(),false)) != 0)
1114 {
1115 string Ver = Parse->Version();
1116
1117 // Skip name mismatches
1118 if (IsMatch == true && Parse->Package() != Src)
1119 continue;
1120
1121 if (VerTag.empty() == false)
1122 {
1123 /* Don't want to fall through because we are doing exact version
1124 matching. */
1125 if (Cache.VS().CmpVersion(VerTag,Ver) != 0)
1126 continue;
1127
1128 Last = Parse;
1129 Offset = Parse->Offset();
1130 break;
1131 }
1132
1133 // Newer version or an exact match
1134 if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0 ||
1135 (Parse->Package() == Src && IsMatch == false))
1136 {
1137 IsMatch = Parse->Package() == Src;
1138 Last = Parse;
1139 Offset = Parse->Offset();
1140 Version = Ver;
1141 }
1142 }
1143
1144 if (Last == 0)
1145 return 0;
1146
1147 if (Last->Jump(Offset) == false)
1148 return 0;
1149
1150 return Last;
1151 }
1152 /*}}}*/
1153
1154 // DoUpdate - Update the package lists /*{{{*/
1155 // ---------------------------------------------------------------------
1156 /* */
1157 bool DoUpdate(CommandLine &CmdL)
1158 {
1159 if (CmdL.FileSize() != 1)
1160 return _error->Error(_("The update command takes no arguments"));
1161
1162 // Get the source list
1163 pkgSourceList List;
1164 if (List.ReadMainList() == false)
1165 return false;
1166
1167 // Lock the list directory
1168 FileFd Lock;
1169 if (_config->FindB("Debug::NoLocking",false) == false)
1170 {
1171 Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
1172 if (_error->PendingError() == true)
1173 return _error->Error(_("Unable to lock the list directory"));
1174 }
1175
1176 // Create the download object
1177 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1178 pkgAcquire Fetcher(&Stat);
1179
1180 // Populate it with the source selection
1181 if (List.GetIndexes(&Fetcher) == false)
1182 return false;
1183
1184 // Run it
1185 if (Fetcher.Run() == pkgAcquire::Failed)
1186 return false;
1187
1188 bool Failed = false;
1189 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
1190 {
1191 if ((*I)->Status == pkgAcquire::Item::StatDone)
1192 continue;
1193
1194 (*I)->Finished();
1195
1196 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1197 (*I)->ErrorText.c_str());
1198 Failed = true;
1199 }
1200
1201 // Clean out any old list files
1202 if (_config->FindB("APT::Get::List-Cleanup",true) == true)
1203 {
1204 if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
1205 Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
1206 return false;
1207 }
1208
1209 // Prepare the cache.
1210 CacheFile Cache;
1211 if (Cache.Open() == false)
1212 return false;
1213
1214 if (Failed == true)
1215 return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
1216
1217 return true;
1218 }
1219 /*}}}*/
1220 // DoUpgrade - Upgrade all packages /*{{{*/
1221 // ---------------------------------------------------------------------
1222 /* Upgrade all packages without installing new packages or erasing old
1223 packages */
1224 bool DoUpgrade(CommandLine &CmdL)
1225 {
1226 CacheFile Cache;
1227 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1228 return false;
1229
1230 // Do the upgrade
1231 if (pkgAllUpgrade(Cache) == false)
1232 {
1233 ShowBroken(c1out,Cache,false);
1234 return _error->Error(_("Internal Error, AllUpgrade broke stuff"));
1235 }
1236
1237 return InstallPackages(Cache,true);
1238 }
1239 /*}}}*/
1240 // DoInstall - Install packages from the command line /*{{{*/
1241 // ---------------------------------------------------------------------
1242 /* Install named packages */
1243 bool DoInstall(CommandLine &CmdL)
1244 {
1245 CacheFile Cache;
1246 if (Cache.OpenForInstall() == false ||
1247 Cache.CheckDeps(CmdL.FileSize() != 1) == false)
1248 return false;
1249
1250 // Enter the special broken fixing mode if the user specified arguments
1251 bool BrokenFix = false;
1252 if (Cache->BrokenCount() != 0)
1253 BrokenFix = true;
1254
1255 unsigned int ExpectedInst = 0;
1256 unsigned int Packages = 0;
1257 pkgProblemResolver Fix(Cache);
1258
1259 bool DefRemove = false;
1260 if (strcasecmp(CmdL.FileList[0],"remove") == 0)
1261 DefRemove = true;
1262
1263 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
1264 {
1265 // Duplicate the string
1266 unsigned int Length = strlen(*I);
1267 char S[300];
1268 if (Length >= sizeof(S))
1269 continue;
1270 strcpy(S,*I);
1271
1272 // See if we are removing and special indicators..
1273 bool Remove = DefRemove;
1274 char *VerTag = 0;
1275 bool VerIsRel = false;
1276 while (Cache->FindPkg(S).end() == true)
1277 {
1278 // Handle an optional end tag indicating what to do
1279 if (S[Length - 1] == '-')
1280 {
1281 Remove = true;
1282 S[--Length] = 0;
1283 continue;
1284 }
1285
1286 if (S[Length - 1] == '+')
1287 {
1288 Remove = false;
1289 S[--Length] = 0;
1290 continue;
1291 }
1292
1293 char *Slash = strchr(S,'=');
1294 if (Slash != 0)
1295 {
1296 VerIsRel = false;
1297 *Slash = 0;
1298 VerTag = Slash + 1;
1299 }
1300
1301 Slash = strchr(S,'/');
1302 if (Slash != 0)
1303 {
1304 VerIsRel = true;
1305 *Slash = 0;
1306 VerTag = Slash + 1;
1307 }
1308
1309 break;
1310 }
1311
1312 // Locate the package
1313 pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
1314 Packages++;
1315 if (Pkg.end() == true)
1316 {
1317 // Check if the name is a regex
1318 const char *I;
1319 for (I = S; *I != 0; I++)
1320 if (*I == '.' || *I == '?' || *I == '*' || *I == '|')
1321 break;
1322 if (*I == 0)
1323 return _error->Error(_("Couldn't find package %s"),S);
1324
1325 // Regexs must always be confirmed
1326 ExpectedInst += 1000;
1327
1328 // Compile the regex pattern
1329 regex_t Pattern;
1330 int Res;
1331 if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE |
1332 REG_NOSUB)) != 0)
1333 {
1334 char Error[300];
1335 regerror(Res,&Pattern,Error,sizeof(Error));
1336 return _error->Error(_("Regex compilation error - %s"),Error);
1337 }
1338
1339 // Run over the matches
1340 bool Hit = false;
1341 for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++)
1342 {
1343 if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0)
1344 continue;
1345
1346 if (VerTag != 0)
1347 if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
1348 return false;
1349
1350 Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
1351 ExpectedInst,false);
1352 }
1353 regfree(&Pattern);
1354
1355 if (Hit == false)
1356 return _error->Error(_("Couldn't find package %s"),S);
1357 }
1358 else
1359 {
1360 if (VerTag != 0)
1361 if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
1362 return false;
1363 if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
1364 return false;
1365 }
1366 }
1367
1368 /* If we are in the Broken fixing mode we do not attempt to fix the
1369 problems. This is if the user invoked install without -f and gave
1370 packages */
1371 if (BrokenFix == true && Cache->BrokenCount() != 0)
1372 {
1373 c1out << _("You might want to run `apt-get -f install' to correct these:") << endl;
1374 ShowBroken(c1out,Cache,false);
1375
1376 return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
1377 }
1378
1379 // Call the scored problem resolver
1380 Fix.InstallProtect();
1381 if (Fix.Resolve(true) == false)
1382 _error->Discard();
1383
1384 // Now we check the state of the packages,
1385 if (Cache->BrokenCount() != 0)
1386 {
1387 c1out <<
1388 _("Some packages could not be installed. This may mean that you have\n"
1389 "requested an impossible situation or if you are using the unstable\n"
1390 "distribution that some required packages have not yet been created\n"
1391 "or been moved out of Incoming.") << endl;
1392 if (Packages == 1)
1393 {
1394 c1out << endl;
1395 c1out <<
1396 _("Since you only requested a single operation it is extremely likely that\n"
1397 "the package is simply not installable and a bug report against\n"
1398 "that package should be filed.") << endl;
1399 }
1400
1401 c1out << _("The following information may help to resolve the situation:") << endl;
1402 c1out << endl;
1403 ShowBroken(c1out,Cache,false);
1404 return _error->Error(_("Sorry, broken packages"));
1405 }
1406
1407 /* Print out a list of packages that are going to be installed extra
1408 to what the user asked */
1409 if (Cache->InstCount() != ExpectedInst)
1410 {
1411 string List;
1412 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
1413 {
1414 pkgCache::PkgIterator I(Cache,Cache.List[J]);
1415 if ((*Cache)[I].Install() == false)
1416 continue;
1417
1418 const char **J;
1419 for (J = CmdL.FileList + 1; *J != 0; J++)
1420 if (strcmp(*J,I.Name()) == 0)
1421 break;
1422
1423 if (*J == 0)
1424 List += string(I.Name()) + " ";
1425 }
1426
1427 ShowList(c1out,_("The following extra packages will be installed:"),List);
1428 }
1429
1430 // See if we need to prompt
1431 if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
1432 return InstallPackages(Cache,false,false);
1433
1434 return InstallPackages(Cache,false);
1435 }
1436 /*}}}*/
1437 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
1438 // ---------------------------------------------------------------------
1439 /* Intelligent upgrader that will install and remove packages at will */
1440 bool DoDistUpgrade(CommandLine &CmdL)
1441 {
1442 CacheFile Cache;
1443 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1444 return false;
1445
1446 c0out << _("Calculating Upgrade... ") << flush;
1447 if (pkgDistUpgrade(*Cache) == false)
1448 {
1449 c0out << _("Failed") << endl;
1450 ShowBroken(c1out,Cache,false);
1451 return false;
1452 }
1453
1454 c0out << _("Done") << endl;
1455
1456 return InstallPackages(Cache,true);
1457 }
1458 /*}}}*/
1459 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
1460 // ---------------------------------------------------------------------
1461 /* Follows dselect's selections */
1462 bool DoDSelectUpgrade(CommandLine &CmdL)
1463 {
1464 CacheFile Cache;
1465 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1466 return false;
1467
1468 // Install everything with the install flag set
1469 pkgCache::PkgIterator I = Cache->PkgBegin();
1470 for (;I.end() != true; I++)
1471 {
1472 /* Install the package only if it is a new install, the autoupgrader
1473 will deal with the rest */
1474 if (I->SelectedState == pkgCache::State::Install)
1475 Cache->MarkInstall(I,false);
1476 }
1477
1478 /* Now install their deps too, if we do this above then order of
1479 the status file is significant for | groups */
1480 for (I = Cache->PkgBegin();I.end() != true; I++)
1481 {
1482 /* Install the package only if it is a new install, the autoupgrader
1483 will deal with the rest */
1484 if (I->SelectedState == pkgCache::State::Install)
1485 Cache->MarkInstall(I,true);
1486 }
1487
1488 // Apply erasures now, they override everything else.
1489 for (I = Cache->PkgBegin();I.end() != true; I++)
1490 {
1491 // Remove packages
1492 if (I->SelectedState == pkgCache::State::DeInstall ||
1493 I->SelectedState == pkgCache::State::Purge)
1494 Cache->MarkDelete(I,I->SelectedState == pkgCache::State::Purge);
1495 }
1496
1497 /* Resolve any problems that dselect created, allupgrade cannot handle
1498 such things. We do so quite agressively too.. */
1499 if (Cache->BrokenCount() != 0)
1500 {
1501 pkgProblemResolver Fix(Cache);
1502
1503 // Hold back held packages.
1504 if (_config->FindB("APT::Ignore-Hold",false) == false)
1505 {
1506 for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++)
1507 {
1508 if (I->SelectedState == pkgCache::State::Hold)
1509 {
1510 Fix.Protect(I);
1511 Cache->MarkKeep(I);
1512 }
1513 }
1514 }
1515
1516 if (Fix.Resolve() == false)
1517 {
1518 ShowBroken(c1out,Cache,false);
1519 return _error->Error("Internal Error, problem resolver broke stuff");
1520 }
1521 }
1522
1523 // Now upgrade everything
1524 if (pkgAllUpgrade(Cache) == false)
1525 {
1526 ShowBroken(c1out,Cache,false);
1527 return _error->Error("Internal Error, problem resolver broke stuff");
1528 }
1529
1530 return InstallPackages(Cache,false);
1531 }
1532 /*}}}*/
1533 // DoClean - Remove download archives /*{{{*/
1534 // ---------------------------------------------------------------------
1535 /* */
1536 bool DoClean(CommandLine &CmdL)
1537 {
1538 if (_config->FindB("APT::Get::Simulate") == true)
1539 {
1540 cout << "Del " << _config->FindDir("Dir::Cache::archives") << "* " <<
1541 _config->FindDir("Dir::Cache::archives") << "partial/*" << endl;
1542 return true;
1543 }
1544
1545 // Lock the archive directory
1546 FileFd Lock;
1547 if (_config->FindB("Debug::NoLocking",false) == false)
1548 {
1549 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1550 if (_error->PendingError() == true)
1551 return _error->Error(_("Unable to lock the download directory"));
1552 }
1553
1554 pkgAcquire Fetcher;
1555 Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
1556 Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
1557 return true;
1558 }
1559 /*}}}*/
1560 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
1561 // ---------------------------------------------------------------------
1562 /* This is similar to clean but it only purges things that cannot be
1563 downloaded, that is old versions of cached packages. */
1564 class LogCleaner : public pkgArchiveCleaner
1565 {
1566 protected:
1567 virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St)
1568 {
1569 c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << endl;
1570
1571 if (_config->FindB("APT::Get::Simulate") == false)
1572 unlink(File);
1573 };
1574 };
1575
1576 bool DoAutoClean(CommandLine &CmdL)
1577 {
1578 // Lock the archive directory
1579 FileFd Lock;
1580 if (_config->FindB("Debug::NoLocking",false) == false)
1581 {
1582 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1583 if (_error->PendingError() == true)
1584 return _error->Error(_("Unable to lock the download directory"));
1585 }
1586
1587 CacheFile Cache;
1588 if (Cache.Open() == false)
1589 return false;
1590
1591 LogCleaner Cleaner;
1592
1593 return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) &&
1594 Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache);
1595 }
1596 /*}}}*/
1597 // DoCheck - Perform the check operation /*{{{*/
1598 // ---------------------------------------------------------------------
1599 /* Opening automatically checks the system, this command is mostly used
1600 for debugging */
1601 bool DoCheck(CommandLine &CmdL)
1602 {
1603 CacheFile Cache;
1604 Cache.Open();
1605 Cache.CheckDeps();
1606
1607 return true;
1608 }
1609 /*}}}*/
1610 // DoSource - Fetch a source archive /*{{{*/
1611 // ---------------------------------------------------------------------
1612 /* Fetch souce packages */
1613 struct DscFile
1614 {
1615 string Package;
1616 string Version;
1617 string Dsc;
1618 };
1619
1620 bool DoSource(CommandLine &CmdL)
1621 {
1622 CacheFile Cache;
1623 if (Cache.Open(false) == false)
1624 return false;
1625
1626 if (CmdL.FileSize() <= 1)
1627 return _error->Error(_("Must specify at least one package to fetch source for"));
1628
1629 // Read the source list
1630 pkgSourceList List;
1631 if (List.ReadMainList() == false)
1632 return _error->Error(_("The list of sources could not be read."));
1633
1634 // Create the text record parsers
1635 pkgRecords Recs(Cache);
1636 pkgSrcRecords SrcRecs(List);
1637 if (_error->PendingError() == true)
1638 return false;
1639
1640 // Create the download object
1641 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1642 pkgAcquire Fetcher(&Stat);
1643
1644 DscFile *Dsc = new DscFile[CmdL.FileSize()];
1645
1646 // Load the requestd sources into the fetcher
1647 unsigned J = 0;
1648 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
1649 {
1650 string Src;
1651 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
1652
1653 if (Last == 0)
1654 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
1655
1656 // Back track
1657 vector<pkgSrcRecords::File> Lst;
1658 if (Last->Files(Lst) == false)
1659 return false;
1660
1661 // Load them into the fetcher
1662 for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
1663 I != Lst.end(); I++)
1664 {
1665 // Try to guess what sort of file it is we are getting.
1666 if (I->Type == "dsc")
1667 {
1668 Dsc[J].Package = Last->Package();
1669 Dsc[J].Version = Last->Version();
1670 Dsc[J].Dsc = flNotDir(I->Path);
1671 }
1672
1673 // Diff only mode only fetches .diff files
1674 if (_config->FindB("APT::Get::Diff-Only",false) == true &&
1675 I->Type != "diff")
1676 continue;
1677
1678 // Tar only mode only fetches .tar files
1679 if (_config->FindB("APT::Get::Tar-Only",false) == true &&
1680 I->Type != "tar")
1681 continue;
1682
1683 new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path),
1684 I->MD5Hash,I->Size,
1685 Last->Index().SourceInfo(*Last,*I),Src);
1686 }
1687 }
1688
1689 // Display statistics
1690 double FetchBytes = Fetcher.FetchNeeded();
1691 double FetchPBytes = Fetcher.PartialPresent();
1692 double DebBytes = Fetcher.TotalNeeded();
1693
1694 // Check for enough free space
1695 struct statvfs Buf;
1696 string OutputDir = ".";
1697 if (statvfs(OutputDir.c_str(),&Buf) != 0)
1698 return _error->Errno("statvfs","Couldn't determine free space in %s",
1699 OutputDir.c_str());
1700 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
1701 return _error->Error(_("Sorry, you don't have enough free space in %s"),
1702 OutputDir.c_str());
1703
1704 // Number of bytes
1705 if (DebBytes != FetchBytes)
1706 ioprintf(c1out,_("Need to get %sB/%sB of source archives.\n"),
1707 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
1708 else
1709 ioprintf(c1out,_("Need to get %sB of source archives.\n"),
1710 SizeToStr(DebBytes).c_str());
1711
1712 if (_config->FindB("APT::Get::Simulate",false) == true)
1713 {
1714 for (unsigned I = 0; I != J; I++)
1715 ioprintf(cout,_("Fetch Source %s\n"),Dsc[I].Package.c_str());
1716 return true;
1717 }
1718
1719 // Just print out the uris an exit if the --print-uris flag was used
1720 if (_config->FindB("APT::Get::Print-URIs") == true)
1721 {
1722 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1723 for (; I != Fetcher.UriEnd(); I++)
1724 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1725 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
1726 return true;
1727 }
1728
1729 // Run it
1730 if (Fetcher.Run() == pkgAcquire::Failed)
1731 return false;
1732
1733 // Print error messages
1734 bool Failed = false;
1735 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
1736 {
1737 if ((*I)->Status == pkgAcquire::Item::StatDone &&
1738 (*I)->Complete == true)
1739 continue;
1740
1741 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1742 (*I)->ErrorText.c_str());
1743 Failed = true;
1744 }
1745 if (Failed == true)
1746 return _error->Error(_("Failed to fetch some archives."));
1747
1748 if (_config->FindB("APT::Get::Download-only",false) == true)
1749 {
1750 c1out << _("Download complete and in download only mode") << endl;
1751 return true;
1752 }
1753
1754 // Unpack the sources
1755 pid_t Process = ExecFork();
1756
1757 if (Process == 0)
1758 {
1759 for (unsigned I = 0; I != J; I++)
1760 {
1761 string Dir = Dsc[I].Package + '-' + Cache->VS().UpstreamVersion(Dsc[I].Version.c_str());
1762
1763 // Diff only mode only fetches .diff files
1764 if (_config->FindB("APT::Get::Diff-Only",false) == true ||
1765 _config->FindB("APT::Get::Tar-Only",false) == true ||
1766 Dsc[I].Dsc.empty() == true)
1767 continue;
1768
1769 // See if the package is already unpacked
1770 struct stat Stat;
1771 if (stat(Dir.c_str(),&Stat) == 0 &&
1772 S_ISDIR(Stat.st_mode) != 0)
1773 {
1774 ioprintf(c0out ,_("Skipping unpack of already unpacked source in %s\n"),
1775 Dir.c_str());
1776 }
1777 else
1778 {
1779 // Call dpkg-source
1780 char S[500];
1781 snprintf(S,sizeof(S),"%s -x %s",
1782 _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
1783 Dsc[I].Dsc.c_str());
1784 if (system(S) != 0)
1785 {
1786 fprintf(stderr,_("Unpack command '%s' failed.\n"),S);
1787 _exit(1);
1788 }
1789 }
1790
1791 // Try to compile it with dpkg-buildpackage
1792 if (_config->FindB("APT::Get::Compile",false) == true)
1793 {
1794 // Call dpkg-buildpackage
1795 char S[500];
1796 snprintf(S,sizeof(S),"cd %s && %s %s",
1797 Dir.c_str(),
1798 _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
1799 _config->Find("DPkg::Build-Options","-b -uc").c_str());
1800
1801 if (system(S) != 0)
1802 {
1803 fprintf(stderr,_("Build command '%s' failed.\n"),S);
1804 _exit(1);
1805 }
1806 }
1807 }
1808
1809 _exit(0);
1810 }
1811
1812 // Wait for the subprocess
1813 int Status = 0;
1814 while (waitpid(Process,&Status,0) != Process)
1815 {
1816 if (errno == EINTR)
1817 continue;
1818 return _error->Errno("waitpid","Couldn't wait for subprocess");
1819 }
1820
1821 if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
1822 return _error->Error(_("Child process failed"));
1823
1824 return true;
1825 }
1826 /*}}}*/
1827 // DoBuildDep - Install/removes packages to satisfy build dependencies /*{{{*/
1828 // ---------------------------------------------------------------------
1829 /* This function will look at the build depends list of the given source
1830 package and install the necessary packages to make it true, or fail. */
1831 bool DoBuildDep(CommandLine &CmdL)
1832 {
1833 CacheFile Cache;
1834 if (Cache.Open(true) == false)
1835 return false;
1836
1837 if (CmdL.FileSize() <= 1)
1838 return _error->Error(_("Must specify at least one package to check builddeps for"));
1839
1840 // Read the source list
1841 pkgSourceList List;
1842 if (List.ReadMainList() == false)
1843 return _error->Error(_("The list of sources could not be read."));
1844
1845 // Create the text record parsers
1846 pkgRecords Recs(Cache);
1847 pkgSrcRecords SrcRecs(List);
1848 if (_error->PendingError() == true)
1849 return false;
1850
1851 // Create the download object
1852 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1853 pkgAcquire Fetcher(&Stat);
1854
1855 unsigned J = 0;
1856 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
1857 {
1858 string Src;
1859 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
1860 if (Last == 0)
1861 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
1862
1863 // Process the build-dependencies
1864 vector<pkgSrcRecords::Parser::BuildDepRec> BuildDeps;
1865 if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only",false)) == false)
1866 return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str());
1867
1868 // Also ensure that build-essential packages are present
1869 Configuration::Item const *Opts = _config->Tree("APT::Build-Essential");
1870 if (Opts)
1871 Opts = Opts->Child;
1872 for (; Opts; Opts = Opts->Next)
1873 {
1874 if (Opts->Value.empty() == true)
1875 continue;
1876
1877 pkgSrcRecords::Parser::BuildDepRec rec;
1878 rec.Package = Opts->Value;
1879 rec.Type = pkgSrcRecords::Parser::BuildDependIndep;
1880 rec.Op = 0;
1881 BuildDeps.insert(BuildDeps.begin(), rec);
1882 }
1883
1884 if (BuildDeps.size() == 0)
1885 {
1886 ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
1887 continue;
1888 }
1889
1890 // Install the requested packages
1891 unsigned int ExpectedInst = 0;
1892 vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
1893 pkgProblemResolver Fix(Cache);
1894 for (D = BuildDeps.begin(); D != BuildDeps.end(); D++)
1895 {
1896 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
1897 if (Pkg.end() == true)
1898 {
1899 /* for a build-conflict; ignore unknown packages */
1900 if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
1901 (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
1902 continue;
1903
1904 return _error->Error(_("%s dependency on %s cannot be satisfied because the package %s cannot be found"),
1905 Last->BuildDepType((*D).Type),Src.c_str(),(*D).Package.c_str());
1906 }
1907 pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
1908
1909 if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
1910 (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
1911 {
1912 /*
1913 * conflict; need to remove if we have an installed version
1914 * that satisfies the version criterial
1915 */
1916 if (IV.end() == false &&
1917 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
1918 TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
1919 }
1920 else
1921 {
1922 /*
1923 * If this is a virtual package, we need to check the list of
1924 * packages that provide it and see if any of those are
1925 * installed
1926 */
1927 pkgCache::PrvIterator Prv = Pkg.ProvidesList();
1928 for (; Prv.end() != true; Prv++)
1929 if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
1930 break;
1931
1932 if (Prv.end() == true)
1933 {
1934 /*
1935 * depends; need to install or upgrade if we don't have the
1936 * package installed or if the version does not satisfy the
1937 * build dep. This is complicated by the fact that if we
1938 * depend on a version lower than what we already have
1939 * installed it is not clear what should be done; in practice
1940 * this case should be rare though and right now nothing
1941 * is done about it :-(
1942 */
1943 if (IV.end() == true ||
1944 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == false)
1945 TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst);
1946 }
1947 }
1948 }
1949
1950 Fix.InstallProtect();
1951 if (Fix.Resolve(true) == false)
1952 _error->Discard();
1953
1954 // Now we check the state of the packages,
1955 if (Cache->BrokenCount() != 0)
1956 return _error->Error(_("Some broken packages were found while trying to process build-dependencies.\n"
1957 "You might want to run `apt-get -f install' to correct these."));
1958 }
1959
1960 if (InstallPackages(Cache, false, true) == false)
1961 return _error->Error(_("Failed to process build dependencies"));
1962 return true;
1963 }
1964 /*}}}*/
1965
1966 // DoMoo - Never Ask, Never Tell /*{{{*/
1967 // ---------------------------------------------------------------------
1968 /* */
1969 bool DoMoo(CommandLine &CmdL)
1970 {
1971 cout <<
1972 " (__) \n"
1973 " (oo) \n"
1974 " /------\\/ \n"
1975 " / | || \n"
1976 " * /\\---/\\ \n"
1977 " ~~ ~~ \n"
1978 "....\"Have you mooed today?\"...\n";
1979
1980 return true;
1981 }
1982 /*}}}*/
1983 // ShowHelp - Show a help screen /*{{{*/
1984 // ---------------------------------------------------------------------
1985 /* */
1986 bool ShowHelp(CommandLine &CmdL)
1987 {
1988 ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
1989 COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
1990
1991 if (_config->FindB("version") == true)
1992 {
1993 cout << _("Supported Modules:") << endl;
1994
1995 for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++)
1996 {
1997 pkgVersioningSystem *VS = pkgVersioningSystem::GlobalList[I];
1998 if (_system != 0 && _system->VS == VS)
1999 cout << '*';
2000 else
2001 cout << ' ';
2002 cout << "Ver: " << VS->Label << endl;
2003
2004 /* Print out all the packaging systems that will work with
2005 this VS */
2006 for (unsigned J = 0; J != pkgSystem::GlobalListLen; J++)
2007 {
2008 pkgSystem *Sys = pkgSystem::GlobalList[J];
2009 if (_system == Sys)
2010 cout << '*';
2011 else
2012 cout << ' ';
2013 if (Sys->VS->TestCompatibility(*VS) == true)
2014 cout << "Pkg: " << Sys->Label << " (Priority " << Sys->Score(*_config) << ")" << endl;
2015 }
2016 }
2017
2018 for (unsigned I = 0; I != pkgSourceList::Type::GlobalListLen; I++)
2019 {
2020 pkgSourceList::Type *Type = pkgSourceList::Type::GlobalList[I];
2021 cout << " S.L: '" << Type->Name << "' " << Type->Label << endl;
2022 }
2023
2024 for (unsigned I = 0; I != pkgIndexFile::Type::GlobalListLen; I++)
2025 {
2026 pkgIndexFile::Type *Type = pkgIndexFile::Type::GlobalList[I];
2027 cout << " Idx: " << Type->Label << endl;
2028 }
2029
2030 return true;
2031 }
2032
2033 cout <<
2034 _("Usage: apt-get [options] command\n"
2035 " apt-get [options] install|remove pkg1 [pkg2 ...]\n"
2036 " apt-get [options] source pkg1 [pkg2 ...]\n"
2037 "\n"
2038 "apt-get is a simple command line interface for downloading and\n"
2039 "installing packages. The most frequently used commands are update\n"
2040 "and install.\n"
2041 "\n"
2042 "Commands:\n"
2043 " update - Retrieve new lists of packages\n"
2044 " upgrade - Perform an upgrade\n"
2045 " install - Install new packages (pkg is libc6 not libc6.deb)\n"
2046 " remove - Remove packages\n"
2047 " source - Download source archives\n"
2048 " build-dep - Configure build-dependencies for source packages\n"
2049 " dist-upgrade - Distribution upgrade, see apt-get(8)\n"
2050 " dselect-upgrade - Follow dselect selections\n"
2051 " clean - Erase downloaded archive files\n"
2052 " autoclean - Erase old downloaded archive files\n"
2053 " check - Verify that there are no broken dependencies\n"
2054 "\n"
2055 "Options:\n"
2056 " -h This help text.\n"
2057 " -q Loggable output - no progress indicator\n"
2058 " -qq No output except for errors\n"
2059 " -d Download only - do NOT install or unpack archives\n"
2060 " -s No-act. Perform ordering simulation\n"
2061 " -y Assume Yes to all queries and do not prompt\n"
2062 " -f Attempt to continue if the integrity check fails\n"
2063 " -m Attempt to continue if archives are unlocatable\n"
2064 " -u Show a list of upgraded packages as well\n"
2065 " -b Build the source package after fetching it\n"
2066 " -c=? Read this configuration file\n"
2067 " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp\n"
2068 "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n"
2069 "pages for more information and options.\n"
2070 " This APT has Super Cow Powers.\n");
2071 return true;
2072 }
2073 /*}}}*/
2074 // GetInitialize - Initialize things for apt-get /*{{{*/
2075 // ---------------------------------------------------------------------
2076 /* */
2077 void GetInitialize()
2078 {
2079 _config->Set("quiet",0);
2080 _config->Set("help",false);
2081 _config->Set("APT::Get::Download-Only",false);
2082 _config->Set("APT::Get::Simulate",false);
2083 _config->Set("APT::Get::Assume-Yes",false);
2084 _config->Set("APT::Get::Fix-Broken",false);
2085 _config->Set("APT::Get::Force-Yes",false);
2086 _config->Set("APT::Get::APT::Get::No-List-Cleanup",true);
2087 }
2088 /*}}}*/
2089 // SigWinch - Window size change signal handler /*{{{*/
2090 // ---------------------------------------------------------------------
2091 /* */
2092 void SigWinch(int)
2093 {
2094 // Riped from GNU ls
2095 #ifdef TIOCGWINSZ
2096 struct winsize ws;
2097
2098 if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
2099 ScreenWidth = ws.ws_col - 1;
2100 #endif
2101 }
2102 /*}}}*/
2103
2104 int main(int argc,const char *argv[])
2105 {
2106 CommandLine::Args Args[] = {
2107 {'h',"help","help",0},
2108 {'v',"version","version",0},
2109 {'q',"quiet","quiet",CommandLine::IntLevel},
2110 {'q',"silent","quiet",CommandLine::IntLevel},
2111 {'d',"download-only","APT::Get::Download-Only",0},
2112 {'b',"compile","APT::Get::Compile",0},
2113 {'b',"build","APT::Get::Compile",0},
2114 {'s',"simulate","APT::Get::Simulate",0},
2115 {'s',"just-print","APT::Get::Simulate",0},
2116 {'s',"recon","APT::Get::Simulate",0},
2117 {'s',"dry-run","APT::Get::Simulate",0},
2118 {'s',"no-act","APT::Get::Simulate",0},
2119 {'y',"yes","APT::Get::Assume-Yes",0},
2120 {'y',"assume-yes","APT::Get::Assume-Yes",0},
2121 {'f',"fix-broken","APT::Get::Fix-Broken",0},
2122 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
2123 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
2124 {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
2125 {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
2126 {0,"download","APT::Get::Download",0},
2127 {0,"fix-missing","APT::Get::Fix-Missing",0},
2128 {0,"ignore-hold","APT::Ignore-Hold",0},
2129 {0,"upgrade","APT::Get::upgrade",0},
2130 {0,"force-yes","APT::Get::force-yes",0},
2131 {0,"print-uris","APT::Get::Print-URIs",0},
2132 {0,"diff-only","APT::Get::Diff-Only",0},
2133 {0,"tar-only","APT::Get::tar-Only",0},
2134 {0,"purge","APT::Get::Purge",0},
2135 {0,"list-cleanup","APT::Get::List-Cleanup",0},
2136 {0,"reinstall","APT::Get::ReInstall",0},
2137 {0,"trivial-only","APT::Get::Trivial-Only",0},
2138 {0,"remove","APT::Get::Remove",0},
2139 {0,"only-source","APT::Get::Only-Source",0},
2140 {0,"arch-only","APT::Get::Arch-Only",0},
2141 {'c',"config-file",0,CommandLine::ConfigFile},
2142 {'o',"option",0,CommandLine::ArbItem},
2143 {0,0,0,0}};
2144 CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
2145 {"upgrade",&DoUpgrade},
2146 {"install",&DoInstall},
2147 {"remove",&DoInstall},
2148 {"dist-upgrade",&DoDistUpgrade},
2149 {"dselect-upgrade",&DoDSelectUpgrade},
2150 {"build-dep",&DoBuildDep},
2151 {"clean",&DoClean},
2152 {"autoclean",&DoAutoClean},
2153 {"check",&DoCheck},
2154 {"source",&DoSource},
2155 {"moo",&DoMoo},
2156 {"help",&ShowHelp},
2157 {0,0}};
2158
2159 // Set up gettext support
2160 setlocale(LC_ALL,"");
2161 textdomain(PACKAGE);
2162
2163 // Parse the command line and initialize the package library
2164 CommandLine CmdL(Args,_config);
2165 if (pkgInitConfig(*_config) == false ||
2166 CmdL.Parse(argc,argv) == false ||
2167 pkgInitSystem(*_config,_system) == false)
2168 {
2169 if (_config->FindB("version") == true)
2170 ShowHelp(CmdL);
2171
2172 _error->DumpErrors();
2173 return 100;
2174 }
2175
2176 // See if the help should be shown
2177 if (_config->FindB("help") == true ||
2178 _config->FindB("version") == true ||
2179 CmdL.FileSize() == 0)
2180 {
2181 ShowHelp(CmdL);
2182 return 0;
2183 }
2184
2185 // Deal with stdout not being a tty
2186 if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
2187 _config->Set("quiet","1");
2188
2189 // Setup the output streams
2190 c0out.rdbuf(cout.rdbuf());
2191 c1out.rdbuf(cout.rdbuf());
2192 c2out.rdbuf(cout.rdbuf());
2193 if (_config->FindI("quiet",0) > 0)
2194 c0out.rdbuf(devnull.rdbuf());
2195 if (_config->FindI("quiet",0) > 1)
2196 c1out.rdbuf(devnull.rdbuf());
2197
2198 // Setup the signals
2199 signal(SIGPIPE,SIG_IGN);
2200 signal(SIGWINCH,SigWinch);
2201 SigWinch(0);
2202
2203 // Match the operation
2204 CmdL.DispatchArg(Cmds);
2205
2206 // Print any errors or warnings found during parsing
2207 if (_error->empty() == false)
2208 {
2209 bool Errors = _error->PendingError();
2210 _error->DumpErrors();
2211 return Errors == true?100:0;
2212 }
2213
2214 return 0;
2215 }