]> git.saurik.com Git - apt.git/blob - cmdline/apt-get.cc
Allow an uninstalled package to be marked for removal
[apt.git] / cmdline / apt-get.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: apt-get.cc,v 1.119 2002/04/26 05:36:43 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 Fix.Clear(Pkg);
931 Fix.Protect(Pkg);
932 Fix.Remove(Pkg);
933
934 /* We want to continue searching for regex hits, so we return false here
935 otherwise this is not really an error. */
936 if (AllowFail == false)
937 return false;
938
939 ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.Name());
940 return true;
941 }
942
943 if (State.CandidateVer == 0 && Remove == false)
944 {
945 if (AllowFail == false)
946 return false;
947
948 if (Pkg->ProvidesList != 0)
949 {
950 ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
951 Pkg.Name());
952
953 pkgCache::PrvIterator I = Pkg.ProvidesList();
954 for (; I.end() == false; I++)
955 {
956 pkgCache::PkgIterator Pkg = I.OwnerPkg();
957
958 if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer())
959 {
960 if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
961 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
962 _(" [Installed]") << endl;
963 else
964 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
965 }
966 }
967 c1out << _("You should explicitly select one to install.") << endl;
968 }
969 else
970 {
971 ioprintf(c1out,
972 _("Package %s has no available version, but exists in the database.\n"
973 "This typically means that the package was mentioned in a dependency and\n"
974 "never uploaded, has been obsoleted or is not available with the contents\n"
975 "of sources.list\n"),Pkg.Name());
976
977 string List;
978 SPtrArray<bool> Seen = new bool[Cache.Head().PackageCount];
979 memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen));
980 pkgCache::DepIterator Dep = Pkg.RevDependsList();
981 for (; Dep.end() == false; Dep++)
982 {
983 if (Dep->Type != pkgCache::Dep::Replaces)
984 continue;
985 if (Seen[Dep.ParentPkg()->ID] == true)
986 continue;
987 Seen[Dep.ParentPkg()->ID] = true;
988 List += string(Dep.ParentPkg().Name()) + " ";
989 }
990 ShowList(c1out,_("However the following packages replace it:"),List);
991 }
992
993 _error->Error(_("Package %s has no installation candidate"),Pkg.Name());
994 return false;
995 }
996
997 Fix.Clear(Pkg);
998 Fix.Protect(Pkg);
999 if (Remove == true)
1000 {
1001 Fix.Remove(Pkg);
1002 Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
1003 return true;
1004 }
1005
1006 // Install it
1007 Cache.MarkInstall(Pkg,false);
1008 if (State.Install() == false)
1009 {
1010 if (_config->FindB("APT::Get::ReInstall",false) == true)
1011 {
1012 if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
1013 ioprintf(c1out,_("Sorry, re-installation of %s is not possible, it cannot be downloaded.\n"),
1014 Pkg.Name());
1015 else
1016 Cache.SetReInstall(Pkg,true);
1017 }
1018 else
1019 {
1020 if (AllowFail == true)
1021 ioprintf(c1out,_("Sorry, %s is already the newest version.\n"),
1022 Pkg.Name());
1023 }
1024 }
1025 else
1026 ExpectedInst++;
1027
1028 // Install it with autoinstalling enabled.
1029 if (State.InstBroken() == true && BrokenFix == false)
1030 Cache.MarkInstall(Pkg,true);
1031 return true;
1032 }
1033 /*}}}*/
1034 // TryToChangeVer - Try to change a candidate version /*{{{*/
1035 // ---------------------------------------------------------------------
1036 /* */
1037 bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
1038 const char *VerTag,bool IsRel)
1039 {
1040 pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release :
1041 pkgVersionMatch::Version));
1042
1043 pkgCache::VerIterator Ver = Match.Find(Pkg);
1044
1045 if (Ver.end() == true)
1046 {
1047 if (IsRel == true)
1048 return _error->Error(_("Release '%s' for '%s' was not found"),
1049 VerTag,Pkg.Name());
1050 return _error->Error(_("Version '%s' for '%s' was not found"),
1051 VerTag,Pkg.Name());
1052 }
1053
1054 if (strcmp(VerTag,Ver.VerStr()) != 0)
1055 {
1056 ioprintf(c1out,_("Selected version %s (%s) for %s\n"),
1057 Ver.VerStr(),Ver.RelStr().c_str(),Pkg.Name());
1058 }
1059
1060 Cache.SetCandidateVersion(Ver);
1061 return true;
1062 }
1063 /*}}}*/
1064 // FindSrc - Find a source record /*{{{*/
1065 // ---------------------------------------------------------------------
1066 /* */
1067 pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
1068 pkgSrcRecords &SrcRecs,string &Src,
1069 pkgDepCache &Cache)
1070 {
1071 // We want to pull the version off the package specification..
1072 string VerTag;
1073 string TmpSrc = Name;
1074 string::size_type Slash = TmpSrc.rfind('=');
1075 if (Slash != string::npos)
1076 {
1077 VerTag = string(TmpSrc.begin() + Slash + 1,TmpSrc.end());
1078 TmpSrc = string(TmpSrc.begin(),TmpSrc.begin() + Slash);
1079 }
1080
1081 /* Lookup the version of the package we would install if we were to
1082 install a version and determine the source package name, then look
1083 in the archive for a source package of the same name. In theory
1084 we could stash the version string as well and match that too but
1085 today there aren't multi source versions in the archive. */
1086 if (_config->FindB("APT::Get::Only-Source") == false &&
1087 VerTag.empty() == true)
1088 {
1089 pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc);
1090 if (Pkg.end() == false)
1091 {
1092 pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
1093 if (Ver.end() == false)
1094 {
1095 pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
1096 Src = Parse.SourcePkg();
1097 }
1098 }
1099 }
1100
1101 // No source package name..
1102 if (Src.empty() == true)
1103 Src = TmpSrc;
1104
1105 // The best hit
1106 pkgSrcRecords::Parser *Last = 0;
1107 unsigned long Offset = 0;
1108 string Version;
1109 bool IsMatch = false;
1110
1111 // If we are matching by version then we need exact matches to be happy
1112 if (VerTag.empty() == false)
1113 IsMatch = true;
1114
1115 /* Iterate over all of the hits, which includes the resulting
1116 binary packages in the search */
1117 pkgSrcRecords::Parser *Parse;
1118 SrcRecs.Restart();
1119 while ((Parse = SrcRecs.Find(Src.c_str(),false)) != 0)
1120 {
1121 string Ver = Parse->Version();
1122
1123 // Skip name mismatches
1124 if (IsMatch == true && Parse->Package() != Src)
1125 continue;
1126
1127 if (VerTag.empty() == false)
1128 {
1129 /* Don't want to fall through because we are doing exact version
1130 matching. */
1131 if (Cache.VS().CmpVersion(VerTag,Ver) != 0)
1132 continue;
1133
1134 Last = Parse;
1135 Offset = Parse->Offset();
1136 break;
1137 }
1138
1139 // Newer version or an exact match
1140 if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0 ||
1141 (Parse->Package() == Src && IsMatch == false))
1142 {
1143 IsMatch = Parse->Package() == Src;
1144 Last = Parse;
1145 Offset = Parse->Offset();
1146 Version = Ver;
1147 }
1148 }
1149
1150 if (Last == 0)
1151 return 0;
1152
1153 if (Last->Jump(Offset) == false)
1154 return 0;
1155
1156 return Last;
1157 }
1158 /*}}}*/
1159
1160 // DoUpdate - Update the package lists /*{{{*/
1161 // ---------------------------------------------------------------------
1162 /* */
1163 bool DoUpdate(CommandLine &CmdL)
1164 {
1165 if (CmdL.FileSize() != 1)
1166 return _error->Error(_("The update command takes no arguments"));
1167
1168 // Get the source list
1169 pkgSourceList List;
1170 if (List.ReadMainList() == false)
1171 return false;
1172
1173 // Lock the list directory
1174 FileFd Lock;
1175 if (_config->FindB("Debug::NoLocking",false) == false)
1176 {
1177 Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
1178 if (_error->PendingError() == true)
1179 return _error->Error(_("Unable to lock the list directory"));
1180 }
1181
1182 // Create the download object
1183 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1184 pkgAcquire Fetcher(&Stat);
1185
1186 // Populate it with the source selection
1187 if (List.GetIndexes(&Fetcher) == false)
1188 return false;
1189
1190 // Just print out the uris an exit if the --print-uris flag was used
1191 if (_config->FindB("APT::Get::Print-URIs") == true)
1192 {
1193 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1194 for (; I != Fetcher.UriEnd(); I++)
1195 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1196 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
1197 return true;
1198 }
1199
1200 // Run it
1201 if (Fetcher.Run() == pkgAcquire::Failed)
1202 return false;
1203
1204 bool Failed = false;
1205 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
1206 {
1207 if ((*I)->Status == pkgAcquire::Item::StatDone)
1208 continue;
1209
1210 (*I)->Finished();
1211
1212 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1213 (*I)->ErrorText.c_str());
1214 Failed = true;
1215 }
1216
1217 // Clean out any old list files
1218 if (_config->FindB("APT::Get::List-Cleanup",true) == true)
1219 {
1220 if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
1221 Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
1222 return false;
1223 }
1224
1225 // Prepare the cache.
1226 CacheFile Cache;
1227 if (Cache.Open() == false)
1228 return false;
1229
1230 if (Failed == true)
1231 return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
1232
1233 return true;
1234 }
1235 /*}}}*/
1236 // DoUpgrade - Upgrade all packages /*{{{*/
1237 // ---------------------------------------------------------------------
1238 /* Upgrade all packages without installing new packages or erasing old
1239 packages */
1240 bool DoUpgrade(CommandLine &CmdL)
1241 {
1242 CacheFile Cache;
1243 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1244 return false;
1245
1246 // Do the upgrade
1247 if (pkgAllUpgrade(Cache) == false)
1248 {
1249 ShowBroken(c1out,Cache,false);
1250 return _error->Error(_("Internal Error, AllUpgrade broke stuff"));
1251 }
1252
1253 return InstallPackages(Cache,true);
1254 }
1255 /*}}}*/
1256 // DoInstall - Install packages from the command line /*{{{*/
1257 // ---------------------------------------------------------------------
1258 /* Install named packages */
1259 bool DoInstall(CommandLine &CmdL)
1260 {
1261 CacheFile Cache;
1262 if (Cache.OpenForInstall() == false ||
1263 Cache.CheckDeps(CmdL.FileSize() != 1) == false)
1264 return false;
1265
1266 // Enter the special broken fixing mode if the user specified arguments
1267 bool BrokenFix = false;
1268 if (Cache->BrokenCount() != 0)
1269 BrokenFix = true;
1270
1271 unsigned int ExpectedInst = 0;
1272 unsigned int Packages = 0;
1273 pkgProblemResolver Fix(Cache);
1274
1275 bool DefRemove = false;
1276 if (strcasecmp(CmdL.FileList[0],"remove") == 0)
1277 DefRemove = true;
1278
1279 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
1280 {
1281 // Duplicate the string
1282 unsigned int Length = strlen(*I);
1283 char S[300];
1284 if (Length >= sizeof(S))
1285 continue;
1286 strcpy(S,*I);
1287
1288 // See if we are removing and special indicators..
1289 bool Remove = DefRemove;
1290 char *VerTag = 0;
1291 bool VerIsRel = false;
1292 while (Cache->FindPkg(S).end() == true)
1293 {
1294 // Handle an optional end tag indicating what to do
1295 if (S[Length - 1] == '-')
1296 {
1297 Remove = true;
1298 S[--Length] = 0;
1299 continue;
1300 }
1301
1302 if (S[Length - 1] == '+')
1303 {
1304 Remove = false;
1305 S[--Length] = 0;
1306 continue;
1307 }
1308
1309 char *Slash = strchr(S,'=');
1310 if (Slash != 0)
1311 {
1312 VerIsRel = false;
1313 *Slash = 0;
1314 VerTag = Slash + 1;
1315 }
1316
1317 Slash = strchr(S,'/');
1318 if (Slash != 0)
1319 {
1320 VerIsRel = true;
1321 *Slash = 0;
1322 VerTag = Slash + 1;
1323 }
1324
1325 break;
1326 }
1327
1328 // Locate the package
1329 pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
1330 Packages++;
1331 if (Pkg.end() == true)
1332 {
1333 // Check if the name is a regex
1334 const char *I;
1335 for (I = S; *I != 0; I++)
1336 if (*I == '.' || *I == '?' || *I == '*' || *I == '|')
1337 break;
1338 if (*I == 0)
1339 return _error->Error(_("Couldn't find package %s"),S);
1340
1341 // Regexs must always be confirmed
1342 ExpectedInst += 1000;
1343
1344 // Compile the regex pattern
1345 regex_t Pattern;
1346 int Res;
1347 if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE |
1348 REG_NOSUB)) != 0)
1349 {
1350 char Error[300];
1351 regerror(Res,&Pattern,Error,sizeof(Error));
1352 return _error->Error(_("Regex compilation error - %s"),Error);
1353 }
1354
1355 // Run over the matches
1356 bool Hit = false;
1357 for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++)
1358 {
1359 if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0)
1360 continue;
1361
1362 if (VerTag != 0)
1363 if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
1364 return false;
1365
1366 Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
1367 ExpectedInst,false);
1368 }
1369 regfree(&Pattern);
1370
1371 if (Hit == false)
1372 return _error->Error(_("Couldn't find package %s"),S);
1373 }
1374 else
1375 {
1376 if (VerTag != 0)
1377 if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
1378 return false;
1379 if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
1380 return false;
1381 }
1382 }
1383
1384 /* If we are in the Broken fixing mode we do not attempt to fix the
1385 problems. This is if the user invoked install without -f and gave
1386 packages */
1387 if (BrokenFix == true && Cache->BrokenCount() != 0)
1388 {
1389 c1out << _("You might want to run `apt-get -f install' to correct these:") << endl;
1390 ShowBroken(c1out,Cache,false);
1391
1392 return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
1393 }
1394
1395 // Call the scored problem resolver
1396 Fix.InstallProtect();
1397 if (Fix.Resolve(true) == false)
1398 _error->Discard();
1399
1400 // Now we check the state of the packages,
1401 if (Cache->BrokenCount() != 0)
1402 {
1403 c1out <<
1404 _("Some packages could not be installed. This may mean that you have\n"
1405 "requested an impossible situation or if you are using the unstable\n"
1406 "distribution that some required packages have not yet been created\n"
1407 "or been moved out of Incoming.") << endl;
1408 if (Packages == 1)
1409 {
1410 c1out << endl;
1411 c1out <<
1412 _("Since you only requested a single operation it is extremely likely that\n"
1413 "the package is simply not installable and a bug report against\n"
1414 "that package should be filed.") << endl;
1415 }
1416
1417 c1out << _("The following information may help to resolve the situation:") << endl;
1418 c1out << endl;
1419 ShowBroken(c1out,Cache,false);
1420 return _error->Error(_("Sorry, broken packages"));
1421 }
1422
1423 /* Print out a list of packages that are going to be installed extra
1424 to what the user asked */
1425 if (Cache->InstCount() != ExpectedInst)
1426 {
1427 string List;
1428 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
1429 {
1430 pkgCache::PkgIterator I(Cache,Cache.List[J]);
1431 if ((*Cache)[I].Install() == false)
1432 continue;
1433
1434 const char **J;
1435 for (J = CmdL.FileList + 1; *J != 0; J++)
1436 if (strcmp(*J,I.Name()) == 0)
1437 break;
1438
1439 if (*J == 0)
1440 List += string(I.Name()) + " ";
1441 }
1442
1443 ShowList(c1out,_("The following extra packages will be installed:"),List);
1444 }
1445
1446 // See if we need to prompt
1447 if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
1448 return InstallPackages(Cache,false,false);
1449
1450 return InstallPackages(Cache,false);
1451 }
1452 /*}}}*/
1453 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
1454 // ---------------------------------------------------------------------
1455 /* Intelligent upgrader that will install and remove packages at will */
1456 bool DoDistUpgrade(CommandLine &CmdL)
1457 {
1458 CacheFile Cache;
1459 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1460 return false;
1461
1462 c0out << _("Calculating Upgrade... ") << flush;
1463 if (pkgDistUpgrade(*Cache) == false)
1464 {
1465 c0out << _("Failed") << endl;
1466 ShowBroken(c1out,Cache,false);
1467 return false;
1468 }
1469
1470 c0out << _("Done") << endl;
1471
1472 return InstallPackages(Cache,true);
1473 }
1474 /*}}}*/
1475 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
1476 // ---------------------------------------------------------------------
1477 /* Follows dselect's selections */
1478 bool DoDSelectUpgrade(CommandLine &CmdL)
1479 {
1480 CacheFile Cache;
1481 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1482 return false;
1483
1484 // Install everything with the install flag set
1485 pkgCache::PkgIterator I = Cache->PkgBegin();
1486 for (;I.end() != true; I++)
1487 {
1488 /* Install the package only if it is a new install, the autoupgrader
1489 will deal with the rest */
1490 if (I->SelectedState == pkgCache::State::Install)
1491 Cache->MarkInstall(I,false);
1492 }
1493
1494 /* Now install their deps too, if we do this above then order of
1495 the status file is significant for | groups */
1496 for (I = Cache->PkgBegin();I.end() != true; I++)
1497 {
1498 /* Install the package only if it is a new install, the autoupgrader
1499 will deal with the rest */
1500 if (I->SelectedState == pkgCache::State::Install)
1501 Cache->MarkInstall(I,true);
1502 }
1503
1504 // Apply erasures now, they override everything else.
1505 for (I = Cache->PkgBegin();I.end() != true; I++)
1506 {
1507 // Remove packages
1508 if (I->SelectedState == pkgCache::State::DeInstall ||
1509 I->SelectedState == pkgCache::State::Purge)
1510 Cache->MarkDelete(I,I->SelectedState == pkgCache::State::Purge);
1511 }
1512
1513 /* Resolve any problems that dselect created, allupgrade cannot handle
1514 such things. We do so quite agressively too.. */
1515 if (Cache->BrokenCount() != 0)
1516 {
1517 pkgProblemResolver Fix(Cache);
1518
1519 // Hold back held packages.
1520 if (_config->FindB("APT::Ignore-Hold",false) == false)
1521 {
1522 for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++)
1523 {
1524 if (I->SelectedState == pkgCache::State::Hold)
1525 {
1526 Fix.Protect(I);
1527 Cache->MarkKeep(I);
1528 }
1529 }
1530 }
1531
1532 if (Fix.Resolve() == false)
1533 {
1534 ShowBroken(c1out,Cache,false);
1535 return _error->Error("Internal Error, problem resolver broke stuff");
1536 }
1537 }
1538
1539 // Now upgrade everything
1540 if (pkgAllUpgrade(Cache) == false)
1541 {
1542 ShowBroken(c1out,Cache,false);
1543 return _error->Error("Internal Error, problem resolver broke stuff");
1544 }
1545
1546 return InstallPackages(Cache,false);
1547 }
1548 /*}}}*/
1549 // DoClean - Remove download archives /*{{{*/
1550 // ---------------------------------------------------------------------
1551 /* */
1552 bool DoClean(CommandLine &CmdL)
1553 {
1554 if (_config->FindB("APT::Get::Simulate") == true)
1555 {
1556 cout << "Del " << _config->FindDir("Dir::Cache::archives") << "* " <<
1557 _config->FindDir("Dir::Cache::archives") << "partial/*" << endl;
1558 return true;
1559 }
1560
1561 // Lock the archive directory
1562 FileFd Lock;
1563 if (_config->FindB("Debug::NoLocking",false) == false)
1564 {
1565 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1566 if (_error->PendingError() == true)
1567 return _error->Error(_("Unable to lock the download directory"));
1568 }
1569
1570 pkgAcquire Fetcher;
1571 Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
1572 Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
1573 return true;
1574 }
1575 /*}}}*/
1576 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
1577 // ---------------------------------------------------------------------
1578 /* This is similar to clean but it only purges things that cannot be
1579 downloaded, that is old versions of cached packages. */
1580 class LogCleaner : public pkgArchiveCleaner
1581 {
1582 protected:
1583 virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St)
1584 {
1585 c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << endl;
1586
1587 if (_config->FindB("APT::Get::Simulate") == false)
1588 unlink(File);
1589 };
1590 };
1591
1592 bool DoAutoClean(CommandLine &CmdL)
1593 {
1594 // Lock the archive directory
1595 FileFd Lock;
1596 if (_config->FindB("Debug::NoLocking",false) == false)
1597 {
1598 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1599 if (_error->PendingError() == true)
1600 return _error->Error(_("Unable to lock the download directory"));
1601 }
1602
1603 CacheFile Cache;
1604 if (Cache.Open() == false)
1605 return false;
1606
1607 LogCleaner Cleaner;
1608
1609 return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) &&
1610 Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache);
1611 }
1612 /*}}}*/
1613 // DoCheck - Perform the check operation /*{{{*/
1614 // ---------------------------------------------------------------------
1615 /* Opening automatically checks the system, this command is mostly used
1616 for debugging */
1617 bool DoCheck(CommandLine &CmdL)
1618 {
1619 CacheFile Cache;
1620 Cache.Open();
1621 Cache.CheckDeps();
1622
1623 return true;
1624 }
1625 /*}}}*/
1626 // DoSource - Fetch a source archive /*{{{*/
1627 // ---------------------------------------------------------------------
1628 /* Fetch souce packages */
1629 struct DscFile
1630 {
1631 string Package;
1632 string Version;
1633 string Dsc;
1634 };
1635
1636 bool DoSource(CommandLine &CmdL)
1637 {
1638 CacheFile Cache;
1639 if (Cache.Open(false) == false)
1640 return false;
1641
1642 if (CmdL.FileSize() <= 1)
1643 return _error->Error(_("Must specify at least one package to fetch source for"));
1644
1645 // Read the source list
1646 pkgSourceList List;
1647 if (List.ReadMainList() == false)
1648 return _error->Error(_("The list of sources could not be read."));
1649
1650 // Create the text record parsers
1651 pkgRecords Recs(Cache);
1652 pkgSrcRecords SrcRecs(List);
1653 if (_error->PendingError() == true)
1654 return false;
1655
1656 // Create the download object
1657 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1658 pkgAcquire Fetcher(&Stat);
1659
1660 DscFile *Dsc = new DscFile[CmdL.FileSize()];
1661
1662 // Load the requestd sources into the fetcher
1663 unsigned J = 0;
1664 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
1665 {
1666 string Src;
1667 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
1668
1669 if (Last == 0)
1670 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
1671
1672 // Back track
1673 vector<pkgSrcRecords::File> Lst;
1674 if (Last->Files(Lst) == false)
1675 return false;
1676
1677 // Load them into the fetcher
1678 for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
1679 I != Lst.end(); I++)
1680 {
1681 // Try to guess what sort of file it is we are getting.
1682 if (I->Type == "dsc")
1683 {
1684 Dsc[J].Package = Last->Package();
1685 Dsc[J].Version = Last->Version();
1686 Dsc[J].Dsc = flNotDir(I->Path);
1687 }
1688
1689 // Diff only mode only fetches .diff files
1690 if (_config->FindB("APT::Get::Diff-Only",false) == true &&
1691 I->Type != "diff")
1692 continue;
1693
1694 // Tar only mode only fetches .tar files
1695 if (_config->FindB("APT::Get::Tar-Only",false) == true &&
1696 I->Type != "tar")
1697 continue;
1698
1699 new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path),
1700 I->MD5Hash,I->Size,
1701 Last->Index().SourceInfo(*Last,*I),Src);
1702 }
1703 }
1704
1705 // Display statistics
1706 double FetchBytes = Fetcher.FetchNeeded();
1707 double FetchPBytes = Fetcher.PartialPresent();
1708 double DebBytes = Fetcher.TotalNeeded();
1709
1710 // Check for enough free space
1711 struct statvfs Buf;
1712 string OutputDir = ".";
1713 if (statvfs(OutputDir.c_str(),&Buf) != 0)
1714 return _error->Errno("statvfs","Couldn't determine free space in %s",
1715 OutputDir.c_str());
1716 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
1717 return _error->Error(_("Sorry, you don't have enough free space in %s"),
1718 OutputDir.c_str());
1719
1720 // Number of bytes
1721 if (DebBytes != FetchBytes)
1722 ioprintf(c1out,_("Need to get %sB/%sB of source archives.\n"),
1723 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
1724 else
1725 ioprintf(c1out,_("Need to get %sB of source archives.\n"),
1726 SizeToStr(DebBytes).c_str());
1727
1728 if (_config->FindB("APT::Get::Simulate",false) == true)
1729 {
1730 for (unsigned I = 0; I != J; I++)
1731 ioprintf(cout,_("Fetch Source %s\n"),Dsc[I].Package.c_str());
1732 return true;
1733 }
1734
1735 // Just print out the uris an exit if the --print-uris flag was used
1736 if (_config->FindB("APT::Get::Print-URIs") == true)
1737 {
1738 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1739 for (; I != Fetcher.UriEnd(); I++)
1740 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1741 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
1742 return true;
1743 }
1744
1745 // Run it
1746 if (Fetcher.Run() == pkgAcquire::Failed)
1747 return false;
1748
1749 // Print error messages
1750 bool Failed = false;
1751 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
1752 {
1753 if ((*I)->Status == pkgAcquire::Item::StatDone &&
1754 (*I)->Complete == true)
1755 continue;
1756
1757 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1758 (*I)->ErrorText.c_str());
1759 Failed = true;
1760 }
1761 if (Failed == true)
1762 return _error->Error(_("Failed to fetch some archives."));
1763
1764 if (_config->FindB("APT::Get::Download-only",false) == true)
1765 {
1766 c1out << _("Download complete and in download only mode") << endl;
1767 return true;
1768 }
1769
1770 // Unpack the sources
1771 pid_t Process = ExecFork();
1772
1773 if (Process == 0)
1774 {
1775 for (unsigned I = 0; I != J; I++)
1776 {
1777 string Dir = Dsc[I].Package + '-' + Cache->VS().UpstreamVersion(Dsc[I].Version.c_str());
1778
1779 // Diff only mode only fetches .diff files
1780 if (_config->FindB("APT::Get::Diff-Only",false) == true ||
1781 _config->FindB("APT::Get::Tar-Only",false) == true ||
1782 Dsc[I].Dsc.empty() == true)
1783 continue;
1784
1785 // See if the package is already unpacked
1786 struct stat Stat;
1787 if (stat(Dir.c_str(),&Stat) == 0 &&
1788 S_ISDIR(Stat.st_mode) != 0)
1789 {
1790 ioprintf(c0out ,_("Skipping unpack of already unpacked source in %s\n"),
1791 Dir.c_str());
1792 }
1793 else
1794 {
1795 // Call dpkg-source
1796 char S[500];
1797 snprintf(S,sizeof(S),"%s -x %s",
1798 _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
1799 Dsc[I].Dsc.c_str());
1800 if (system(S) != 0)
1801 {
1802 fprintf(stderr,_("Unpack command '%s' failed.\n"),S);
1803 _exit(1);
1804 }
1805 }
1806
1807 // Try to compile it with dpkg-buildpackage
1808 if (_config->FindB("APT::Get::Compile",false) == true)
1809 {
1810 // Call dpkg-buildpackage
1811 char S[500];
1812 snprintf(S,sizeof(S),"cd %s && %s %s",
1813 Dir.c_str(),
1814 _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
1815 _config->Find("DPkg::Build-Options","-b -uc").c_str());
1816
1817 if (system(S) != 0)
1818 {
1819 fprintf(stderr,_("Build command '%s' failed.\n"),S);
1820 _exit(1);
1821 }
1822 }
1823 }
1824
1825 _exit(0);
1826 }
1827
1828 // Wait for the subprocess
1829 int Status = 0;
1830 while (waitpid(Process,&Status,0) != Process)
1831 {
1832 if (errno == EINTR)
1833 continue;
1834 return _error->Errno("waitpid","Couldn't wait for subprocess");
1835 }
1836
1837 if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
1838 return _error->Error(_("Child process failed"));
1839
1840 return true;
1841 }
1842 /*}}}*/
1843 // DoBuildDep - Install/removes packages to satisfy build dependencies /*{{{*/
1844 // ---------------------------------------------------------------------
1845 /* This function will look at the build depends list of the given source
1846 package and install the necessary packages to make it true, or fail. */
1847 bool DoBuildDep(CommandLine &CmdL)
1848 {
1849 CacheFile Cache;
1850 if (Cache.Open(true) == false)
1851 return false;
1852
1853 if (CmdL.FileSize() <= 1)
1854 return _error->Error(_("Must specify at least one package to check builddeps for"));
1855
1856 // Read the source list
1857 pkgSourceList List;
1858 if (List.ReadMainList() == false)
1859 return _error->Error(_("The list of sources could not be read."));
1860
1861 // Create the text record parsers
1862 pkgRecords Recs(Cache);
1863 pkgSrcRecords SrcRecs(List);
1864 if (_error->PendingError() == true)
1865 return false;
1866
1867 // Create the download object
1868 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1869 pkgAcquire Fetcher(&Stat);
1870
1871 unsigned J = 0;
1872 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
1873 {
1874 string Src;
1875 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
1876 if (Last == 0)
1877 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
1878
1879 // Process the build-dependencies
1880 vector<pkgSrcRecords::Parser::BuildDepRec> BuildDeps;
1881 if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only",false)) == false)
1882 return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str());
1883
1884 // Also ensure that build-essential packages are present
1885 Configuration::Item const *Opts = _config->Tree("APT::Build-Essential");
1886 if (Opts)
1887 Opts = Opts->Child;
1888 for (; Opts; Opts = Opts->Next)
1889 {
1890 if (Opts->Value.empty() == true)
1891 continue;
1892
1893 pkgSrcRecords::Parser::BuildDepRec rec;
1894 rec.Package = Opts->Value;
1895 rec.Type = pkgSrcRecords::Parser::BuildDependIndep;
1896 rec.Op = 0;
1897 BuildDeps.insert(BuildDeps.begin(), rec);
1898 }
1899
1900 if (BuildDeps.size() == 0)
1901 {
1902 ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
1903 continue;
1904 }
1905
1906 // Install the requested packages
1907 unsigned int ExpectedInst = 0;
1908 vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
1909 pkgProblemResolver Fix(Cache);
1910 for (D = BuildDeps.begin(); D != BuildDeps.end(); D++)
1911 {
1912 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
1913 if (Pkg.end() == true)
1914 {
1915 /* for a build-conflict; ignore unknown packages */
1916 if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
1917 (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
1918 continue;
1919
1920 return _error->Error(_("%s dependency on %s cannot be satisfied because the package %s cannot be found"),
1921 Last->BuildDepType((*D).Type),Src.c_str(),(*D).Package.c_str());
1922 }
1923 pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
1924
1925 if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
1926 (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
1927 {
1928 /*
1929 * conflict; need to remove if we have an installed version
1930 * that satisfies the version criterial
1931 */
1932 if (IV.end() == false &&
1933 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
1934 TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
1935 }
1936 else
1937 {
1938 /*
1939 * If this is a virtual package, we need to check the list of
1940 * packages that provide it and see if any of those are
1941 * installed
1942 */
1943 pkgCache::PrvIterator Prv = Pkg.ProvidesList();
1944 for (; Prv.end() != true; Prv++)
1945 if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
1946 break;
1947
1948 if (Prv.end() == true)
1949 {
1950 /*
1951 * depends; need to install or upgrade if we don't have the
1952 * package installed or if the version does not satisfy the
1953 * build dep. This is complicated by the fact that if we
1954 * depend on a version lower than what we already have
1955 * installed it is not clear what should be done; in practice
1956 * this case should be rare though and right now nothing
1957 * is done about it :-(
1958 */
1959 if (IV.end() == true ||
1960 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == false)
1961 TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst);
1962 }
1963 }
1964 }
1965
1966 Fix.InstallProtect();
1967 if (Fix.Resolve(true) == false)
1968 _error->Discard();
1969
1970 // Now we check the state of the packages,
1971 if (Cache->BrokenCount() != 0)
1972 return _error->Error(_("Some broken packages were found while trying to process build-dependencies.\n"
1973 "You might want to run `apt-get -f install' to correct these."));
1974 }
1975
1976 if (InstallPackages(Cache, false, true) == false)
1977 return _error->Error(_("Failed to process build dependencies"));
1978 return true;
1979 }
1980 /*}}}*/
1981
1982 // DoMoo - Never Ask, Never Tell /*{{{*/
1983 // ---------------------------------------------------------------------
1984 /* */
1985 bool DoMoo(CommandLine &CmdL)
1986 {
1987 cout <<
1988 " (__) \n"
1989 " (oo) \n"
1990 " /------\\/ \n"
1991 " / | || \n"
1992 " * /\\---/\\ \n"
1993 " ~~ ~~ \n"
1994 "....\"Have you mooed today?\"...\n";
1995
1996 return true;
1997 }
1998 /*}}}*/
1999 // ShowHelp - Show a help screen /*{{{*/
2000 // ---------------------------------------------------------------------
2001 /* */
2002 bool ShowHelp(CommandLine &CmdL)
2003 {
2004 ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
2005 COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
2006
2007 if (_config->FindB("version") == true)
2008 {
2009 cout << _("Supported Modules:") << endl;
2010
2011 for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++)
2012 {
2013 pkgVersioningSystem *VS = pkgVersioningSystem::GlobalList[I];
2014 if (_system != 0 && _system->VS == VS)
2015 cout << '*';
2016 else
2017 cout << ' ';
2018 cout << "Ver: " << VS->Label << endl;
2019
2020 /* Print out all the packaging systems that will work with
2021 this VS */
2022 for (unsigned J = 0; J != pkgSystem::GlobalListLen; J++)
2023 {
2024 pkgSystem *Sys = pkgSystem::GlobalList[J];
2025 if (_system == Sys)
2026 cout << '*';
2027 else
2028 cout << ' ';
2029 if (Sys->VS->TestCompatibility(*VS) == true)
2030 cout << "Pkg: " << Sys->Label << " (Priority " << Sys->Score(*_config) << ")" << endl;
2031 }
2032 }
2033
2034 for (unsigned I = 0; I != pkgSourceList::Type::GlobalListLen; I++)
2035 {
2036 pkgSourceList::Type *Type = pkgSourceList::Type::GlobalList[I];
2037 cout << " S.L: '" << Type->Name << "' " << Type->Label << endl;
2038 }
2039
2040 for (unsigned I = 0; I != pkgIndexFile::Type::GlobalListLen; I++)
2041 {
2042 pkgIndexFile::Type *Type = pkgIndexFile::Type::GlobalList[I];
2043 cout << " Idx: " << Type->Label << endl;
2044 }
2045
2046 return true;
2047 }
2048
2049 cout <<
2050 _("Usage: apt-get [options] command\n"
2051 " apt-get [options] install|remove pkg1 [pkg2 ...]\n"
2052 " apt-get [options] source pkg1 [pkg2 ...]\n"
2053 "\n"
2054 "apt-get is a simple command line interface for downloading and\n"
2055 "installing packages. The most frequently used commands are update\n"
2056 "and install.\n"
2057 "\n"
2058 "Commands:\n"
2059 " update - Retrieve new lists of packages\n"
2060 " upgrade - Perform an upgrade\n"
2061 " install - Install new packages (pkg is libc6 not libc6.deb)\n"
2062 " remove - Remove packages\n"
2063 " source - Download source archives\n"
2064 " build-dep - Configure build-dependencies for source packages\n"
2065 " dist-upgrade - Distribution upgrade, see apt-get(8)\n"
2066 " dselect-upgrade - Follow dselect selections\n"
2067 " clean - Erase downloaded archive files\n"
2068 " autoclean - Erase old downloaded archive files\n"
2069 " check - Verify that there are no broken dependencies\n"
2070 "\n"
2071 "Options:\n"
2072 " -h This help text.\n"
2073 " -q Loggable output - no progress indicator\n"
2074 " -qq No output except for errors\n"
2075 " -d Download only - do NOT install or unpack archives\n"
2076 " -s No-act. Perform ordering simulation\n"
2077 " -y Assume Yes to all queries and do not prompt\n"
2078 " -f Attempt to continue if the integrity check fails\n"
2079 " -m Attempt to continue if archives are unlocatable\n"
2080 " -u Show a list of upgraded packages as well\n"
2081 " -b Build the source package after fetching it\n"
2082 " -c=? Read this configuration file\n"
2083 " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp\n"
2084 "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n"
2085 "pages for more information and options.\n"
2086 " This APT has Super Cow Powers.\n");
2087 return true;
2088 }
2089 /*}}}*/
2090 // GetInitialize - Initialize things for apt-get /*{{{*/
2091 // ---------------------------------------------------------------------
2092 /* */
2093 void GetInitialize()
2094 {
2095 _config->Set("quiet",0);
2096 _config->Set("help",false);
2097 _config->Set("APT::Get::Download-Only",false);
2098 _config->Set("APT::Get::Simulate",false);
2099 _config->Set("APT::Get::Assume-Yes",false);
2100 _config->Set("APT::Get::Fix-Broken",false);
2101 _config->Set("APT::Get::Force-Yes",false);
2102 _config->Set("APT::Get::APT::Get::No-List-Cleanup",true);
2103 }
2104 /*}}}*/
2105 // SigWinch - Window size change signal handler /*{{{*/
2106 // ---------------------------------------------------------------------
2107 /* */
2108 void SigWinch(int)
2109 {
2110 // Riped from GNU ls
2111 #ifdef TIOCGWINSZ
2112 struct winsize ws;
2113
2114 if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
2115 ScreenWidth = ws.ws_col - 1;
2116 #endif
2117 }
2118 /*}}}*/
2119
2120 int main(int argc,const char *argv[])
2121 {
2122 CommandLine::Args Args[] = {
2123 {'h',"help","help",0},
2124 {'v',"version","version",0},
2125 {'q',"quiet","quiet",CommandLine::IntLevel},
2126 {'q',"silent","quiet",CommandLine::IntLevel},
2127 {'d',"download-only","APT::Get::Download-Only",0},
2128 {'b',"compile","APT::Get::Compile",0},
2129 {'b',"build","APT::Get::Compile",0},
2130 {'s',"simulate","APT::Get::Simulate",0},
2131 {'s',"just-print","APT::Get::Simulate",0},
2132 {'s',"recon","APT::Get::Simulate",0},
2133 {'s',"dry-run","APT::Get::Simulate",0},
2134 {'s',"no-act","APT::Get::Simulate",0},
2135 {'y',"yes","APT::Get::Assume-Yes",0},
2136 {'y',"assume-yes","APT::Get::Assume-Yes",0},
2137 {'f',"fix-broken","APT::Get::Fix-Broken",0},
2138 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
2139 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
2140 {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
2141 {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
2142 {0,"download","APT::Get::Download",0},
2143 {0,"fix-missing","APT::Get::Fix-Missing",0},
2144 {0,"ignore-hold","APT::Ignore-Hold",0},
2145 {0,"upgrade","APT::Get::upgrade",0},
2146 {0,"force-yes","APT::Get::force-yes",0},
2147 {0,"print-uris","APT::Get::Print-URIs",0},
2148 {0,"diff-only","APT::Get::Diff-Only",0},
2149 {0,"tar-only","APT::Get::tar-Only",0},
2150 {0,"purge","APT::Get::Purge",0},
2151 {0,"list-cleanup","APT::Get::List-Cleanup",0},
2152 {0,"reinstall","APT::Get::ReInstall",0},
2153 {0,"trivial-only","APT::Get::Trivial-Only",0},
2154 {0,"remove","APT::Get::Remove",0},
2155 {0,"only-source","APT::Get::Only-Source",0},
2156 {0,"arch-only","APT::Get::Arch-Only",0},
2157 {'c',"config-file",0,CommandLine::ConfigFile},
2158 {'o',"option",0,CommandLine::ArbItem},
2159 {0,0,0,0}};
2160 CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
2161 {"upgrade",&DoUpgrade},
2162 {"install",&DoInstall},
2163 {"remove",&DoInstall},
2164 {"dist-upgrade",&DoDistUpgrade},
2165 {"dselect-upgrade",&DoDSelectUpgrade},
2166 {"build-dep",&DoBuildDep},
2167 {"clean",&DoClean},
2168 {"autoclean",&DoAutoClean},
2169 {"check",&DoCheck},
2170 {"source",&DoSource},
2171 {"moo",&DoMoo},
2172 {"help",&ShowHelp},
2173 {0,0}};
2174
2175 // Set up gettext support
2176 setlocale(LC_ALL,"");
2177 textdomain(PACKAGE);
2178
2179 // Parse the command line and initialize the package library
2180 CommandLine CmdL(Args,_config);
2181 if (pkgInitConfig(*_config) == false ||
2182 CmdL.Parse(argc,argv) == false ||
2183 pkgInitSystem(*_config,_system) == false)
2184 {
2185 if (_config->FindB("version") == true)
2186 ShowHelp(CmdL);
2187
2188 _error->DumpErrors();
2189 return 100;
2190 }
2191
2192 // See if the help should be shown
2193 if (_config->FindB("help") == true ||
2194 _config->FindB("version") == true ||
2195 CmdL.FileSize() == 0)
2196 {
2197 ShowHelp(CmdL);
2198 return 0;
2199 }
2200
2201 // Deal with stdout not being a tty
2202 if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
2203 _config->Set("quiet","1");
2204
2205 // Setup the output streams
2206 c0out.rdbuf(cout.rdbuf());
2207 c1out.rdbuf(cout.rdbuf());
2208 c2out.rdbuf(cout.rdbuf());
2209 if (_config->FindI("quiet",0) > 0)
2210 c0out.rdbuf(devnull.rdbuf());
2211 if (_config->FindI("quiet",0) > 1)
2212 c1out.rdbuf(devnull.rdbuf());
2213
2214 // Setup the signals
2215 signal(SIGPIPE,SIG_IGN);
2216 signal(SIGWINCH,SigWinch);
2217 SigWinch(0);
2218
2219 // Match the operation
2220 CmdL.DispatchArg(Cmds);
2221
2222 // Print any errors or warnings found during parsing
2223 if (_error->empty() == false)
2224 {
2225 bool Errors = _error->PendingError();
2226 _error->DumpErrors();
2227 return Errors == true?100:0;
2228 }
2229
2230 return 0;
2231 }