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