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