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