* Skip version check if a build-dependency is provided ...
[ntk/apt.git] / cmdline / apt-get.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: apt-get.cc,v 1.132 2003/07/22 03:00:19 mdz 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 if (_config->FindB("APT::Get::Download-Only",false) == false)
689 Essential = !ShowEssential(c1out,Cache);
690 Fail |= Essential;
691 Stats(c1out,Cache);
692
693 // Sanity check
694 if (Cache->BrokenCount() != 0)
695 {
696 ShowBroken(c1out,Cache,false);
697 return _error->Error("Internal Error, InstallPackages was called with broken packages!");
698 }
699
700 if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
701 Cache->BadCount() == 0)
702 return true;
703
704 // No remove flag
705 if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
706 return _error->Error(_("Packages need to be removed but Remove is disabled."));
707
708 // Run the simulator ..
709 if (_config->FindB("APT::Get::Simulate") == true)
710 {
711 pkgSimulate PM(Cache);
712 pkgPackageManager::OrderResult Res = PM.DoInstall();
713 if (Res == pkgPackageManager::Failed)
714 return false;
715 if (Res != pkgPackageManager::Completed)
716 return _error->Error("Internal Error, Ordering didn't finish");
717 return true;
718 }
719
720 // Create the text record parser
721 pkgRecords Recs(Cache);
722 if (_error->PendingError() == true)
723 return false;
724
725 // Lock the archive directory
726 FileFd Lock;
727 if (_config->FindB("Debug::NoLocking",false) == false &&
728 _config->FindB("APT::Get::Print-URIs") == false)
729 {
730 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
731 if (_error->PendingError() == true)
732 return _error->Error(_("Unable to lock the download directory"));
733 }
734
735 // Create the download object
736 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
737 pkgAcquire Fetcher(&Stat);
738
739 // Read the source list
740 pkgSourceList List;
741 if (List.ReadMainList() == false)
742 return _error->Error(_("The list of sources could not be read."));
743
744 // Create the package manager and prepare to download
745 SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
746 if (PM->GetArchives(&Fetcher,&List,&Recs) == false ||
747 _error->PendingError() == true)
748 return false;
749
750 // Display statistics
751 double FetchBytes = Fetcher.FetchNeeded();
752 double FetchPBytes = Fetcher.PartialPresent();
753 double DebBytes = Fetcher.TotalNeeded();
754 if (DebBytes != Cache->DebSize())
755 {
756 c0out << DebBytes << ',' << Cache->DebSize() << endl;
757 c0out << "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl;
758 }
759
760 // Number of bytes
761 if (DebBytes != FetchBytes)
762 ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
763 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
764 else
765 ioprintf(c1out,_("Need to get %sB of archives.\n"),
766 SizeToStr(DebBytes).c_str());
767
768 // Size delta
769 if (Cache->UsrSize() >= 0)
770 ioprintf(c1out,_("After unpacking %sB of additional disk space will be used.\n"),
771 SizeToStr(Cache->UsrSize()).c_str());
772 else
773 ioprintf(c1out,_("After unpacking %sB disk space will be freed.\n"),
774 SizeToStr(-1*Cache->UsrSize()).c_str());
775
776 if (_error->PendingError() == true)
777 return false;
778
779 /* Check for enough free space, but only if we are actually going to
780 download */
781 if (_config->FindB("APT::Get::Print-URIs") == false &&
782 _config->FindB("APT::Get::Download",true) == true)
783 {
784 struct statvfs Buf;
785 string OutputDir = _config->FindDir("Dir::Cache::Archives");
786 if (statvfs(OutputDir.c_str(),&Buf) != 0)
787 return _error->Errno("statvfs","Couldn't determine free space in %s",
788 OutputDir.c_str());
789 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
790 return _error->Error(_("You don't have enough free space in %s."),
791 OutputDir.c_str());
792 }
793
794 // Fail safe check
795 if (_config->FindI("quiet",0) >= 2 ||
796 _config->FindB("APT::Get::Assume-Yes",false) == true)
797 {
798 if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
799 return _error->Error(_("There are problems and -y was used without --force-yes"));
800 }
801
802 if (Essential == true && Saftey == true)
803 {
804 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
805 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
806
807 const char *Prompt = _("Yes, do as I say!");
808 ioprintf(c2out,
809 _("You are about to do something potentially harmful\n"
810 "To continue type in the phrase '%s'\n"
811 " ?] "),Prompt);
812 c2out << flush;
813 if (AnalPrompt(Prompt) == false)
814 {
815 c2out << _("Abort.") << endl;
816 exit(1);
817 }
818 }
819 else
820 {
821 // Prompt to continue
822 if (Ask == true || Fail == true)
823 {
824 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
825 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
826
827 if (_config->FindI("quiet",0) < 2 &&
828 _config->FindB("APT::Get::Assume-Yes",false) == false)
829 {
830 c2out << _("Do you want to continue? [Y/n] ") << flush;
831
832 if (YnPrompt() == false)
833 {
834 c2out << _("Abort.") << endl;
835 exit(1);
836 }
837 }
838 }
839 }
840
841 // Just print out the uris an exit if the --print-uris flag was used
842 if (_config->FindB("APT::Get::Print-URIs") == true)
843 {
844 pkgAcquire::UriIterator I = Fetcher.UriBegin();
845 for (; I != Fetcher.UriEnd(); I++)
846 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
847 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
848 return true;
849 }
850
851 /* Unlock the dpkg lock if we are not going to be doing an install
852 after. */
853 if (_config->FindB("APT::Get::Download-Only",false) == true)
854 _system->UnLock();
855
856 // Run it
857 while (1)
858 {
859 bool Transient = false;
860 if (_config->FindB("APT::Get::Download",true) == false)
861 {
862 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
863 {
864 if ((*I)->Local == true)
865 {
866 I++;
867 continue;
868 }
869
870 // Close the item and check if it was found in cache
871 (*I)->Finished();
872 if ((*I)->Complete == false)
873 Transient = true;
874
875 // Clear it out of the fetch list
876 delete *I;
877 I = Fetcher.ItemsBegin();
878 }
879 }
880
881 if (Fetcher.Run() == pkgAcquire::Failed)
882 return false;
883
884 // Print out errors
885 bool Failed = false;
886 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
887 {
888 if ((*I)->Status == pkgAcquire::Item::StatDone &&
889 (*I)->Complete == true)
890 continue;
891
892 if ((*I)->Status == pkgAcquire::Item::StatIdle)
893 {
894 Transient = true;
895 // Failed = true;
896 continue;
897 }
898
899 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
900 (*I)->ErrorText.c_str());
901 Failed = true;
902 }
903
904 /* If we are in no download mode and missing files and there were
905 'failures' then the user must specify -m. Furthermore, there
906 is no such thing as a transient error in no-download mode! */
907 if (Transient == true &&
908 _config->FindB("APT::Get::Download",true) == false)
909 {
910 Transient = false;
911 Failed = true;
912 }
913
914 if (_config->FindB("APT::Get::Download-Only",false) == true)
915 {
916 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
917 return _error->Error(_("Some files failed to download"));
918 c1out << _("Download complete and in download only mode") << endl;
919 return true;
920 }
921
922 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
923 {
924 return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
925 }
926
927 if (Transient == true && Failed == true)
928 return _error->Error(_("--fix-missing and media swapping is not currently supported"));
929
930 // Try to deal with missing package files
931 if (Failed == true && PM->FixMissing() == false)
932 {
933 cerr << _("Unable to correct missing packages.") << endl;
934 return _error->Error(_("Aborting Install."));
935 }
936
937 _system->UnLock();
938 pkgPackageManager::OrderResult Res = PM->DoInstall();
939 if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
940 return false;
941 if (Res == pkgPackageManager::Completed)
942 return true;
943
944 // Reload the fetcher object and loop again for media swapping
945 Fetcher.Shutdown();
946 if (PM->GetArchives(&Fetcher,&List,&Recs) == false)
947 return false;
948
949 _system->Lock();
950 }
951 }
952 /*}}}*/
953 // TryToInstall - Try to install a single package /*{{{*/
954 // ---------------------------------------------------------------------
955 /* This used to be inlined in DoInstall, but with the advent of regex package
956 name matching it was split out.. */
957 bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
958 pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
959 unsigned int &ExpectedInst,bool AllowFail = true)
960 {
961 /* This is a pure virtual package and there is a single available
962 provides */
963 if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0 &&
964 Pkg.ProvidesList()->NextProvides == 0)
965 {
966 pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg();
967 ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
968 Tmp.Name(),Pkg.Name());
969 Pkg = Tmp;
970 }
971
972 // Handle the no-upgrade case
973 if (_config->FindB("APT::Get::upgrade",true) == false &&
974 Pkg->CurrentVer != 0)
975 {
976 if (AllowFail == true)
977 ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
978 Pkg.Name());
979 return true;
980 }
981
982 // Check if there is something at all to install
983 pkgDepCache::StateCache &State = Cache[Pkg];
984 if (Remove == true && Pkg->CurrentVer == 0)
985 {
986 Fix.Clear(Pkg);
987 Fix.Protect(Pkg);
988 Fix.Remove(Pkg);
989
990 /* We want to continue searching for regex hits, so we return false here
991 otherwise this is not really an error. */
992 if (AllowFail == false)
993 return false;
994
995 ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.Name());
996 return true;
997 }
998
999 if (State.CandidateVer == 0 && Remove == false)
1000 {
1001 if (AllowFail == false)
1002 return false;
1003
1004 if (Pkg->ProvidesList != 0)
1005 {
1006 ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
1007 Pkg.Name());
1008
1009 pkgCache::PrvIterator I = Pkg.ProvidesList();
1010 for (; I.end() == false; I++)
1011 {
1012 pkgCache::PkgIterator Pkg = I.OwnerPkg();
1013
1014 if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer())
1015 {
1016 if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
1017 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
1018 _(" [Installed]") << endl;
1019 else
1020 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
1021 }
1022 }
1023 c1out << _("You should explicitly select one to install.") << endl;
1024 }
1025 else
1026 {
1027 ioprintf(c1out,
1028 _("Package %s has no available version, but exists in the database.\n"
1029 "This typically means that the package was mentioned in a dependency and\n"
1030 "never uploaded, has been obsoleted or is not available with the contents\n"
1031 "of sources.list\n"),Pkg.Name());
1032
1033 string List;
1034 string VersionsList;
1035 SPtrArray<bool> Seen = new bool[Cache.Head().PackageCount];
1036 memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen));
1037 pkgCache::DepIterator Dep = Pkg.RevDependsList();
1038 for (; Dep.end() == false; Dep++)
1039 {
1040 if (Dep->Type != pkgCache::Dep::Replaces)
1041 continue;
1042 if (Seen[Dep.ParentPkg()->ID] == true)
1043 continue;
1044 Seen[Dep.ParentPkg()->ID] = true;
1045 List += string(Dep.ParentPkg().Name()) + " ";
1046 //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ???
1047 }
1048 ShowList(c1out,_("However the following packages replace it:"),List,VersionsList);
1049 }
1050
1051 _error->Error(_("Package %s has no installation candidate"),Pkg.Name());
1052 return false;
1053 }
1054
1055 Fix.Clear(Pkg);
1056 Fix.Protect(Pkg);
1057 if (Remove == true)
1058 {
1059 Fix.Remove(Pkg);
1060 Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
1061 return true;
1062 }
1063
1064 // Install it
1065 Cache.MarkInstall(Pkg,false);
1066 if (State.Install() == false)
1067 {
1068 if (_config->FindB("APT::Get::ReInstall",false) == true)
1069 {
1070 if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
1071 ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
1072 Pkg.Name());
1073 else
1074 Cache.SetReInstall(Pkg,true);
1075 }
1076 else
1077 {
1078 if (AllowFail == true)
1079 ioprintf(c1out,_("%s is already the newest version.\n"),
1080 Pkg.Name());
1081 }
1082 }
1083 else
1084 ExpectedInst++;
1085
1086 // Install it with autoinstalling enabled.
1087 if (State.InstBroken() == true && BrokenFix == false)
1088 Cache.MarkInstall(Pkg,true);
1089 return true;
1090 }
1091 /*}}}*/
1092 // TryToChangeVer - Try to change a candidate version /*{{{*/
1093 // ---------------------------------------------------------------------
1094 /* */
1095 bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
1096 const char *VerTag,bool IsRel)
1097 {
1098 pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release :
1099 pkgVersionMatch::Version));
1100
1101 pkgCache::VerIterator Ver = Match.Find(Pkg);
1102
1103 if (Ver.end() == true)
1104 {
1105 if (IsRel == true)
1106 return _error->Error(_("Release '%s' for '%s' was not found"),
1107 VerTag,Pkg.Name());
1108 return _error->Error(_("Version '%s' for '%s' was not found"),
1109 VerTag,Pkg.Name());
1110 }
1111
1112 if (strcmp(VerTag,Ver.VerStr()) != 0)
1113 {
1114 ioprintf(c1out,_("Selected version %s (%s) for %s\n"),
1115 Ver.VerStr(),Ver.RelStr().c_str(),Pkg.Name());
1116 }
1117
1118 Cache.SetCandidateVersion(Ver);
1119 return true;
1120 }
1121 /*}}}*/
1122 // FindSrc - Find a source record /*{{{*/
1123 // ---------------------------------------------------------------------
1124 /* */
1125 pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
1126 pkgSrcRecords &SrcRecs,string &Src,
1127 pkgDepCache &Cache)
1128 {
1129 // We want to pull the version off the package specification..
1130 string VerTag;
1131 string TmpSrc = Name;
1132 string::size_type Slash = TmpSrc.rfind('=');
1133 if (Slash != string::npos)
1134 {
1135 VerTag = string(TmpSrc.begin() + Slash + 1,TmpSrc.end());
1136 TmpSrc = string(TmpSrc.begin(),TmpSrc.begin() + Slash);
1137 }
1138
1139 /* Lookup the version of the package we would install if we were to
1140 install a version and determine the source package name, then look
1141 in the archive for a source package of the same name. In theory
1142 we could stash the version string as well and match that too but
1143 today there aren't multi source versions in the archive. */
1144 if (_config->FindB("APT::Get::Only-Source") == false &&
1145 VerTag.empty() == true)
1146 {
1147 pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc);
1148 if (Pkg.end() == false)
1149 {
1150 pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
1151 if (Ver.end() == false)
1152 {
1153 pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
1154 Src = Parse.SourcePkg();
1155 }
1156 }
1157 }
1158
1159 // No source package name..
1160 if (Src.empty() == true)
1161 Src = TmpSrc;
1162
1163 // The best hit
1164 pkgSrcRecords::Parser *Last = 0;
1165 unsigned long Offset = 0;
1166 string Version;
1167 bool IsMatch = false;
1168
1169 // If we are matching by version then we need exact matches to be happy
1170 if (VerTag.empty() == false)
1171 IsMatch = true;
1172
1173 /* Iterate over all of the hits, which includes the resulting
1174 binary packages in the search */
1175 pkgSrcRecords::Parser *Parse;
1176 SrcRecs.Restart();
1177 while ((Parse = SrcRecs.Find(Src.c_str(),false)) != 0)
1178 {
1179 string Ver = Parse->Version();
1180
1181 // Skip name mismatches
1182 if (IsMatch == true && Parse->Package() != Src)
1183 continue;
1184
1185 if (VerTag.empty() == false)
1186 {
1187 /* Don't want to fall through because we are doing exact version
1188 matching. */
1189 if (Cache.VS().CmpVersion(VerTag,Ver) != 0)
1190 continue;
1191
1192 Last = Parse;
1193 Offset = Parse->Offset();
1194 break;
1195 }
1196
1197 // Newer version or an exact match
1198 if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0 ||
1199 (Parse->Package() == Src && IsMatch == false))
1200 {
1201 IsMatch = Parse->Package() == Src;
1202 Last = Parse;
1203 Offset = Parse->Offset();
1204 Version = Ver;
1205 }
1206 }
1207
1208 if (Last == 0)
1209 return 0;
1210
1211 if (Last->Jump(Offset) == false)
1212 return 0;
1213
1214 return Last;
1215 }
1216 /*}}}*/
1217
1218 // DoUpdate - Update the package lists /*{{{*/
1219 // ---------------------------------------------------------------------
1220 /* */
1221 bool DoUpdate(CommandLine &CmdL)
1222 {
1223 if (CmdL.FileSize() != 1)
1224 return _error->Error(_("The update command takes no arguments"));
1225
1226 // Get the source list
1227 pkgSourceList List;
1228 if (List.ReadMainList() == false)
1229 return false;
1230
1231 // Lock the list directory
1232 FileFd Lock;
1233 if (_config->FindB("Debug::NoLocking",false) == false)
1234 {
1235 Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
1236 if (_error->PendingError() == true)
1237 return _error->Error(_("Unable to lock the list directory"));
1238 }
1239
1240 // Create the download object
1241 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1242 pkgAcquire Fetcher(&Stat);
1243
1244 // Populate it with the source selection
1245 if (List.GetIndexes(&Fetcher) == false)
1246 return false;
1247
1248 // Just print out the uris an exit if the --print-uris flag was used
1249 if (_config->FindB("APT::Get::Print-URIs") == true)
1250 {
1251 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1252 for (; I != Fetcher.UriEnd(); I++)
1253 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1254 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
1255 return true;
1256 }
1257
1258 // Run it
1259 if (Fetcher.Run() == pkgAcquire::Failed)
1260 return false;
1261
1262 bool Failed = false;
1263 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
1264 {
1265 if ((*I)->Status == pkgAcquire::Item::StatDone)
1266 continue;
1267
1268 (*I)->Finished();
1269
1270 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1271 (*I)->ErrorText.c_str());
1272 Failed = true;
1273 }
1274
1275 // Clean out any old list files
1276 if (_config->FindB("APT::Get::List-Cleanup",true) == true)
1277 {
1278 if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
1279 Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
1280 return false;
1281 }
1282
1283 // Prepare the cache.
1284 CacheFile Cache;
1285 if (Cache.BuildCaches() == false)
1286 return false;
1287
1288 if (Failed == true)
1289 return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
1290
1291 return true;
1292 }
1293 /*}}}*/
1294 // DoUpgrade - Upgrade all packages /*{{{*/
1295 // ---------------------------------------------------------------------
1296 /* Upgrade all packages without installing new packages or erasing old
1297 packages */
1298 bool DoUpgrade(CommandLine &CmdL)
1299 {
1300 CacheFile Cache;
1301 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1302 return false;
1303
1304 // Do the upgrade
1305 if (pkgAllUpgrade(Cache) == false)
1306 {
1307 ShowBroken(c1out,Cache,false);
1308 return _error->Error(_("Internal Error, AllUpgrade broke stuff"));
1309 }
1310
1311 return InstallPackages(Cache,true);
1312 }
1313 /*}}}*/
1314 // DoInstall - Install packages from the command line /*{{{*/
1315 // ---------------------------------------------------------------------
1316 /* Install named packages */
1317 bool DoInstall(CommandLine &CmdL)
1318 {
1319 CacheFile Cache;
1320 if (Cache.OpenForInstall() == false ||
1321 Cache.CheckDeps(CmdL.FileSize() != 1) == false)
1322 return false;
1323
1324 // Enter the special broken fixing mode if the user specified arguments
1325 bool BrokenFix = false;
1326 if (Cache->BrokenCount() != 0)
1327 BrokenFix = true;
1328
1329 unsigned int ExpectedInst = 0;
1330 unsigned int Packages = 0;
1331 pkgProblemResolver Fix(Cache);
1332
1333 bool DefRemove = false;
1334 if (strcasecmp(CmdL.FileList[0],"remove") == 0)
1335 DefRemove = true;
1336
1337 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
1338 {
1339 // Duplicate the string
1340 unsigned int Length = strlen(*I);
1341 char S[300];
1342 if (Length >= sizeof(S))
1343 continue;
1344 strcpy(S,*I);
1345
1346 // See if we are removing and special indicators..
1347 bool Remove = DefRemove;
1348 char *VerTag = 0;
1349 bool VerIsRel = false;
1350 while (Cache->FindPkg(S).end() == true)
1351 {
1352 // Handle an optional end tag indicating what to do
1353 if (S[Length - 1] == '-')
1354 {
1355 Remove = true;
1356 S[--Length] = 0;
1357 continue;
1358 }
1359
1360 if (S[Length - 1] == '+')
1361 {
1362 Remove = false;
1363 S[--Length] = 0;
1364 continue;
1365 }
1366
1367 char *Slash = strchr(S,'=');
1368 if (Slash != 0)
1369 {
1370 VerIsRel = false;
1371 *Slash = 0;
1372 VerTag = Slash + 1;
1373 }
1374
1375 Slash = strchr(S,'/');
1376 if (Slash != 0)
1377 {
1378 VerIsRel = true;
1379 *Slash = 0;
1380 VerTag = Slash + 1;
1381 }
1382
1383 break;
1384 }
1385
1386 // Locate the package
1387 pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
1388 Packages++;
1389 if (Pkg.end() == true)
1390 {
1391 // Check if the name is a regex
1392 const char *I;
1393 for (I = S; *I != 0; I++)
1394 if (*I == '?' || *I == '*' || *I == '|' ||
1395 *I == '[' || *I == '^' || *I == '$')
1396 break;
1397 if (*I == 0)
1398 return _error->Error(_("Couldn't find package %s"),S);
1399
1400 // Regexs must always be confirmed
1401 ExpectedInst += 1000;
1402
1403 // Compile the regex pattern
1404 regex_t Pattern;
1405 int Res;
1406 if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE |
1407 REG_NOSUB)) != 0)
1408 {
1409 char Error[300];
1410 regerror(Res,&Pattern,Error,sizeof(Error));
1411 return _error->Error(_("Regex compilation error - %s"),Error);
1412 }
1413
1414 // Run over the matches
1415 bool Hit = false;
1416 for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++)
1417 {
1418 if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0)
1419 continue;
1420
1421 ioprintf(c1out,_("Note, selecting %s for regex '%s'\n"),
1422 Pkg.Name(),S);
1423
1424 if (VerTag != 0)
1425 if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
1426 return false;
1427
1428 Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
1429 ExpectedInst,false);
1430 }
1431 regfree(&Pattern);
1432
1433 if (Hit == false)
1434 return _error->Error(_("Couldn't find package %s"),S);
1435 }
1436 else
1437 {
1438 if (VerTag != 0)
1439 if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
1440 return false;
1441 if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
1442 return false;
1443 }
1444 }
1445
1446 /* If we are in the Broken fixing mode we do not attempt to fix the
1447 problems. This is if the user invoked install without -f and gave
1448 packages */
1449 if (BrokenFix == true && Cache->BrokenCount() != 0)
1450 {
1451 c1out << _("You might want to run `apt-get -f install' to correct these:") << endl;
1452 ShowBroken(c1out,Cache,false);
1453
1454 return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
1455 }
1456
1457 // Call the scored problem resolver
1458 Fix.InstallProtect();
1459 if (Fix.Resolve(true) == false)
1460 _error->Discard();
1461
1462 // Now we check the state of the packages,
1463 if (Cache->BrokenCount() != 0)
1464 {
1465 c1out <<
1466 _("Some packages could not be installed. This may mean that you have\n"
1467 "requested an impossible situation or if you are using the unstable\n"
1468 "distribution that some required packages have not yet been created\n"
1469 "or been moved out of Incoming.") << endl;
1470 if (Packages == 1)
1471 {
1472 c1out << endl;
1473 c1out <<
1474 _("Since you only requested a single operation it is extremely likely that\n"
1475 "the package is simply not installable and a bug report against\n"
1476 "that package should be filed.") << endl;
1477 }
1478
1479 c1out << _("The following information may help to resolve the situation:") << endl;
1480 c1out << endl;
1481 ShowBroken(c1out,Cache,false);
1482 return _error->Error(_("Broken packages"));
1483 }
1484
1485 /* Print out a list of packages that are going to be installed extra
1486 to what the user asked */
1487 if (Cache->InstCount() != ExpectedInst)
1488 {
1489 string List;
1490 string VersionsList;
1491 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
1492 {
1493 pkgCache::PkgIterator I(Cache,Cache.List[J]);
1494 if ((*Cache)[I].Install() == false)
1495 continue;
1496
1497 const char **J;
1498 for (J = CmdL.FileList + 1; *J != 0; J++)
1499 if (strcmp(*J,I.Name()) == 0)
1500 break;
1501
1502 if (*J == 0) {
1503 List += string(I.Name()) + " ";
1504 VersionsList += string(Cache[I].CandVersion) + "\n";
1505 }
1506 }
1507
1508 ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList);
1509 }
1510
1511 /* Print out a list of suggested and recommended packages */
1512 {
1513 string SuggestsList, RecommendsList, List;
1514 string SuggestsVersions, RecommendsVersions;
1515 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
1516 {
1517 pkgCache::PkgIterator I(Cache,Cache.List[J]);
1518
1519 /* Just look at the ones we want to install */
1520 if ((*Cache)[I].Install() == false)
1521 continue;
1522
1523 for (pkgCache::VerIterator V = I.VersionList(); V.end() == false; V++)
1524 {
1525 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
1526 {
1527 pkgCache::DepIterator Start;
1528 pkgCache::DepIterator End;
1529 D.GlobOr(Start,End);
1530 do
1531 {
1532 if (Start->Type == pkgCache::Dep::Suggests) {
1533
1534 /* A suggests relations, let's see if we have it
1535 installed already */
1536
1537 string target = string(Start.TargetPkg().Name()) + " ";
1538 if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install)
1539 break;
1540 /* Does another package suggest it as well? If so,
1541 don't print it twice */
1542 if (int(SuggestsList.find(target)) > -1)
1543 break;
1544 SuggestsList += target;
1545 SuggestsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
1546 }
1547
1548 if (Start->Type == pkgCache::Dep::Recommends) {
1549
1550 /* A recommends relation, let's see if we have it
1551 installed already */
1552
1553 string target = string(Start.TargetPkg().Name()) + " ";
1554 if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install)
1555 break;
1556
1557 /* Does another package recommend it as well? If so,
1558 don't print it twice */
1559
1560 if (int(RecommendsList.find(target)) > -1)
1561 break;
1562 RecommendsList += target;
1563 SuggestsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
1564 }
1565 if (Start == End)
1566 break;
1567 Start++;
1568 } while (1);
1569 }
1570 }
1571 }
1572 ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions);
1573 ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions);
1574
1575 }
1576
1577 // See if we need to prompt
1578 if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
1579 return InstallPackages(Cache,false,false);
1580
1581 return InstallPackages(Cache,false);
1582 }
1583 /*}}}*/
1584 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
1585 // ---------------------------------------------------------------------
1586 /* Intelligent upgrader that will install and remove packages at will */
1587 bool DoDistUpgrade(CommandLine &CmdL)
1588 {
1589 CacheFile Cache;
1590 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1591 return false;
1592
1593 c0out << _("Calculating Upgrade... ") << flush;
1594 if (pkgDistUpgrade(*Cache) == false)
1595 {
1596 c0out << _("Failed") << endl;
1597 ShowBroken(c1out,Cache,false);
1598 return false;
1599 }
1600
1601 c0out << _("Done") << endl;
1602
1603 return InstallPackages(Cache,true);
1604 }
1605 /*}}}*/
1606 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
1607 // ---------------------------------------------------------------------
1608 /* Follows dselect's selections */
1609 bool DoDSelectUpgrade(CommandLine &CmdL)
1610 {
1611 CacheFile Cache;
1612 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1613 return false;
1614
1615 // Install everything with the install flag set
1616 pkgCache::PkgIterator I = Cache->PkgBegin();
1617 for (;I.end() != true; I++)
1618 {
1619 /* Install the package only if it is a new install, the autoupgrader
1620 will deal with the rest */
1621 if (I->SelectedState == pkgCache::State::Install)
1622 Cache->MarkInstall(I,false);
1623 }
1624
1625 /* Now install their deps too, if we do this above then order of
1626 the status file is significant for | groups */
1627 for (I = Cache->PkgBegin();I.end() != true; I++)
1628 {
1629 /* Install the package only if it is a new install, the autoupgrader
1630 will deal with the rest */
1631 if (I->SelectedState == pkgCache::State::Install)
1632 Cache->MarkInstall(I,true);
1633 }
1634
1635 // Apply erasures now, they override everything else.
1636 for (I = Cache->PkgBegin();I.end() != true; I++)
1637 {
1638 // Remove packages
1639 if (I->SelectedState == pkgCache::State::DeInstall ||
1640 I->SelectedState == pkgCache::State::Purge)
1641 Cache->MarkDelete(I,I->SelectedState == pkgCache::State::Purge);
1642 }
1643
1644 /* Resolve any problems that dselect created, allupgrade cannot handle
1645 such things. We do so quite agressively too.. */
1646 if (Cache->BrokenCount() != 0)
1647 {
1648 pkgProblemResolver Fix(Cache);
1649
1650 // Hold back held packages.
1651 if (_config->FindB("APT::Ignore-Hold",false) == false)
1652 {
1653 for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++)
1654 {
1655 if (I->SelectedState == pkgCache::State::Hold)
1656 {
1657 Fix.Protect(I);
1658 Cache->MarkKeep(I);
1659 }
1660 }
1661 }
1662
1663 if (Fix.Resolve() == false)
1664 {
1665 ShowBroken(c1out,Cache,false);
1666 return _error->Error("Internal Error, problem resolver broke stuff");
1667 }
1668 }
1669
1670 // Now upgrade everything
1671 if (pkgAllUpgrade(Cache) == false)
1672 {
1673 ShowBroken(c1out,Cache,false);
1674 return _error->Error("Internal Error, problem resolver broke stuff");
1675 }
1676
1677 return InstallPackages(Cache,false);
1678 }
1679 /*}}}*/
1680 // DoClean - Remove download archives /*{{{*/
1681 // ---------------------------------------------------------------------
1682 /* */
1683 bool DoClean(CommandLine &CmdL)
1684 {
1685 if (_config->FindB("APT::Get::Simulate") == true)
1686 {
1687 cout << "Del " << _config->FindDir("Dir::Cache::archives") << "* " <<
1688 _config->FindDir("Dir::Cache::archives") << "partial/*" << endl;
1689 return true;
1690 }
1691
1692 // Lock the archive directory
1693 FileFd Lock;
1694 if (_config->FindB("Debug::NoLocking",false) == false)
1695 {
1696 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1697 if (_error->PendingError() == true)
1698 return _error->Error(_("Unable to lock the download directory"));
1699 }
1700
1701 pkgAcquire Fetcher;
1702 Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
1703 Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
1704 return true;
1705 }
1706 /*}}}*/
1707 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
1708 // ---------------------------------------------------------------------
1709 /* This is similar to clean but it only purges things that cannot be
1710 downloaded, that is old versions of cached packages. */
1711 class LogCleaner : public pkgArchiveCleaner
1712 {
1713 protected:
1714 virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St)
1715 {
1716 c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << endl;
1717
1718 if (_config->FindB("APT::Get::Simulate") == false)
1719 unlink(File);
1720 };
1721 };
1722
1723 bool DoAutoClean(CommandLine &CmdL)
1724 {
1725 // Lock the archive directory
1726 FileFd Lock;
1727 if (_config->FindB("Debug::NoLocking",false) == false)
1728 {
1729 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1730 if (_error->PendingError() == true)
1731 return _error->Error(_("Unable to lock the download directory"));
1732 }
1733
1734 CacheFile Cache;
1735 if (Cache.Open() == false)
1736 return false;
1737
1738 LogCleaner Cleaner;
1739
1740 return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) &&
1741 Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache);
1742 }
1743 /*}}}*/
1744 // DoCheck - Perform the check operation /*{{{*/
1745 // ---------------------------------------------------------------------
1746 /* Opening automatically checks the system, this command is mostly used
1747 for debugging */
1748 bool DoCheck(CommandLine &CmdL)
1749 {
1750 CacheFile Cache;
1751 Cache.Open();
1752 Cache.CheckDeps();
1753
1754 return true;
1755 }
1756 /*}}}*/
1757 // DoSource - Fetch a source archive /*{{{*/
1758 // ---------------------------------------------------------------------
1759 /* Fetch souce packages */
1760 struct DscFile
1761 {
1762 string Package;
1763 string Version;
1764 string Dsc;
1765 };
1766
1767 bool DoSource(CommandLine &CmdL)
1768 {
1769 CacheFile Cache;
1770 if (Cache.Open(false) == false)
1771 return false;
1772
1773 if (CmdL.FileSize() <= 1)
1774 return _error->Error(_("Must specify at least one package to fetch source for"));
1775
1776 // Read the source list
1777 pkgSourceList List;
1778 if (List.ReadMainList() == false)
1779 return _error->Error(_("The list of sources could not be read."));
1780
1781 // Create the text record parsers
1782 pkgRecords Recs(Cache);
1783 pkgSrcRecords SrcRecs(List);
1784 if (_error->PendingError() == true)
1785 return false;
1786
1787 // Create the download object
1788 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1789 pkgAcquire Fetcher(&Stat);
1790
1791 DscFile *Dsc = new DscFile[CmdL.FileSize()];
1792
1793 // Load the requestd sources into the fetcher
1794 unsigned J = 0;
1795 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
1796 {
1797 string Src;
1798 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
1799
1800 if (Last == 0)
1801 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
1802
1803 // Back track
1804 vector<pkgSrcRecords::File> Lst;
1805 if (Last->Files(Lst) == false)
1806 return false;
1807
1808 // Load them into the fetcher
1809 for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
1810 I != Lst.end(); I++)
1811 {
1812 // Try to guess what sort of file it is we are getting.
1813 if (I->Type == "dsc")
1814 {
1815 Dsc[J].Package = Last->Package();
1816 Dsc[J].Version = Last->Version();
1817 Dsc[J].Dsc = flNotDir(I->Path);
1818 }
1819
1820 // Diff only mode only fetches .diff files
1821 if (_config->FindB("APT::Get::Diff-Only",false) == true &&
1822 I->Type != "diff")
1823 continue;
1824
1825 // Tar only mode only fetches .tar files
1826 if (_config->FindB("APT::Get::Tar-Only",false) == true &&
1827 I->Type != "tar")
1828 continue;
1829
1830 new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path),
1831 I->MD5Hash,I->Size,
1832 Last->Index().SourceInfo(*Last,*I),Src);
1833 }
1834 }
1835
1836 // Display statistics
1837 double FetchBytes = Fetcher.FetchNeeded();
1838 double FetchPBytes = Fetcher.PartialPresent();
1839 double DebBytes = Fetcher.TotalNeeded();
1840
1841 // Check for enough free space
1842 struct statvfs Buf;
1843 string OutputDir = ".";
1844 if (statvfs(OutputDir.c_str(),&Buf) != 0)
1845 return _error->Errno("statvfs","Couldn't determine free space in %s",
1846 OutputDir.c_str());
1847 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
1848 return _error->Error(_("You don't have enough free space in %s"),
1849 OutputDir.c_str());
1850
1851 // Number of bytes
1852 if (DebBytes != FetchBytes)
1853 ioprintf(c1out,_("Need to get %sB/%sB of source archives.\n"),
1854 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
1855 else
1856 ioprintf(c1out,_("Need to get %sB of source archives.\n"),
1857 SizeToStr(DebBytes).c_str());
1858
1859 if (_config->FindB("APT::Get::Simulate",false) == true)
1860 {
1861 for (unsigned I = 0; I != J; I++)
1862 ioprintf(cout,_("Fetch Source %s\n"),Dsc[I].Package.c_str());
1863 return true;
1864 }
1865
1866 // Just print out the uris an exit if the --print-uris flag was used
1867 if (_config->FindB("APT::Get::Print-URIs") == true)
1868 {
1869 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1870 for (; I != Fetcher.UriEnd(); I++)
1871 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1872 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
1873 return true;
1874 }
1875
1876 // Run it
1877 if (Fetcher.Run() == pkgAcquire::Failed)
1878 return false;
1879
1880 // Print error messages
1881 bool Failed = false;
1882 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
1883 {
1884 if ((*I)->Status == pkgAcquire::Item::StatDone &&
1885 (*I)->Complete == true)
1886 continue;
1887
1888 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1889 (*I)->ErrorText.c_str());
1890 Failed = true;
1891 }
1892 if (Failed == true)
1893 return _error->Error(_("Failed to fetch some archives."));
1894
1895 if (_config->FindB("APT::Get::Download-only",false) == true)
1896 {
1897 c1out << _("Download complete and in download only mode") << endl;
1898 return true;
1899 }
1900
1901 // Unpack the sources
1902 pid_t Process = ExecFork();
1903
1904 if (Process == 0)
1905 {
1906 for (unsigned I = 0; I != J; I++)
1907 {
1908 string Dir = Dsc[I].Package + '-' + Cache->VS().UpstreamVersion(Dsc[I].Version.c_str());
1909
1910 // Diff only mode only fetches .diff files
1911 if (_config->FindB("APT::Get::Diff-Only",false) == true ||
1912 _config->FindB("APT::Get::Tar-Only",false) == true ||
1913 Dsc[I].Dsc.empty() == true)
1914 continue;
1915
1916 // See if the package is already unpacked
1917 struct stat Stat;
1918 if (stat(Dir.c_str(),&Stat) == 0 &&
1919 S_ISDIR(Stat.st_mode) != 0)
1920 {
1921 ioprintf(c0out ,_("Skipping unpack of already unpacked source in %s\n"),
1922 Dir.c_str());
1923 }
1924 else
1925 {
1926 // Call dpkg-source
1927 char S[500];
1928 snprintf(S,sizeof(S),"%s -x %s",
1929 _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
1930 Dsc[I].Dsc.c_str());
1931 if (system(S) != 0)
1932 {
1933 fprintf(stderr,_("Unpack command '%s' failed.\n"),S);
1934 _exit(1);
1935 }
1936 }
1937
1938 // Try to compile it with dpkg-buildpackage
1939 if (_config->FindB("APT::Get::Compile",false) == true)
1940 {
1941 // Call dpkg-buildpackage
1942 char S[500];
1943 snprintf(S,sizeof(S),"cd %s && %s %s",
1944 Dir.c_str(),
1945 _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
1946 _config->Find("DPkg::Build-Options","-b -uc").c_str());
1947
1948 if (system(S) != 0)
1949 {
1950 fprintf(stderr,_("Build command '%s' failed.\n"),S);
1951 _exit(1);
1952 }
1953 }
1954 }
1955
1956 _exit(0);
1957 }
1958
1959 // Wait for the subprocess
1960 int Status = 0;
1961 while (waitpid(Process,&Status,0) != Process)
1962 {
1963 if (errno == EINTR)
1964 continue;
1965 return _error->Errno("waitpid","Couldn't wait for subprocess");
1966 }
1967
1968 if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
1969 return _error->Error(_("Child process failed"));
1970
1971 return true;
1972 }
1973 /*}}}*/
1974 // DoBuildDep - Install/removes packages to satisfy build dependencies /*{{{*/
1975 // ---------------------------------------------------------------------
1976 /* This function will look at the build depends list of the given source
1977 package and install the necessary packages to make it true, or fail. */
1978 bool DoBuildDep(CommandLine &CmdL)
1979 {
1980 CacheFile Cache;
1981 if (Cache.Open(true) == false)
1982 return false;
1983
1984 if (CmdL.FileSize() <= 1)
1985 return _error->Error(_("Must specify at least one package to check builddeps for"));
1986
1987 // Read the source list
1988 pkgSourceList List;
1989 if (List.ReadMainList() == false)
1990 return _error->Error(_("The list of sources could not be read."));
1991
1992 // Create the text record parsers
1993 pkgRecords Recs(Cache);
1994 pkgSrcRecords SrcRecs(List);
1995 if (_error->PendingError() == true)
1996 return false;
1997
1998 // Create the download object
1999 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
2000 pkgAcquire Fetcher(&Stat);
2001
2002 unsigned J = 0;
2003 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
2004 {
2005 string Src;
2006 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
2007 if (Last == 0)
2008 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
2009
2010 // Process the build-dependencies
2011 vector<pkgSrcRecords::Parser::BuildDepRec> BuildDeps;
2012 if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only",false)) == false)
2013 return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str());
2014
2015 // Also ensure that build-essential packages are present
2016 Configuration::Item const *Opts = _config->Tree("APT::Build-Essential");
2017 if (Opts)
2018 Opts = Opts->Child;
2019 for (; Opts; Opts = Opts->Next)
2020 {
2021 if (Opts->Value.empty() == true)
2022 continue;
2023
2024 pkgSrcRecords::Parser::BuildDepRec rec;
2025 rec.Package = Opts->Value;
2026 rec.Type = pkgSrcRecords::Parser::BuildDependIndep;
2027 rec.Op = 0;
2028 BuildDeps.insert(BuildDeps.begin(), rec);
2029 }
2030
2031 if (BuildDeps.size() == 0)
2032 {
2033 ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
2034 continue;
2035 }
2036
2037 // Install the requested packages
2038 unsigned int ExpectedInst = 0;
2039 vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
2040 pkgProblemResolver Fix(Cache);
2041 for (D = BuildDeps.begin(); D != BuildDeps.end(); D++)
2042 {
2043 if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
2044 (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
2045 {
2046 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
2047 // Build-conflicts on unknown packages are silently ignored
2048 if (Pkg.end() == true)
2049 continue;
2050
2051 pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
2052
2053 /*
2054 * Remove if we have an installed version that satisfies the
2055 * version criteria
2056 */
2057 if (IV.end() == false &&
2058 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
2059 TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
2060 }
2061 else // BuildDep || BuildDepIndep
2062 {
2063 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
2064 if (Pkg.end() == true)
2065 {
2066 // Check if there are any alternatives
2067 if (((*D).Op & pkgCache::Dep::Or) != pkgCache::Dep::Or)
2068 return _error->Error(_("%s dependency for %s cannot be satisfied "
2069 "because the package %s cannot be found"),
2070 Last->BuildDepType((*D).Type),Src.c_str(),
2071 (*D).Package.c_str());
2072 // Try the next alternative
2073 continue;
2074 }
2075
2076 /*
2077 * if there are alternatives, we've already picked one, so skip
2078 * the rest
2079 *
2080 * TODO: this means that if there's a build-dep on A|B and B is
2081 * installed, we'll still try to install A; more importantly,
2082 * if A is currently broken, we cannot go back and try B. To fix
2083 * this would require we do a Resolve cycle for each package we
2084 * add to the install list. Ugh
2085 */
2086 while (D != BuildDeps.end() &&
2087 (((*D).Op & pkgCache::Dep::Or) == pkgCache::Dep::Or))
2088 D++;
2089
2090 /*
2091 * If this is a virtual package, we need to check the list of
2092 * packages that provide it and see if any of those are
2093 * installed
2094 */
2095 pkgCache::PrvIterator Prv = Pkg.ProvidesList();
2096 for (; Prv.end() != true; Prv++) {
2097 if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
2098 break;
2099 }
2100
2101 // Get installed version and version we are going to install
2102 pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
2103
2104 if (Prv.end() == true || (*D).Version != "") {
2105 /* We either have a versioned dependency (so a provides won't do)
2106 or nothing is providing this package */
2107
2108 pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
2109
2110 for (; CV.end() != true; CV++)
2111 {
2112 if (Cache->VS().CheckDep(CV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
2113 break;
2114 }
2115 if (CV.end() == true)
2116 return _error->Error(_("%s dependency for %s cannot be satisfied "
2117 "because no available versions of package %s "
2118 "can satisfy version requirements"),
2119 Last->BuildDepType((*D).Type),Src.c_str(),
2120 (*D).Package.c_str());
2121 }
2122
2123 /*
2124 * TODO: if we depend on a version lower than what we already have
2125 * installed it is not clear what should be done; in practice
2126 * this case should be rare, and right now nothing is
2127 * done about it :-(
2128 */
2129 if (Prv.end() == true && // Nothing provides it; and
2130 (IV.end() == true || // It is not installed, or
2131 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == false))
2132 // the version installed doesn't
2133 // satisfy constraints
2134 TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst);
2135 }
2136 }
2137
2138 Fix.InstallProtect();
2139 if (Fix.Resolve(true) == false)
2140 _error->Discard();
2141
2142 // Now we check the state of the packages,
2143 if (Cache->BrokenCount() != 0)
2144 return _error->Error(_("Some broken packages were found while trying to process build-dependencies.\n"
2145 "You might want to run `apt-get -f install' to correct these."));
2146 }
2147
2148 if (InstallPackages(Cache, false, true) == false)
2149 return _error->Error(_("Failed to process build dependencies"));
2150 return true;
2151 }
2152 /*}}}*/
2153
2154 // DoMoo - Never Ask, Never Tell /*{{{*/
2155 // ---------------------------------------------------------------------
2156 /* */
2157 bool DoMoo(CommandLine &CmdL)
2158 {
2159 cout <<
2160 " (__) \n"
2161 " (oo) \n"
2162 " /------\\/ \n"
2163 " / | || \n"
2164 " * /\\---/\\ \n"
2165 " ~~ ~~ \n"
2166 "....\"Have you mooed today?\"...\n";
2167
2168 return true;
2169 }
2170 /*}}}*/
2171 // ShowHelp - Show a help screen /*{{{*/
2172 // ---------------------------------------------------------------------
2173 /* */
2174 bool ShowHelp(CommandLine &CmdL)
2175 {
2176 ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
2177 COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
2178
2179 if (_config->FindB("version") == true)
2180 {
2181 cout << _("Supported Modules:") << endl;
2182
2183 for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++)
2184 {
2185 pkgVersioningSystem *VS = pkgVersioningSystem::GlobalList[I];
2186 if (_system != 0 && _system->VS == VS)
2187 cout << '*';
2188 else
2189 cout << ' ';
2190 cout << "Ver: " << VS->Label << endl;
2191
2192 /* Print out all the packaging systems that will work with
2193 this VS */
2194 for (unsigned J = 0; J != pkgSystem::GlobalListLen; J++)
2195 {
2196 pkgSystem *Sys = pkgSystem::GlobalList[J];
2197 if (_system == Sys)
2198 cout << '*';
2199 else
2200 cout << ' ';
2201 if (Sys->VS->TestCompatibility(*VS) == true)
2202 cout << "Pkg: " << Sys->Label << " (Priority " << Sys->Score(*_config) << ")" << endl;
2203 }
2204 }
2205
2206 for (unsigned I = 0; I != pkgSourceList::Type::GlobalListLen; I++)
2207 {
2208 pkgSourceList::Type *Type = pkgSourceList::Type::GlobalList[I];
2209 cout << " S.L: '" << Type->Name << "' " << Type->Label << endl;
2210 }
2211
2212 for (unsigned I = 0; I != pkgIndexFile::Type::GlobalListLen; I++)
2213 {
2214 pkgIndexFile::Type *Type = pkgIndexFile::Type::GlobalList[I];
2215 cout << " Idx: " << Type->Label << endl;
2216 }
2217
2218 return true;
2219 }
2220
2221 cout <<
2222 _("Usage: apt-get [options] command\n"
2223 " apt-get [options] install|remove pkg1 [pkg2 ...]\n"
2224 " apt-get [options] source pkg1 [pkg2 ...]\n"
2225 "\n"
2226 "apt-get is a simple command line interface for downloading and\n"
2227 "installing packages. The most frequently used commands are update\n"
2228 "and install.\n"
2229 "\n"
2230 "Commands:\n"
2231 " update - Retrieve new lists of packages\n"
2232 " upgrade - Perform an upgrade\n"
2233 " install - Install new packages (pkg is libc6 not libc6.deb)\n"
2234 " remove - Remove packages\n"
2235 " source - Download source archives\n"
2236 " build-dep - Configure build-dependencies for source packages\n"
2237 " dist-upgrade - Distribution upgrade, see apt-get(8)\n"
2238 " dselect-upgrade - Follow dselect selections\n"
2239 " clean - Erase downloaded archive files\n"
2240 " autoclean - Erase old downloaded archive files\n"
2241 " check - Verify that there are no broken dependencies\n"
2242 "\n"
2243 "Options:\n"
2244 " -h This help text.\n"
2245 " -q Loggable output - no progress indicator\n"
2246 " -qq No output except for errors\n"
2247 " -d Download only - do NOT install or unpack archives\n"
2248 " -s No-act. Perform ordering simulation\n"
2249 " -y Assume Yes to all queries and do not prompt\n"
2250 " -f Attempt to continue if the integrity check fails\n"
2251 " -m Attempt to continue if archives are unlocatable\n"
2252 " -u Show a list of upgraded packages as well\n"
2253 " -b Build the source package after fetching it\n"
2254 " -V Show verbose version numbers\n"
2255 " -c=? Read this configuration file\n"
2256 " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp\n"
2257 "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n"
2258 "pages for more information and options.\n"
2259 " This APT has Super Cow Powers.\n");
2260 return true;
2261 }
2262 /*}}}*/
2263 // GetInitialize - Initialize things for apt-get /*{{{*/
2264 // ---------------------------------------------------------------------
2265 /* */
2266 void GetInitialize()
2267 {
2268 _config->Set("quiet",0);
2269 _config->Set("help",false);
2270 _config->Set("APT::Get::Download-Only",false);
2271 _config->Set("APT::Get::Simulate",false);
2272 _config->Set("APT::Get::Assume-Yes",false);
2273 _config->Set("APT::Get::Fix-Broken",false);
2274 _config->Set("APT::Get::Force-Yes",false);
2275 _config->Set("APT::Get::APT::Get::No-List-Cleanup",true);
2276 }
2277 /*}}}*/
2278 // SigWinch - Window size change signal handler /*{{{*/
2279 // ---------------------------------------------------------------------
2280 /* */
2281 void SigWinch(int)
2282 {
2283 // Riped from GNU ls
2284 #ifdef TIOCGWINSZ
2285 struct winsize ws;
2286
2287 if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
2288 ScreenWidth = ws.ws_col - 1;
2289 #endif
2290 }
2291 /*}}}*/
2292
2293 int main(int argc,const char *argv[])
2294 {
2295 CommandLine::Args Args[] = {
2296 {'h',"help","help",0},
2297 {'v',"version","version",0},
2298 {'V',"verbose-versions","APT::Get::Show-Versions",0},
2299 {'q',"quiet","quiet",CommandLine::IntLevel},
2300 {'q',"silent","quiet",CommandLine::IntLevel},
2301 {'d',"download-only","APT::Get::Download-Only",0},
2302 {'b',"compile","APT::Get::Compile",0},
2303 {'b',"build","APT::Get::Compile",0},
2304 {'s',"simulate","APT::Get::Simulate",0},
2305 {'s',"just-print","APT::Get::Simulate",0},
2306 {'s',"recon","APT::Get::Simulate",0},
2307 {'s',"dry-run","APT::Get::Simulate",0},
2308 {'s',"no-act","APT::Get::Simulate",0},
2309 {'y',"yes","APT::Get::Assume-Yes",0},
2310 {'y',"assume-yes","APT::Get::Assume-Yes",0},
2311 {'f',"fix-broken","APT::Get::Fix-Broken",0},
2312 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
2313 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
2314 {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
2315 {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
2316 {0,"download","APT::Get::Download",0},
2317 {0,"fix-missing","APT::Get::Fix-Missing",0},
2318 {0,"ignore-hold","APT::Ignore-Hold",0},
2319 {0,"upgrade","APT::Get::upgrade",0},
2320 {0,"force-yes","APT::Get::force-yes",0},
2321 {0,"print-uris","APT::Get::Print-URIs",0},
2322 {0,"diff-only","APT::Get::Diff-Only",0},
2323 {0,"tar-only","APT::Get::tar-Only",0},
2324 {0,"purge","APT::Get::Purge",0},
2325 {0,"list-cleanup","APT::Get::List-Cleanup",0},
2326 {0,"reinstall","APT::Get::ReInstall",0},
2327 {0,"trivial-only","APT::Get::Trivial-Only",0},
2328 {0,"remove","APT::Get::Remove",0},
2329 {0,"only-source","APT::Get::Only-Source",0},
2330 {0,"arch-only","APT::Get::Arch-Only",0},
2331 {'c',"config-file",0,CommandLine::ConfigFile},
2332 {'o',"option",0,CommandLine::ArbItem},
2333 {0,0,0,0}};
2334 CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
2335 {"upgrade",&DoUpgrade},
2336 {"install",&DoInstall},
2337 {"remove",&DoInstall},
2338 {"dist-upgrade",&DoDistUpgrade},
2339 {"dselect-upgrade",&DoDSelectUpgrade},
2340 {"build-dep",&DoBuildDep},
2341 {"clean",&DoClean},
2342 {"autoclean",&DoAutoClean},
2343 {"check",&DoCheck},
2344 {"source",&DoSource},
2345 {"moo",&DoMoo},
2346 {"help",&ShowHelp},
2347 {0,0}};
2348
2349 // Set up gettext support
2350 setlocale(LC_ALL,"");
2351 textdomain(PACKAGE);
2352
2353 // Parse the command line and initialize the package library
2354 CommandLine CmdL(Args,_config);
2355 if (pkgInitConfig(*_config) == false ||
2356 CmdL.Parse(argc,argv) == false ||
2357 pkgInitSystem(*_config,_system) == false)
2358 {
2359 if (_config->FindB("version") == true)
2360 ShowHelp(CmdL);
2361
2362 _error->DumpErrors();
2363 return 100;
2364 }
2365
2366 // See if the help should be shown
2367 if (_config->FindB("help") == true ||
2368 _config->FindB("version") == true ||
2369 CmdL.FileSize() == 0)
2370 {
2371 ShowHelp(CmdL);
2372 return 0;
2373 }
2374
2375 // Deal with stdout not being a tty
2376 if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
2377 _config->Set("quiet","1");
2378
2379 // Setup the output streams
2380 c0out.rdbuf(cout.rdbuf());
2381 c1out.rdbuf(cout.rdbuf());
2382 c2out.rdbuf(cout.rdbuf());
2383 if (_config->FindI("quiet",0) > 0)
2384 c0out.rdbuf(devnull.rdbuf());
2385 if (_config->FindI("quiet",0) > 1)
2386 c1out.rdbuf(devnull.rdbuf());
2387
2388 // Setup the signals
2389 signal(SIGPIPE,SIG_IGN);
2390 signal(SIGWINCH,SigWinch);
2391 SigWinch(0);
2392
2393 // Match the operation
2394 CmdL.DispatchArg(Cmds);
2395
2396 // Print any errors or warnings found during parsing
2397 if (_error->empty() == false)
2398 {
2399 bool Errors = _error->PendingError();
2400 _error->DumpErrors();
2401 return Errors == true?100:0;
2402 }
2403
2404 return 0;
2405 }