* cmdline/apt-get.cc:
[ntk/apt.git] / cmdline / apt-get.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: apt-get.cc,v 1.156 2004/08/28 01:05:16 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 #define _LARGEFILE_SOURCE
29 #define _LARGEFILE64_SOURCE
30
31 #include <apt-pkg/error.h>
32 #include <apt-pkg/cmndline.h>
33 #include <apt-pkg/init.h>
34 #include <apt-pkg/depcache.h>
35 #include <apt-pkg/sourcelist.h>
36 #include <apt-pkg/algorithms.h>
37 #include <apt-pkg/acquire-item.h>
38 #include <apt-pkg/strutl.h>
39 #include <apt-pkg/clean.h>
40 #include <apt-pkg/srcrecords.h>
41 #include <apt-pkg/version.h>
42 #include <apt-pkg/cachefile.h>
43 #include <apt-pkg/sptr.h>
44 #include <apt-pkg/md5.h>
45 #include <apt-pkg/versionmatch.h>
46
47 #include <config.h>
48 #include <apti18n.h>
49
50 #include "acqprogress.h"
51 #include "cacheset.h"
52
53 #include <set>
54 #include <locale.h>
55 #include <langinfo.h>
56 #include <fstream>
57 #include <termios.h>
58 #include <sys/ioctl.h>
59 #include <sys/stat.h>
60 #include <sys/statfs.h>
61 #include <sys/statvfs.h>
62 #include <signal.h>
63 #include <unistd.h>
64 #include <stdio.h>
65 #include <errno.h>
66 #include <regex.h>
67 #include <sys/wait.h>
68 #include <sstream>
69
70 #define statfs statfs64
71 #define statvfs statvfs64
72 /*}}}*/
73
74 #define RAMFS_MAGIC 0x858458f6
75
76 using namespace std;
77
78 ostream c0out(0);
79 ostream c1out(0);
80 ostream c2out(0);
81 ofstream devnull("/dev/null");
82 unsigned int ScreenWidth = 80 - 1; /* - 1 for the cursor */
83
84 // class CacheFile - Cover class for some dependency cache functions /*{{{*/
85 // ---------------------------------------------------------------------
86 /* */
87 class CacheFile : public pkgCacheFile
88 {
89 static pkgCache *SortCache;
90 static int NameComp(const void *a,const void *b);
91
92 public:
93 pkgCache::Package **List;
94
95 void Sort();
96 bool CheckDeps(bool AllowBroken = false);
97 bool BuildCaches(bool WithLock = true)
98 {
99 OpTextProgress Prog(*_config);
100 if (pkgCacheFile::BuildCaches(&Prog,WithLock) == false)
101 return false;
102 return true;
103 }
104 bool Open(bool WithLock = true)
105 {
106 OpTextProgress Prog(*_config);
107 if (pkgCacheFile::Open(&Prog,WithLock) == false)
108 return false;
109 Sort();
110
111 return true;
112 };
113 bool OpenForInstall()
114 {
115 if (_config->FindB("APT::Get::Print-URIs") == true)
116 return Open(false);
117 else
118 return Open(true);
119 }
120 CacheFile() : List(0) {};
121 ~CacheFile() {
122 delete[] List;
123 }
124 };
125 /*}}}*/
126
127 // YnPrompt - Yes No Prompt. /*{{{*/
128 // ---------------------------------------------------------------------
129 /* Returns true on a Yes.*/
130 bool YnPrompt(bool Default=true)
131 {
132 if (_config->FindB("APT::Get::Assume-Yes",false) == true)
133 {
134 c1out << _("Y") << endl;
135 return true;
136 }
137
138 char response[1024] = "";
139 cin.getline(response, sizeof(response));
140
141 if (!cin)
142 return false;
143
144 if (strlen(response) == 0)
145 return Default;
146
147 regex_t Pattern;
148 int Res;
149
150 Res = regcomp(&Pattern, nl_langinfo(YESEXPR),
151 REG_EXTENDED|REG_ICASE|REG_NOSUB);
152
153 if (Res != 0) {
154 char Error[300];
155 regerror(Res,&Pattern,Error,sizeof(Error));
156 return _error->Error(_("Regex compilation error - %s"),Error);
157 }
158
159 Res = regexec(&Pattern, response, 0, NULL, 0);
160 if (Res == 0)
161 return true;
162 return false;
163 }
164 /*}}}*/
165 // AnalPrompt - Annoying Yes No Prompt. /*{{{*/
166 // ---------------------------------------------------------------------
167 /* Returns true on a Yes.*/
168 bool AnalPrompt(const char *Text)
169 {
170 char Buf[1024];
171 cin.getline(Buf,sizeof(Buf));
172 if (strcmp(Buf,Text) == 0)
173 return true;
174 return false;
175 }
176 /*}}}*/
177 // ShowList - Show a list /*{{{*/
178 // ---------------------------------------------------------------------
179 /* This prints out a string of space separated words with a title and
180 a two space indent line wraped to the current screen width. */
181 bool ShowList(ostream &out,string Title,string List,string VersionsList)
182 {
183 if (List.empty() == true)
184 return true;
185 // trim trailing space
186 int NonSpace = List.find_last_not_of(' ');
187 if (NonSpace != -1)
188 {
189 List = List.erase(NonSpace + 1);
190 if (List.empty() == true)
191 return true;
192 }
193
194 // Acount for the leading space
195 int ScreenWidth = ::ScreenWidth - 3;
196
197 out << Title << endl;
198 string::size_type Start = 0;
199 string::size_type VersionsStart = 0;
200 while (Start < List.size())
201 {
202 if(_config->FindB("APT::Get::Show-Versions",false) == true &&
203 VersionsList.size() > 0) {
204 string::size_type End;
205 string::size_type VersionsEnd;
206
207 End = List.find(' ',Start);
208 VersionsEnd = VersionsList.find('\n', VersionsStart);
209
210 out << " " << string(List,Start,End - Start) << " (" <<
211 string(VersionsList,VersionsStart,VersionsEnd - VersionsStart) <<
212 ")" << endl;
213
214 if (End == string::npos || End < Start)
215 End = Start + ScreenWidth;
216
217 Start = End + 1;
218 VersionsStart = VersionsEnd + 1;
219 } else {
220 string::size_type End;
221
222 if (Start + ScreenWidth >= List.size())
223 End = List.size();
224 else
225 End = List.rfind(' ',Start+ScreenWidth);
226
227 if (End == string::npos || End < Start)
228 End = Start + ScreenWidth;
229 out << " " << string(List,Start,End - Start) << endl;
230 Start = End + 1;
231 }
232 }
233
234 return false;
235 }
236 /*}}}*/
237 // ShowBroken - Debugging aide /*{{{*/
238 // ---------------------------------------------------------------------
239 /* This prints out the names of all the packages that are broken along
240 with the name of each each broken dependency and a quite version
241 description.
242
243 The output looks like:
244 The following packages have unmet dependencies:
245 exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed
246 Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
247 Depends: libsasl7 but it is not going to be installed
248 */
249 void ShowBroken(ostream &out,CacheFile &Cache,bool Now)
250 {
251 out << _("The following packages have unmet dependencies:") << endl;
252 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
253 {
254 pkgCache::PkgIterator I(Cache,Cache.List[J]);
255
256 if (Now == true)
257 {
258 if (Cache[I].NowBroken() == false)
259 continue;
260 }
261 else
262 {
263 if (Cache[I].InstBroken() == false)
264 continue;
265 }
266
267 // Print out each package and the failed dependencies
268 out << " " << I.FullName(true) << " :";
269 unsigned const Indent = I.FullName(true).size() + 3;
270 bool First = true;
271 pkgCache::VerIterator Ver;
272
273 if (Now == true)
274 Ver = I.CurrentVer();
275 else
276 Ver = Cache[I].InstVerIter(Cache);
277
278 if (Ver.end() == true)
279 {
280 out << endl;
281 continue;
282 }
283
284 for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
285 {
286 // Compute a single dependency element (glob or)
287 pkgCache::DepIterator Start;
288 pkgCache::DepIterator End;
289 D.GlobOr(Start,End); // advances D
290
291 if (Cache->IsImportantDep(End) == false)
292 continue;
293
294 if (Now == true)
295 {
296 if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
297 continue;
298 }
299 else
300 {
301 if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
302 continue;
303 }
304
305 bool FirstOr = true;
306 while (1)
307 {
308 if (First == false)
309 for (unsigned J = 0; J != Indent; J++)
310 out << ' ';
311 First = false;
312
313 if (FirstOr == false)
314 {
315 for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
316 out << ' ';
317 }
318 else
319 out << ' ' << End.DepType() << ": ";
320 FirstOr = false;
321
322 out << Start.TargetPkg().FullName(true);
323
324 // Show a quick summary of the version requirements
325 if (Start.TargetVer() != 0)
326 out << " (" << Start.CompType() << " " << Start.TargetVer() << ")";
327
328 /* Show a summary of the target package if possible. In the case
329 of virtual packages we show nothing */
330 pkgCache::PkgIterator Targ = Start.TargetPkg();
331 if (Targ->ProvidesList == 0)
332 {
333 out << ' ';
334 pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
335 if (Now == true)
336 Ver = Targ.CurrentVer();
337
338 if (Ver.end() == false)
339 {
340 if (Now == true)
341 ioprintf(out,_("but %s is installed"),Ver.VerStr());
342 else
343 ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
344 }
345 else
346 {
347 if (Cache[Targ].CandidateVerIter(Cache).end() == true)
348 {
349 if (Targ->ProvidesList == 0)
350 out << _("but it is not installable");
351 else
352 out << _("but it is a virtual package");
353 }
354 else
355 out << (Now?_("but it is not installed"):_("but it is not going to be installed"));
356 }
357 }
358
359 if (Start != End)
360 out << _(" or");
361 out << endl;
362
363 if (Start == End)
364 break;
365 Start++;
366 }
367 }
368 }
369 }
370 /*}}}*/
371 // ShowNew - Show packages to newly install /*{{{*/
372 // ---------------------------------------------------------------------
373 /* */
374 void ShowNew(ostream &out,CacheFile &Cache)
375 {
376 /* Print out a list of packages that are going to be installed extra
377 to what the user asked */
378 string List;
379 string VersionsList;
380 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
381 {
382 pkgCache::PkgIterator I(Cache,Cache.List[J]);
383 if (Cache[I].NewInstall() == true) {
384 if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
385 continue;
386 List += I.FullName(true) + " ";
387 VersionsList += string(Cache[I].CandVersion) + "\n";
388 }
389 }
390
391 ShowList(out,_("The following NEW packages will be installed:"),List,VersionsList);
392 }
393 /*}}}*/
394 // ShowDel - Show packages to delete /*{{{*/
395 // ---------------------------------------------------------------------
396 /* */
397 void ShowDel(ostream &out,CacheFile &Cache)
398 {
399 /* Print out a list of packages that are going to be removed extra
400 to what the user asked */
401 string List;
402 string VersionsList;
403 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
404 {
405 pkgCache::PkgIterator I(Cache,Cache.List[J]);
406 if (Cache[I].Delete() == true)
407 {
408 if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
409 continue;
410 if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
411 List += I.FullName(true) + "* ";
412 else
413 List += I.FullName(true) + " ";
414
415 VersionsList += string(Cache[I].CandVersion)+ "\n";
416 }
417 }
418
419 ShowList(out,_("The following packages will be REMOVED:"),List,VersionsList);
420 }
421 /*}}}*/
422 // ShowKept - Show kept packages /*{{{*/
423 // ---------------------------------------------------------------------
424 /* */
425 void ShowKept(ostream &out,CacheFile &Cache)
426 {
427 string List;
428 string VersionsList;
429 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
430 {
431 pkgCache::PkgIterator I(Cache,Cache.List[J]);
432
433 // Not interesting
434 if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false ||
435 I->CurrentVer == 0 || Cache[I].Delete() == true)
436 continue;
437
438 List += I.FullName(true) + " ";
439 VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
440 }
441 ShowList(out,_("The following packages have been kept back:"),List,VersionsList);
442 }
443 /*}}}*/
444 // ShowUpgraded - Show upgraded packages /*{{{*/
445 // ---------------------------------------------------------------------
446 /* */
447 void ShowUpgraded(ostream &out,CacheFile &Cache)
448 {
449 string List;
450 string VersionsList;
451 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
452 {
453 pkgCache::PkgIterator I(Cache,Cache.List[J]);
454
455 // Not interesting
456 if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
457 continue;
458 if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
459 continue;
460
461 List += I.FullName(true) + " ";
462 VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
463 }
464 ShowList(out,_("The following packages will be upgraded:"),List,VersionsList);
465 }
466 /*}}}*/
467 // ShowDowngraded - Show downgraded packages /*{{{*/
468 // ---------------------------------------------------------------------
469 /* */
470 bool ShowDowngraded(ostream &out,CacheFile &Cache)
471 {
472 string List;
473 string VersionsList;
474 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
475 {
476 pkgCache::PkgIterator I(Cache,Cache.List[J]);
477
478 // Not interesting
479 if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
480 continue;
481 if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
482 continue;
483
484 List += I.FullName(true) + " ";
485 VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
486 }
487 return ShowList(out,_("The following packages will be DOWNGRADED:"),List,VersionsList);
488 }
489 /*}}}*/
490 // ShowHold - Show held but changed packages /*{{{*/
491 // ---------------------------------------------------------------------
492 /* */
493 bool ShowHold(ostream &out,CacheFile &Cache)
494 {
495 string List;
496 string VersionsList;
497 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
498 {
499 pkgCache::PkgIterator I(Cache,Cache.List[J]);
500 if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
501 I->SelectedState == pkgCache::State::Hold) {
502 List += I.FullName(true) + " ";
503 VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
504 }
505 }
506
507 return ShowList(out,_("The following held packages will be changed:"),List,VersionsList);
508 }
509 /*}}}*/
510 // ShowEssential - Show an essential package warning /*{{{*/
511 // ---------------------------------------------------------------------
512 /* This prints out a warning message that is not to be ignored. It shows
513 all essential packages and their dependents that are to be removed.
514 It is insanely risky to remove the dependents of an essential package! */
515 bool ShowEssential(ostream &out,CacheFile &Cache)
516 {
517 string List;
518 string VersionsList;
519 bool *Added = new bool[Cache->Head().PackageCount];
520 for (unsigned int I = 0; I != Cache->Head().PackageCount; I++)
521 Added[I] = false;
522
523 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
524 {
525 pkgCache::PkgIterator I(Cache,Cache.List[J]);
526 if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
527 (I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
528 continue;
529
530 // The essential package is being removed
531 if (Cache[I].Delete() == true)
532 {
533 if (Added[I->ID] == false)
534 {
535 Added[I->ID] = true;
536 List += I.FullName(true) + " ";
537 //VersionsList += string(Cache[I].CurVersion) + "\n"; ???
538 }
539 }
540
541 if (I->CurrentVer == 0)
542 continue;
543
544 // Print out any essential package depenendents that are to be removed
545 for (pkgCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; D++)
546 {
547 // Skip everything but depends
548 if (D->Type != pkgCache::Dep::PreDepends &&
549 D->Type != pkgCache::Dep::Depends)
550 continue;
551
552 pkgCache::PkgIterator P = D.SmartTargetPkg();
553 if (Cache[P].Delete() == true)
554 {
555 if (Added[P->ID] == true)
556 continue;
557 Added[P->ID] = true;
558
559 char S[300];
560 snprintf(S,sizeof(S),_("%s (due to %s) "),P.FullName(true).c_str(),I.FullName(true).c_str());
561 List += S;
562 //VersionsList += "\n"; ???
563 }
564 }
565 }
566
567 delete [] Added;
568 return ShowList(out,_("WARNING: The following essential packages will be removed.\n"
569 "This should NOT be done unless you know exactly what you are doing!"),List,VersionsList);
570 }
571
572 /*}}}*/
573 // Stats - Show some statistics /*{{{*/
574 // ---------------------------------------------------------------------
575 /* */
576 void Stats(ostream &out,pkgDepCache &Dep)
577 {
578 unsigned long Upgrade = 0;
579 unsigned long Downgrade = 0;
580 unsigned long Install = 0;
581 unsigned long ReInstall = 0;
582 for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++)
583 {
584 if (pkgCache::VerIterator(Dep, Dep[I].CandidateVer).Pseudo() == true)
585 continue;
586
587 if (Dep[I].NewInstall() == true)
588 Install++;
589 else
590 {
591 if (Dep[I].Upgrade() == true)
592 Upgrade++;
593 else
594 if (Dep[I].Downgrade() == true)
595 Downgrade++;
596 }
597
598 if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
599 ReInstall++;
600 }
601
602 ioprintf(out,_("%lu upgraded, %lu newly installed, "),
603 Upgrade,Install);
604
605 if (ReInstall != 0)
606 ioprintf(out,_("%lu reinstalled, "),ReInstall);
607 if (Downgrade != 0)
608 ioprintf(out,_("%lu downgraded, "),Downgrade);
609
610 ioprintf(out,_("%lu to remove and %lu not upgraded.\n"),
611 Dep.DelCount(),Dep.KeepCount());
612
613 if (Dep.BadCount() != 0)
614 ioprintf(out,_("%lu not fully installed or removed.\n"),
615 Dep.BadCount());
616 }
617 /*}}}*/
618 // CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/
619 class CacheSetHelperAPTGet : public APT::CacheSetHelper {
620 /** \brief stream message should be printed to */
621 std::ostream &out;
622 /** \brief were things like Task or RegEx used to select packages? */
623 bool explicitlyNamed;
624
625 APT::PackageSet virtualPkgs;
626
627 public:
628 CacheSetHelperAPTGet(std::ostream &out) : APT::CacheSetHelper(true), out(out) {
629 explicitlyNamed = true;
630 }
631
632 virtual void showTaskSelection(APT::PackageSet const &pkgset, string const &pattern) {
633 for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
634 ioprintf(out, _("Note, selecting '%s' for task '%s'\n"),
635 Pkg.FullName(true).c_str(), pattern.c_str());
636 explicitlyNamed = false;
637 }
638 virtual void showRegExSelection(APT::PackageSet const &pkgset, string const &pattern) {
639 for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
640 ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"),
641 Pkg.FullName(true).c_str(), pattern.c_str());
642 explicitlyNamed = false;
643 }
644 virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
645 string const &ver, bool const &verIsRel) {
646 if (ver != Ver.VerStr())
647 ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"),
648 Ver.VerStr(), Ver.RelStr().c_str(), Pkg.FullName(true).c_str());
649 }
650
651 bool showVirtualPackageErrors(pkgCacheFile &Cache) {
652 if (virtualPkgs.empty() == true)
653 return true;
654 for (APT::PackageSet::const_iterator Pkg = virtualPkgs.begin();
655 Pkg != virtualPkgs.end(); ++Pkg) {
656 if (Pkg->ProvidesList != 0) {
657 ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
658 Pkg.FullName(true).c_str());
659
660 pkgCache::PrvIterator I = Pkg.ProvidesList();
661 unsigned short provider = 0;
662 for (; I.end() == false; ++I) {
663 pkgCache::PkgIterator Pkg = I.OwnerPkg();
664
665 if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) {
666 out << " " << Pkg.FullName(true) << " " << I.OwnerVer().VerStr();
667 if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
668 out << _(" [Installed]");
669 out << endl;
670 ++provider;
671 }
672 }
673 // if we found no candidate which provide this package, show non-candidates
674 if (provider == 0)
675 for (I = Pkg.ProvidesList(); I.end() == false; I++)
676 out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr()
677 << _(" [Not candidate version]") << endl;
678 else
679 out << _("You should explicitly select one to install.") << endl;
680 } else {
681 ioprintf(out,
682 _("Package %s is not available, but is referred to by another package.\n"
683 "This may mean that the package is missing, has been obsoleted, or\n"
684 "is only available from another source\n"),Pkg.FullName(true).c_str());
685
686 string List;
687 string VersionsList;
688 SPtrArray<bool> Seen = new bool[Cache.GetPkgCache()->Head().PackageCount];
689 memset(Seen,0,Cache.GetPkgCache()->Head().PackageCount*sizeof(*Seen));
690 for (pkgCache::DepIterator Dep = Pkg.RevDependsList();
691 Dep.end() == false; Dep++) {
692 if (Dep->Type != pkgCache::Dep::Replaces)
693 continue;
694 if (Seen[Dep.ParentPkg()->ID] == true)
695 continue;
696 Seen[Dep.ParentPkg()->ID] = true;
697 List += Dep.ParentPkg().FullName(true) + " ";
698 //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ???
699 }
700 ShowList(out,_("However the following packages replace it:"),List,VersionsList);
701 }
702 out << std::endl;
703 }
704 return false;
705 }
706
707 virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
708 APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDIDATE);
709 if (verset.empty() == false)
710 return *(verset.begin());
711 if (ShowError == true) {
712 _error->Error(_("Package '%s' has no installation candidate"),Pkg.FullName(true).c_str());
713 virtualPkgs.insert(Pkg);
714 }
715 return pkgCache::VerIterator(Cache, 0);
716 }
717
718 virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
719 APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST);
720 if (verset.empty() == false)
721 return *(verset.begin());
722 if (ShowError == true)
723 ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str());
724 return pkgCache::VerIterator(Cache, 0);
725 }
726
727 APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg,
728 APT::VersionSet::Version const &select) {
729 /* This is a pure virtual package and there is a single available
730 candidate providing it. */
731 if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0)
732 return APT::VersionSet();
733
734 pkgCache::PkgIterator Prov;
735 bool found_one = false;
736 for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) {
737 pkgCache::VerIterator const PVer = P.OwnerVer();
738 pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
739
740 /* Ignore versions that are not a candidate. */
741 if (Cache[PPkg].CandidateVer != PVer)
742 continue;
743
744 if (found_one == false) {
745 Prov = PPkg;
746 found_one = true;
747 } else if (PPkg != Prov) {
748 found_one = false; // we found at least two
749 break;
750 }
751 }
752
753 if (found_one == true) {
754 ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"),
755 Prov.FullName(true).c_str(), Pkg.FullName(true).c_str());
756 return APT::VersionSet::FromPackage(Cache, Prov, select, *this);
757 }
758 return APT::VersionSet();
759 }
760
761 inline bool allPkgNamedExplicitly() const { return explicitlyNamed; }
762
763 };
764 /*}}}*/
765 // TryToInstall - Mark a package for installation /*{{{*/
766 struct TryToInstall {
767 pkgCacheFile* Cache;
768 pkgProblemResolver* Fix;
769 bool FixBroken;
770 unsigned long AutoMarkChanged;
771 APT::PackageSet doAutoInstallLater;
772
773 TryToInstall(pkgCacheFile &Cache, pkgProblemResolver &PM, bool const &FixBroken) : Cache(&Cache), Fix(&PM),
774 FixBroken(FixBroken), AutoMarkChanged(0) {};
775
776 void operator() (pkgCache::VerIterator const &Ver) {
777 pkgCache::PkgIterator Pkg = Ver.ParentPkg();
778
779 Cache->GetDepCache()->SetCandidateVersion(Ver);
780 pkgDepCache::StateCache &State = (*Cache)[Pkg];
781
782 // Handle the no-upgrade case
783 if (_config->FindB("APT::Get::upgrade",true) == false && Pkg->CurrentVer != 0)
784 ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
785 Pkg.FullName(true).c_str());
786 // Ignore request for install if package would be new
787 else if (_config->FindB("APT::Get::Only-Upgrade", false) == true && Pkg->CurrentVer == 0)
788 ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
789 Pkg.FullName(true).c_str());
790 else {
791 Fix->Clear(Pkg);
792 Fix->Protect(Pkg);
793 Cache->GetDepCache()->MarkInstall(Pkg,false);
794
795 if (State.Install() == false) {
796 if (_config->FindB("APT::Get::ReInstall",false) == true) {
797 if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
798 ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
799 Pkg.FullName(true).c_str());
800 else
801 Cache->GetDepCache()->SetReInstall(Pkg, true);
802 } else
803 ioprintf(c1out,_("%s is already the newest version.\n"),
804 Pkg.FullName(true).c_str());
805 }
806
807 // Install it with autoinstalling enabled (if we not respect the minial
808 // required deps or the policy)
809 if (FixBroken == false)
810 doAutoInstallLater.insert(Pkg);
811 }
812
813 // see if we need to fix the auto-mark flag
814 // e.g. apt-get install foo
815 // where foo is marked automatic
816 if (State.Install() == false &&
817 (State.Flags & pkgCache::Flag::Auto) &&
818 _config->FindB("APT::Get::ReInstall",false) == false &&
819 _config->FindB("APT::Get::Only-Upgrade",false) == false &&
820 _config->FindB("APT::Get::Download-Only",false) == false)
821 {
822 ioprintf(c1out,_("%s set to manually installed.\n"),
823 Pkg.FullName(true).c_str());
824 Cache->GetDepCache()->MarkAuto(Pkg,false);
825 AutoMarkChanged++;
826 }
827 }
828
829 void doAutoInstall() {
830 for (APT::PackageSet::const_iterator P = doAutoInstallLater.begin();
831 P != doAutoInstallLater.end(); ++P) {
832 pkgDepCache::StateCache &State = (*Cache)[P];
833 if (State.InstBroken() == false && State.InstPolicyBroken() == false)
834 continue;
835 Cache->GetDepCache()->MarkInstall(P, true);
836 }
837 doAutoInstallLater.clear();
838 }
839 };
840 /*}}}*/
841 // TryToRemove - Mark a package for removal /*{{{*/
842 struct TryToRemove {
843 pkgCacheFile* Cache;
844 pkgProblemResolver* Fix;
845 bool FixBroken;
846 unsigned long AutoMarkChanged;
847
848 TryToRemove(pkgCacheFile &Cache, pkgProblemResolver &PM) : Cache(&Cache), Fix(&PM) {};
849
850 void operator() (pkgCache::VerIterator const &Ver)
851 {
852 pkgCache::PkgIterator Pkg = Ver.ParentPkg();
853
854 Fix->Clear(Pkg);
855 Fix->Protect(Pkg);
856 Fix->Remove(Pkg);
857
858 if (Pkg->CurrentVer == 0)
859 ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.FullName(true).c_str());
860 else
861 Cache->GetDepCache()->MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
862 }
863 };
864 /*}}}*/
865 // CacheFile::NameComp - QSort compare by name /*{{{*/
866 // ---------------------------------------------------------------------
867 /* */
868 pkgCache *CacheFile::SortCache = 0;
869 int CacheFile::NameComp(const void *a,const void *b)
870 {
871 if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0)
872 return *(pkgCache::Package **)a - *(pkgCache::Package **)b;
873
874 const pkgCache::Package &A = **(pkgCache::Package **)a;
875 const pkgCache::Package &B = **(pkgCache::Package **)b;
876
877 return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name);
878 }
879 /*}}}*/
880 // CacheFile::Sort - Sort by name /*{{{*/
881 // ---------------------------------------------------------------------
882 /* */
883 void CacheFile::Sort()
884 {
885 delete [] List;
886 List = new pkgCache::Package *[Cache->Head().PackageCount];
887 memset(List,0,sizeof(*List)*Cache->Head().PackageCount);
888 pkgCache::PkgIterator I = Cache->PkgBegin();
889 for (;I.end() != true; I++)
890 List[I->ID] = I;
891
892 SortCache = *this;
893 qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp);
894 }
895 /*}}}*/
896 // CacheFile::CheckDeps - Open the cache file /*{{{*/
897 // ---------------------------------------------------------------------
898 /* This routine generates the caches and then opens the dependency cache
899 and verifies that the system is OK. */
900 bool CacheFile::CheckDeps(bool AllowBroken)
901 {
902 bool FixBroken = _config->FindB("APT::Get::Fix-Broken",false);
903
904 if (_error->PendingError() == true)
905 return false;
906
907 // Check that the system is OK
908 if (DCache->DelCount() != 0 || DCache->InstCount() != 0)
909 return _error->Error("Internal error, non-zero counts");
910
911 // Apply corrections for half-installed packages
912 if (pkgApplyStatus(*DCache) == false)
913 return false;
914
915 if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true)
916 {
917 FixBroken = true;
918 if ((DCache->PolicyBrokenCount() > 0))
919 {
920 // upgrade all policy-broken packages with ForceImportantDeps=True
921 for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); I++)
922 if ((*DCache)[I].NowPolicyBroken() == true)
923 DCache->MarkInstall(I,true,0, false, true);
924 }
925 }
926
927 // Nothing is broken
928 if (DCache->BrokenCount() == 0 || AllowBroken == true)
929 return true;
930
931 // Attempt to fix broken things
932 if (FixBroken == true)
933 {
934 c1out << _("Correcting dependencies...") << flush;
935 if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
936 {
937 c1out << _(" failed.") << endl;
938 ShowBroken(c1out,*this,true);
939
940 return _error->Error(_("Unable to correct dependencies"));
941 }
942 if (pkgMinimizeUpgrade(*DCache) == false)
943 return _error->Error(_("Unable to minimize the upgrade set"));
944
945 c1out << _(" Done") << endl;
946 }
947 else
948 {
949 c1out << _("You might want to run 'apt-get -f install' to correct these.") << endl;
950 ShowBroken(c1out,*this,true);
951
952 return _error->Error(_("Unmet dependencies. Try using -f."));
953 }
954
955 return true;
956 }
957 /*}}}*/
958 // CheckAuth - check if each download comes form a trusted source /*{{{*/
959 // ---------------------------------------------------------------------
960 /* */
961 static bool CheckAuth(pkgAcquire& Fetcher)
962 {
963 string UntrustedList;
964 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I)
965 {
966 if (!(*I)->IsTrusted())
967 {
968 UntrustedList += string((*I)->ShortDesc()) + " ";
969 }
970 }
971
972 if (UntrustedList == "")
973 {
974 return true;
975 }
976
977 ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,"");
978
979 if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true)
980 {
981 c2out << _("Authentication warning overridden.\n");
982 return true;
983 }
984
985 if (_config->FindI("quiet",0) < 2
986 && _config->FindB("APT::Get::Assume-Yes",false) == false)
987 {
988 c2out << _("Install these packages without verification [y/N]? ") << flush;
989 if (!YnPrompt(false))
990 return _error->Error(_("Some packages could not be authenticated"));
991
992 return true;
993 }
994 else if (_config->FindB("APT::Get::Force-Yes",false) == true)
995 {
996 return true;
997 }
998
999 return _error->Error(_("There are problems and -y was used without --force-yes"));
1000 }
1001 /*}}}*/
1002 // InstallPackages - Actually download and install the packages /*{{{*/
1003 // ---------------------------------------------------------------------
1004 /* This displays the informative messages describing what is going to
1005 happen and then calls the download routines */
1006 bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
1007 bool Safety = true)
1008 {
1009 if (_config->FindB("APT::Get::Purge",false) == true)
1010 {
1011 pkgCache::PkgIterator I = Cache->PkgBegin();
1012 for (; I.end() == false; I++)
1013 {
1014 if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
1015 Cache->MarkDelete(I,true);
1016 }
1017 }
1018
1019 bool Fail = false;
1020 bool Essential = false;
1021
1022 // Show all the various warning indicators
1023 ShowDel(c1out,Cache);
1024 ShowNew(c1out,Cache);
1025 if (ShwKept == true)
1026 ShowKept(c1out,Cache);
1027 Fail |= !ShowHold(c1out,Cache);
1028 if (_config->FindB("APT::Get::Show-Upgraded",true) == true)
1029 ShowUpgraded(c1out,Cache);
1030 Fail |= !ShowDowngraded(c1out,Cache);
1031 if (_config->FindB("APT::Get::Download-Only",false) == false)
1032 Essential = !ShowEssential(c1out,Cache);
1033 Fail |= Essential;
1034 Stats(c1out,Cache);
1035
1036 // Sanity check
1037 if (Cache->BrokenCount() != 0)
1038 {
1039 ShowBroken(c1out,Cache,false);
1040 return _error->Error(_("Internal error, InstallPackages was called with broken packages!"));
1041 }
1042
1043 if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
1044 Cache->BadCount() == 0)
1045 return true;
1046
1047 // No remove flag
1048 if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
1049 return _error->Error(_("Packages need to be removed but remove is disabled."));
1050
1051 // Run the simulator ..
1052 if (_config->FindB("APT::Get::Simulate") == true)
1053 {
1054 pkgSimulate PM(Cache);
1055 int status_fd = _config->FindI("APT::Status-Fd",-1);
1056 pkgPackageManager::OrderResult Res = PM.DoInstall(status_fd);
1057 if (Res == pkgPackageManager::Failed)
1058 return false;
1059 if (Res != pkgPackageManager::Completed)
1060 return _error->Error(_("Internal error, Ordering didn't finish"));
1061 return true;
1062 }
1063
1064 // Create the text record parser
1065 pkgRecords Recs(Cache);
1066 if (_error->PendingError() == true)
1067 return false;
1068
1069 // Create the download object
1070 pkgAcquire Fetcher;
1071 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1072 if (_config->FindB("APT::Get::Print-URIs", false) == true)
1073 {
1074 // force a hashsum for compatibility reasons
1075 _config->CndSet("Acquire::ForceHash", "md5sum");
1076 if (Fetcher.Setup(&Stat, "") == false)
1077 return false;
1078 }
1079 else if (Fetcher.Setup(&Stat, _config->FindDir("Dir::Cache::Archives")) == false)
1080 return false;
1081
1082 // Read the source list
1083 pkgSourceList List;
1084 if (List.ReadMainList() == false)
1085 return _error->Error(_("The list of sources could not be read."));
1086
1087 // Create the package manager and prepare to download
1088 SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
1089 if (PM->GetArchives(&Fetcher,&List,&Recs) == false ||
1090 _error->PendingError() == true)
1091 return false;
1092
1093 // Display statistics
1094 unsigned long long FetchBytes = Fetcher.FetchNeeded();
1095 unsigned long long FetchPBytes = Fetcher.PartialPresent();
1096 unsigned long long DebBytes = Fetcher.TotalNeeded();
1097 if (DebBytes != Cache->DebSize())
1098 {
1099 c0out << DebBytes << ',' << Cache->DebSize() << endl;
1100 c0out << _("How odd.. The sizes didn't match, email apt@packages.debian.org") << endl;
1101 }
1102
1103 // Number of bytes
1104 if (DebBytes != FetchBytes)
1105 ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
1106 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
1107 else if (DebBytes != 0)
1108 ioprintf(c1out,_("Need to get %sB of archives.\n"),
1109 SizeToStr(DebBytes).c_str());
1110
1111 // Size delta
1112 if (Cache->UsrSize() >= 0)
1113 ioprintf(c1out,_("After this operation, %sB of additional disk space will be used.\n"),
1114 SizeToStr(Cache->UsrSize()).c_str());
1115 else
1116 ioprintf(c1out,_("After this operation, %sB disk space will be freed.\n"),
1117 SizeToStr(-1*Cache->UsrSize()).c_str());
1118
1119 if (_error->PendingError() == true)
1120 return false;
1121
1122 /* Check for enough free space, but only if we are actually going to
1123 download */
1124 if (_config->FindB("APT::Get::Print-URIs") == false &&
1125 _config->FindB("APT::Get::Download",true) == true)
1126 {
1127 struct statvfs Buf;
1128 string OutputDir = _config->FindDir("Dir::Cache::Archives");
1129 if (statvfs(OutputDir.c_str(),&Buf) != 0) {
1130 if (errno == EOVERFLOW)
1131 return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
1132 OutputDir.c_str());
1133 else
1134 return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
1135 OutputDir.c_str());
1136 } else if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
1137 {
1138 struct statfs Stat;
1139 if (statfs(OutputDir.c_str(),&Stat) != 0
1140 #if HAVE_STRUCT_STATFS_F_TYPE
1141 || unsigned(Stat.f_type) != RAMFS_MAGIC
1142 #endif
1143 )
1144 return _error->Error(_("You don't have enough free space in %s."),
1145 OutputDir.c_str());
1146 }
1147 }
1148
1149 // Fail safe check
1150 if (_config->FindI("quiet",0) >= 2 ||
1151 _config->FindB("APT::Get::Assume-Yes",false) == true)
1152 {
1153 if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
1154 return _error->Error(_("There are problems and -y was used without --force-yes"));
1155 }
1156
1157 if (Essential == true && Safety == true)
1158 {
1159 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
1160 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
1161
1162 const char *Prompt = _("Yes, do as I say!");
1163 ioprintf(c2out,
1164 _("You are about to do something potentially harmful.\n"
1165 "To continue type in the phrase '%s'\n"
1166 " ?] "),Prompt);
1167 c2out << flush;
1168 if (AnalPrompt(Prompt) == false)
1169 {
1170 c2out << _("Abort.") << endl;
1171 exit(1);
1172 }
1173 }
1174 else
1175 {
1176 // Prompt to continue
1177 if (Ask == true || Fail == true)
1178 {
1179 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
1180 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
1181
1182 if (_config->FindI("quiet",0) < 2 &&
1183 _config->FindB("APT::Get::Assume-Yes",false) == false)
1184 {
1185 c2out << _("Do you want to continue [Y/n]? ") << flush;
1186
1187 if (YnPrompt() == false)
1188 {
1189 c2out << _("Abort.") << endl;
1190 exit(1);
1191 }
1192 }
1193 }
1194 }
1195
1196 // Just print out the uris an exit if the --print-uris flag was used
1197 if (_config->FindB("APT::Get::Print-URIs") == true)
1198 {
1199 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1200 for (; I != Fetcher.UriEnd(); I++)
1201 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1202 I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
1203 return true;
1204 }
1205
1206 if (!CheckAuth(Fetcher))
1207 return false;
1208
1209 /* Unlock the dpkg lock if we are not going to be doing an install
1210 after. */
1211 if (_config->FindB("APT::Get::Download-Only",false) == true)
1212 _system->UnLock();
1213
1214 // Run it
1215 while (1)
1216 {
1217 bool Transient = false;
1218 if (_config->FindB("APT::Get::Download",true) == false)
1219 {
1220 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
1221 {
1222 if ((*I)->Local == true)
1223 {
1224 I++;
1225 continue;
1226 }
1227
1228 // Close the item and check if it was found in cache
1229 (*I)->Finished();
1230 if ((*I)->Complete == false)
1231 Transient = true;
1232
1233 // Clear it out of the fetch list
1234 delete *I;
1235 I = Fetcher.ItemsBegin();
1236 }
1237 }
1238
1239 if (Fetcher.Run() == pkgAcquire::Failed)
1240 return false;
1241
1242 // Print out errors
1243 bool Failed = false;
1244 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
1245 {
1246 if ((*I)->Status == pkgAcquire::Item::StatDone &&
1247 (*I)->Complete == true)
1248 continue;
1249
1250 if ((*I)->Status == pkgAcquire::Item::StatIdle)
1251 {
1252 Transient = true;
1253 // Failed = true;
1254 continue;
1255 }
1256
1257 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1258 (*I)->ErrorText.c_str());
1259 Failed = true;
1260 }
1261
1262 /* If we are in no download mode and missing files and there were
1263 'failures' then the user must specify -m. Furthermore, there
1264 is no such thing as a transient error in no-download mode! */
1265 if (Transient == true &&
1266 _config->FindB("APT::Get::Download",true) == false)
1267 {
1268 Transient = false;
1269 Failed = true;
1270 }
1271
1272 if (_config->FindB("APT::Get::Download-Only",false) == true)
1273 {
1274 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
1275 return _error->Error(_("Some files failed to download"));
1276 c1out << _("Download complete and in download only mode") << endl;
1277 return true;
1278 }
1279
1280 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
1281 {
1282 return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
1283 }
1284
1285 if (Transient == true && Failed == true)
1286 return _error->Error(_("--fix-missing and media swapping is not currently supported"));
1287
1288 // Try to deal with missing package files
1289 if (Failed == true && PM->FixMissing() == false)
1290 {
1291 cerr << _("Unable to correct missing packages.") << endl;
1292 return _error->Error(_("Aborting install."));
1293 }
1294
1295 _system->UnLock();
1296 int status_fd = _config->FindI("APT::Status-Fd",-1);
1297 pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd);
1298 if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
1299 return false;
1300 if (Res == pkgPackageManager::Completed)
1301 break;
1302
1303 // Reload the fetcher object and loop again for media swapping
1304 Fetcher.Shutdown();
1305 if (PM->GetArchives(&Fetcher,&List,&Recs) == false)
1306 return false;
1307
1308 _system->Lock();
1309 }
1310
1311 std::set<std::string> const disappearedPkgs = PM->GetDisappearedPackages();
1312 if (disappearedPkgs.empty() == true)
1313 return true;
1314
1315 string disappear;
1316 for (std::set<std::string>::const_iterator d = disappearedPkgs.begin();
1317 d != disappearedPkgs.end(); ++d)
1318 disappear.append(*d).append(" ");
1319
1320 ShowList(c1out, P_("The following package disappeared from your system as\n"
1321 "all files have been overwritten by other packages:",
1322 "The following packages disappeared from your system as\n"
1323 "all files have been overwritten by other packages:", disappearedPkgs.size()), disappear, "");
1324 c0out << _("Note: This is done automatic and on purpose by dpkg.") << std::endl;
1325
1326 return true;
1327 }
1328 /*}}}*/
1329 // TryToInstallBuildDep - Try to install a single package /*{{{*/
1330 // ---------------------------------------------------------------------
1331 /* This used to be inlined in DoInstall, but with the advent of regex package
1332 name matching it was split out.. */
1333 bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache,
1334 pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
1335 bool AllowFail = true)
1336 {
1337 if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0)
1338 {
1339 CacheSetHelperAPTGet helper(c1out);
1340 helper.showErrors(AllowFail == false);
1341 pkgCache::VerIterator Ver = helper.canNotFindNewestVer(Cache, Pkg);
1342 if (Ver.end() == false)
1343 Pkg = Ver.ParentPkg();
1344 else if (helper.showVirtualPackageErrors(Cache) == false)
1345 return AllowFail;
1346 }
1347
1348 if (Remove == true)
1349 {
1350 TryToRemove RemoveAction(Cache, Fix);
1351 RemoveAction(Pkg.VersionList());
1352 } else if (Cache[Pkg].CandidateVer != 0) {
1353 TryToInstall InstallAction(Cache, Fix, BrokenFix);
1354 InstallAction(Cache[Pkg].CandidateVerIter(Cache));
1355 InstallAction.doAutoInstall();
1356 } else
1357 return AllowFail;
1358
1359 return true;
1360 }
1361 /*}}}*/
1362 // FindSrc - Find a source record /*{{{*/
1363 // ---------------------------------------------------------------------
1364 /* */
1365 pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
1366 pkgSrcRecords &SrcRecs,string &Src,
1367 pkgDepCache &Cache)
1368 {
1369 string VerTag;
1370 string DefRel = _config->Find("APT::Default-Release");
1371 string TmpSrc = Name;
1372
1373 // extract the version/release from the pkgname
1374 const size_t found = TmpSrc.find_last_of("/=");
1375 if (found != string::npos) {
1376 if (TmpSrc[found] == '/')
1377 DefRel = TmpSrc.substr(found+1);
1378 else
1379 VerTag = TmpSrc.substr(found+1);
1380 TmpSrc = TmpSrc.substr(0,found);
1381 }
1382
1383 /* Lookup the version of the package we would install if we were to
1384 install a version and determine the source package name, then look
1385 in the archive for a source package of the same name. */
1386 bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source");
1387 const pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc);
1388 if (MatchSrcOnly == false && Pkg.end() == false)
1389 {
1390 if(VerTag.empty() == false || DefRel.empty() == false)
1391 {
1392 bool fuzzy = false;
1393 // we have a default release, try to locate the pkg. we do it like
1394 // this because GetCandidateVer() will not "downgrade", that means
1395 // "apt-get source -t stable apt" won't work on a unstable system
1396 for (pkgCache::VerIterator Ver = Pkg.VersionList();; Ver++)
1397 {
1398 // try first only exact matches, later fuzzy matches
1399 if (Ver.end() == true)
1400 {
1401 if (fuzzy == true)
1402 break;
1403 fuzzy = true;
1404 Ver = Pkg.VersionList();
1405 // exit right away from the Pkg.VersionList() loop if we
1406 // don't have any versions
1407 if (Ver.end() == true)
1408 break;
1409 }
1410 // We match against a concrete version (or a part of this version)
1411 if (VerTag.empty() == false &&
1412 (fuzzy == true || Cache.VS().CmpVersion(VerTag, Ver.VerStr()) != 0) && // exact match
1413 (fuzzy == false || strncmp(VerTag.c_str(), Ver.VerStr(), VerTag.size()) != 0)) // fuzzy match
1414 continue;
1415
1416 for (pkgCache::VerFileIterator VF = Ver.FileList();
1417 VF.end() == false; VF++)
1418 {
1419 /* If this is the status file, and the current version is not the
1420 version in the status file (ie it is not installed, or somesuch)
1421 then it is not a candidate for installation, ever. This weeds
1422 out bogus entries that may be due to config-file states, or
1423 other. */
1424 if ((VF.File()->Flags & pkgCache::Flag::NotSource) ==
1425 pkgCache::Flag::NotSource && Pkg.CurrentVer() != Ver)
1426 continue;
1427
1428 // or we match against a release
1429 if(VerTag.empty() == false ||
1430 (VF.File().Archive() != 0 && VF.File().Archive() == DefRel) ||
1431 (VF.File().Codename() != 0 && VF.File().Codename() == DefRel))
1432 {
1433 pkgRecords::Parser &Parse = Recs.Lookup(VF);
1434 Src = Parse.SourcePkg();
1435 // no SourcePkg name, so it is the "binary" name
1436 if (Src.empty() == true)
1437 Src = TmpSrc;
1438 // the Version we have is possibly fuzzy or includes binUploads,
1439 // so we use the Version of the SourcePkg (empty if same as package)
1440 VerTag = Parse.SourceVer();
1441 if (VerTag.empty() == true)
1442 VerTag = Ver.VerStr();
1443 break;
1444 }
1445 }
1446 if (Src.empty() == false)
1447 break;
1448 }
1449 if (Src.empty() == true)
1450 {
1451 // Sources files have no codename information
1452 if (VerTag.empty() == true && DefRel.empty() == false)
1453 {
1454 _error->Error(_("Ignore unavailable target release '%s' of package '%s'"), DefRel.c_str(), TmpSrc.c_str());
1455 return 0;
1456 }
1457 }
1458 }
1459 if (Src.empty() == true)
1460 {
1461 // if we don't have found a fitting package yet so we will
1462 // choose a good candidate and proceed with that.
1463 // Maybe we will find a source later on with the right VerTag
1464 pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
1465 if (Ver.end() == false)
1466 {
1467 pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
1468 Src = Parse.SourcePkg();
1469 if (VerTag.empty() == true)
1470 VerTag = Parse.SourceVer();
1471 }
1472 }
1473 }
1474
1475 if (Src.empty() == true)
1476 Src = TmpSrc;
1477 else
1478 {
1479 /* if we have a source pkg name, make sure to only search
1480 for srcpkg names, otherwise apt gets confused if there
1481 is a binary package "pkg1" and a source package "pkg1"
1482 with the same name but that comes from different packages */
1483 MatchSrcOnly = true;
1484 if (Src != TmpSrc)
1485 {
1486 ioprintf(c1out, _("Picking '%s' as source package instead of '%s'\n"), Src.c_str(), TmpSrc.c_str());
1487 }
1488 }
1489
1490 // The best hit
1491 pkgSrcRecords::Parser *Last = 0;
1492 unsigned long Offset = 0;
1493 string Version;
1494
1495 /* Iterate over all of the hits, which includes the resulting
1496 binary packages in the search */
1497 pkgSrcRecords::Parser *Parse;
1498 while (true)
1499 {
1500 SrcRecs.Restart();
1501 while ((Parse = SrcRecs.Find(Src.c_str(), MatchSrcOnly)) != 0)
1502 {
1503 const string Ver = Parse->Version();
1504
1505 // Ignore all versions which doesn't fit
1506 if (VerTag.empty() == false &&
1507 Cache.VS().CmpVersion(VerTag, Ver) != 0) // exact match
1508 continue;
1509
1510 // Newer version or an exact match? Save the hit
1511 if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0) {
1512 Last = Parse;
1513 Offset = Parse->Offset();
1514 Version = Ver;
1515 }
1516
1517 // was the version check above an exact match? If so, we don't need to look further
1518 if (VerTag.empty() == false && VerTag.size() == Ver.size())
1519 break;
1520 }
1521 if (Last != 0 || VerTag.empty() == true)
1522 break;
1523 //if (VerTag.empty() == false && Last == 0)
1524 _error->Error(_("Ignore unavailable version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str());
1525 return 0;
1526 }
1527
1528 if (Last == 0 || Last->Jump(Offset) == false)
1529 return 0;
1530
1531 return Last;
1532 }
1533 /*}}}*/
1534 // DoUpdate - Update the package lists /*{{{*/
1535 // ---------------------------------------------------------------------
1536 /* */
1537 bool DoUpdate(CommandLine &CmdL)
1538 {
1539 if (CmdL.FileSize() != 1)
1540 return _error->Error(_("The update command takes no arguments"));
1541
1542 // Get the source list
1543 pkgSourceList List;
1544 if (List.ReadMainList() == false)
1545 return false;
1546
1547 // Create the progress
1548 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1549
1550 // Just print out the uris an exit if the --print-uris flag was used
1551 if (_config->FindB("APT::Get::Print-URIs") == true)
1552 {
1553 // force a hashsum for compatibility reasons
1554 _config->CndSet("Acquire::ForceHash", "md5sum");
1555
1556 // get a fetcher
1557 pkgAcquire Fetcher;
1558 if (Fetcher.Setup(&Stat) == false)
1559 return false;
1560
1561 // Populate it with the source selection and get all Indexes
1562 // (GetAll=true)
1563 if (List.GetIndexes(&Fetcher,true) == false)
1564 return false;
1565
1566 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1567 for (; I != Fetcher.UriEnd(); I++)
1568 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1569 I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
1570 return true;
1571 }
1572
1573 // do the work
1574 CacheFile Cache;
1575 if (_config->FindB("APT::Get::Download",true) == true)
1576 ListUpdate(Stat, List);
1577
1578 // Rebuild the cache.
1579 if (Cache.BuildCaches() == false)
1580 return false;
1581
1582 return true;
1583 }
1584 /*}}}*/
1585 // DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
1586 // ---------------------------------------------------------------------
1587 /* Remove unused automatic packages */
1588 bool DoAutomaticRemove(CacheFile &Cache)
1589 {
1590 bool Debug = _config->FindI("Debug::pkgAutoRemove",false);
1591 bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
1592 bool hideAutoRemove = _config->FindB("APT::Get::HideAutoRemove");
1593
1594 pkgDepCache::ActionGroup group(*Cache);
1595 if(Debug)
1596 std::cout << "DoAutomaticRemove()" << std::endl;
1597
1598 // we don't want to autoremove and we don't want to see it, so why calculating?
1599 if (doAutoRemove == false && hideAutoRemove == true)
1600 return true;
1601
1602 if (doAutoRemove == true &&
1603 _config->FindB("APT::Get::Remove",true) == false)
1604 {
1605 c1out << _("We are not supposed to delete stuff, can't start "
1606 "AutoRemover") << std::endl;
1607 return false;
1608 }
1609
1610 bool purgePkgs = _config->FindB("APT::Get::Purge", false);
1611 bool smallList = (hideAutoRemove == false &&
1612 strcasecmp(_config->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
1613
1614 string autoremovelist, autoremoveversions;
1615 unsigned long autoRemoveCount = 0;
1616 // look over the cache to see what can be removed
1617 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg)
1618 {
1619 if (Cache[Pkg].Garbage)
1620 {
1621 if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
1622 if(Debug)
1623 std::cout << "We could delete %s" << Pkg.FullName(true).c_str() << std::endl;
1624
1625 if (doAutoRemove)
1626 {
1627 if(Pkg.CurrentVer() != 0 &&
1628 Pkg->CurrentState != pkgCache::State::ConfigFiles)
1629 Cache->MarkDelete(Pkg, purgePkgs);
1630 else
1631 Cache->MarkKeep(Pkg, false, false);
1632 }
1633 else
1634 {
1635 // only show stuff in the list that is not yet marked for removal
1636 if(Cache[Pkg].Delete() == false)
1637 {
1638 ++autoRemoveCount;
1639 // we don't need to fill the strings if we don't need them
1640 if (smallList == false)
1641 {
1642 autoremovelist += Pkg.FullName(true) + " ";
1643 autoremoveversions += string(Cache[Pkg].CandVersion) + "\n";
1644 }
1645 }
1646 }
1647 }
1648 }
1649 // if we don't remove them, we should show them!
1650 if (doAutoRemove == false && (autoremovelist.empty() == false || autoRemoveCount != 0))
1651 {
1652 if (smallList == false)
1653 ShowList(c1out, P_("The following package is automatically installed and is no longer required:",
1654 "The following packages were automatically installed and are no longer required:",
1655 autoRemoveCount), autoremovelist, autoremoveversions);
1656 else
1657 ioprintf(c1out, P_("%lu package was automatically installed and is no longer required.\n",
1658 "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount), autoRemoveCount);
1659 c1out << _("Use 'apt-get autoremove' to remove them.") << std::endl;
1660 }
1661 // Now see if we had destroyed anything (if we had done anything)
1662 else if (Cache->BrokenCount() != 0)
1663 {
1664 c1out << _("Hmm, seems like the AutoRemover destroyed something which really\n"
1665 "shouldn't happen. Please file a bug report against apt.") << endl;
1666 c1out << endl;
1667 c1out << _("The following information may help to resolve the situation:") << endl;
1668 c1out << endl;
1669 ShowBroken(c1out,Cache,false);
1670
1671 return _error->Error(_("Internal Error, AutoRemover broke stuff"));
1672 }
1673 return true;
1674 }
1675 /*}}}*/
1676 // DoUpgrade - Upgrade all packages /*{{{*/
1677 // ---------------------------------------------------------------------
1678 /* Upgrade all packages without installing new packages or erasing old
1679 packages */
1680 bool DoUpgrade(CommandLine &CmdL)
1681 {
1682 CacheFile Cache;
1683 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1684 return false;
1685
1686 // Do the upgrade
1687 if (pkgAllUpgrade(Cache) == false)
1688 {
1689 ShowBroken(c1out,Cache,false);
1690 return _error->Error(_("Internal error, AllUpgrade broke stuff"));
1691 }
1692
1693 return InstallPackages(Cache,true);
1694 }
1695 /*}}}*/
1696 // DoInstall - Install packages from the command line /*{{{*/
1697 // ---------------------------------------------------------------------
1698 /* Install named packages */
1699 bool DoInstall(CommandLine &CmdL)
1700 {
1701 CacheFile Cache;
1702 if (Cache.OpenForInstall() == false ||
1703 Cache.CheckDeps(CmdL.FileSize() != 1) == false)
1704 return false;
1705
1706 // Enter the special broken fixing mode if the user specified arguments
1707 bool BrokenFix = false;
1708 if (Cache->BrokenCount() != 0)
1709 BrokenFix = true;
1710
1711 pkgProblemResolver Fix(Cache);
1712
1713 static const unsigned short MOD_REMOVE = 1;
1714 static const unsigned short MOD_INSTALL = 2;
1715
1716 unsigned short fallback = MOD_INSTALL;
1717 if (strcasecmp(CmdL.FileList[0],"remove") == 0)
1718 fallback = MOD_REMOVE;
1719 else if (strcasecmp(CmdL.FileList[0], "purge") == 0)
1720 {
1721 _config->Set("APT::Get::Purge", true);
1722 fallback = MOD_REMOVE;
1723 }
1724 else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0)
1725 {
1726 _config->Set("APT::Get::AutomaticRemove", "true");
1727 fallback = MOD_REMOVE;
1728 }
1729
1730 std::list<APT::VersionSet::Modifier> mods;
1731 mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+",
1732 APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDIDATE));
1733 mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-",
1734 APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST));
1735 CacheSetHelperAPTGet helper(c0out);
1736 std::map<unsigned short, APT::VersionSet> verset = APT::VersionSet::GroupedFromCommandLine(Cache,
1737 CmdL.FileList + 1, mods, fallback, helper);
1738
1739 if (_error->PendingError() == true)
1740 {
1741 helper.showVirtualPackageErrors(Cache);
1742 return false;
1743 }
1744
1745 unsigned short order[] = { 0, 0, 0 };
1746 if (fallback == MOD_INSTALL) {
1747 order[0] = MOD_INSTALL;
1748 order[1] = MOD_REMOVE;
1749 } else {
1750 order[0] = MOD_REMOVE;
1751 order[1] = MOD_INSTALL;
1752 }
1753
1754 TryToInstall InstallAction(Cache, Fix, BrokenFix);
1755 TryToRemove RemoveAction(Cache, Fix);
1756
1757 // new scope for the ActionGroup
1758 {
1759 pkgDepCache::ActionGroup group(Cache);
1760
1761 for (unsigned short i = 0; order[i] != 0; ++i)
1762 {
1763 if (order[i] == MOD_INSTALL) {
1764 InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction);
1765 InstallAction.doAutoInstall();
1766 }
1767 else if (order[i] == MOD_REMOVE)
1768 RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction);
1769 }
1770
1771 if (_error->PendingError() == true)
1772 return false;
1773
1774 /* If we are in the Broken fixing mode we do not attempt to fix the
1775 problems. This is if the user invoked install without -f and gave
1776 packages */
1777 if (BrokenFix == true && Cache->BrokenCount() != 0)
1778 {
1779 c1out << _("You might want to run 'apt-get -f install' to correct these:") << endl;
1780 ShowBroken(c1out,Cache,false);
1781
1782 return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
1783 }
1784
1785 // Call the scored problem resolver
1786 Fix.InstallProtect();
1787 if (Fix.Resolve(true) == false)
1788 _error->Discard();
1789
1790 // Now we check the state of the packages,
1791 if (Cache->BrokenCount() != 0)
1792 {
1793 c1out <<
1794 _("Some packages could not be installed. This may mean that you have\n"
1795 "requested an impossible situation or if you are using the unstable\n"
1796 "distribution that some required packages have not yet been created\n"
1797 "or been moved out of Incoming.") << endl;
1798 /*
1799 if (Packages == 1)
1800 {
1801 c1out << endl;
1802 c1out <<
1803 _("Since you only requested a single operation it is extremely likely that\n"
1804 "the package is simply not installable and a bug report against\n"
1805 "that package should be filed.") << endl;
1806 }
1807 */
1808
1809 c1out << _("The following information may help to resolve the situation:") << endl;
1810 c1out << endl;
1811 ShowBroken(c1out,Cache,false);
1812 return _error->Error(_("Broken packages"));
1813 }
1814 }
1815 if (!DoAutomaticRemove(Cache))
1816 return false;
1817
1818 /* Print out a list of packages that are going to be installed extra
1819 to what the user asked */
1820 if (Cache->InstCount() != verset[MOD_INSTALL].size())
1821 {
1822 string List;
1823 string VersionsList;
1824 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
1825 {
1826 pkgCache::PkgIterator I(Cache,Cache.List[J]);
1827 if ((*Cache)[I].Install() == false)
1828 continue;
1829
1830 const char **J;
1831 for (J = CmdL.FileList + 1; *J != 0; J++)
1832 if (strcmp(*J,I.Name()) == 0)
1833 break;
1834
1835 if (*J == 0) {
1836 List += I.FullName(true) + " ";
1837 VersionsList += string(Cache[I].CandVersion) + "\n";
1838 }
1839 }
1840
1841 ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList);
1842 }
1843
1844 /* Print out a list of suggested and recommended packages */
1845 {
1846 string SuggestsList, RecommendsList, List;
1847 string SuggestsVersions, RecommendsVersions;
1848 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
1849 {
1850 pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
1851
1852 /* Just look at the ones we want to install */
1853 if ((*Cache)[Pkg].Install() == false)
1854 continue;
1855
1856 // get the recommends/suggests for the candidate ver
1857 pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
1858 for (pkgCache::DepIterator D = CV.DependsList(); D.end() == false; )
1859 {
1860 pkgCache::DepIterator Start;
1861 pkgCache::DepIterator End;
1862 D.GlobOr(Start,End); // advances D
1863
1864 // FIXME: we really should display a or-group as a or-group to the user
1865 // the problem is that ShowList is incapable of doing this
1866 string RecommendsOrList,RecommendsOrVersions;
1867 string SuggestsOrList,SuggestsOrVersions;
1868 bool foundInstalledInOrGroup = false;
1869 for(;;)
1870 {
1871 /* Skip if package is installed already, or is about to be */
1872 string target = Start.TargetPkg().FullName(true) + " ";
1873 pkgCache::PkgIterator const TarPkg = Start.TargetPkg();
1874 if (TarPkg->SelectedState == pkgCache::State::Install ||
1875 TarPkg->SelectedState == pkgCache::State::Hold ||
1876 Cache[Start.TargetPkg()].Install())
1877 {
1878 foundInstalledInOrGroup=true;
1879 break;
1880 }
1881
1882 /* Skip if we already saw it */
1883 if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1)
1884 {
1885 foundInstalledInOrGroup=true;
1886 break;
1887 }
1888
1889 // this is a dep on a virtual pkg, check if any package that provides it
1890 // should be installed
1891 if(Start.TargetPkg().ProvidesList() != 0)
1892 {
1893 pkgCache::PrvIterator I = Start.TargetPkg().ProvidesList();
1894 for (; I.end() == false; I++)
1895 {
1896 pkgCache::PkgIterator Pkg = I.OwnerPkg();
1897 if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer() &&
1898 Pkg.CurrentVer() != 0)
1899 foundInstalledInOrGroup=true;
1900 }
1901 }
1902
1903 if (Start->Type == pkgCache::Dep::Suggests)
1904 {
1905 SuggestsOrList += target;
1906 SuggestsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
1907 }
1908
1909 if (Start->Type == pkgCache::Dep::Recommends)
1910 {
1911 RecommendsOrList += target;
1912 RecommendsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
1913 }
1914
1915 if (Start >= End)
1916 break;
1917 Start++;
1918 }
1919
1920 if(foundInstalledInOrGroup == false)
1921 {
1922 RecommendsList += RecommendsOrList;
1923 RecommendsVersions += RecommendsOrVersions;
1924 SuggestsList += SuggestsOrList;
1925 SuggestsVersions += SuggestsOrVersions;
1926 }
1927
1928 }
1929 }
1930
1931 ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions);
1932 ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions);
1933
1934 }
1935
1936 // if nothing changed in the cache, but only the automark information
1937 // we write the StateFile here, otherwise it will be written in
1938 // cache.commit()
1939 if (InstallAction.AutoMarkChanged > 0 &&
1940 Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
1941 Cache->BadCount() == 0 &&
1942 _config->FindB("APT::Get::Simulate",false) == false)
1943 Cache->writeStateFile(NULL);
1944
1945 // See if we need to prompt
1946 // FIXME: check if really the packages in the set are going to be installed
1947 if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0)
1948 return InstallPackages(Cache,false,false);
1949
1950 return InstallPackages(Cache,false);
1951 }
1952
1953 /* mark packages as automatically/manually installed. */
1954 bool DoMarkAuto(CommandLine &CmdL)
1955 {
1956 bool Action = true;
1957 int AutoMarkChanged = 0;
1958 OpTextProgress progress;
1959 CacheFile Cache;
1960 if (Cache.Open() == false)
1961 return false;
1962
1963 if (strcasecmp(CmdL.FileList[0],"markauto") == 0)
1964 Action = true;
1965 else if (strcasecmp(CmdL.FileList[0],"unmarkauto") == 0)
1966 Action = false;
1967
1968 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
1969 {
1970 const char *S = *I;
1971 // Locate the package
1972 pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
1973 if (Pkg.end() == true) {
1974 return _error->Error(_("Couldn't find package %s"),S);
1975 }
1976 else
1977 {
1978 if (!Action)
1979 ioprintf(c1out,_("%s set to manually installed.\n"), Pkg.Name());
1980 else
1981 ioprintf(c1out,_("%s set to automatically installed.\n"),
1982 Pkg.Name());
1983
1984 Cache->MarkAuto(Pkg,Action);
1985 AutoMarkChanged++;
1986 }
1987 }
1988 if (AutoMarkChanged && ! _config->FindB("APT::Get::Simulate",false))
1989 return Cache->writeStateFile(NULL);
1990 return false;
1991 }
1992 /*}}}*/
1993 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
1994 // ---------------------------------------------------------------------
1995 /* Intelligent upgrader that will install and remove packages at will */
1996 bool DoDistUpgrade(CommandLine &CmdL)
1997 {
1998 CacheFile Cache;
1999 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
2000 return false;
2001
2002 c0out << _("Calculating upgrade... ") << flush;
2003 if (pkgDistUpgrade(*Cache) == false)
2004 {
2005 c0out << _("Failed") << endl;
2006 ShowBroken(c1out,Cache,false);
2007 return false;
2008 }
2009
2010 c0out << _("Done") << endl;
2011
2012 return InstallPackages(Cache,true);
2013 }
2014 /*}}}*/
2015 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
2016 // ---------------------------------------------------------------------
2017 /* Follows dselect's selections */
2018 bool DoDSelectUpgrade(CommandLine &CmdL)
2019 {
2020 CacheFile Cache;
2021 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
2022 return false;
2023
2024 pkgDepCache::ActionGroup group(Cache);
2025
2026 // Install everything with the install flag set
2027 pkgCache::PkgIterator I = Cache->PkgBegin();
2028 for (;I.end() != true; I++)
2029 {
2030 /* Install the package only if it is a new install, the autoupgrader
2031 will deal with the rest */
2032 if (I->SelectedState == pkgCache::State::Install)
2033 Cache->MarkInstall(I,false);
2034 }
2035
2036 /* Now install their deps too, if we do this above then order of
2037 the status file is significant for | groups */
2038 for (I = Cache->PkgBegin();I.end() != true; I++)
2039 {
2040 /* Install the package only if it is a new install, the autoupgrader
2041 will deal with the rest */
2042 if (I->SelectedState == pkgCache::State::Install)
2043 Cache->MarkInstall(I,true);
2044 }
2045
2046 // Apply erasures now, they override everything else.
2047 for (I = Cache->PkgBegin();I.end() != true; I++)
2048 {
2049 // Remove packages
2050 if (I->SelectedState == pkgCache::State::DeInstall ||
2051 I->SelectedState == pkgCache::State::Purge)
2052 Cache->MarkDelete(I,I->SelectedState == pkgCache::State::Purge);
2053 }
2054
2055 /* Resolve any problems that dselect created, allupgrade cannot handle
2056 such things. We do so quite agressively too.. */
2057 if (Cache->BrokenCount() != 0)
2058 {
2059 pkgProblemResolver Fix(Cache);
2060
2061 // Hold back held packages.
2062 if (_config->FindB("APT::Ignore-Hold",false) == false)
2063 {
2064 for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++)
2065 {
2066 if (I->SelectedState == pkgCache::State::Hold)
2067 {
2068 Fix.Protect(I);
2069 Cache->MarkKeep(I);
2070 }
2071 }
2072 }
2073
2074 if (Fix.Resolve() == false)
2075 {
2076 ShowBroken(c1out,Cache,false);
2077 return _error->Error(_("Internal error, problem resolver broke stuff"));
2078 }
2079 }
2080
2081 // Now upgrade everything
2082 if (pkgAllUpgrade(Cache) == false)
2083 {
2084 ShowBroken(c1out,Cache,false);
2085 return _error->Error(_("Internal error, problem resolver broke stuff"));
2086 }
2087
2088 return InstallPackages(Cache,false);
2089 }
2090 /*}}}*/
2091 // DoClean - Remove download archives /*{{{*/
2092 // ---------------------------------------------------------------------
2093 /* */
2094 bool DoClean(CommandLine &CmdL)
2095 {
2096 if (_config->FindB("APT::Get::Simulate") == true)
2097 {
2098 cout << "Del " << _config->FindDir("Dir::Cache::archives") << "* " <<
2099 _config->FindDir("Dir::Cache::archives") << "partial/*" << endl;
2100 return true;
2101 }
2102
2103 // Lock the archive directory
2104 FileFd Lock;
2105 if (_config->FindB("Debug::NoLocking",false) == false)
2106 {
2107 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
2108 if (_error->PendingError() == true)
2109 return _error->Error(_("Unable to lock the download directory"));
2110 }
2111
2112 pkgAcquire Fetcher;
2113 Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
2114 Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
2115 return true;
2116 }
2117 /*}}}*/
2118 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
2119 // ---------------------------------------------------------------------
2120 /* This is similar to clean but it only purges things that cannot be
2121 downloaded, that is old versions of cached packages. */
2122 class LogCleaner : public pkgArchiveCleaner
2123 {
2124 protected:
2125 virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St)
2126 {
2127 c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << endl;
2128
2129 if (_config->FindB("APT::Get::Simulate") == false)
2130 unlink(File);
2131 };
2132 };
2133
2134 bool DoAutoClean(CommandLine &CmdL)
2135 {
2136 // Lock the archive directory
2137 FileFd Lock;
2138 if (_config->FindB("Debug::NoLocking",false) == false)
2139 {
2140 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
2141 if (_error->PendingError() == true)
2142 return _error->Error(_("Unable to lock the download directory"));
2143 }
2144
2145 CacheFile Cache;
2146 if (Cache.Open() == false)
2147 return false;
2148
2149 LogCleaner Cleaner;
2150
2151 return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) &&
2152 Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache);
2153 }
2154 /*}}}*/
2155 // DoCheck - Perform the check operation /*{{{*/
2156 // ---------------------------------------------------------------------
2157 /* Opening automatically checks the system, this command is mostly used
2158 for debugging */
2159 bool DoCheck(CommandLine &CmdL)
2160 {
2161 CacheFile Cache;
2162 Cache.Open();
2163 Cache.CheckDeps();
2164
2165 return true;
2166 }
2167 /*}}}*/
2168 // DoSource - Fetch a source archive /*{{{*/
2169 // ---------------------------------------------------------------------
2170 /* Fetch souce packages */
2171 struct DscFile
2172 {
2173 string Package;
2174 string Version;
2175 string Dsc;
2176 };
2177
2178 bool DoSource(CommandLine &CmdL)
2179 {
2180 CacheFile Cache;
2181 if (Cache.Open(false) == false)
2182 return false;
2183
2184 if (CmdL.FileSize() <= 1)
2185 return _error->Error(_("Must specify at least one package to fetch source for"));
2186
2187 // Read the source list
2188 pkgSourceList List;
2189 if (List.ReadMainList() == false)
2190 return _error->Error(_("The list of sources could not be read."));
2191
2192 // Create the text record parsers
2193 pkgRecords Recs(Cache);
2194 pkgSrcRecords SrcRecs(List);
2195 if (_error->PendingError() == true)
2196 return false;
2197
2198 // Create the download object
2199 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
2200 pkgAcquire Fetcher;
2201 if (Fetcher.Setup(&Stat) == false)
2202 return false;
2203
2204 DscFile *Dsc = new DscFile[CmdL.FileSize()];
2205
2206 // insert all downloaded uris into this set to avoid downloading them
2207 // twice
2208 set<string> queued;
2209
2210 // Diff only mode only fetches .diff files
2211 bool const diffOnly = _config->FindB("APT::Get::Diff-Only", false);
2212 // Tar only mode only fetches .tar files
2213 bool const tarOnly = _config->FindB("APT::Get::Tar-Only", false);
2214 // Dsc only mode only fetches .dsc files
2215 bool const dscOnly = _config->FindB("APT::Get::Dsc-Only", false);
2216
2217 // Load the requestd sources into the fetcher
2218 unsigned J = 0;
2219 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
2220 {
2221 string Src;
2222 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
2223
2224 if (Last == 0)
2225 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
2226
2227 string srec = Last->AsStr();
2228 string::size_type pos = srec.find("\nVcs-");
2229 while (pos != string::npos)
2230 {
2231 pos += strlen("\nVcs-");
2232 string vcs = srec.substr(pos,srec.find(":",pos)-pos);
2233 if(vcs == "Browser")
2234 {
2235 pos = srec.find("\nVcs-", pos);
2236 continue;
2237 }
2238 pos += vcs.length()+2;
2239 string::size_type epos = srec.find("\n", pos);
2240 string uri = srec.substr(pos,epos-pos).c_str();
2241 ioprintf(c1out, _("NOTICE: '%s' packaging is maintained in "
2242 "the '%s' version control system at:\n"
2243 "%s\n"),
2244 Src.c_str(), vcs.c_str(), uri.c_str());
2245 if(vcs == "Bzr")
2246 ioprintf(c1out,_("Please use:\n"
2247 "bzr get %s\n"
2248 "to retrieve the latest (possibly unreleased) "
2249 "updates to the package.\n"),
2250 uri.c_str());
2251 break;
2252 }
2253
2254 // Back track
2255 vector<pkgSrcRecords::File> Lst;
2256 if (Last->Files(Lst) == false)
2257 return false;
2258
2259 // Load them into the fetcher
2260 for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
2261 I != Lst.end(); I++)
2262 {
2263 // Try to guess what sort of file it is we are getting.
2264 if (I->Type == "dsc")
2265 {
2266 Dsc[J].Package = Last->Package();
2267 Dsc[J].Version = Last->Version();
2268 Dsc[J].Dsc = flNotDir(I->Path);
2269 }
2270
2271 // Handle the only options so that multiple can be used at once
2272 if (diffOnly == true || tarOnly == true || dscOnly == true)
2273 {
2274 if ((diffOnly == true && I->Type == "diff") ||
2275 (tarOnly == true && I->Type == "tar") ||
2276 (dscOnly == true && I->Type == "dsc"))
2277 ; // Fine, we want this file downloaded
2278 else
2279 continue;
2280 }
2281
2282 // don't download the same uri twice (should this be moved to
2283 // the fetcher interface itself?)
2284 if(queued.find(Last->Index().ArchiveURI(I->Path)) != queued.end())
2285 continue;
2286 queued.insert(Last->Index().ArchiveURI(I->Path));
2287
2288 // check if we have a file with that md5 sum already localy
2289 if(!I->MD5Hash.empty() && FileExists(flNotDir(I->Path)))
2290 {
2291 FileFd Fd(flNotDir(I->Path), FileFd::ReadOnly);
2292 MD5Summation sum;
2293 sum.AddFD(Fd.Fd(), Fd.Size());
2294 Fd.Close();
2295 if((string)sum.Result() == I->MD5Hash)
2296 {
2297 ioprintf(c1out,_("Skipping already downloaded file '%s'\n"),
2298 flNotDir(I->Path).c_str());
2299 continue;
2300 }
2301 }
2302
2303 new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path),
2304 I->MD5Hash,I->Size,
2305 Last->Index().SourceInfo(*Last,*I),Src);
2306 }
2307 }
2308
2309 // Display statistics
2310 unsigned long long FetchBytes = Fetcher.FetchNeeded();
2311 unsigned long long FetchPBytes = Fetcher.PartialPresent();
2312 unsigned long long DebBytes = Fetcher.TotalNeeded();
2313
2314 // Check for enough free space
2315 struct statvfs Buf;
2316 string OutputDir = ".";
2317 if (statvfs(OutputDir.c_str(),&Buf) != 0) {
2318 if (errno == EOVERFLOW)
2319 return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
2320 OutputDir.c_str());
2321 else
2322 return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
2323 OutputDir.c_str());
2324 } else if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
2325 {
2326 struct statfs Stat;
2327 if (statfs(OutputDir.c_str(),&Stat) != 0
2328 #if HAVE_STRUCT_STATFS_F_TYPE
2329 || unsigned(Stat.f_type) != RAMFS_MAGIC
2330 #endif
2331 )
2332 return _error->Error(_("You don't have enough free space in %s"),
2333 OutputDir.c_str());
2334 }
2335
2336 // Number of bytes
2337 if (DebBytes != FetchBytes)
2338 ioprintf(c1out,_("Need to get %sB/%sB of source archives.\n"),
2339 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
2340 else
2341 ioprintf(c1out,_("Need to get %sB of source archives.\n"),
2342 SizeToStr(DebBytes).c_str());
2343
2344 if (_config->FindB("APT::Get::Simulate",false) == true)
2345 {
2346 for (unsigned I = 0; I != J; I++)
2347 ioprintf(cout,_("Fetch source %s\n"),Dsc[I].Package.c_str());
2348 delete[] Dsc;
2349 return true;
2350 }
2351
2352 // Just print out the uris an exit if the --print-uris flag was used
2353 if (_config->FindB("APT::Get::Print-URIs") == true)
2354 {
2355 pkgAcquire::UriIterator I = Fetcher.UriBegin();
2356 for (; I != Fetcher.UriEnd(); I++)
2357 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
2358 I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
2359 delete[] Dsc;
2360 return true;
2361 }
2362
2363 // Run it
2364 if (Fetcher.Run() == pkgAcquire::Failed)
2365 return false;
2366
2367 // Print error messages
2368 bool Failed = false;
2369 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
2370 {
2371 if ((*I)->Status == pkgAcquire::Item::StatDone &&
2372 (*I)->Complete == true)
2373 continue;
2374
2375 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
2376 (*I)->ErrorText.c_str());
2377 Failed = true;
2378 }
2379 if (Failed == true)
2380 return _error->Error(_("Failed to fetch some archives."));
2381
2382 if (_config->FindB("APT::Get::Download-only",false) == true)
2383 {
2384 c1out << _("Download complete and in download only mode") << endl;
2385 delete[] Dsc;
2386 return true;
2387 }
2388
2389 // Unpack the sources
2390 pid_t Process = ExecFork();
2391
2392 if (Process == 0)
2393 {
2394 bool const fixBroken = _config->FindB("APT::Get::Fix-Broken", false);
2395 for (unsigned I = 0; I != J; I++)
2396 {
2397 string Dir = Dsc[I].Package + '-' + Cache->VS().UpstreamVersion(Dsc[I].Version.c_str());
2398
2399 // Diff only mode only fetches .diff files
2400 if (_config->FindB("APT::Get::Diff-Only",false) == true ||
2401 _config->FindB("APT::Get::Tar-Only",false) == true ||
2402 Dsc[I].Dsc.empty() == true)
2403 continue;
2404
2405 // See if the package is already unpacked
2406 struct stat Stat;
2407 if (fixBroken == false && stat(Dir.c_str(),&Stat) == 0 &&
2408 S_ISDIR(Stat.st_mode) != 0)
2409 {
2410 ioprintf(c0out ,_("Skipping unpack of already unpacked source in %s\n"),
2411 Dir.c_str());
2412 }
2413 else
2414 {
2415 // Call dpkg-source
2416 char S[500];
2417 snprintf(S,sizeof(S),"%s -x %s",
2418 _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
2419 Dsc[I].Dsc.c_str());
2420 if (system(S) != 0)
2421 {
2422 fprintf(stderr,_("Unpack command '%s' failed.\n"),S);
2423 fprintf(stderr,_("Check if the 'dpkg-dev' package is installed.\n"));
2424 _exit(1);
2425 }
2426 }
2427
2428 // Try to compile it with dpkg-buildpackage
2429 if (_config->FindB("APT::Get::Compile",false) == true)
2430 {
2431 // Call dpkg-buildpackage
2432 char S[500];
2433 snprintf(S,sizeof(S),"cd %s && %s %s",
2434 Dir.c_str(),
2435 _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
2436 _config->Find("DPkg::Build-Options","-b -uc").c_str());
2437
2438 if (system(S) != 0)
2439 {
2440 fprintf(stderr,_("Build command '%s' failed.\n"),S);
2441 _exit(1);
2442 }
2443 }
2444 }
2445
2446 _exit(0);
2447 }
2448 delete[] Dsc;
2449
2450 // Wait for the subprocess
2451 int Status = 0;
2452 while (waitpid(Process,&Status,0) != Process)
2453 {
2454 if (errno == EINTR)
2455 continue;
2456 return _error->Errno("waitpid","Couldn't wait for subprocess");
2457 }
2458
2459 if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
2460 return _error->Error(_("Child process failed"));
2461
2462 return true;
2463 }
2464 /*}}}*/
2465 // DoBuildDep - Install/removes packages to satisfy build dependencies /*{{{*/
2466 // ---------------------------------------------------------------------
2467 /* This function will look at the build depends list of the given source
2468 package and install the necessary packages to make it true, or fail. */
2469 bool DoBuildDep(CommandLine &CmdL)
2470 {
2471 CacheFile Cache;
2472 if (Cache.Open(true) == false)
2473 return false;
2474
2475 if (CmdL.FileSize() <= 1)
2476 return _error->Error(_("Must specify at least one package to check builddeps for"));
2477
2478 // Read the source list
2479 pkgSourceList List;
2480 if (List.ReadMainList() == false)
2481 return _error->Error(_("The list of sources could not be read."));
2482
2483 // Create the text record parsers
2484 pkgRecords Recs(Cache);
2485 pkgSrcRecords SrcRecs(List);
2486 if (_error->PendingError() == true)
2487 return false;
2488
2489 // Create the download object
2490 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
2491 pkgAcquire Fetcher;
2492 if (Fetcher.Setup(&Stat) == false)
2493 return false;
2494
2495 unsigned J = 0;
2496 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
2497 {
2498 string Src;
2499 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
2500 if (Last == 0)
2501 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
2502
2503 // Process the build-dependencies
2504 vector<pkgSrcRecords::Parser::BuildDepRec> BuildDeps;
2505 if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only",true)) == false)
2506 return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str());
2507
2508 // Also ensure that build-essential packages are present
2509 Configuration::Item const *Opts = _config->Tree("APT::Build-Essential");
2510 if (Opts)
2511 Opts = Opts->Child;
2512 for (; Opts; Opts = Opts->Next)
2513 {
2514 if (Opts->Value.empty() == true)
2515 continue;
2516
2517 pkgSrcRecords::Parser::BuildDepRec rec;
2518 rec.Package = Opts->Value;
2519 rec.Type = pkgSrcRecords::Parser::BuildDependIndep;
2520 rec.Op = 0;
2521 BuildDeps.push_back(rec);
2522 }
2523
2524 if (BuildDeps.size() == 0)
2525 {
2526 ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
2527 continue;
2528 }
2529
2530 // Install the requested packages
2531 vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
2532 pkgProblemResolver Fix(Cache);
2533 bool skipAlternatives = false; // skip remaining alternatives in an or group
2534 for (D = BuildDeps.begin(); D != BuildDeps.end(); D++)
2535 {
2536 bool hasAlternatives = (((*D).Op & pkgCache::Dep::Or) == pkgCache::Dep::Or);
2537
2538 if (skipAlternatives == true)
2539 {
2540 if (!hasAlternatives)
2541 skipAlternatives = false; // end of or group
2542 continue;
2543 }
2544
2545 if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
2546 (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
2547 {
2548 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
2549 // Build-conflicts on unknown packages are silently ignored
2550 if (Pkg.end() == true)
2551 continue;
2552
2553 pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
2554
2555 /*
2556 * Remove if we have an installed version that satisfies the
2557 * version criteria
2558 */
2559 if (IV.end() == false &&
2560 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
2561 TryToInstallBuildDep(Pkg,Cache,Fix,true,false);
2562 }
2563 else // BuildDep || BuildDepIndep
2564 {
2565 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
2566 if (_config->FindB("Debug::BuildDeps",false) == true)
2567 cout << "Looking for " << (*D).Package << "...\n";
2568
2569 if (Pkg.end() == true)
2570 {
2571 if (_config->FindB("Debug::BuildDeps",false) == true)
2572 cout << " (not found)" << (*D).Package << endl;
2573
2574 if (hasAlternatives)
2575 continue;
2576
2577 return _error->Error(_("%s dependency for %s cannot be satisfied "
2578 "because the package %s cannot be found"),
2579 Last->BuildDepType((*D).Type),Src.c_str(),
2580 (*D).Package.c_str());
2581 }
2582
2583 /*
2584 * if there are alternatives, we've already picked one, so skip
2585 * the rest
2586 *
2587 * TODO: this means that if there's a build-dep on A|B and B is
2588 * installed, we'll still try to install A; more importantly,
2589 * if A is currently broken, we cannot go back and try B. To fix
2590 * this would require we do a Resolve cycle for each package we
2591 * add to the install list. Ugh
2592 */
2593
2594 /*
2595 * If this is a virtual package, we need to check the list of
2596 * packages that provide it and see if any of those are
2597 * installed
2598 */
2599 pkgCache::PrvIterator Prv = Pkg.ProvidesList();
2600 for (; Prv.end() != true; Prv++)
2601 {
2602 if (_config->FindB("Debug::BuildDeps",false) == true)
2603 cout << " Checking provider " << Prv.OwnerPkg().FullName() << endl;
2604
2605 if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
2606 break;
2607 }
2608
2609 // Get installed version and version we are going to install
2610 pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
2611
2612 if ((*D).Version[0] != '\0') {
2613 // Versioned dependency
2614
2615 pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
2616
2617 for (; CV.end() != true; CV++)
2618 {
2619 if (Cache->VS().CheckDep(CV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
2620 break;
2621 }
2622 if (CV.end() == true)
2623 {
2624 if (hasAlternatives)
2625 {
2626 continue;
2627 }
2628 else
2629 {
2630 return _error->Error(_("%s dependency for %s cannot be satisfied "
2631 "because no available versions of package %s "
2632 "can satisfy version requirements"),
2633 Last->BuildDepType((*D).Type),Src.c_str(),
2634 (*D).Package.c_str());
2635 }
2636 }
2637 }
2638 else
2639 {
2640 // Only consider virtual packages if there is no versioned dependency
2641 if (Prv.end() == false)
2642 {
2643 if (_config->FindB("Debug::BuildDeps",false) == true)
2644 cout << " Is provided by installed package " << Prv.OwnerPkg().FullName() << endl;
2645 skipAlternatives = hasAlternatives;
2646 continue;
2647 }
2648 }
2649
2650 if (IV.end() == false)
2651 {
2652 if (_config->FindB("Debug::BuildDeps",false) == true)
2653 cout << " Is installed\n";
2654
2655 if (Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
2656 {
2657 skipAlternatives = hasAlternatives;
2658 continue;
2659 }
2660
2661 if (_config->FindB("Debug::BuildDeps",false) == true)
2662 cout << " ...but the installed version doesn't meet the version requirement\n";
2663
2664 if (((*D).Op & pkgCache::Dep::LessEq) == pkgCache::Dep::LessEq)
2665 {
2666 return _error->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"),
2667 Last->BuildDepType((*D).Type),
2668 Src.c_str(),
2669 Pkg.FullName(true).c_str());
2670 }
2671 }
2672
2673
2674 if (_config->FindB("Debug::BuildDeps",false) == true)
2675 cout << " Trying to install " << (*D).Package << endl;
2676
2677 if (TryToInstallBuildDep(Pkg,Cache,Fix,false,false) == true)
2678 {
2679 // We successfully installed something; skip remaining alternatives
2680 skipAlternatives = hasAlternatives;
2681 if(_config->FindB("APT::Get::Build-Dep-Automatic", false) == true)
2682 Cache->MarkAuto(Pkg, true);
2683 continue;
2684 }
2685 else if (hasAlternatives)
2686 {
2687 if (_config->FindB("Debug::BuildDeps",false) == true)
2688 cout << " Unsatisfiable, trying alternatives\n";
2689 continue;
2690 }
2691 else
2692 {
2693 return _error->Error(_("Failed to satisfy %s dependency for %s: %s"),
2694 Last->BuildDepType((*D).Type),
2695 Src.c_str(),
2696 (*D).Package.c_str());
2697 }
2698 }
2699 }
2700
2701 Fix.InstallProtect();
2702 if (Fix.Resolve(true) == false)
2703 _error->Discard();
2704
2705 // Now we check the state of the packages,
2706 if (Cache->BrokenCount() != 0)
2707 {
2708 ShowBroken(cout, Cache, false);
2709 return _error->Error(_("Build-dependencies for %s could not be satisfied."),*I);
2710 }
2711 }
2712
2713 if (InstallPackages(Cache, false, true) == false)
2714 return _error->Error(_("Failed to process build dependencies"));
2715 return true;
2716 }
2717 /*}}}*/
2718 // DoMoo - Never Ask, Never Tell /*{{{*/
2719 // ---------------------------------------------------------------------
2720 /* */
2721 bool DoMoo(CommandLine &CmdL)
2722 {
2723 cout <<
2724 " (__) \n"
2725 " (oo) \n"
2726 " /------\\/ \n"
2727 " / | || \n"
2728 " * /\\---/\\ \n"
2729 " ~~ ~~ \n"
2730 "....\"Have you mooed today?\"...\n";
2731
2732 return true;
2733 }
2734 /*}}}*/
2735 // ShowHelp - Show a help screen /*{{{*/
2736 // ---------------------------------------------------------------------
2737 /* */
2738 bool ShowHelp(CommandLine &CmdL)
2739 {
2740 ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
2741 COMMON_ARCH,__DATE__,__TIME__);
2742
2743 if (_config->FindB("version") == true)
2744 {
2745 cout << _("Supported modules:") << endl;
2746
2747 for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++)
2748 {
2749 pkgVersioningSystem *VS = pkgVersioningSystem::GlobalList[I];
2750 if (_system != 0 && _system->VS == VS)
2751 cout << '*';
2752 else
2753 cout << ' ';
2754 cout << "Ver: " << VS->Label << endl;
2755
2756 /* Print out all the packaging systems that will work with
2757 this VS */
2758 for (unsigned J = 0; J != pkgSystem::GlobalListLen; J++)
2759 {
2760 pkgSystem *Sys = pkgSystem::GlobalList[J];
2761 if (_system == Sys)
2762 cout << '*';
2763 else
2764 cout << ' ';
2765 if (Sys->VS->TestCompatibility(*VS) == true)
2766 cout << "Pkg: " << Sys->Label << " (Priority " << Sys->Score(*_config) << ")" << endl;
2767 }
2768 }
2769
2770 for (unsigned I = 0; I != pkgSourceList::Type::GlobalListLen; I++)
2771 {
2772 pkgSourceList::Type *Type = pkgSourceList::Type::GlobalList[I];
2773 cout << " S.L: '" << Type->Name << "' " << Type->Label << endl;
2774 }
2775
2776 for (unsigned I = 0; I != pkgIndexFile::Type::GlobalListLen; I++)
2777 {
2778 pkgIndexFile::Type *Type = pkgIndexFile::Type::GlobalList[I];
2779 cout << " Idx: " << Type->Label << endl;
2780 }
2781
2782 return true;
2783 }
2784
2785 cout <<
2786 _("Usage: apt-get [options] command\n"
2787 " apt-get [options] install|remove pkg1 [pkg2 ...]\n"
2788 " apt-get [options] source pkg1 [pkg2 ...]\n"
2789 "\n"
2790 "apt-get is a simple command line interface for downloading and\n"
2791 "installing packages. The most frequently used commands are update\n"
2792 "and install.\n"
2793 "\n"
2794 "Commands:\n"
2795 " update - Retrieve new lists of packages\n"
2796 " upgrade - Perform an upgrade\n"
2797 " install - Install new packages (pkg is libc6 not libc6.deb)\n"
2798 " remove - Remove packages\n"
2799 " autoremove - Remove automatically all unused packages\n"
2800 " purge - Remove packages and config files\n"
2801 " source - Download source archives\n"
2802 " build-dep - Configure build-dependencies for source packages\n"
2803 " dist-upgrade - Distribution upgrade, see apt-get(8)\n"
2804 " dselect-upgrade - Follow dselect selections\n"
2805 " clean - Erase downloaded archive files\n"
2806 " autoclean - Erase old downloaded archive files\n"
2807 " check - Verify that there are no broken dependencies\n"
2808 " markauto - Mark the given packages as automatically installed\n"
2809 " unmarkauto - Mark the given packages as manually installed\n"
2810 "\n"
2811 "Options:\n"
2812 " -h This help text.\n"
2813 " -q Loggable output - no progress indicator\n"
2814 " -qq No output except for errors\n"
2815 " -d Download only - do NOT install or unpack archives\n"
2816 " -s No-act. Perform ordering simulation\n"
2817 " -y Assume Yes to all queries and do not prompt\n"
2818 " -f Attempt to correct a system with broken dependencies in place\n"
2819 " -m Attempt to continue if archives are unlocatable\n"
2820 " -u Show a list of upgraded packages as well\n"
2821 " -b Build the source package after fetching it\n"
2822 " -V Show verbose version numbers\n"
2823 " -c=? Read this configuration file\n"
2824 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
2825 "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n"
2826 "pages for more information and options.\n"
2827 " This APT has Super Cow Powers.\n");
2828 return true;
2829 }
2830 /*}}}*/
2831 // GetInitialize - Initialize things for apt-get /*{{{*/
2832 // ---------------------------------------------------------------------
2833 /* */
2834 void GetInitialize()
2835 {
2836 _config->Set("quiet",0);
2837 _config->Set("help",false);
2838 _config->Set("APT::Get::Download-Only",false);
2839 _config->Set("APT::Get::Simulate",false);
2840 _config->Set("APT::Get::Assume-Yes",false);
2841 _config->Set("APT::Get::Fix-Broken",false);
2842 _config->Set("APT::Get::Force-Yes",false);
2843 _config->Set("APT::Get::List-Cleanup",true);
2844 _config->Set("APT::Get::AutomaticRemove",false);
2845 }
2846 /*}}}*/
2847 // SigWinch - Window size change signal handler /*{{{*/
2848 // ---------------------------------------------------------------------
2849 /* */
2850 void SigWinch(int)
2851 {
2852 // Riped from GNU ls
2853 #ifdef TIOCGWINSZ
2854 struct winsize ws;
2855
2856 if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
2857 ScreenWidth = ws.ws_col - 1;
2858 #endif
2859 }
2860 /*}}}*/
2861 int main(int argc,const char *argv[]) /*{{{*/
2862 {
2863 CommandLine::Args Args[] = {
2864 {'h',"help","help",0},
2865 {'v',"version","version",0},
2866 {'V',"verbose-versions","APT::Get::Show-Versions",0},
2867 {'q',"quiet","quiet",CommandLine::IntLevel},
2868 {'q',"silent","quiet",CommandLine::IntLevel},
2869 {'d',"download-only","APT::Get::Download-Only",0},
2870 {'b',"compile","APT::Get::Compile",0},
2871 {'b',"build","APT::Get::Compile",0},
2872 {'s',"simulate","APT::Get::Simulate",0},
2873 {'s',"just-print","APT::Get::Simulate",0},
2874 {'s',"recon","APT::Get::Simulate",0},
2875 {'s',"dry-run","APT::Get::Simulate",0},
2876 {'s',"no-act","APT::Get::Simulate",0},
2877 {'y',"yes","APT::Get::Assume-Yes",0},
2878 {'y',"assume-yes","APT::Get::Assume-Yes",0},
2879 {'f',"fix-broken","APT::Get::Fix-Broken",0},
2880 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
2881 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
2882 {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
2883 {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
2884 {0,"download","APT::Get::Download",0},
2885 {0,"fix-missing","APT::Get::Fix-Missing",0},
2886 {0,"ignore-hold","APT::Ignore-Hold",0},
2887 {0,"upgrade","APT::Get::upgrade",0},
2888 {0,"only-upgrade","APT::Get::Only-Upgrade",0},
2889 {0,"force-yes","APT::Get::force-yes",0},
2890 {0,"print-uris","APT::Get::Print-URIs",0},
2891 {0,"diff-only","APT::Get::Diff-Only",0},
2892 {0,"debian-only","APT::Get::Diff-Only",0},
2893 {0,"tar-only","APT::Get::Tar-Only",0},
2894 {0,"dsc-only","APT::Get::Dsc-Only",0},
2895 {0,"purge","APT::Get::Purge",0},
2896 {0,"list-cleanup","APT::Get::List-Cleanup",0},
2897 {0,"reinstall","APT::Get::ReInstall",0},
2898 {0,"trivial-only","APT::Get::Trivial-Only",0},
2899 {0,"remove","APT::Get::Remove",0},
2900 {0,"only-source","APT::Get::Only-Source",0},
2901 {0,"arch-only","APT::Get::Arch-Only",0},
2902 {0,"auto-remove","APT::Get::AutomaticRemove",0},
2903 {0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0},
2904 {0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean},
2905 {0,"fix-policy","APT::Get::Fix-Policy-Broken",0},
2906 {'c',"config-file",0,CommandLine::ConfigFile},
2907 {'o',"option",0,CommandLine::ArbItem},
2908 {0,0,0,0}};
2909 CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
2910 {"upgrade",&DoUpgrade},
2911 {"install",&DoInstall},
2912 {"remove",&DoInstall},
2913 {"purge",&DoInstall},
2914 {"autoremove",&DoInstall},
2915 {"markauto",&DoMarkAuto},
2916 {"unmarkauto",&DoMarkAuto},
2917 {"dist-upgrade",&DoDistUpgrade},
2918 {"dselect-upgrade",&DoDSelectUpgrade},
2919 {"build-dep",&DoBuildDep},
2920 {"clean",&DoClean},
2921 {"autoclean",&DoAutoClean},
2922 {"check",&DoCheck},
2923 {"source",&DoSource},
2924 {"moo",&DoMoo},
2925 {"help",&ShowHelp},
2926 {0,0}};
2927
2928 // Set up gettext support
2929 setlocale(LC_ALL,"");
2930 textdomain(PACKAGE);
2931
2932 // Parse the command line and initialize the package library
2933 CommandLine CmdL(Args,_config);
2934 if (pkgInitConfig(*_config) == false ||
2935 CmdL.Parse(argc,argv) == false ||
2936 pkgInitSystem(*_config,_system) == false)
2937 {
2938 if (_config->FindB("version") == true)
2939 ShowHelp(CmdL);
2940
2941 _error->DumpErrors();
2942 return 100;
2943 }
2944
2945 // See if the help should be shown
2946 if (_config->FindB("help") == true ||
2947 _config->FindB("version") == true ||
2948 CmdL.FileSize() == 0)
2949 {
2950 ShowHelp(CmdL);
2951 return 0;
2952 }
2953
2954 // simulate user-friendly if apt-get has no root privileges
2955 if (getuid() != 0 && _config->FindB("APT::Get::Simulate") == true)
2956 {
2957 if (_config->FindB("APT::Get::Show-User-Simulation-Note",true) == true)
2958 cout << _("NOTE: This is only a simulation!\n"
2959 " apt-get needs root privileges for real execution.\n"
2960 " Keep also in mind that locking is deactivated,\n"
2961 " so don't depend on the relevance to the real current situation!"
2962 ) << std::endl;
2963 _config->Set("Debug::NoLocking",true);
2964 }
2965
2966 // Deal with stdout not being a tty
2967 if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
2968 _config->Set("quiet","1");
2969
2970 // Setup the output streams
2971 c0out.rdbuf(cout.rdbuf());
2972 c1out.rdbuf(cout.rdbuf());
2973 c2out.rdbuf(cout.rdbuf());
2974 if (_config->FindI("quiet",0) > 0)
2975 c0out.rdbuf(devnull.rdbuf());
2976 if (_config->FindI("quiet",0) > 1)
2977 c1out.rdbuf(devnull.rdbuf());
2978
2979 // Setup the signals
2980 signal(SIGPIPE,SIG_IGN);
2981 signal(SIGWINCH,SigWinch);
2982 SigWinch(0);
2983
2984 // Match the operation
2985 CmdL.DispatchArg(Cmds);
2986
2987 // Print any errors or warnings found during parsing
2988 bool const Errors = _error->PendingError();
2989 if (_config->FindI("quiet",0) > 0)
2990 _error->DumpErrors();
2991 else
2992 _error->DumpErrors(GlobalError::DEBUG);
2993 return Errors == true ? 100 : 0;
2994 }
2995 /*}}}*/