]> git.saurik.com Git - apt.git/blame - cmdline/apt-get.cc
ifdef for i18n stuff
[apt.git] / cmdline / apt-get.cc
CommitLineData
5ec427c2
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
7d6f9f8f 3// $Id: apt-get.cc,v 1.112 2001/12/05 07:22:40 tausq 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 /*{{{*/
0a8e3465
AL
28#include <apt-pkg/error.h>
29#include <apt-pkg/cmndline.h>
30#include <apt-pkg/init.h>
31#include <apt-pkg/depcache.h>
32#include <apt-pkg/sourcelist.h>
0a8e3465 33#include <apt-pkg/algorithms.h>
0919e3f9 34#include <apt-pkg/acquire-item.h>
cdcc6d34 35#include <apt-pkg/strutl.h>
1bc849af 36#include <apt-pkg/clean.h>
36375005
AL
37#include <apt-pkg/srcrecords.h>
38#include <apt-pkg/version.h>
2d11135a 39#include <apt-pkg/cachefile.h>
b2e465d6
AL
40#include <apt-pkg/sptr.h>
41#include <apt-pkg/versionmatch.h>
42
0a8e3465 43#include <config.h>
b2e465d6 44#include <apti18n.h>
0a8e3465 45
0919e3f9
AL
46#include "acqprogress.h"
47
0a8e3465 48#include <fstream.h>
d7827aca
AL
49#include <termios.h>
50#include <sys/ioctl.h>
1bc849af 51#include <sys/stat.h>
101030ab 52#include <sys/statvfs.h>
d7827aca 53#include <signal.h>
65a1e968 54#include <unistd.h>
3e3221ba 55#include <stdio.h>
d6e79b75 56#include <errno.h>
c373c37a 57#include <regex.h>
54676e1a 58#include <sys/wait.h>
0a8e3465
AL
59 /*}}}*/
60
076d01b0
AL
61using namespace std;
62
63ostream c0out(0);
64ostream c1out(0);
65ostream c2out(0);
0a8e3465
AL
66ofstream devnull("/dev/null");
67unsigned int ScreenWidth = 80;
68
1089ca89
AL
69// class CacheFile - Cover class for some dependency cache functions /*{{{*/
70// ---------------------------------------------------------------------
71/* */
72class CacheFile : public pkgCacheFile
73{
74 static pkgCache *SortCache;
75 static int NameComp(const void *a,const void *b);
76
77 public:
78 pkgCache::Package **List;
79
80 void Sort();
81 bool CheckDeps(bool AllowBroken = false);
82 bool Open(bool WithLock = true)
83 {
84 OpTextProgress Prog(*_config);
85 if (pkgCacheFile::Open(Prog,WithLock) == false)
86 return false;
87 Sort();
b2e465d6 88
1089ca89
AL
89 return true;
90 };
c37b9502
AL
91 bool OpenForInstall()
92 {
93 if (_config->FindB("APT::Get::Print-URIs") == true)
079a992d 94 return Open(false);
c37b9502 95 else
079a992d 96 return Open(true);
c37b9502 97 }
1089ca89
AL
98 CacheFile() : List(0) {};
99};
100 /*}}}*/
101
a6568219
AL
102// YnPrompt - Yes No Prompt. /*{{{*/
103// ---------------------------------------------------------------------
104/* Returns true on a Yes.*/
105bool YnPrompt()
106{
b2e465d6
AL
107 // This needs to be a capital
108 const char *Yes = _("Y");
109
a6568219
AL
110 if (_config->FindB("APT::Get::Assume-Yes",false) == true)
111 {
b2e465d6 112 c1out << Yes << endl;
a6568219
AL
113 return true;
114 }
115
116 char C = 0;
117 char Jnk = 0;
b2e465d6
AL
118 if (read(STDIN_FILENO,&C,1) != 1)
119 return false;
120 while (C != '\n' && Jnk != '\n')
121 if (read(STDIN_FILENO,&Jnk,1) != 1)
122 return false;
a6568219 123
b2e465d6 124 if (!(toupper(C) == *Yes || C == '\n' || C == '\r'))
a6568219
AL
125 return false;
126 return true;
127}
128 /*}}}*/
6f86c974
AL
129// AnalPrompt - Annoying Yes No Prompt. /*{{{*/
130// ---------------------------------------------------------------------
131/* Returns true on a Yes.*/
132bool AnalPrompt(const char *Text)
133{
134 char Buf[1024];
135 cin.getline(Buf,sizeof(Buf));
136 if (strcmp(Buf,Text) == 0)
137 return true;
138 return false;
139}
140 /*}}}*/
0a8e3465
AL
141// ShowList - Show a list /*{{{*/
142// ---------------------------------------------------------------------
b2e465d6 143/* This prints out a string of space separated words with a title and
0a8e3465 144 a two space indent line wraped to the current screen width. */
83d89a9f 145bool ShowList(ostream &out,string Title,string List)
0a8e3465
AL
146{
147 if (List.empty() == true)
83d89a9f 148 return true;
0a8e3465
AL
149
150 // Acount for the leading space
151 int ScreenWidth = ::ScreenWidth - 3;
152
153 out << Title << endl;
154 string::size_type Start = 0;
155 while (Start < List.size())
156 {
157 string::size_type End;
158 if (Start + ScreenWidth >= List.size())
159 End = List.size();
160 else
161 End = List.rfind(' ',Start+ScreenWidth);
162
163 if (End == string::npos || End < Start)
164 End = Start + ScreenWidth;
165 out << " " << string(List,Start,End - Start) << endl;
166 Start = End + 1;
167 }
83d89a9f 168 return false;
0a8e3465
AL
169}
170 /*}}}*/
171// ShowBroken - Debugging aide /*{{{*/
172// ---------------------------------------------------------------------
173/* This prints out the names of all the packages that are broken along
174 with the name of each each broken dependency and a quite version
b2e465d6
AL
175 description.
176
177 The output looks like:
178 Sorry, but the following packages have unmet dependencies:
179 exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed
180 Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
181 Depends: libsasl7 but it is not going to be installed
182 */
421c8d10 183void ShowBroken(ostream &out,CacheFile &Cache,bool Now)
0a8e3465 184{
b2e465d6 185 out << _("Sorry, but the following packages have unmet dependencies:") << endl;
1089ca89 186 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
0a8e3465 187 {
1089ca89
AL
188 pkgCache::PkgIterator I(Cache,Cache.List[J]);
189
079a992d
AL
190 if (Now == true)
191 {
192 if (Cache[I].NowBroken() == false)
193 continue;
194 }
195 else
196 {
197 if (Cache[I].InstBroken() == false)
198 continue;
199 }
200
303a1703
AL
201 // Print out each package and the failed dependencies
202 out <<" " << I.Name() << ":";
648e3cb4 203 unsigned Indent = strlen(I.Name()) + 3;
303a1703 204 bool First = true;
079a992d
AL
205 pkgCache::VerIterator Ver;
206
207 if (Now == true)
208 Ver = I.CurrentVer();
209 else
210 Ver = Cache[I].InstVerIter(Cache);
211
212 if (Ver.end() == true)
0a8e3465 213 {
079a992d 214 out << endl;
303a1703
AL
215 continue;
216 }
217
079a992d 218 for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
303a1703 219 {
30e1eab5
AL
220 // Compute a single dependency element (glob or)
221 pkgCache::DepIterator Start;
222 pkgCache::DepIterator End;
223 D.GlobOr(Start,End);
76fbce56 224
079a992d 225 if (Cache->IsImportantDep(End) == false)
303a1703 226 continue;
079a992d
AL
227
228 if (Now == true)
229 {
230 if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
231 continue;
232 }
233 else
234 {
235 if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
236 continue;
237 }
238
648e3cb4
AL
239 bool FirstOr = true;
240 while (1)
0a8e3465 241 {
648e3cb4
AL
242 if (First == false)
243 for (unsigned J = 0; J != Indent; J++)
244 out << ' ';
245 First = false;
246
247 if (FirstOr == false)
248 {
249 for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
250 out << ' ';
251 }
0a8e3465 252 else
648e3cb4
AL
253 out << ' ' << End.DepType() << ": ";
254 FirstOr = false;
255
256 out << Start.TargetPkg().Name();
257
258 // Show a quick summary of the version requirements
259 if (Start.TargetVer() != 0)
b2e465d6 260 out << " (" << Start.CompType() << " " << Start.TargetVer() << ")";
648e3cb4
AL
261
262 /* Show a summary of the target package if possible. In the case
263 of virtual packages we show nothing */
264 pkgCache::PkgIterator Targ = Start.TargetPkg();
265 if (Targ->ProvidesList == 0)
7e798dd7 266 {
b2e465d6 267 out << ' ';
648e3cb4 268 pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
f0ec51c2
AL
269 if (Now == true)
270 Ver = Targ.CurrentVer();
079a992d 271
648e3cb4 272 if (Ver.end() == false)
b2e465d6
AL
273 {
274 if (Now == true)
275 ioprintf(out,_("but %s is installed"),Ver.VerStr());
276 else
277 ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
278 }
648e3cb4 279 else
303a1703 280 {
648e3cb4
AL
281 if (Cache[Targ].CandidateVerIter(Cache).end() == true)
282 {
283 if (Targ->ProvidesList == 0)
b2e465d6 284 out << _("but it is not installable");
648e3cb4 285 else
b2e465d6 286 out << _("but it is a virtual package");
648e3cb4 287 }
303a1703 288 else
b2e465d6 289 out << (Now?_("but it is not installed"):_("but it is not going to be installed"));
648e3cb4
AL
290 }
291 }
292
293 if (Start != End)
b2e465d6 294 out << _(" or");
648e3cb4
AL
295 out << endl;
296
297 if (Start == End)
298 break;
299 Start++;
300 }
303a1703 301 }
0a8e3465
AL
302 }
303}
304 /*}}}*/
305// ShowNew - Show packages to newly install /*{{{*/
306// ---------------------------------------------------------------------
307/* */
1089ca89 308void ShowNew(ostream &out,CacheFile &Cache)
0a8e3465
AL
309{
310 /* Print out a list of packages that are going to be removed extra
311 to what the user asked */
0a8e3465 312 string List;
1089ca89
AL
313 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
314 {
315 pkgCache::PkgIterator I(Cache,Cache.List[J]);
316 if (Cache[I].NewInstall() == true)
0a8e3465 317 List += string(I.Name()) + " ";
1089ca89
AL
318 }
319
b2e465d6 320 ShowList(out,_("The following NEW packages will be installed:"),List);
0a8e3465
AL
321}
322 /*}}}*/
323// ShowDel - Show packages to delete /*{{{*/
324// ---------------------------------------------------------------------
325/* */
1089ca89 326void ShowDel(ostream &out,CacheFile &Cache)
0a8e3465
AL
327{
328 /* Print out a list of packages that are going to be removed extra
329 to what the user asked */
0a8e3465 330 string List;
1089ca89 331 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
fc4b5c9f 332 {
1089ca89
AL
333 pkgCache::PkgIterator I(Cache,Cache.List[J]);
334 if (Cache[I].Delete() == true)
fc4b5c9f 335 {
1089ca89 336 if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
fc4b5c9f
AL
337 List += string(I.Name()) + "* ";
338 else
339 List += string(I.Name()) + " ";
340 }
341 }
3d615484 342
b2e465d6 343 ShowList(out,_("The following packages will be REMOVED:"),List);
0a8e3465
AL
344}
345 /*}}}*/
346// ShowKept - Show kept packages /*{{{*/
347// ---------------------------------------------------------------------
348/* */
f292686b 349void ShowKept(ostream &out,CacheFile &Cache)
0a8e3465 350{
0a8e3465 351 string List;
f292686b 352 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
0a8e3465 353 {
f292686b
AL
354 pkgCache::PkgIterator I(Cache,Cache.List[J]);
355
0a8e3465 356 // Not interesting
f292686b
AL
357 if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false ||
358 I->CurrentVer == 0 || Cache[I].Delete() == true)
0a8e3465
AL
359 continue;
360
361 List += string(I.Name()) + " ";
362 }
b2e465d6 363 ShowList(out,_("The following packages have been kept back"),List);
0a8e3465
AL
364}
365 /*}}}*/
366// ShowUpgraded - Show upgraded packages /*{{{*/
367// ---------------------------------------------------------------------
368/* */
1089ca89 369void ShowUpgraded(ostream &out,CacheFile &Cache)
0a8e3465 370{
0a8e3465 371 string List;
1089ca89 372 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
0a8e3465 373 {
1089ca89
AL
374 pkgCache::PkgIterator I(Cache,Cache.List[J]);
375
0a8e3465 376 // Not interesting
1089ca89 377 if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
0a8e3465
AL
378 continue;
379
380 List += string(I.Name()) + " ";
381 }
b2e465d6
AL
382 ShowList(out,_("The following packages will be upgraded"),List);
383}
384 /*}}}*/
385// ShowDowngraded - Show downgraded packages /*{{{*/
386// ---------------------------------------------------------------------
387/* */
388bool ShowDowngraded(ostream &out,CacheFile &Cache)
389{
390 string List;
391 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
392 {
393 pkgCache::PkgIterator I(Cache,Cache.List[J]);
394
395 // Not interesting
396 if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
397 continue;
398
399 List += string(I.Name()) + " ";
400 }
401 return ShowList(out,_("The following packages will be DOWNGRADED"),List);
0a8e3465
AL
402}
403 /*}}}*/
404// ShowHold - Show held but changed packages /*{{{*/
405// ---------------------------------------------------------------------
406/* */
1089ca89 407bool ShowHold(ostream &out,CacheFile &Cache)
0a8e3465 408{
0a8e3465 409 string List;
1089ca89 410 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
0a8e3465 411 {
1089ca89
AL
412 pkgCache::PkgIterator I(Cache,Cache.List[J]);
413 if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
0a8e3465
AL
414 I->SelectedState == pkgCache::State::Hold)
415 List += string(I.Name()) + " ";
416 }
417
b2e465d6 418 return ShowList(out,_("The following held packages will be changed:"),List);
0a8e3465
AL
419}
420 /*}}}*/
421// ShowEssential - Show an essential package warning /*{{{*/
422// ---------------------------------------------------------------------
423/* This prints out a warning message that is not to be ignored. It shows
424 all essential packages and their dependents that are to be removed.
425 It is insanely risky to remove the dependents of an essential package! */
1089ca89 426bool ShowEssential(ostream &out,CacheFile &Cache)
0a8e3465 427{
0a8e3465 428 string List;
b2e465d6
AL
429 bool *Added = new bool[Cache->Head().PackageCount];
430 for (unsigned int I = 0; I != Cache->Head().PackageCount; I++)
0a8e3465
AL
431 Added[I] = false;
432
1089ca89 433 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
0a8e3465 434 {
1089ca89 435 pkgCache::PkgIterator I(Cache,Cache.List[J]);
b2e465d6
AL
436 if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
437 (I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
0a8e3465
AL
438 continue;
439
440 // The essential package is being removed
1089ca89 441 if (Cache[I].Delete() == true)
0a8e3465
AL
442 {
443 if (Added[I->ID] == false)
444 {
445 Added[I->ID] = true;
446 List += string(I.Name()) + " ";
447 }
448 }
449
450 if (I->CurrentVer == 0)
451 continue;
452
453 // Print out any essential package depenendents that are to be removed
b2e465d6 454 for (pkgCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; D++)
0a8e3465 455 {
3e3221ba
AL
456 // Skip everything but depends
457 if (D->Type != pkgCache::Dep::PreDepends &&
458 D->Type != pkgCache::Dep::Depends)
459 continue;
460
0a8e3465 461 pkgCache::PkgIterator P = D.SmartTargetPkg();
1089ca89 462 if (Cache[P].Delete() == true)
0a8e3465
AL
463 {
464 if (Added[P->ID] == true)
465 continue;
466 Added[P->ID] = true;
3e3221ba
AL
467
468 char S[300];
20ebd488 469 snprintf(S,sizeof(S),_("%s (due to %s) "),P.Name(),I.Name());
3e3221ba 470 List += S;
0a8e3465
AL
471 }
472 }
473 }
474
83d89a9f 475 delete [] Added;
b2e465d6
AL
476 return ShowList(out,_("WARNING: The following essential packages will be removed\n"
477 "This should NOT be done unless you know exactly what you are doing!"),List);
0a8e3465
AL
478}
479 /*}}}*/
480// Stats - Show some statistics /*{{{*/
481// ---------------------------------------------------------------------
482/* */
483void Stats(ostream &out,pkgDepCache &Dep)
484{
485 unsigned long Upgrade = 0;
b2e465d6 486 unsigned long Downgrade = 0;
0a8e3465 487 unsigned long Install = 0;
d0c59649 488 unsigned long ReInstall = 0;
0a8e3465
AL
489 for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++)
490 {
491 if (Dep[I].NewInstall() == true)
492 Install++;
493 else
b2e465d6 494 {
0a8e3465
AL
495 if (Dep[I].Upgrade() == true)
496 Upgrade++;
b2e465d6
AL
497 else
498 if (Dep[I].Downgrade() == true)
499 Downgrade++;
500 }
501
d0c59649
AL
502 if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
503 ReInstall++;
0a8e3465
AL
504 }
505
b2e465d6
AL
506 ioprintf(out,_("%lu packages upgraded, %lu newly installed, "),
507 Upgrade,Install);
508
d0c59649 509 if (ReInstall != 0)
b2e465d6
AL
510 ioprintf(out,_("%lu reinstalled, "),ReInstall);
511 if (Downgrade != 0)
512 ioprintf(out,_("%lu downgraded, "),Downgrade);
0a8e3465 513
b2e465d6
AL
514 ioprintf(out,_("%lu to remove and %lu not upgraded.\n"),
515 Dep.DelCount(),Dep.KeepCount());
516
0a8e3465 517 if (Dep.BadCount() != 0)
b2e465d6
AL
518 ioprintf(out,_("%lu packages not fully installed or removed.\n"),
519 Dep.BadCount());
0a8e3465
AL
520}
521 /*}}}*/
522
1089ca89 523// CacheFile::NameComp - QSort compare by name /*{{{*/
0a8e3465
AL
524// ---------------------------------------------------------------------
525/* */
1089ca89
AL
526pkgCache *CacheFile::SortCache = 0;
527int CacheFile::NameComp(const void *a,const void *b)
0a8e3465 528{
8508b1df
AL
529 if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0)
530 return *(pkgCache::Package **)a - *(pkgCache::Package **)b;
0a8e3465 531
1089ca89
AL
532 const pkgCache::Package &A = **(pkgCache::Package **)a;
533 const pkgCache::Package &B = **(pkgCache::Package **)b;
534
535 return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name);
536}
537 /*}}}*/
538// CacheFile::Sort - Sort by name /*{{{*/
539// ---------------------------------------------------------------------
540/* */
541void CacheFile::Sort()
542{
543 delete [] List;
544 List = new pkgCache::Package *[Cache->Head().PackageCount];
545 memset(List,0,sizeof(*List)*Cache->Head().PackageCount);
546 pkgCache::PkgIterator I = Cache->PkgBegin();
547 for (;I.end() != true; I++)
548 List[I->ID] = I;
549
550 SortCache = *this;
551 qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp);
552}
0a8e3465 553 /*}}}*/
b2e465d6 554// CacheFile::CheckDeps - Open the cache file /*{{{*/
0a8e3465
AL
555// ---------------------------------------------------------------------
556/* This routine generates the caches and then opens the dependency cache
557 and verifies that the system is OK. */
2d11135a 558bool CacheFile::CheckDeps(bool AllowBroken)
0a8e3465 559{
d38b7b3d
AL
560 if (_error->PendingError() == true)
561 return false;
0a8e3465 562
0a8e3465 563 // Check that the system is OK
b2e465d6 564 if (DCache->DelCount() != 0 || DCache->InstCount() != 0)
0a8e3465
AL
565 return _error->Error("Internal Error, non-zero counts");
566
567 // Apply corrections for half-installed packages
b2e465d6 568 if (pkgApplyStatus(*DCache) == false)
0a8e3465
AL
569 return false;
570
571 // Nothing is broken
b2e465d6 572 if (DCache->BrokenCount() == 0 || AllowBroken == true)
0a8e3465
AL
573 return true;
574
575 // Attempt to fix broken things
576 if (_config->FindB("APT::Get::Fix-Broken",false) == true)
577 {
b2e465d6
AL
578 c1out << _("Correcting dependencies...") << flush;
579 if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
0a8e3465 580 {
b2e465d6 581 c1out << _(" failed.") << endl;
421c8d10 582 ShowBroken(c1out,*this,true);
0a8e3465 583
b2e465d6 584 return _error->Error(_("Unable to correct dependencies"));
0a8e3465 585 }
b2e465d6
AL
586 if (pkgMinimizeUpgrade(*DCache) == false)
587 return _error->Error(_("Unable to minimize the upgrade set"));
0a8e3465 588
b2e465d6 589 c1out << _(" Done") << endl;
0a8e3465
AL
590 }
591 else
592 {
b2e465d6 593 c1out << _("You might want to run `apt-get -f install' to correct these.") << endl;
421c8d10 594 ShowBroken(c1out,*this,true);
0a8e3465 595
b2e465d6 596 return _error->Error(_("Unmet dependencies. Try using -f."));
0a8e3465
AL
597 }
598
599 return true;
600}
601 /*}}}*/
602
603// InstallPackages - Actually download and install the packages /*{{{*/
604// ---------------------------------------------------------------------
605/* This displays the informative messages describing what is going to
606 happen and then calls the download routines */
a3eaf954
AL
607bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
608 bool Saftey = true)
0a8e3465 609{
fc4b5c9f
AL
610 if (_config->FindB("APT::Get::Purge",false) == true)
611 {
612 pkgCache::PkgIterator I = Cache->PkgBegin();
613 for (; I.end() == false; I++)
d556d1a1
AL
614 {
615 if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
616 Cache->MarkDelete(I,true);
617 }
fc4b5c9f
AL
618 }
619
83d89a9f 620 bool Fail = false;
6f86c974 621 bool Essential = false;
83d89a9f 622
a6568219 623 // Show all the various warning indicators
0a8e3465
AL
624 ShowDel(c1out,Cache);
625 ShowNew(c1out,Cache);
626 if (ShwKept == true)
627 ShowKept(c1out,Cache);
7a215bee 628 Fail |= !ShowHold(c1out,Cache);
0a8e3465
AL
629 if (_config->FindB("APT::Get::Show-Upgraded",false) == true)
630 ShowUpgraded(c1out,Cache);
b2e465d6 631 Fail |= !ShowDowngraded(c1out,Cache);
6f86c974
AL
632 Essential = !ShowEssential(c1out,Cache);
633 Fail |= Essential;
0a8e3465
AL
634 Stats(c1out,Cache);
635
636 // Sanity check
d38b7b3d 637 if (Cache->BrokenCount() != 0)
0a8e3465 638 {
421c8d10 639 ShowBroken(c1out,Cache,false);
0a8e3465
AL
640 return _error->Error("Internal Error, InstallPackages was called with broken packages!");
641 }
642
d0c59649 643 if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
d38b7b3d 644 Cache->BadCount() == 0)
c60d151b 645 return true;
03e39e59 646
d150b09d 647 // No remove flag
b2e465d6
AL
648 if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
649 return _error->Error(_("Packages need to be removed but Remove is disabled."));
d150b09d 650
03e39e59
AL
651 // Run the simulator ..
652 if (_config->FindB("APT::Get::Simulate") == true)
653 {
654 pkgSimulate PM(Cache);
281daf46
AL
655 pkgPackageManager::OrderResult Res = PM.DoInstall();
656 if (Res == pkgPackageManager::Failed)
657 return false;
658 if (Res != pkgPackageManager::Completed)
659 return _error->Error("Internal Error, Ordering didn't finish");
660 return true;
03e39e59
AL
661 }
662
663 // Create the text record parser
664 pkgRecords Recs(Cache);
83d89a9f
AL
665 if (_error->PendingError() == true)
666 return false;
667
d38b7b3d 668 // Lock the archive directory
36375005 669 FileFd Lock;
c37b9502
AL
670 if (_config->FindB("Debug::NoLocking",false) == false &&
671 _config->FindB("APT::Get::Print-URIs") == false)
d38b7b3d 672 {
36375005 673 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
d38b7b3d 674 if (_error->PendingError() == true)
b2e465d6 675 return _error->Error(_("Unable to lock the download directory"));
d38b7b3d 676 }
03e39e59
AL
677
678 // Create the download object
679 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
680 pkgAcquire Fetcher(&Stat);
681
682 // Read the source list
683 pkgSourceList List;
684 if (List.ReadMainList() == false)
b2e465d6 685 return _error->Error(_("The list of sources could not be read."));
03e39e59
AL
686
687 // Create the package manager and prepare to download
b2e465d6
AL
688 SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
689 if (PM->GetArchives(&Fetcher,&List,&Recs) == false ||
424c3bc0 690 _error->PendingError() == true)
03e39e59
AL
691 return false;
692
7a1b1f8b 693 // Display statistics
b2e465d6
AL
694 double FetchBytes = Fetcher.FetchNeeded();
695 double FetchPBytes = Fetcher.PartialPresent();
696 double DebBytes = Fetcher.TotalNeeded();
d38b7b3d
AL
697 if (DebBytes != Cache->DebSize())
698 {
699 c0out << DebBytes << ',' << Cache->DebSize() << endl;
a6568219 700 c0out << "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl;
d38b7b3d 701 }
138d4b3d 702
7a1b1f8b 703 // Number of bytes
a6568219 704 if (DebBytes != FetchBytes)
b2e465d6
AL
705 ioprintf(c1out,_("Need to get %sB/%sB of archives. "),
706 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
a6568219 707 else
b2e465d6
AL
708 ioprintf(c1out,_("Need to get %sB of archives. "),
709 SizeToStr(DebBytes).c_str());
710
10bb1f5f
AL
711 // Size delta
712 if (Cache->UsrSize() >= 0)
b2e465d6
AL
713 ioprintf(c1out,_("After unpacking %sB will be used.\n"),
714 SizeToStr(Cache->UsrSize()).c_str());
10bb1f5f 715 else
b2e465d6
AL
716 ioprintf(c1out,_("After unpacking %sB will be freed.\n"),
717 SizeToStr(-1*Cache->UsrSize()).c_str());
10bb1f5f
AL
718
719 if (_error->PendingError() == true)
720 return false;
31a0531d 721
01b64152
AL
722 /* Check for enough free space, but only if we are actually going to
723 download */
724 if (_config->FindB("APT::Get::Print-URIs") == false)
725 {
726 struct statvfs Buf;
727 string OutputDir = _config->FindDir("Dir::Cache::Archives");
728 if (statvfs(OutputDir.c_str(),&Buf) != 0)
729 return _error->Errno("statvfs","Couldn't determine free space in %s",
730 OutputDir.c_str());
731 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
b2e465d6 732 return _error->Error(_("Sorry, you don't have enough free space in %s to hold all the .debs."),
01b64152
AL
733 OutputDir.c_str());
734 }
735
83d89a9f 736 // Fail safe check
0c95c765
AL
737 if (_config->FindI("quiet",0) >= 2 ||
738 _config->FindB("APT::Get::Assume-Yes",false) == true)
83d89a9f
AL
739 {
740 if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
b2e465d6 741 return _error->Error(_("There are problems and -y was used without --force-yes"));
83d89a9f 742 }
83d89a9f 743
6f86c974
AL
744 if (Essential == true && Saftey == true)
745 {
d150b09d 746 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
b2e465d6 747 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
d150b09d 748
b2e465d6
AL
749 const char *Prompt = _("Yes, do as I say!");
750 ioprintf(c2out,
751 _("You are about to do something potentially harmful\n"
752 "To continue type in the phrase '%s'\n"
753 " ?] "),Prompt);
754 c2out << flush;
755 if (AnalPrompt(Prompt) == false)
6f86c974 756 {
b2e465d6 757 c2out << _("Abort.") << endl;
a6568219 758 exit(1);
6f86c974
AL
759 }
760 }
761 else
d150b09d 762 {
6f86c974 763 // Prompt to continue
38262e68 764 if (Ask == true || Fail == true)
6f86c974 765 {
d150b09d 766 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
b2e465d6 767 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
d150b09d 768
0c95c765 769 if (_config->FindI("quiet",0) < 2 &&
6f86c974 770 _config->FindB("APT::Get::Assume-Yes",false) == false)
0c95c765 771 {
b2e465d6 772 c2out << _("Do you want to continue? [Y/n] ") << flush;
6f86c974 773
0c95c765
AL
774 if (YnPrompt() == false)
775 {
b2e465d6 776 c2out << _("Abort.") << endl;
0c95c765
AL
777 exit(1);
778 }
779 }
6f86c974
AL
780 }
781 }
782
36375005 783 // Just print out the uris an exit if the --print-uris flag was used
f7a08e33
AL
784 if (_config->FindB("APT::Get::Print-URIs") == true)
785 {
786 pkgAcquire::UriIterator I = Fetcher.UriBegin();
787 for (; I != Fetcher.UriEnd(); I++)
788 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
789 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
790 return true;
791 }
b2e465d6
AL
792
793 /* Unlock the dpkg lock if we are not going to be doing an install
794 after. */
795 if (_config->FindB("APT::Get::Download-Only",false) == true)
796 _system->UnLock();
83d89a9f 797
03e39e59 798 // Run it
281daf46 799 while (1)
30e1eab5 800 {
a3eaf954 801 bool Transient = false;
b2e465d6 802 if (_config->FindB("APT::Get::Download",true) == false)
a3eaf954 803 {
076d01b0 804 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
a3eaf954
AL
805 {
806 if ((*I)->Local == true)
807 {
808 I++;
809 continue;
810 }
811
812 // Close the item and check if it was found in cache
813 (*I)->Finished();
814 if ((*I)->Complete == false)
815 Transient = true;
816
817 // Clear it out of the fetch list
818 delete *I;
819 I = Fetcher.ItemsBegin();
820 }
821 }
822
823 if (Fetcher.Run() == pkgAcquire::Failed)
824 return false;
30e1eab5 825
281daf46
AL
826 // Print out errors
827 bool Failed = false;
076d01b0 828 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
f01fe790 829 {
281daf46
AL
830 if ((*I)->Status == pkgAcquire::Item::StatDone &&
831 (*I)->Complete == true)
832 continue;
833
281daf46
AL
834 if ((*I)->Status == pkgAcquire::Item::StatIdle)
835 {
836 Transient = true;
837 // Failed = true;
838 continue;
839 }
a3eaf954 840
b2e465d6
AL
841 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
842 (*I)->ErrorText.c_str());
f01fe790 843 Failed = true;
f01fe790 844 }
5ec427c2 845
a3eaf954 846 /* If we are in no download mode and missing files and there were
5ec427c2
AL
847 'failures' then the user must specify -m. Furthermore, there
848 is no such thing as a transient error in no-download mode! */
a3eaf954 849 if (Transient == true &&
b2e465d6 850 _config->FindB("APT::Get::Download",true) == false)
5ec427c2
AL
851 {
852 Transient = false;
853 Failed = true;
854 }
f01fe790 855
281daf46
AL
856 if (_config->FindB("APT::Get::Download-Only",false) == true)
857 {
858 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
b2e465d6
AL
859 return _error->Error(_("Some files failed to download"));
860 c1out << _("Download complete and in download only mode") << endl;
281daf46
AL
861 return true;
862 }
863
8195ae46 864 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
f01fe790 865 {
b2e465d6 866 return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
f01fe790
AL
867 }
868
281daf46 869 if (Transient == true && Failed == true)
b2e465d6 870 return _error->Error(_("--fix-missing and media swapping is not currently supported"));
281daf46
AL
871
872 // Try to deal with missing package files
b2e465d6 873 if (Failed == true && PM->FixMissing() == false)
281daf46 874 {
b2e465d6
AL
875 cerr << _("Unable to correct missing packages.") << endl;
876 return _error->Error(_("Aborting Install."));
281daf46 877 }
a3eaf954 878
b2e465d6
AL
879 _system->UnLock();
880 pkgPackageManager::OrderResult Res = PM->DoInstall();
281daf46
AL
881 if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
882 return false;
883 if (Res == pkgPackageManager::Completed)
884 return true;
885
886 // Reload the fetcher object and loop again for media swapping
887 Fetcher.Shutdown();
b2e465d6 888 if (PM->GetArchives(&Fetcher,&List,&Recs) == false)
281daf46 889 return false;
b2e465d6
AL
890
891 _system->Lock();
281daf46 892 }
0a8e3465
AL
893}
894 /*}}}*/
c373c37a
AL
895// TryToInstall - Try to install a single package /*{{{*/
896// ---------------------------------------------------------------------
897/* This used to be inlined in DoInstall, but with the advent of regex package
898 name matching it was split out.. */
899bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
900 pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
901 unsigned int &ExpectedInst,bool AllowFail = true)
902{
903 /* This is a pure virtual package and there is a single available
904 provides */
905 if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0 &&
906 Pkg.ProvidesList()->NextProvides == 0)
907 {
908 pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg();
b2e465d6
AL
909 ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
910 Tmp.Name(),Pkg.Name());
c373c37a
AL
911 Pkg = Tmp;
912 }
913
914 // Handle the no-upgrade case
b2e465d6 915 if (_config->FindB("APT::Get::upgrade",true) == false &&
c373c37a
AL
916 Pkg->CurrentVer != 0)
917 {
918 if (AllowFail == true)
b2e465d6
AL
919 ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
920 Pkg.Name());
c373c37a
AL
921 return true;
922 }
923
924 // Check if there is something at all to install
925 pkgDepCache::StateCache &State = Cache[Pkg];
a146c927 926 if (Remove == true && Pkg->CurrentVer == 0)
10bb1f5f 927 {
b2e465d6
AL
928 /* We want to continue searching for regex hits, so we return false here
929 otherwise this is not really an error. */
10bb1f5f 930 if (AllowFail == false)
b2e465d6 931 return false;
1156d969 932 ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.Name());
b2e465d6 933 return true;
10bb1f5f 934 }
a146c927
AL
935
936 if (State.CandidateVer == 0 && Remove == false)
c373c37a
AL
937 {
938 if (AllowFail == false)
939 return false;
940
941 if (Pkg->ProvidesList != 0)
942 {
b2e465d6
AL
943 ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
944 Pkg.Name());
c373c37a
AL
945
946 pkgCache::PrvIterator I = Pkg.ProvidesList();
947 for (; I.end() == false; I++)
948 {
949 pkgCache::PkgIterator Pkg = I.OwnerPkg();
950
951 if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer())
952 {
953 if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
954 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
b2e465d6 955 _(" [Installed]") << endl;
c373c37a
AL
956 else
957 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
958 }
959 }
b2e465d6 960 c1out << _("You should explicitly select one to install.") << endl;
c373c37a
AL
961 }
962 else
963 {
b2e465d6
AL
964 ioprintf(c1out,
965 _("Package %s has no available version, but exists in the database.\n"
966 "This typically means that the package was mentioned in a dependency and\n"
967 "never uploaded, has been obsoleted or is not available with the contents\n"
968 "of sources.list\n"),Pkg.Name());
c373c37a
AL
969
970 string List;
c82ffeb6
AL
971 SPtrArray<bool> Seen = new bool[Cache.Head().PackageCount];
972 memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen));
c373c37a
AL
973 pkgCache::DepIterator Dep = Pkg.RevDependsList();
974 for (; Dep.end() == false; Dep++)
975 {
976 if (Dep->Type != pkgCache::Dep::Replaces)
977 continue;
b2e465d6
AL
978 if (Seen[Dep.ParentPkg()->ID] == true)
979 continue;
980 Seen[Dep.ParentPkg()->ID] = true;
c373c37a
AL
981 List += string(Dep.ParentPkg().Name()) + " ";
982 }
b2e465d6 983 ShowList(c1out,_("However the following packages replace it:"),List);
c373c37a
AL
984 }
985
b2e465d6 986 _error->Error(_("Package %s has no installation candidate"),Pkg.Name());
c373c37a
AL
987 return false;
988 }
61d6a8de
AL
989
990 Fix.Clear(Pkg);
70777d4b 991 Fix.Protect(Pkg);
c373c37a
AL
992 if (Remove == true)
993 {
994 Fix.Remove(Pkg);
995 Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
996 return true;
997 }
998
999 // Install it
1000 Cache.MarkInstall(Pkg,false);
1001 if (State.Install() == false)
1002 {
d0c59649
AL
1003 if (_config->FindB("APT::Get::ReInstall",false) == true)
1004 {
1005 if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
70d73d7e 1006 ioprintf(c1out,_("Sorry, re-installation of %s is not possible, it cannot be downloaded.\n"),
b2e465d6 1007 Pkg.Name());
d0c59649
AL
1008 else
1009 Cache.SetReInstall(Pkg,true);
1010 }
1011 else
1012 {
1013 if (AllowFail == true)
b2e465d6
AL
1014 ioprintf(c1out,_("Sorry, %s is already the newest version.\n"),
1015 Pkg.Name());
d0c59649 1016 }
c373c37a
AL
1017 }
1018 else
1019 ExpectedInst++;
1020
1021 // Install it with autoinstalling enabled.
1022 if (State.InstBroken() == true && BrokenFix == false)
1023 Cache.MarkInstall(Pkg,true);
1024 return true;
1025}
1026 /*}}}*/
b2e465d6
AL
1027// TryToChangeVer - Try to change a candidate version /*{{{*/
1028// ---------------------------------------------------------------------
1029/* */
1030bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
1031 const char *VerTag,bool IsRel)
1032{
1033 pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release:pkgVersionMatch::Version));
1034
1035 pkgCache::VerIterator Ver = Match.Find(Pkg);
1036
1037 if (Ver.end() == true)
1038 {
1039 if (IsRel == true)
1040 return _error->Error(_("Release '%s' for '%s' was not found"),
1041 VerTag,Pkg.Name());
1042 return _error->Error(_("Version '%s' for '%s' was not found"),
1043 VerTag,Pkg.Name());
1044 }
1045
1046 if (strcmp(VerTag,Ver.VerStr()) != 0)
1047 {
1048 ioprintf(c1out,_("Selected version %s (%s) for %s\n"),
1049 Ver.VerStr(),Ver.RelStr().c_str(),Pkg.Name());
1050 }
1051
1052 Cache.SetCandidateVersion(Ver);
1053 return true;
1054}
1055 /*}}}*/
1056// FindSrc - Find a source record /*{{{*/
1057// ---------------------------------------------------------------------
1058/* */
1059pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
1060 pkgSrcRecords &SrcRecs,string &Src,
1061 pkgDepCache &Cache)
1062{
1063 // We want to pull the version off the package specification..
1064 string VerTag;
1065 string TmpSrc = Name;
1066 string::size_type Slash = TmpSrc.rfind('=');
1067 if (Slash != string::npos)
1068 {
1069 VerTag = string(TmpSrc.begin() + Slash + 1,TmpSrc.end());
1070 TmpSrc = string(TmpSrc.begin(),TmpSrc.begin() + Slash);
1071 }
1072
1073 /* Lookup the version of the package we would install if we were to
1074 install a version and determine the source package name, then look
1075 in the archive for a source package of the same name. In theory
1076 we could stash the version string as well and match that too but
1077 today there aren't multi source versions in the archive. */
1078 if (_config->FindB("APT::Get::Only-Source") == false &&
1079 VerTag.empty() == true)
1080 {
1081 pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc);
1082 if (Pkg.end() == false)
1083 {
1084 pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
1085 if (Ver.end() == false)
1086 {
1087 pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
1088 Src = Parse.SourcePkg();
1089 }
1090 }
1091 }
1092
1093 // No source package name..
1094 if (Src.empty() == true)
1095 Src = TmpSrc;
1096
1097 // The best hit
1098 pkgSrcRecords::Parser *Last = 0;
1099 unsigned long Offset = 0;
1100 string Version;
1101 bool IsMatch = false;
1102
1103 // If we are matching by version then we need exact matches to be happy
1104 if (VerTag.empty() == false)
1105 IsMatch = true;
1106
1107 /* Iterate over all of the hits, which includes the resulting
1108 binary packages in the search */
1109 pkgSrcRecords::Parser *Parse;
1110 SrcRecs.Restart();
1111 while ((Parse = SrcRecs.Find(Src.c_str(),false)) != 0)
1112 {
1113 string Ver = Parse->Version();
1114
1115 // Skip name mismatches
1116 if (IsMatch == true && Parse->Package() != Src)
1117 continue;
1118
1119 if (VerTag.empty() == false)
1120 {
1121 /* Don't want to fall through because we are doing exact version
1122 matching. */
1123 if (Cache.VS().CmpVersion(VerTag,Ver) != 0)
1124 continue;
1125
1126 Last = Parse;
1127 Offset = Parse->Offset();
1128 break;
1129 }
1130
1131 // Newer version or an exact match
1132 if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0 ||
1133 (Parse->Package() == Src && IsMatch == false))
1134 {
1135 IsMatch = Parse->Package() == Src;
1136 Last = Parse;
1137 Offset = Parse->Offset();
1138 Version = Ver;
1139 }
1140 }
1141
1142 if (Last == 0)
1143 return 0;
1144
1145 if (Last->Jump(Offset) == false)
1146 return 0;
1147
1148 return Last;
1149}
1150 /*}}}*/
0a8e3465
AL
1151
1152// DoUpdate - Update the package lists /*{{{*/
1153// ---------------------------------------------------------------------
1154/* */
b2e465d6 1155bool DoUpdate(CommandLine &CmdL)
0a8e3465 1156{
b2e465d6
AL
1157 if (CmdL.FileSize() != 1)
1158 return _error->Error(_("The update command takes no arguments"));
1159
0919e3f9
AL
1160 // Get the source list
1161 pkgSourceList List;
1162 if (List.ReadMainList() == false)
1163 return false;
1164
d38b7b3d 1165 // Lock the list directory
36375005 1166 FileFd Lock;
d38b7b3d
AL
1167 if (_config->FindB("Debug::NoLocking",false) == false)
1168 {
36375005 1169 Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
d38b7b3d 1170 if (_error->PendingError() == true)
b2e465d6 1171 return _error->Error(_("Unable to lock the list directory"));
d38b7b3d
AL
1172 }
1173
0919e3f9
AL
1174 // Create the download object
1175 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1176 pkgAcquire Fetcher(&Stat);
1177
1178 // Populate it with the source selection
b2e465d6 1179 if (List.GetIndexes(&Fetcher) == false)
0919e3f9 1180 return false;
0919e3f9
AL
1181
1182 // Run it
024d1123 1183 if (Fetcher.Run() == pkgAcquire::Failed)
0919e3f9
AL
1184 return false;
1185
9df71a5b 1186 bool Failed = false;
076d01b0 1187 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
9df71a5b
AL
1188 {
1189 if ((*I)->Status == pkgAcquire::Item::StatDone)
1190 continue;
1191
1192 (*I)->Finished();
1193
b2e465d6
AL
1194 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1195 (*I)->ErrorText.c_str());
9df71a5b
AL
1196 Failed = true;
1197 }
1198
7a7fa5f0 1199 // Clean out any old list files
67ff87bf 1200 if (_config->FindB("APT::Get::List-Cleanup",true) == true)
9df71a5b
AL
1201 {
1202 if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
1203 Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
1204 return false;
1205 }
7a7fa5f0 1206
0919e3f9
AL
1207 // Prepare the cache.
1208 CacheFile Cache;
a65cbe33 1209 if (Cache.Open() == false)
0919e3f9
AL
1210 return false;
1211
9df71a5b 1212 if (Failed == true)
b2e465d6
AL
1213 return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
1214
0919e3f9 1215 return true;
0a8e3465
AL
1216}
1217 /*}}}*/
1218// DoUpgrade - Upgrade all packages /*{{{*/
1219// ---------------------------------------------------------------------
1220/* Upgrade all packages without installing new packages or erasing old
1221 packages */
1222bool DoUpgrade(CommandLine &CmdL)
1223{
1224 CacheFile Cache;
c37b9502 1225 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
0a8e3465
AL
1226 return false;
1227
1228 // Do the upgrade
0a8e3465
AL
1229 if (pkgAllUpgrade(Cache) == false)
1230 {
421c8d10 1231 ShowBroken(c1out,Cache,false);
b2e465d6 1232 return _error->Error(_("Internal Error, AllUpgrade broke stuff"));
0a8e3465
AL
1233 }
1234
1235 return InstallPackages(Cache,true);
1236}
1237 /*}}}*/
1238// DoInstall - Install packages from the command line /*{{{*/
1239// ---------------------------------------------------------------------
1240/* Install named packages */
1241bool DoInstall(CommandLine &CmdL)
1242{
1243 CacheFile Cache;
c37b9502
AL
1244 if (Cache.OpenForInstall() == false ||
1245 Cache.CheckDeps(CmdL.FileSize() != 1) == false)
0a8e3465
AL
1246 return false;
1247
7c57fe64
AL
1248 // Enter the special broken fixing mode if the user specified arguments
1249 bool BrokenFix = false;
1250 if (Cache->BrokenCount() != 0)
1251 BrokenFix = true;
1252
a6568219
AL
1253 unsigned int ExpectedInst = 0;
1254 unsigned int Packages = 0;
0a8e3465
AL
1255 pkgProblemResolver Fix(Cache);
1256
303a1703
AL
1257 bool DefRemove = false;
1258 if (strcasecmp(CmdL.FileList[0],"remove") == 0)
1259 DefRemove = true;
b2e465d6 1260
0a8e3465
AL
1261 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
1262 {
1263 // Duplicate the string
1264 unsigned int Length = strlen(*I);
1265 char S[300];
1266 if (Length >= sizeof(S))
1267 continue;
1268 strcpy(S,*I);
1269
b2e465d6 1270 // See if we are removing and special indicators..
303a1703 1271 bool Remove = DefRemove;
b2e465d6
AL
1272 char *VerTag = 0;
1273 bool VerIsRel = false;
fc4b5c9f 1274 while (Cache->FindPkg(S).end() == true)
0a8e3465 1275 {
2c3bc8bb
AL
1276 // Handle an optional end tag indicating what to do
1277 if (S[Length - 1] == '-')
1278 {
1279 Remove = true;
1280 S[--Length] = 0;
fc4b5c9f 1281 continue;
2c3bc8bb 1282 }
fc4b5c9f 1283
2c3bc8bb
AL
1284 if (S[Length - 1] == '+')
1285 {
1286 Remove = false;
1287 S[--Length] = 0;
fc4b5c9f 1288 continue;
2c3bc8bb 1289 }
b2e465d6
AL
1290
1291 char *Slash = strchr(S,'=');
1292 if (Slash != 0)
1293 {
1294 VerIsRel = false;
1295 *Slash = 0;
1296 VerTag = Slash + 1;
1297 }
1298
1299 Slash = strchr(S,'/');
1300 if (Slash != 0)
1301 {
1302 VerIsRel = true;
1303 *Slash = 0;
1304 VerTag = Slash + 1;
1305 }
1306
fc4b5c9f 1307 break;
303a1703 1308 }
0a8e3465
AL
1309
1310 // Locate the package
1311 pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
303a1703 1312 Packages++;
0a8e3465 1313 if (Pkg.end() == true)
2c3bc8bb 1314 {
c373c37a
AL
1315 // Check if the name is a regex
1316 const char *I;
1317 for (I = S; *I != 0; I++)
b2e465d6 1318 if (*I == '.' || *I == '?' || *I == '*' || *I == '|')
c373c37a
AL
1319 break;
1320 if (*I == 0)
b2e465d6 1321 return _error->Error(_("Couldn't find package %s"),S);
303a1703 1322
c373c37a
AL
1323 // Regexs must always be confirmed
1324 ExpectedInst += 1000;
1325
1326 // Compile the regex pattern
1327 regex_t Pattern;
b2e465d6
AL
1328 int Res;
1329 if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE |
1330 REG_NOSUB)) != 0)
1331 {
1332 char Error[300];
1333 regerror(Res,&Pattern,Error,sizeof(Error));
1334 return _error->Error(_("Regex compilation error - %s"),Error);
1335 }
c373c37a
AL
1336
1337 // Run over the matches
1338 bool Hit = false;
1339 for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++)
303a1703 1340 {
c373c37a
AL
1341 if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0)
1342 continue;
07801a6d 1343
b2e465d6
AL
1344 if (VerTag != 0)
1345 if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
1346 return false;
1347
c373c37a
AL
1348 Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
1349 ExpectedInst,false);
303a1703 1350 }
c373c37a 1351 regfree(&Pattern);
303a1703 1352
c373c37a 1353 if (Hit == false)
b2e465d6 1354 return _error->Error(_("Couldn't find package %s"),S);
0a8e3465 1355 }
0a8e3465 1356 else
c373c37a 1357 {
b2e465d6
AL
1358 if (VerTag != 0)
1359 if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
1360 return false;
c373c37a
AL
1361 if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
1362 return false;
1363 }
0a8e3465
AL
1364 }
1365
7c57fe64
AL
1366 /* If we are in the Broken fixing mode we do not attempt to fix the
1367 problems. This is if the user invoked install without -f and gave
1368 packages */
1369 if (BrokenFix == true && Cache->BrokenCount() != 0)
1370 {
b2e465d6 1371 c1out << _("You might want to run `apt-get -f install' to correct these:") << endl;
421c8d10 1372 ShowBroken(c1out,Cache,false);
7c57fe64 1373
b2e465d6 1374 return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
7c57fe64
AL
1375 }
1376
0a8e3465 1377 // Call the scored problem resolver
303a1703 1378 Fix.InstallProtect();
0a8e3465
AL
1379 if (Fix.Resolve(true) == false)
1380 _error->Discard();
1381
1382 // Now we check the state of the packages,
1383 if (Cache->BrokenCount() != 0)
1384 {
b2e465d6
AL
1385 c1out <<
1386 _("Some packages could not be installed. This may mean that you have\n"
1387 "requested an impossible situation or if you are using the unstable\n"
1388 "distribution that some required packages have not yet been created\n"
1389 "or been moved out of Incoming.") << endl;
303a1703
AL
1390 if (Packages == 1)
1391 {
1392 c1out << endl;
b2e465d6
AL
1393 c1out <<
1394 _("Since you only requested a single operation it is extremely likely that\n"
1395 "the package is simply not installable and a bug report against\n"
1396 "that package should be filed.") << endl;
303a1703
AL
1397 }
1398
b2e465d6 1399 c1out << _("The following information may help to resolve the situation:") << endl;
303a1703 1400 c1out << endl;
421c8d10 1401 ShowBroken(c1out,Cache,false);
b2e465d6 1402 return _error->Error(_("Sorry, broken packages"));
0a8e3465
AL
1403 }
1404
1405 /* Print out a list of packages that are going to be installed extra
1406 to what the user asked */
1407 if (Cache->InstCount() != ExpectedInst)
1408 {
1409 string List;
1089ca89 1410 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
0a8e3465 1411 {
1089ca89 1412 pkgCache::PkgIterator I(Cache,Cache.List[J]);
0a8e3465
AL
1413 if ((*Cache)[I].Install() == false)
1414 continue;
1415
1416 const char **J;
1417 for (J = CmdL.FileList + 1; *J != 0; J++)
1418 if (strcmp(*J,I.Name()) == 0)
1419 break;
1420
1421 if (*J == 0)
1422 List += string(I.Name()) + " ";
1423 }
1424
b2e465d6 1425 ShowList(c1out,_("The following extra packages will be installed:"),List);
0a8e3465
AL
1426 }
1427
03e39e59 1428 // See if we need to prompt
2c3bc8bb 1429 if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
2c3bc8bb 1430 return InstallPackages(Cache,false,false);
2c3bc8bb 1431
03e39e59 1432 return InstallPackages(Cache,false);
0a8e3465
AL
1433}
1434 /*}}}*/
1435// DoDistUpgrade - Automatic smart upgrader /*{{{*/
1436// ---------------------------------------------------------------------
1437/* Intelligent upgrader that will install and remove packages at will */
1438bool DoDistUpgrade(CommandLine &CmdL)
1439{
1440 CacheFile Cache;
c37b9502 1441 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
0a8e3465
AL
1442 return false;
1443
b2e465d6 1444 c0out << _("Calculating Upgrade... ") << flush;
0a8e3465
AL
1445 if (pkgDistUpgrade(*Cache) == false)
1446 {
b2e465d6 1447 c0out << _("Failed") << endl;
421c8d10 1448 ShowBroken(c1out,Cache,false);
0a8e3465
AL
1449 return false;
1450 }
1451
b2e465d6 1452 c0out << _("Done") << endl;
0a8e3465
AL
1453
1454 return InstallPackages(Cache,true);
1455}
1456 /*}}}*/
1457// DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
1458// ---------------------------------------------------------------------
1459/* Follows dselect's selections */
1460bool DoDSelectUpgrade(CommandLine &CmdL)
1461{
1462 CacheFile Cache;
c37b9502 1463 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
0a8e3465
AL
1464 return false;
1465
1466 // Install everything with the install flag set
1467 pkgCache::PkgIterator I = Cache->PkgBegin();
1468 for (;I.end() != true; I++)
1469 {
1470 /* Install the package only if it is a new install, the autoupgrader
1471 will deal with the rest */
1472 if (I->SelectedState == pkgCache::State::Install)
1473 Cache->MarkInstall(I,false);
1474 }
1475
1476 /* Now install their deps too, if we do this above then order of
1477 the status file is significant for | groups */
1478 for (I = Cache->PkgBegin();I.end() != true; I++)
1479 {
1480 /* Install the package only if it is a new install, the autoupgrader
1481 will deal with the rest */
1482 if (I->SelectedState == pkgCache::State::Install)
2f45c76a 1483 Cache->MarkInstall(I,true);
0a8e3465
AL
1484 }
1485
1486 // Apply erasures now, they override everything else.
1487 for (I = Cache->PkgBegin();I.end() != true; I++)
1488 {
1489 // Remove packages
1490 if (I->SelectedState == pkgCache::State::DeInstall ||
1491 I->SelectedState == pkgCache::State::Purge)
d556d1a1 1492 Cache->MarkDelete(I,I->SelectedState == pkgCache::State::Purge);
0a8e3465
AL
1493 }
1494
2f45c76a
AL
1495 /* Resolve any problems that dselect created, allupgrade cannot handle
1496 such things. We do so quite agressively too.. */
1497 if (Cache->BrokenCount() != 0)
1498 {
1499 pkgProblemResolver Fix(Cache);
1500
1501 // Hold back held packages.
b2e465d6 1502 if (_config->FindB("APT::Ignore-Hold",false) == false)
2f45c76a
AL
1503 {
1504 for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++)
1505 {
1506 if (I->SelectedState == pkgCache::State::Hold)
1507 {
1508 Fix.Protect(I);
1509 Cache->MarkKeep(I);
1510 }
1511 }
1512 }
1513
1514 if (Fix.Resolve() == false)
1515 {
421c8d10 1516 ShowBroken(c1out,Cache,false);
2f45c76a
AL
1517 return _error->Error("Internal Error, problem resolver broke stuff");
1518 }
1519 }
1520
1521 // Now upgrade everything
0a8e3465
AL
1522 if (pkgAllUpgrade(Cache) == false)
1523 {
421c8d10 1524 ShowBroken(c1out,Cache,false);
2f45c76a 1525 return _error->Error("Internal Error, problem resolver broke stuff");
0a8e3465
AL
1526 }
1527
1528 return InstallPackages(Cache,false);
1529}
1530 /*}}}*/
1531// DoClean - Remove download archives /*{{{*/
1532// ---------------------------------------------------------------------
1533/* */
1534bool DoClean(CommandLine &CmdL)
1535{
8b067c22
AL
1536 if (_config->FindB("APT::Get::Simulate") == true)
1537 {
1538 cout << "Del " << _config->FindDir("Dir::Cache::archives") << "* " <<
1539 _config->FindDir("Dir::Cache::archives") << "partial/*" << endl;
1540 return true;
1541 }
1542
1b6d659c
AL
1543 // Lock the archive directory
1544 FileFd Lock;
1545 if (_config->FindB("Debug::NoLocking",false) == false)
1546 {
1547 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1548 if (_error->PendingError() == true)
b2e465d6 1549 return _error->Error(_("Unable to lock the download directory"));
1b6d659c
AL
1550 }
1551
7a1b1f8b
AL
1552 pkgAcquire Fetcher;
1553 Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
1554 Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
0a8e3465
AL
1555 return true;
1556}
1557 /*}}}*/
1bc849af
AL
1558// DoAutoClean - Smartly remove downloaded archives /*{{{*/
1559// ---------------------------------------------------------------------
1560/* This is similar to clean but it only purges things that cannot be
1561 downloaded, that is old versions of cached packages. */
65a1e968
AL
1562class LogCleaner : public pkgArchiveCleaner
1563{
1564 protected:
1565 virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St)
1566 {
4cc8bab0 1567 c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << endl;
c1e78ee5
AL
1568
1569 if (_config->FindB("APT::Get::Simulate") == false)
1570 unlink(File);
65a1e968
AL
1571 };
1572};
1573
1bc849af
AL
1574bool DoAutoClean(CommandLine &CmdL)
1575{
1b6d659c
AL
1576 // Lock the archive directory
1577 FileFd Lock;
1578 if (_config->FindB("Debug::NoLocking",false) == false)
1579 {
1580 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1581 if (_error->PendingError() == true)
b2e465d6 1582 return _error->Error(_("Unable to lock the download directory"));
1b6d659c
AL
1583 }
1584
1bc849af 1585 CacheFile Cache;
2d11135a 1586 if (Cache.Open() == false)
1bc849af
AL
1587 return false;
1588
65a1e968 1589 LogCleaner Cleaner;
1bc849af
AL
1590
1591 return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) &&
1592 Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache);
1593}
1594 /*}}}*/
0a8e3465
AL
1595// DoCheck - Perform the check operation /*{{{*/
1596// ---------------------------------------------------------------------
1597/* Opening automatically checks the system, this command is mostly used
1598 for debugging */
1599bool DoCheck(CommandLine &CmdL)
1600{
1601 CacheFile Cache;
1602 Cache.Open();
2d11135a 1603 Cache.CheckDeps();
0a8e3465
AL
1604
1605 return true;
1606}
1607 /*}}}*/
36375005
AL
1608// DoSource - Fetch a source archive /*{{{*/
1609// ---------------------------------------------------------------------
2d11135a 1610/* Fetch souce packages */
fb0ee66e
AL
1611struct DscFile
1612{
1613 string Package;
1614 string Version;
1615 string Dsc;
1616};
1617
36375005
AL
1618bool DoSource(CommandLine &CmdL)
1619{
1620 CacheFile Cache;
2d11135a 1621 if (Cache.Open(false) == false)
36375005
AL
1622 return false;
1623
2d11135a 1624 if (CmdL.FileSize() <= 1)
b2e465d6 1625 return _error->Error(_("Must specify at least one package to fetch source for"));
2d11135a 1626
36375005
AL
1627 // Read the source list
1628 pkgSourceList List;
1629 if (List.ReadMainList() == false)
b2e465d6 1630 return _error->Error(_("The list of sources could not be read."));
36375005
AL
1631
1632 // Create the text record parsers
1633 pkgRecords Recs(Cache);
1634 pkgSrcRecords SrcRecs(List);
1635 if (_error->PendingError() == true)
1636 return false;
1637
1638 // Create the download object
1639 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1640 pkgAcquire Fetcher(&Stat);
fb0ee66e
AL
1641
1642 DscFile *Dsc = new DscFile[CmdL.FileSize()];
36375005
AL
1643
1644 // Load the requestd sources into the fetcher
fb0ee66e
AL
1645 unsigned J = 0;
1646 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
36375005
AL
1647 {
1648 string Src;
b2e465d6 1649 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
36375005
AL
1650
1651 if (Last == 0)
b2e465d6 1652 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
36375005
AL
1653
1654 // Back track
1655 vector<pkgSrcRecords::File> Lst;
b2e465d6 1656 if (Last->Files(Lst) == false)
36375005
AL
1657 return false;
1658
1659 // Load them into the fetcher
1660 for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
1661 I != Lst.end(); I++)
1662 {
1663 // Try to guess what sort of file it is we are getting.
b2e465d6 1664 if (I->Type == "dsc")
fb0ee66e 1665 {
fb0ee66e
AL
1666 Dsc[J].Package = Last->Package();
1667 Dsc[J].Version = Last->Version();
1668 Dsc[J].Dsc = flNotDir(I->Path);
1669 }
1670
17c0e8e1
AL
1671 // Diff only mode only fetches .diff files
1672 if (_config->FindB("APT::Get::Diff-Only",false) == true &&
b2e465d6 1673 I->Type != "diff")
17c0e8e1
AL
1674 continue;
1675
1676 // Tar only mode only fetches .tar files
1677 if (_config->FindB("APT::Get::Tar-Only",false) == true &&
b2e465d6 1678 I->Type != "tar")
17c0e8e1
AL
1679 continue;
1680
b2e465d6
AL
1681 new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path),
1682 I->MD5Hash,I->Size,
1683 Last->Index().SourceInfo(*Last,*I),Src);
36375005
AL
1684 }
1685 }
1686
1687 // Display statistics
b2e465d6
AL
1688 double FetchBytes = Fetcher.FetchNeeded();
1689 double FetchPBytes = Fetcher.PartialPresent();
1690 double DebBytes = Fetcher.TotalNeeded();
36375005
AL
1691
1692 // Check for enough free space
f332b62b 1693 struct statvfs Buf;
36375005 1694 string OutputDir = ".";
f332b62b
AL
1695 if (statvfs(OutputDir.c_str(),&Buf) != 0)
1696 return _error->Errno("statvfs","Couldn't determine free space in %s",
36375005
AL
1697 OutputDir.c_str());
1698 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
b2e465d6 1699 return _error->Error(_("Sorry, you don't have enough free space in %s"),
36375005
AL
1700 OutputDir.c_str());
1701
1702 // Number of bytes
36375005 1703 if (DebBytes != FetchBytes)
b2e465d6
AL
1704 ioprintf(c1out,_("Need to get %sB/%sB of source archives.\n"),
1705 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
36375005 1706 else
b2e465d6
AL
1707 ioprintf(c1out,_("Need to get %sB of source archives.\n"),
1708 SizeToStr(DebBytes).c_str());
1709
2c0c53b3
AL
1710 if (_config->FindB("APT::Get::Simulate",false) == true)
1711 {
1712 for (unsigned I = 0; I != J; I++)
b2e465d6 1713 ioprintf(cout,_("Fetch Source %s\n"),Dsc[I].Package.c_str());
2c0c53b3
AL
1714 return true;
1715 }
1716
36375005
AL
1717 // Just print out the uris an exit if the --print-uris flag was used
1718 if (_config->FindB("APT::Get::Print-URIs") == true)
1719 {
1720 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1721 for (; I != Fetcher.UriEnd(); I++)
1722 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1723 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
1724 return true;
1725 }
1726
1727 // Run it
024d1123 1728 if (Fetcher.Run() == pkgAcquire::Failed)
36375005
AL
1729 return false;
1730
1731 // Print error messages
fb0ee66e 1732 bool Failed = false;
076d01b0 1733 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
36375005
AL
1734 {
1735 if ((*I)->Status == pkgAcquire::Item::StatDone &&
1736 (*I)->Complete == true)
1737 continue;
1738
b2e465d6
AL
1739 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1740 (*I)->ErrorText.c_str());
fb0ee66e 1741 Failed = true;
36375005 1742 }
fb0ee66e 1743 if (Failed == true)
b2e465d6 1744 return _error->Error(_("Failed to fetch some archives."));
fb0ee66e
AL
1745
1746 if (_config->FindB("APT::Get::Download-only",false) == true)
b2e465d6
AL
1747 {
1748 c1out << _("Download complete and in download only mode") << endl;
fb0ee66e 1749 return true;
b2e465d6
AL
1750 }
1751
fb0ee66e 1752 // Unpack the sources
54676e1a
AL
1753 pid_t Process = ExecFork();
1754
1755 if (Process == 0)
fb0ee66e 1756 {
54676e1a 1757 for (unsigned I = 0; I != J; I++)
fb0ee66e 1758 {
b2e465d6 1759 string Dir = Dsc[I].Package + '-' + Cache->VS().UpstreamVersion(Dsc[I].Version.c_str());
fb0ee66e 1760
17c0e8e1
AL
1761 // Diff only mode only fetches .diff files
1762 if (_config->FindB("APT::Get::Diff-Only",false) == true ||
a3eaf954
AL
1763 _config->FindB("APT::Get::Tar-Only",false) == true ||
1764 Dsc[I].Dsc.empty() == true)
17c0e8e1 1765 continue;
a3eaf954 1766
54676e1a
AL
1767 // See if the package is already unpacked
1768 struct stat Stat;
1769 if (stat(Dir.c_str(),&Stat) == 0 &&
1770 S_ISDIR(Stat.st_mode) != 0)
1771 {
b2e465d6
AL
1772 ioprintf(c0out ,_("Skipping unpack of already unpacked source in %s\n"),
1773 Dir.c_str());
54676e1a
AL
1774 }
1775 else
1776 {
1777 // Call dpkg-source
1778 char S[500];
1779 snprintf(S,sizeof(S),"%s -x %s",
1780 _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
1781 Dsc[I].Dsc.c_str());
1782 if (system(S) != 0)
1783 {
b2e465d6 1784 fprintf(stderr,_("Unpack command '%s' failed.\n"),S);
54676e1a
AL
1785 _exit(1);
1786 }
1787 }
1788
1789 // Try to compile it with dpkg-buildpackage
1790 if (_config->FindB("APT::Get::Compile",false) == true)
1791 {
1792 // Call dpkg-buildpackage
1793 char S[500];
1794 snprintf(S,sizeof(S),"cd %s && %s %s",
1795 Dir.c_str(),
1796 _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
1797 _config->Find("DPkg::Build-Options","-b -uc").c_str());
1798
1799 if (system(S) != 0)
1800 {
b2e465d6 1801 fprintf(stderr,_("Build command '%s' failed.\n"),S);
54676e1a
AL
1802 _exit(1);
1803 }
1804 }
1805 }
1806
1807 _exit(0);
1808 }
1809
1810 // Wait for the subprocess
1811 int Status = 0;
1812 while (waitpid(Process,&Status,0) != Process)
1813 {
1814 if (errno == EINTR)
1815 continue;
1816 return _error->Errno("waitpid","Couldn't wait for subprocess");
1817 }
1818
1819 if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
b2e465d6
AL
1820 return _error->Error(_("Child process failed"));
1821
1822 return true;
1823}
1824 /*}}}*/
1825// DoBuildDep - Install/removes packages to satisfy build dependencies /*{{{*/
1826// ---------------------------------------------------------------------
1827/* This function will look at the build depends list of the given source
1828 package and install the necessary packages to make it true, or fail. */
1829bool DoBuildDep(CommandLine &CmdL)
1830{
1831 CacheFile Cache;
1832 if (Cache.Open(true) == false)
1833 return false;
1834
1835 if (CmdL.FileSize() <= 1)
1836 return _error->Error(_("Must specify at least one package to check builddeps for"));
1837
1838 // Read the source list
1839 pkgSourceList List;
1840 if (List.ReadMainList() == false)
1841 return _error->Error(_("The list of sources could not be read."));
54676e1a 1842
b2e465d6
AL
1843 // Create the text record parsers
1844 pkgRecords Recs(Cache);
1845 pkgSrcRecords SrcRecs(List);
1846 if (_error->PendingError() == true)
1847 return false;
1848
1849 // Create the download object
1850 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1851 pkgAcquire Fetcher(&Stat);
1852
1853 unsigned J = 0;
1854 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
1855 {
1856 string Src;
1857 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
1858 if (Last == 0)
1859 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
1860
1861 // Process the build-dependencies
1862 vector<pkgSrcRecords::Parser::BuildDepRec> BuildDeps;
45430cbf 1863 if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only",false)) == false)
b2e465d6
AL
1864 return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str());
1865
7d6f9f8f
AL
1866 // Also ensure that build-essential packages are present
1867 Configuration::Item const *Opts = _config->Tree("APT::Build-Essential");
1868 if (Opts)
1869 Opts = Opts->Child;
1870 for (; Opts; Opts = Opts->Next)
1871 {
1872 if (Opts->Value.empty() == true)
1873 continue;
1874
1875 pkgSrcRecords::Parser::BuildDepRec rec;
1876 rec.Package = Opts->Value;
1877 rec.Type = pkgSrcRecords::Parser::BuildDependIndep;
1878 rec.Op = 0;
1879 BuildDeps.insert(BuildDeps.begin(), rec);
1880 }
1881
b2e465d6
AL
1882 if (BuildDeps.size() == 0)
1883 {
1884 ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
1885 continue;
1886 }
1887
1888 // Install the requested packages
1889 unsigned int ExpectedInst = 0;
1890 vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
1891 pkgProblemResolver Fix(Cache);
1892 for (D = BuildDeps.begin(); D != BuildDeps.end(); D++)
1893 {
1894 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
1895 if (Pkg.end() == true)
d3fc0061
AL
1896 {
1897 /* for a build-conflict; ignore unknown packages */
1898 if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
1899 (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
1900 continue;
1901
b2e465d6
AL
1902 return _error->Error(_("%s dependency on %s cannot be satisfied because the package %s cannot be found"),
1903 Last->BuildDepType((*D).Type),Src.c_str(),(*D).Package.c_str());
d3fc0061 1904 }
b2e465d6
AL
1905 pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
1906
1907 if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
1908 (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
1909 {
cfa5659c
AL
1910 /*
1911 * conflict; need to remove if we have an installed version
1912 * that satisfies the version criterial
1913 */
b2e465d6
AL
1914 if (IV.end() == false &&
1915 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
1916 TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
1917 }
1918 else
1919 {
cfa5659c
AL
1920 /*
1921 * If this is a virtual package, we need to check the list of
1922 * packages that provide it and see if any of those are
1923 * installed
1924 */
1925 pkgCache::PrvIterator Prv = Pkg.ProvidesList();
1926 for (; Prv.end() != true; Prv++)
1927 if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
1928 break;
1929
1930 if (Prv.end() == true)
1931 {
1932 /*
1933 * depends; need to install or upgrade if we don't have the
1934 * package installed or if the version does not satisfy the
1935 * build dep. This is complicated by the fact that if we
1936 * depend on a version lower than what we already have
1937 * installed it is not clear what should be done; in practice
1938 * this case should be rare though and right now nothing
1939 * is done about it :-(
1940 */
1941 if (IV.end() == true ||
1942 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == false)
1943 TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst);
1944 }
b2e465d6
AL
1945 }
1946 }
1947
1948 Fix.InstallProtect();
1949 if (Fix.Resolve(true) == false)
1950 _error->Discard();
1951
1952 // Now we check the state of the packages,
1953 if (Cache->BrokenCount() != 0)
1954 return _error->Error(_("Some broken packages were found while trying to process build-dependencies.\n"
1955 "You might want to run `apt-get -f install' to correct these."));
1956 }
1957
1958 if (InstallPackages(Cache, false, true) == false)
1959 return _error->Error(_("Failed to process build dependencies"));
36375005
AL
1960 return true;
1961}
1962 /*}}}*/
1963
b2e465d6
AL
1964// DoMoo - Never Ask, Never Tell /*{{{*/
1965// ---------------------------------------------------------------------
1966/* */
1967bool DoMoo(CommandLine &CmdL)
1968{
1969 cout <<
1970 " (__) \n"
1971 " (oo) \n"
1972 " /------\\/ \n"
1973 " / | || \n"
1974 " * /\\---/\\ \n"
1975 " ~~ ~~ \n"
1976 "....\"Have you mooed today?\"...\n";
1977
1978 return true;
1979}
1980 /*}}}*/
0a8e3465
AL
1981// ShowHelp - Show a help screen /*{{{*/
1982// ---------------------------------------------------------------------
1983/* */
212ad54a 1984bool ShowHelp(CommandLine &CmdL)
0a8e3465 1985{
b2e465d6
AL
1986 ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
1987 COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
1988
04aa15a8 1989 if (_config->FindB("version") == true)
b2e465d6
AL
1990 {
1991 cout << _("Supported Modules:") << endl;
1992
1993 for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++)
1994 {
1995 pkgVersioningSystem *VS = pkgVersioningSystem::GlobalList[I];
1996 if (_system != 0 && _system->VS == VS)
1997 cout << '*';
1998 else
1999 cout << ' ';
2000 cout << "Ver: " << VS->Label << endl;
2001
2002 /* Print out all the packaging systems that will work with
2003 this VS */
2004 for (unsigned J = 0; J != pkgSystem::GlobalListLen; J++)
2005 {
2006 pkgSystem *Sys = pkgSystem::GlobalList[J];
2007 if (_system == Sys)
2008 cout << '*';
2009 else
2010 cout << ' ';
2011 if (Sys->VS->TestCompatibility(*VS) == true)
2012 cout << "Pkg: " << Sys->Label << " (Priority " << Sys->Score(*_config) << ")" << endl;
2013 }
2014 }
2015
2016 for (unsigned I = 0; I != pkgSourceList::Type::GlobalListLen; I++)
2017 {
2018 pkgSourceList::Type *Type = pkgSourceList::Type::GlobalList[I];
2019 cout << " S.L: '" << Type->Name << "' " << Type->Label << endl;
2020 }
2021
2022 for (unsigned I = 0; I != pkgIndexFile::Type::GlobalListLen; I++)
2023 {
2024 pkgIndexFile::Type *Type = pkgIndexFile::Type::GlobalList[I];
2025 cout << " Idx: " << Type->Label << endl;
2026 }
2027
2028 return true;
2029 }
2030
2031 cout <<
2032 _("Usage: apt-get [options] command\n"
2033 " apt-get [options] install|remove pkg1 [pkg2 ...]\n"
2034 " apt-get [options] source pkg1 [pkg2 ...]\n"
2035 "\n"
2036 "apt-get is a simple command line interface for downloading and\n"
2037 "installing packages. The most frequently used commands are update\n"
2038 "and install.\n"
2039 "\n"
2040 "Commands:\n"
2041 " update - Retrieve new lists of packages\n"
2042 " upgrade - Perform an upgrade\n"
2043 " install - Install new packages (pkg is libc6 not libc6.deb)\n"
2044 " remove - Remove packages\n"
2045 " source - Download source archives\n"
2046 " build-dep - Configure build-dependencies for source packages\n"
2047 " dist-upgrade - Distribution upgrade, see apt-get(8)\n"
2048 " dselect-upgrade - Follow dselect selections\n"
2049 " clean - Erase downloaded archive files\n"
2050 " autoclean - Erase old downloaded archive files\n"
2051 " check - Verify that there are no broken dependencies\n"
2052 "\n"
2053 "Options:\n"
2054 " -h This help text.\n"
2055 " -q Loggable output - no progress indicator\n"
2056 " -qq No output except for errors\n"
2057 " -d Download only - do NOT install or unpack archives\n"
2058 " -s No-act. Perform ordering simulation\n"
2059 " -y Assume Yes to all queries and do not prompt\n"
2060 " -f Attempt to continue if the integrity check fails\n"
2061 " -m Attempt to continue if archives are unlocatable\n"
2062 " -u Show a list of upgraded packages as well\n"
2063 " -b Build the source package after fetching it\n"
2064 " -c=? Read this configuration file\n"
2065 " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp\n"
2066 "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n"
2067 "pages for more information and options.\n"
2068 " This APT has Super Cow Powers.\n");
2069 return true;
0a8e3465
AL
2070}
2071 /*}}}*/
2072// GetInitialize - Initialize things for apt-get /*{{{*/
2073// ---------------------------------------------------------------------
2074/* */
2075void GetInitialize()
2076{
2077 _config->Set("quiet",0);
2078 _config->Set("help",false);
2079 _config->Set("APT::Get::Download-Only",false);
2080 _config->Set("APT::Get::Simulate",false);
2081 _config->Set("APT::Get::Assume-Yes",false);
2082 _config->Set("APT::Get::Fix-Broken",false);
83d89a9f 2083 _config->Set("APT::Get::Force-Yes",false);
9df71a5b 2084 _config->Set("APT::Get::APT::Get::No-List-Cleanup",true);
0a8e3465
AL
2085}
2086 /*}}}*/
d7827aca
AL
2087// SigWinch - Window size change signal handler /*{{{*/
2088// ---------------------------------------------------------------------
2089/* */
2090void SigWinch(int)
2091{
2092 // Riped from GNU ls
2093#ifdef TIOCGWINSZ
2094 struct winsize ws;
2095
2096 if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
2097 ScreenWidth = ws.ws_col - 1;
2098#endif
2099}
2100 /*}}}*/
0a8e3465
AL
2101
2102int main(int argc,const char *argv[])
2103{
2104 CommandLine::Args Args[] = {
2105 {'h',"help","help",0},
04aa15a8 2106 {'v',"version","version",0},
0a8e3465
AL
2107 {'q',"quiet","quiet",CommandLine::IntLevel},
2108 {'q',"silent","quiet",CommandLine::IntLevel},
2109 {'d',"download-only","APT::Get::Download-Only",0},
fb0ee66e
AL
2110 {'b',"compile","APT::Get::Compile",0},
2111 {'b',"build","APT::Get::Compile",0},
d150b09d
AL
2112 {'s',"simulate","APT::Get::Simulate",0},
2113 {'s',"just-print","APT::Get::Simulate",0},
2114 {'s',"recon","APT::Get::Simulate",0},
6df23d2f 2115 {'s',"dry-run","APT::Get::Simulate",0},
d150b09d
AL
2116 {'s',"no-act","APT::Get::Simulate",0},
2117 {'y',"yes","APT::Get::Assume-Yes",0},
0a8e3465
AL
2118 {'y',"assume-yes","APT::Get::Assume-Yes",0},
2119 {'f',"fix-broken","APT::Get::Fix-Broken",0},
2120 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
30e1eab5 2121 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
b2e465d6
AL
2122 {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
2123 {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
2124 {0,"download","APT::Get::Download",0},
30e1eab5 2125 {0,"fix-missing","APT::Get::Fix-Missing",0},
b2e465d6
AL
2126 {0,"ignore-hold","APT::Ignore-Hold",0},
2127 {0,"upgrade","APT::Get::upgrade",0},
83d89a9f 2128 {0,"force-yes","APT::Get::force-yes",0},
f7a08e33 2129 {0,"print-uris","APT::Get::Print-URIs",0},
5fafc0ef
AL
2130 {0,"diff-only","APT::Get::Diff-Only",0},
2131 {0,"tar-only","APT::Get::tar-Only",0},
fc4b5c9f 2132 {0,"purge","APT::Get::Purge",0},
9df71a5b 2133 {0,"list-cleanup","APT::Get::List-Cleanup",0},
d0c59649 2134 {0,"reinstall","APT::Get::ReInstall",0},
d150b09d 2135 {0,"trivial-only","APT::Get::Trivial-Only",0},
b2e465d6
AL
2136 {0,"remove","APT::Get::Remove",0},
2137 {0,"only-source","APT::Get::Only-Source",0},
45430cbf 2138 {0,"arch-only","APT::Get::Arch-Only",0},
0a8e3465
AL
2139 {'c',"config-file",0,CommandLine::ConfigFile},
2140 {'o',"option",0,CommandLine::ArbItem},
2141 {0,0,0,0}};
83d89a9f
AL
2142 CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
2143 {"upgrade",&DoUpgrade},
2144 {"install",&DoInstall},
2145 {"remove",&DoInstall},
2146 {"dist-upgrade",&DoDistUpgrade},
2147 {"dselect-upgrade",&DoDSelectUpgrade},
b2e465d6 2148 {"build-dep",&DoBuildDep},
83d89a9f 2149 {"clean",&DoClean},
1bc849af 2150 {"autoclean",&DoAutoClean},
83d89a9f 2151 {"check",&DoCheck},
36375005 2152 {"source",&DoSource},
b2e465d6 2153 {"moo",&DoMoo},
3d615484 2154 {"help",&ShowHelp},
83d89a9f 2155 {0,0}};
0a8e3465
AL
2156
2157 // Parse the command line and initialize the package library
2158 CommandLine CmdL(Args,_config);
b2e465d6
AL
2159 if (pkgInitConfig(*_config) == false ||
2160 CmdL.Parse(argc,argv) == false ||
2161 pkgInitSystem(*_config,_system) == false)
0a8e3465 2162 {
b2e465d6
AL
2163 if (_config->FindB("version") == true)
2164 ShowHelp(CmdL);
2165
0a8e3465
AL
2166 _error->DumpErrors();
2167 return 100;
2168 }
2169
2170 // See if the help should be shown
2171 if (_config->FindB("help") == true ||
04aa15a8 2172 _config->FindB("version") == true ||
0a8e3465 2173 CmdL.FileSize() == 0)
b2e465d6
AL
2174 {
2175 ShowHelp(CmdL);
2176 return 0;
2177 }
67ff87bf 2178
a9a5908d
AL
2179 // Deal with stdout not being a tty
2180 if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
2181 _config->Set("quiet","1");
01b64152 2182
0a8e3465
AL
2183 // Setup the output streams
2184 c0out.rdbuf(cout.rdbuf());
2185 c1out.rdbuf(cout.rdbuf());
2186 c2out.rdbuf(cout.rdbuf());
2187 if (_config->FindI("quiet",0) > 0)
2188 c0out.rdbuf(devnull.rdbuf());
2189 if (_config->FindI("quiet",0) > 1)
2190 c1out.rdbuf(devnull.rdbuf());
d7827aca
AL
2191
2192 // Setup the signals
2193 signal(SIGPIPE,SIG_IGN);
2194 signal(SIGWINCH,SigWinch);
2195 SigWinch(0);
b2e465d6 2196
0a8e3465 2197 // Match the operation
83d89a9f 2198 CmdL.DispatchArg(Cmds);
0a8e3465
AL
2199
2200 // Print any errors or warnings found during parsing
2201 if (_error->empty() == false)
2202 {
2203 bool Errors = _error->PendingError();
2204 _error->DumpErrors();
0a8e3465
AL
2205 return Errors == true?100:0;
2206 }
2207
2208 return 0;
2209}