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