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