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