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