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