]> git.saurik.com Git - apt.git/blame - cmdline/apt-get.cc
Added wakko{jgg}~#cd work/ap
[apt.git] / cmdline / apt-get.cc
CommitLineData
5ec427c2
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
233c2b66 3// $Id: apt-get.cc,v 1.114 2002/02/15 03:40:00 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>
0a8e3465 49#include <fstream.h>
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
b2e465d6
AL
515 ioprintf(out,_("%lu to remove and %lu not upgraded.\n"),
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 */
725 if (_config->FindB("APT::Get::Print-URIs") == false)
726 {
727 struct statvfs Buf;
728 string OutputDir = _config->FindDir("Dir::Cache::Archives");
729 if (statvfs(OutputDir.c_str(),&Buf) != 0)
730 return _error->Errno("statvfs","Couldn't determine free space in %s",
731 OutputDir.c_str());
732 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
b2e465d6 733 return _error->Error(_("Sorry, you don't have enough free space in %s to hold all the .debs."),
01b64152
AL
734 OutputDir.c_str());
735 }
736
83d89a9f 737 // Fail safe check
0c95c765
AL
738 if (_config->FindI("quiet",0) >= 2 ||
739 _config->FindB("APT::Get::Assume-Yes",false) == true)
83d89a9f
AL
740 {
741 if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
b2e465d6 742 return _error->Error(_("There are problems and -y was used without --force-yes"));
83d89a9f 743 }
83d89a9f 744
6f86c974
AL
745 if (Essential == true && Saftey == true)
746 {
d150b09d 747 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
b2e465d6 748 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
d150b09d 749
b2e465d6
AL
750 const char *Prompt = _("Yes, do as I say!");
751 ioprintf(c2out,
752 _("You are about to do something potentially harmful\n"
753 "To continue type in the phrase '%s'\n"
754 " ?] "),Prompt);
755 c2out << flush;
756 if (AnalPrompt(Prompt) == false)
6f86c974 757 {
b2e465d6 758 c2out << _("Abort.") << endl;
a6568219 759 exit(1);
6f86c974
AL
760 }
761 }
762 else
d150b09d 763 {
6f86c974 764 // Prompt to continue
38262e68 765 if (Ask == true || Fail == true)
6f86c974 766 {
d150b09d 767 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
b2e465d6 768 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
d150b09d 769
0c95c765 770 if (_config->FindI("quiet",0) < 2 &&
6f86c974 771 _config->FindB("APT::Get::Assume-Yes",false) == false)
0c95c765 772 {
b2e465d6 773 c2out << _("Do you want to continue? [Y/n] ") << flush;
6f86c974 774
0c95c765
AL
775 if (YnPrompt() == false)
776 {
b2e465d6 777 c2out << _("Abort.") << endl;
0c95c765
AL
778 exit(1);
779 }
780 }
6f86c974
AL
781 }
782 }
783
36375005 784 // Just print out the uris an exit if the --print-uris flag was used
f7a08e33
AL
785 if (_config->FindB("APT::Get::Print-URIs") == true)
786 {
787 pkgAcquire::UriIterator I = Fetcher.UriBegin();
788 for (; I != Fetcher.UriEnd(); I++)
789 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
790 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
791 return true;
792 }
b2e465d6
AL
793
794 /* Unlock the dpkg lock if we are not going to be doing an install
795 after. */
796 if (_config->FindB("APT::Get::Download-Only",false) == true)
797 _system->UnLock();
83d89a9f 798
03e39e59 799 // Run it
281daf46 800 while (1)
30e1eab5 801 {
a3eaf954 802 bool Transient = false;
b2e465d6 803 if (_config->FindB("APT::Get::Download",true) == false)
a3eaf954 804 {
076d01b0 805 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
a3eaf954
AL
806 {
807 if ((*I)->Local == true)
808 {
809 I++;
810 continue;
811 }
812
813 // Close the item and check if it was found in cache
814 (*I)->Finished();
815 if ((*I)->Complete == false)
816 Transient = true;
817
818 // Clear it out of the fetch list
819 delete *I;
820 I = Fetcher.ItemsBegin();
821 }
822 }
823
824 if (Fetcher.Run() == pkgAcquire::Failed)
825 return false;
30e1eab5 826
281daf46
AL
827 // Print out errors
828 bool Failed = false;
076d01b0 829 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
f01fe790 830 {
281daf46
AL
831 if ((*I)->Status == pkgAcquire::Item::StatDone &&
832 (*I)->Complete == true)
833 continue;
834
281daf46
AL
835 if ((*I)->Status == pkgAcquire::Item::StatIdle)
836 {
837 Transient = true;
838 // Failed = true;
839 continue;
840 }
a3eaf954 841
b2e465d6
AL
842 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
843 (*I)->ErrorText.c_str());
f01fe790 844 Failed = true;
f01fe790 845 }
5ec427c2 846
a3eaf954 847 /* If we are in no download mode and missing files and there were
5ec427c2
AL
848 'failures' then the user must specify -m. Furthermore, there
849 is no such thing as a transient error in no-download mode! */
a3eaf954 850 if (Transient == true &&
b2e465d6 851 _config->FindB("APT::Get::Download",true) == false)
5ec427c2
AL
852 {
853 Transient = false;
854 Failed = true;
855 }
f01fe790 856
281daf46
AL
857 if (_config->FindB("APT::Get::Download-Only",false) == true)
858 {
859 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
b2e465d6
AL
860 return _error->Error(_("Some files failed to download"));
861 c1out << _("Download complete and in download only mode") << endl;
281daf46
AL
862 return true;
863 }
864
8195ae46 865 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
f01fe790 866 {
b2e465d6 867 return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
f01fe790
AL
868 }
869
281daf46 870 if (Transient == true && Failed == true)
b2e465d6 871 return _error->Error(_("--fix-missing and media swapping is not currently supported"));
281daf46
AL
872
873 // Try to deal with missing package files
b2e465d6 874 if (Failed == true && PM->FixMissing() == false)
281daf46 875 {
b2e465d6
AL
876 cerr << _("Unable to correct missing packages.") << endl;
877 return _error->Error(_("Aborting Install."));
281daf46 878 }
a3eaf954 879
b2e465d6
AL
880 _system->UnLock();
881 pkgPackageManager::OrderResult Res = PM->DoInstall();
281daf46
AL
882 if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
883 return false;
884 if (Res == pkgPackageManager::Completed)
885 return true;
886
887 // Reload the fetcher object and loop again for media swapping
888 Fetcher.Shutdown();
b2e465d6 889 if (PM->GetArchives(&Fetcher,&List,&Recs) == false)
281daf46 890 return false;
b2e465d6
AL
891
892 _system->Lock();
281daf46 893 }
0a8e3465
AL
894}
895 /*}}}*/
c373c37a
AL
896// TryToInstall - Try to install a single package /*{{{*/
897// ---------------------------------------------------------------------
898/* This used to be inlined in DoInstall, but with the advent of regex package
899 name matching it was split out.. */
900bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
901 pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
902 unsigned int &ExpectedInst,bool AllowFail = true)
903{
904 /* This is a pure virtual package and there is a single available
905 provides */
906 if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0 &&
907 Pkg.ProvidesList()->NextProvides == 0)
908 {
909 pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg();
b2e465d6
AL
910 ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
911 Tmp.Name(),Pkg.Name());
c373c37a
AL
912 Pkg = Tmp;
913 }
914
915 // Handle the no-upgrade case
b2e465d6 916 if (_config->FindB("APT::Get::upgrade",true) == false &&
c373c37a
AL
917 Pkg->CurrentVer != 0)
918 {
919 if (AllowFail == true)
b2e465d6
AL
920 ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
921 Pkg.Name());
c373c37a
AL
922 return true;
923 }
924
925 // Check if there is something at all to install
926 pkgDepCache::StateCache &State = Cache[Pkg];
a146c927 927 if (Remove == true && Pkg->CurrentVer == 0)
10bb1f5f 928 {
b2e465d6
AL
929 /* We want to continue searching for regex hits, so we return false here
930 otherwise this is not really an error. */
10bb1f5f 931 if (AllowFail == false)
b2e465d6 932 return false;
1156d969 933 ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.Name());
b2e465d6 934 return true;
10bb1f5f 935 }
a146c927
AL
936
937 if (State.CandidateVer == 0 && Remove == false)
c373c37a
AL
938 {
939 if (AllowFail == false)
940 return false;
941
942 if (Pkg->ProvidesList != 0)
943 {
b2e465d6
AL
944 ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
945 Pkg.Name());
c373c37a
AL
946
947 pkgCache::PrvIterator I = Pkg.ProvidesList();
948 for (; I.end() == false; I++)
949 {
950 pkgCache::PkgIterator Pkg = I.OwnerPkg();
951
952 if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer())
953 {
954 if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
955 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
b2e465d6 956 _(" [Installed]") << endl;
c373c37a
AL
957 else
958 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
959 }
960 }
b2e465d6 961 c1out << _("You should explicitly select one to install.") << endl;
c373c37a
AL
962 }
963 else
964 {
b2e465d6
AL
965 ioprintf(c1out,
966 _("Package %s has no available version, but exists in the database.\n"
967 "This typically means that the package was mentioned in a dependency and\n"
968 "never uploaded, has been obsoleted or is not available with the contents\n"
969 "of sources.list\n"),Pkg.Name());
c373c37a
AL
970
971 string List;
c82ffeb6
AL
972 SPtrArray<bool> Seen = new bool[Cache.Head().PackageCount];
973 memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen));
c373c37a
AL
974 pkgCache::DepIterator Dep = Pkg.RevDependsList();
975 for (; Dep.end() == false; Dep++)
976 {
977 if (Dep->Type != pkgCache::Dep::Replaces)
978 continue;
b2e465d6
AL
979 if (Seen[Dep.ParentPkg()->ID] == true)
980 continue;
981 Seen[Dep.ParentPkg()->ID] = true;
c373c37a
AL
982 List += string(Dep.ParentPkg().Name()) + " ";
983 }
b2e465d6 984 ShowList(c1out,_("However the following packages replace it:"),List);
c373c37a
AL
985 }
986
b2e465d6 987 _error->Error(_("Package %s has no installation candidate"),Pkg.Name());
c373c37a
AL
988 return false;
989 }
61d6a8de
AL
990
991 Fix.Clear(Pkg);
70777d4b 992 Fix.Protect(Pkg);
c373c37a
AL
993 if (Remove == true)
994 {
995 Fix.Remove(Pkg);
996 Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
997 return true;
998 }
999
1000 // Install it
1001 Cache.MarkInstall(Pkg,false);
1002 if (State.Install() == false)
1003 {
d0c59649
AL
1004 if (_config->FindB("APT::Get::ReInstall",false) == true)
1005 {
1006 if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
70d73d7e 1007 ioprintf(c1out,_("Sorry, re-installation of %s is not possible, it cannot be downloaded.\n"),
b2e465d6 1008 Pkg.Name());
d0c59649
AL
1009 else
1010 Cache.SetReInstall(Pkg,true);
1011 }
1012 else
1013 {
1014 if (AllowFail == true)
b2e465d6
AL
1015 ioprintf(c1out,_("Sorry, %s is already the newest version.\n"),
1016 Pkg.Name());
d0c59649 1017 }
c373c37a
AL
1018 }
1019 else
1020 ExpectedInst++;
1021
1022 // Install it with autoinstalling enabled.
1023 if (State.InstBroken() == true && BrokenFix == false)
1024 Cache.MarkInstall(Pkg,true);
1025 return true;
1026}
1027 /*}}}*/
b2e465d6
AL
1028// TryToChangeVer - Try to change a candidate version /*{{{*/
1029// ---------------------------------------------------------------------
1030/* */
1031bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
1032 const char *VerTag,bool IsRel)
1033{
1034 pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release:pkgVersionMatch::Version));
1035
1036 pkgCache::VerIterator Ver = Match.Find(Pkg);
1037
1038 if (Ver.end() == true)
1039 {
1040 if (IsRel == true)
1041 return _error->Error(_("Release '%s' for '%s' was not found"),
1042 VerTag,Pkg.Name());
1043 return _error->Error(_("Version '%s' for '%s' was not found"),
1044 VerTag,Pkg.Name());
1045 }
1046
1047 if (strcmp(VerTag,Ver.VerStr()) != 0)
1048 {
1049 ioprintf(c1out,_("Selected version %s (%s) for %s\n"),
1050 Ver.VerStr(),Ver.RelStr().c_str(),Pkg.Name());
1051 }
1052
1053 Cache.SetCandidateVersion(Ver);
1054 return true;
1055}
1056 /*}}}*/
1057// FindSrc - Find a source record /*{{{*/
1058// ---------------------------------------------------------------------
1059/* */
1060pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
1061 pkgSrcRecords &SrcRecs,string &Src,
1062 pkgDepCache &Cache)
1063{
1064 // We want to pull the version off the package specification..
1065 string VerTag;
1066 string TmpSrc = Name;
1067 string::size_type Slash = TmpSrc.rfind('=');
1068 if (Slash != string::npos)
1069 {
1070 VerTag = string(TmpSrc.begin() + Slash + 1,TmpSrc.end());
1071 TmpSrc = string(TmpSrc.begin(),TmpSrc.begin() + Slash);
1072 }
1073
1074 /* Lookup the version of the package we would install if we were to
1075 install a version and determine the source package name, then look
1076 in the archive for a source package of the same name. In theory
1077 we could stash the version string as well and match that too but
1078 today there aren't multi source versions in the archive. */
1079 if (_config->FindB("APT::Get::Only-Source") == false &&
1080 VerTag.empty() == true)
1081 {
1082 pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc);
1083 if (Pkg.end() == false)
1084 {
1085 pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
1086 if (Ver.end() == false)
1087 {
1088 pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
1089 Src = Parse.SourcePkg();
1090 }
1091 }
1092 }
1093
1094 // No source package name..
1095 if (Src.empty() == true)
1096 Src = TmpSrc;
1097
1098 // The best hit
1099 pkgSrcRecords::Parser *Last = 0;
1100 unsigned long Offset = 0;
1101 string Version;
1102 bool IsMatch = false;
1103
1104 // If we are matching by version then we need exact matches to be happy
1105 if (VerTag.empty() == false)
1106 IsMatch = true;
1107
1108 /* Iterate over all of the hits, which includes the resulting
1109 binary packages in the search */
1110 pkgSrcRecords::Parser *Parse;
1111 SrcRecs.Restart();
1112 while ((Parse = SrcRecs.Find(Src.c_str(),false)) != 0)
1113 {
1114 string Ver = Parse->Version();
1115
1116 // Skip name mismatches
1117 if (IsMatch == true && Parse->Package() != Src)
1118 continue;
1119
1120 if (VerTag.empty() == false)
1121 {
1122 /* Don't want to fall through because we are doing exact version
1123 matching. */
1124 if (Cache.VS().CmpVersion(VerTag,Ver) != 0)
1125 continue;
1126
1127 Last = Parse;
1128 Offset = Parse->Offset();
1129 break;
1130 }
1131
1132 // Newer version or an exact match
1133 if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0 ||
1134 (Parse->Package() == Src && IsMatch == false))
1135 {
1136 IsMatch = Parse->Package() == Src;
1137 Last = Parse;
1138 Offset = Parse->Offset();
1139 Version = Ver;
1140 }
1141 }
1142
1143 if (Last == 0)
1144 return 0;
1145
1146 if (Last->Jump(Offset) == false)
1147 return 0;
1148
1149 return Last;
1150}
1151 /*}}}*/
0a8e3465
AL
1152
1153// DoUpdate - Update the package lists /*{{{*/
1154// ---------------------------------------------------------------------
1155/* */
b2e465d6 1156bool DoUpdate(CommandLine &CmdL)
0a8e3465 1157{
b2e465d6
AL
1158 if (CmdL.FileSize() != 1)
1159 return _error->Error(_("The update command takes no arguments"));
1160
0919e3f9
AL
1161 // Get the source list
1162 pkgSourceList List;
1163 if (List.ReadMainList() == false)
1164 return false;
1165
d38b7b3d 1166 // Lock the list directory
36375005 1167 FileFd Lock;
d38b7b3d
AL
1168 if (_config->FindB("Debug::NoLocking",false) == false)
1169 {
36375005 1170 Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
d38b7b3d 1171 if (_error->PendingError() == true)
b2e465d6 1172 return _error->Error(_("Unable to lock the list directory"));
d38b7b3d
AL
1173 }
1174
0919e3f9
AL
1175 // Create the download object
1176 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1177 pkgAcquire Fetcher(&Stat);
1178
1179 // Populate it with the source selection
b2e465d6 1180 if (List.GetIndexes(&Fetcher) == false)
0919e3f9 1181 return false;
0919e3f9
AL
1182
1183 // Run it
024d1123 1184 if (Fetcher.Run() == pkgAcquire::Failed)
0919e3f9
AL
1185 return false;
1186
9df71a5b 1187 bool Failed = false;
076d01b0 1188 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
9df71a5b
AL
1189 {
1190 if ((*I)->Status == pkgAcquire::Item::StatDone)
1191 continue;
1192
1193 (*I)->Finished();
1194
b2e465d6
AL
1195 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1196 (*I)->ErrorText.c_str());
9df71a5b
AL
1197 Failed = true;
1198 }
1199
7a7fa5f0 1200 // Clean out any old list files
67ff87bf 1201 if (_config->FindB("APT::Get::List-Cleanup",true) == true)
9df71a5b
AL
1202 {
1203 if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
1204 Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
1205 return false;
1206 }
7a7fa5f0 1207
0919e3f9
AL
1208 // Prepare the cache.
1209 CacheFile Cache;
a65cbe33 1210 if (Cache.Open() == false)
0919e3f9
AL
1211 return false;
1212
9df71a5b 1213 if (Failed == true)
b2e465d6
AL
1214 return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
1215
0919e3f9 1216 return true;
0a8e3465
AL
1217}
1218 /*}}}*/
1219// DoUpgrade - Upgrade all packages /*{{{*/
1220// ---------------------------------------------------------------------
1221/* Upgrade all packages without installing new packages or erasing old
1222 packages */
1223bool DoUpgrade(CommandLine &CmdL)
1224{
1225 CacheFile Cache;
c37b9502 1226 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
0a8e3465
AL
1227 return false;
1228
1229 // Do the upgrade
0a8e3465
AL
1230 if (pkgAllUpgrade(Cache) == false)
1231 {
421c8d10 1232 ShowBroken(c1out,Cache,false);
b2e465d6 1233 return _error->Error(_("Internal Error, AllUpgrade broke stuff"));
0a8e3465
AL
1234 }
1235
1236 return InstallPackages(Cache,true);
1237}
1238 /*}}}*/
1239// DoInstall - Install packages from the command line /*{{{*/
1240// ---------------------------------------------------------------------
1241/* Install named packages */
1242bool DoInstall(CommandLine &CmdL)
1243{
1244 CacheFile Cache;
c37b9502
AL
1245 if (Cache.OpenForInstall() == false ||
1246 Cache.CheckDeps(CmdL.FileSize() != 1) == false)
0a8e3465
AL
1247 return false;
1248
7c57fe64
AL
1249 // Enter the special broken fixing mode if the user specified arguments
1250 bool BrokenFix = false;
1251 if (Cache->BrokenCount() != 0)
1252 BrokenFix = true;
1253
a6568219
AL
1254 unsigned int ExpectedInst = 0;
1255 unsigned int Packages = 0;
0a8e3465
AL
1256 pkgProblemResolver Fix(Cache);
1257
303a1703
AL
1258 bool DefRemove = false;
1259 if (strcasecmp(CmdL.FileList[0],"remove") == 0)
1260 DefRemove = true;
b2e465d6 1261
0a8e3465
AL
1262 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
1263 {
1264 // Duplicate the string
1265 unsigned int Length = strlen(*I);
1266 char S[300];
1267 if (Length >= sizeof(S))
1268 continue;
1269 strcpy(S,*I);
1270
b2e465d6 1271 // See if we are removing and special indicators..
303a1703 1272 bool Remove = DefRemove;
b2e465d6
AL
1273 char *VerTag = 0;
1274 bool VerIsRel = false;
fc4b5c9f 1275 while (Cache->FindPkg(S).end() == true)
0a8e3465 1276 {
2c3bc8bb
AL
1277 // Handle an optional end tag indicating what to do
1278 if (S[Length - 1] == '-')
1279 {
1280 Remove = true;
1281 S[--Length] = 0;
fc4b5c9f 1282 continue;
2c3bc8bb 1283 }
fc4b5c9f 1284
2c3bc8bb
AL
1285 if (S[Length - 1] == '+')
1286 {
1287 Remove = false;
1288 S[--Length] = 0;
fc4b5c9f 1289 continue;
2c3bc8bb 1290 }
b2e465d6
AL
1291
1292 char *Slash = strchr(S,'=');
1293 if (Slash != 0)
1294 {
1295 VerIsRel = false;
1296 *Slash = 0;
1297 VerTag = Slash + 1;
1298 }
1299
1300 Slash = strchr(S,'/');
1301 if (Slash != 0)
1302 {
1303 VerIsRel = true;
1304 *Slash = 0;
1305 VerTag = Slash + 1;
1306 }
1307
fc4b5c9f 1308 break;
303a1703 1309 }
0a8e3465
AL
1310
1311 // Locate the package
1312 pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
303a1703 1313 Packages++;
0a8e3465 1314 if (Pkg.end() == true)
2c3bc8bb 1315 {
c373c37a
AL
1316 // Check if the name is a regex
1317 const char *I;
1318 for (I = S; *I != 0; I++)
b2e465d6 1319 if (*I == '.' || *I == '?' || *I == '*' || *I == '|')
c373c37a
AL
1320 break;
1321 if (*I == 0)
b2e465d6 1322 return _error->Error(_("Couldn't find package %s"),S);
303a1703 1323
c373c37a
AL
1324 // Regexs must always be confirmed
1325 ExpectedInst += 1000;
1326
1327 // Compile the regex pattern
1328 regex_t Pattern;
b2e465d6
AL
1329 int Res;
1330 if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE |
1331 REG_NOSUB)) != 0)
1332 {
1333 char Error[300];
1334 regerror(Res,&Pattern,Error,sizeof(Error));
1335 return _error->Error(_("Regex compilation error - %s"),Error);
1336 }
c373c37a
AL
1337
1338 // Run over the matches
1339 bool Hit = false;
1340 for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++)
303a1703 1341 {
c373c37a
AL
1342 if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0)
1343 continue;
07801a6d 1344
b2e465d6
AL
1345 if (VerTag != 0)
1346 if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
1347 return false;
1348
c373c37a
AL
1349 Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
1350 ExpectedInst,false);
303a1703 1351 }
c373c37a 1352 regfree(&Pattern);
303a1703 1353
c373c37a 1354 if (Hit == false)
b2e465d6 1355 return _error->Error(_("Couldn't find package %s"),S);
0a8e3465 1356 }
0a8e3465 1357 else
c373c37a 1358 {
b2e465d6
AL
1359 if (VerTag != 0)
1360 if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
1361 return false;
c373c37a
AL
1362 if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
1363 return false;
1364 }
0a8e3465
AL
1365 }
1366
7c57fe64
AL
1367 /* If we are in the Broken fixing mode we do not attempt to fix the
1368 problems. This is if the user invoked install without -f and gave
1369 packages */
1370 if (BrokenFix == true && Cache->BrokenCount() != 0)
1371 {
b2e465d6 1372 c1out << _("You might want to run `apt-get -f install' to correct these:") << endl;
421c8d10 1373 ShowBroken(c1out,Cache,false);
7c57fe64 1374
b2e465d6 1375 return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
7c57fe64
AL
1376 }
1377
0a8e3465 1378 // Call the scored problem resolver
303a1703 1379 Fix.InstallProtect();
0a8e3465
AL
1380 if (Fix.Resolve(true) == false)
1381 _error->Discard();
1382
1383 // Now we check the state of the packages,
1384 if (Cache->BrokenCount() != 0)
1385 {
b2e465d6
AL
1386 c1out <<
1387 _("Some packages could not be installed. This may mean that you have\n"
1388 "requested an impossible situation or if you are using the unstable\n"
1389 "distribution that some required packages have not yet been created\n"
1390 "or been moved out of Incoming.") << endl;
303a1703
AL
1391 if (Packages == 1)
1392 {
1393 c1out << endl;
b2e465d6
AL
1394 c1out <<
1395 _("Since you only requested a single operation it is extremely likely that\n"
1396 "the package is simply not installable and a bug report against\n"
1397 "that package should be filed.") << endl;
303a1703
AL
1398 }
1399
b2e465d6 1400 c1out << _("The following information may help to resolve the situation:") << endl;
303a1703 1401 c1out << endl;
421c8d10 1402 ShowBroken(c1out,Cache,false);
b2e465d6 1403 return _error->Error(_("Sorry, broken packages"));
0a8e3465
AL
1404 }
1405
1406 /* Print out a list of packages that are going to be installed extra
1407 to what the user asked */
1408 if (Cache->InstCount() != ExpectedInst)
1409 {
1410 string List;
1089ca89 1411 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
0a8e3465 1412 {
1089ca89 1413 pkgCache::PkgIterator I(Cache,Cache.List[J]);
0a8e3465
AL
1414 if ((*Cache)[I].Install() == false)
1415 continue;
1416
1417 const char **J;
1418 for (J = CmdL.FileList + 1; *J != 0; J++)
1419 if (strcmp(*J,I.Name()) == 0)
1420 break;
1421
1422 if (*J == 0)
1423 List += string(I.Name()) + " ";
1424 }
1425
b2e465d6 1426 ShowList(c1out,_("The following extra packages will be installed:"),List);
0a8e3465
AL
1427 }
1428
03e39e59 1429 // See if we need to prompt
2c3bc8bb 1430 if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
2c3bc8bb 1431 return InstallPackages(Cache,false,false);
2c3bc8bb 1432
03e39e59 1433 return InstallPackages(Cache,false);
0a8e3465
AL
1434}
1435 /*}}}*/
1436// DoDistUpgrade - Automatic smart upgrader /*{{{*/
1437// ---------------------------------------------------------------------
1438/* Intelligent upgrader that will install and remove packages at will */
1439bool DoDistUpgrade(CommandLine &CmdL)
1440{
1441 CacheFile Cache;
c37b9502 1442 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
0a8e3465
AL
1443 return false;
1444
b2e465d6 1445 c0out << _("Calculating Upgrade... ") << flush;
0a8e3465
AL
1446 if (pkgDistUpgrade(*Cache) == false)
1447 {
b2e465d6 1448 c0out << _("Failed") << endl;
421c8d10 1449 ShowBroken(c1out,Cache,false);
0a8e3465
AL
1450 return false;
1451 }
1452
b2e465d6 1453 c0out << _("Done") << endl;
0a8e3465
AL
1454
1455 return InstallPackages(Cache,true);
1456}
1457 /*}}}*/
1458// DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
1459// ---------------------------------------------------------------------
1460/* Follows dselect's selections */
1461bool DoDSelectUpgrade(CommandLine &CmdL)
1462{
1463 CacheFile Cache;
c37b9502 1464 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
0a8e3465
AL
1465 return false;
1466
1467 // Install everything with the install flag set
1468 pkgCache::PkgIterator I = Cache->PkgBegin();
1469 for (;I.end() != true; I++)
1470 {
1471 /* Install the package only if it is a new install, the autoupgrader
1472 will deal with the rest */
1473 if (I->SelectedState == pkgCache::State::Install)
1474 Cache->MarkInstall(I,false);
1475 }
1476
1477 /* Now install their deps too, if we do this above then order of
1478 the status file is significant for | groups */
1479 for (I = Cache->PkgBegin();I.end() != true; I++)
1480 {
1481 /* Install the package only if it is a new install, the autoupgrader
1482 will deal with the rest */
1483 if (I->SelectedState == pkgCache::State::Install)
2f45c76a 1484 Cache->MarkInstall(I,true);
0a8e3465
AL
1485 }
1486
1487 // Apply erasures now, they override everything else.
1488 for (I = Cache->PkgBegin();I.end() != true; I++)
1489 {
1490 // Remove packages
1491 if (I->SelectedState == pkgCache::State::DeInstall ||
1492 I->SelectedState == pkgCache::State::Purge)
d556d1a1 1493 Cache->MarkDelete(I,I->SelectedState == pkgCache::State::Purge);
0a8e3465
AL
1494 }
1495
2f45c76a
AL
1496 /* Resolve any problems that dselect created, allupgrade cannot handle
1497 such things. We do so quite agressively too.. */
1498 if (Cache->BrokenCount() != 0)
1499 {
1500 pkgProblemResolver Fix(Cache);
1501
1502 // Hold back held packages.
b2e465d6 1503 if (_config->FindB("APT::Ignore-Hold",false) == false)
2f45c76a
AL
1504 {
1505 for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++)
1506 {
1507 if (I->SelectedState == pkgCache::State::Hold)
1508 {
1509 Fix.Protect(I);
1510 Cache->MarkKeep(I);
1511 }
1512 }
1513 }
1514
1515 if (Fix.Resolve() == false)
1516 {
421c8d10 1517 ShowBroken(c1out,Cache,false);
2f45c76a
AL
1518 return _error->Error("Internal Error, problem resolver broke stuff");
1519 }
1520 }
1521
1522 // Now upgrade everything
0a8e3465
AL
1523 if (pkgAllUpgrade(Cache) == false)
1524 {
421c8d10 1525 ShowBroken(c1out,Cache,false);
2f45c76a 1526 return _error->Error("Internal Error, problem resolver broke stuff");
0a8e3465
AL
1527 }
1528
1529 return InstallPackages(Cache,false);
1530}
1531 /*}}}*/
1532// DoClean - Remove download archives /*{{{*/
1533// ---------------------------------------------------------------------
1534/* */
1535bool DoClean(CommandLine &CmdL)
1536{
8b067c22
AL
1537 if (_config->FindB("APT::Get::Simulate") == true)
1538 {
1539 cout << "Del " << _config->FindDir("Dir::Cache::archives") << "* " <<
1540 _config->FindDir("Dir::Cache::archives") << "partial/*" << endl;
1541 return true;
1542 }
1543
1b6d659c
AL
1544 // Lock the archive directory
1545 FileFd Lock;
1546 if (_config->FindB("Debug::NoLocking",false) == false)
1547 {
1548 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1549 if (_error->PendingError() == true)
b2e465d6 1550 return _error->Error(_("Unable to lock the download directory"));
1b6d659c
AL
1551 }
1552
7a1b1f8b
AL
1553 pkgAcquire Fetcher;
1554 Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
1555 Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
0a8e3465
AL
1556 return true;
1557}
1558 /*}}}*/
1bc849af
AL
1559// DoAutoClean - Smartly remove downloaded archives /*{{{*/
1560// ---------------------------------------------------------------------
1561/* This is similar to clean but it only purges things that cannot be
1562 downloaded, that is old versions of cached packages. */
65a1e968
AL
1563class LogCleaner : public pkgArchiveCleaner
1564{
1565 protected:
1566 virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St)
1567 {
4cc8bab0 1568 c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << endl;
c1e78ee5
AL
1569
1570 if (_config->FindB("APT::Get::Simulate") == false)
1571 unlink(File);
65a1e968
AL
1572 };
1573};
1574
1bc849af
AL
1575bool DoAutoClean(CommandLine &CmdL)
1576{
1b6d659c
AL
1577 // Lock the archive directory
1578 FileFd Lock;
1579 if (_config->FindB("Debug::NoLocking",false) == false)
1580 {
1581 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1582 if (_error->PendingError() == true)
b2e465d6 1583 return _error->Error(_("Unable to lock the download directory"));
1b6d659c
AL
1584 }
1585
1bc849af 1586 CacheFile Cache;
2d11135a 1587 if (Cache.Open() == false)
1bc849af
AL
1588 return false;
1589
65a1e968 1590 LogCleaner Cleaner;
1bc849af
AL
1591
1592 return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) &&
1593 Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache);
1594}
1595 /*}}}*/
0a8e3465
AL
1596// DoCheck - Perform the check operation /*{{{*/
1597// ---------------------------------------------------------------------
1598/* Opening automatically checks the system, this command is mostly used
1599 for debugging */
1600bool DoCheck(CommandLine &CmdL)
1601{
1602 CacheFile Cache;
1603 Cache.Open();
2d11135a 1604 Cache.CheckDeps();
0a8e3465
AL
1605
1606 return true;
1607}
1608 /*}}}*/
36375005
AL
1609// DoSource - Fetch a source archive /*{{{*/
1610// ---------------------------------------------------------------------
2d11135a 1611/* Fetch souce packages */
fb0ee66e
AL
1612struct DscFile
1613{
1614 string Package;
1615 string Version;
1616 string Dsc;
1617};
1618
36375005
AL
1619bool DoSource(CommandLine &CmdL)
1620{
1621 CacheFile Cache;
2d11135a 1622 if (Cache.Open(false) == false)
36375005
AL
1623 return false;
1624
2d11135a 1625 if (CmdL.FileSize() <= 1)
b2e465d6 1626 return _error->Error(_("Must specify at least one package to fetch source for"));
2d11135a 1627
36375005
AL
1628 // Read the source list
1629 pkgSourceList List;
1630 if (List.ReadMainList() == false)
b2e465d6 1631 return _error->Error(_("The list of sources could not be read."));
36375005
AL
1632
1633 // Create the text record parsers
1634 pkgRecords Recs(Cache);
1635 pkgSrcRecords SrcRecs(List);
1636 if (_error->PendingError() == true)
1637 return false;
1638
1639 // Create the download object
1640 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1641 pkgAcquire Fetcher(&Stat);
fb0ee66e
AL
1642
1643 DscFile *Dsc = new DscFile[CmdL.FileSize()];
36375005
AL
1644
1645 // Load the requestd sources into the fetcher
fb0ee66e
AL
1646 unsigned J = 0;
1647 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
36375005
AL
1648 {
1649 string Src;
b2e465d6 1650 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
36375005
AL
1651
1652 if (Last == 0)
b2e465d6 1653 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
36375005
AL
1654
1655 // Back track
1656 vector<pkgSrcRecords::File> Lst;
b2e465d6 1657 if (Last->Files(Lst) == false)
36375005
AL
1658 return false;
1659
1660 // Load them into the fetcher
1661 for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
1662 I != Lst.end(); I++)
1663 {
1664 // Try to guess what sort of file it is we are getting.
b2e465d6 1665 if (I->Type == "dsc")
fb0ee66e 1666 {
fb0ee66e
AL
1667 Dsc[J].Package = Last->Package();
1668 Dsc[J].Version = Last->Version();
1669 Dsc[J].Dsc = flNotDir(I->Path);
1670 }
1671
17c0e8e1
AL
1672 // Diff only mode only fetches .diff files
1673 if (_config->FindB("APT::Get::Diff-Only",false) == true &&
b2e465d6 1674 I->Type != "diff")
17c0e8e1
AL
1675 continue;
1676
1677 // Tar only mode only fetches .tar files
1678 if (_config->FindB("APT::Get::Tar-Only",false) == true &&
b2e465d6 1679 I->Type != "tar")
17c0e8e1
AL
1680 continue;
1681
b2e465d6
AL
1682 new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path),
1683 I->MD5Hash,I->Size,
1684 Last->Index().SourceInfo(*Last,*I),Src);
36375005
AL
1685 }
1686 }
1687
1688 // Display statistics
b2e465d6
AL
1689 double FetchBytes = Fetcher.FetchNeeded();
1690 double FetchPBytes = Fetcher.PartialPresent();
1691 double DebBytes = Fetcher.TotalNeeded();
36375005
AL
1692
1693 // Check for enough free space
f332b62b 1694 struct statvfs Buf;
36375005 1695 string OutputDir = ".";
f332b62b
AL
1696 if (statvfs(OutputDir.c_str(),&Buf) != 0)
1697 return _error->Errno("statvfs","Couldn't determine free space in %s",
36375005
AL
1698 OutputDir.c_str());
1699 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
b2e465d6 1700 return _error->Error(_("Sorry, you don't have enough free space in %s"),
36375005
AL
1701 OutputDir.c_str());
1702
1703 // Number of bytes
36375005 1704 if (DebBytes != FetchBytes)
b2e465d6
AL
1705 ioprintf(c1out,_("Need to get %sB/%sB of source archives.\n"),
1706 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
36375005 1707 else
b2e465d6
AL
1708 ioprintf(c1out,_("Need to get %sB of source archives.\n"),
1709 SizeToStr(DebBytes).c_str());
1710
2c0c53b3
AL
1711 if (_config->FindB("APT::Get::Simulate",false) == true)
1712 {
1713 for (unsigned I = 0; I != J; I++)
b2e465d6 1714 ioprintf(cout,_("Fetch Source %s\n"),Dsc[I].Package.c_str());
2c0c53b3
AL
1715 return true;
1716 }
1717
36375005
AL
1718 // Just print out the uris an exit if the --print-uris flag was used
1719 if (_config->FindB("APT::Get::Print-URIs") == true)
1720 {
1721 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1722 for (; I != Fetcher.UriEnd(); I++)
1723 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1724 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
1725 return true;
1726 }
1727
1728 // Run it
024d1123 1729 if (Fetcher.Run() == pkgAcquire::Failed)
36375005
AL
1730 return false;
1731
1732 // Print error messages
fb0ee66e 1733 bool Failed = false;
076d01b0 1734 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
36375005
AL
1735 {
1736 if ((*I)->Status == pkgAcquire::Item::StatDone &&
1737 (*I)->Complete == true)
1738 continue;
1739
b2e465d6
AL
1740 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1741 (*I)->ErrorText.c_str());
fb0ee66e 1742 Failed = true;
36375005 1743 }
fb0ee66e 1744 if (Failed == true)
b2e465d6 1745 return _error->Error(_("Failed to fetch some archives."));
fb0ee66e
AL
1746
1747 if (_config->FindB("APT::Get::Download-only",false) == true)
b2e465d6
AL
1748 {
1749 c1out << _("Download complete and in download only mode") << endl;
fb0ee66e 1750 return true;
b2e465d6
AL
1751 }
1752
fb0ee66e 1753 // Unpack the sources
54676e1a
AL
1754 pid_t Process = ExecFork();
1755
1756 if (Process == 0)
fb0ee66e 1757 {
54676e1a 1758 for (unsigned I = 0; I != J; I++)
fb0ee66e 1759 {
b2e465d6 1760 string Dir = Dsc[I].Package + '-' + Cache->VS().UpstreamVersion(Dsc[I].Version.c_str());
fb0ee66e 1761
17c0e8e1
AL
1762 // Diff only mode only fetches .diff files
1763 if (_config->FindB("APT::Get::Diff-Only",false) == true ||
a3eaf954
AL
1764 _config->FindB("APT::Get::Tar-Only",false) == true ||
1765 Dsc[I].Dsc.empty() == true)
17c0e8e1 1766 continue;
a3eaf954 1767
54676e1a
AL
1768 // See if the package is already unpacked
1769 struct stat Stat;
1770 if (stat(Dir.c_str(),&Stat) == 0 &&
1771 S_ISDIR(Stat.st_mode) != 0)
1772 {
b2e465d6
AL
1773 ioprintf(c0out ,_("Skipping unpack of already unpacked source in %s\n"),
1774 Dir.c_str());
54676e1a
AL
1775 }
1776 else
1777 {
1778 // Call dpkg-source
1779 char S[500];
1780 snprintf(S,sizeof(S),"%s -x %s",
1781 _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
1782 Dsc[I].Dsc.c_str());
1783 if (system(S) != 0)
1784 {
b2e465d6 1785 fprintf(stderr,_("Unpack command '%s' failed.\n"),S);
54676e1a
AL
1786 _exit(1);
1787 }
1788 }
1789
1790 // Try to compile it with dpkg-buildpackage
1791 if (_config->FindB("APT::Get::Compile",false) == true)
1792 {
1793 // Call dpkg-buildpackage
1794 char S[500];
1795 snprintf(S,sizeof(S),"cd %s && %s %s",
1796 Dir.c_str(),
1797 _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
1798 _config->Find("DPkg::Build-Options","-b -uc").c_str());
1799
1800 if (system(S) != 0)
1801 {
b2e465d6 1802 fprintf(stderr,_("Build command '%s' failed.\n"),S);
54676e1a
AL
1803 _exit(1);
1804 }
1805 }
1806 }
1807
1808 _exit(0);
1809 }
1810
1811 // Wait for the subprocess
1812 int Status = 0;
1813 while (waitpid(Process,&Status,0) != Process)
1814 {
1815 if (errno == EINTR)
1816 continue;
1817 return _error->Errno("waitpid","Couldn't wait for subprocess");
1818 }
1819
1820 if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
b2e465d6
AL
1821 return _error->Error(_("Child process failed"));
1822
1823 return true;
1824}
1825 /*}}}*/
1826// DoBuildDep - Install/removes packages to satisfy build dependencies /*{{{*/
1827// ---------------------------------------------------------------------
1828/* This function will look at the build depends list of the given source
1829 package and install the necessary packages to make it true, or fail. */
1830bool DoBuildDep(CommandLine &CmdL)
1831{
1832 CacheFile Cache;
1833 if (Cache.Open(true) == false)
1834 return false;
1835
1836 if (CmdL.FileSize() <= 1)
1837 return _error->Error(_("Must specify at least one package to check builddeps for"));
1838
1839 // Read the source list
1840 pkgSourceList List;
1841 if (List.ReadMainList() == false)
1842 return _error->Error(_("The list of sources could not be read."));
54676e1a 1843
b2e465d6
AL
1844 // Create the text record parsers
1845 pkgRecords Recs(Cache);
1846 pkgSrcRecords SrcRecs(List);
1847 if (_error->PendingError() == true)
1848 return false;
1849
1850 // Create the download object
1851 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1852 pkgAcquire Fetcher(&Stat);
1853
1854 unsigned J = 0;
1855 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
1856 {
1857 string Src;
1858 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
1859 if (Last == 0)
1860 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
1861
1862 // Process the build-dependencies
1863 vector<pkgSrcRecords::Parser::BuildDepRec> BuildDeps;
45430cbf 1864 if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only",false)) == false)
b2e465d6
AL
1865 return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str());
1866
7d6f9f8f
AL
1867 // Also ensure that build-essential packages are present
1868 Configuration::Item const *Opts = _config->Tree("APT::Build-Essential");
1869 if (Opts)
1870 Opts = Opts->Child;
1871 for (; Opts; Opts = Opts->Next)
1872 {
1873 if (Opts->Value.empty() == true)
1874 continue;
1875
1876 pkgSrcRecords::Parser::BuildDepRec rec;
1877 rec.Package = Opts->Value;
1878 rec.Type = pkgSrcRecords::Parser::BuildDependIndep;
1879 rec.Op = 0;
1880 BuildDeps.insert(BuildDeps.begin(), rec);
1881 }
1882
b2e465d6
AL
1883 if (BuildDeps.size() == 0)
1884 {
1885 ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
1886 continue;
1887 }
1888
1889 // Install the requested packages
1890 unsigned int ExpectedInst = 0;
1891 vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
1892 pkgProblemResolver Fix(Cache);
1893 for (D = BuildDeps.begin(); D != BuildDeps.end(); D++)
1894 {
1895 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
1896 if (Pkg.end() == true)
d3fc0061
AL
1897 {
1898 /* for a build-conflict; ignore unknown packages */
1899 if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
1900 (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
1901 continue;
1902
b2e465d6
AL
1903 return _error->Error(_("%s dependency on %s cannot be satisfied because the package %s cannot be found"),
1904 Last->BuildDepType((*D).Type),Src.c_str(),(*D).Package.c_str());
d3fc0061 1905 }
b2e465d6
AL
1906 pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
1907
1908 if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
1909 (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
1910 {
cfa5659c
AL
1911 /*
1912 * conflict; need to remove if we have an installed version
1913 * that satisfies the version criterial
1914 */
b2e465d6
AL
1915 if (IV.end() == false &&
1916 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
1917 TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
1918 }
1919 else
1920 {
cfa5659c
AL
1921 /*
1922 * If this is a virtual package, we need to check the list of
1923 * packages that provide it and see if any of those are
1924 * installed
1925 */
1926 pkgCache::PrvIterator Prv = Pkg.ProvidesList();
1927 for (; Prv.end() != true; Prv++)
1928 if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
1929 break;
1930
1931 if (Prv.end() == true)
1932 {
1933 /*
1934 * depends; need to install or upgrade if we don't have the
1935 * package installed or if the version does not satisfy the
1936 * build dep. This is complicated by the fact that if we
1937 * depend on a version lower than what we already have
1938 * installed it is not clear what should be done; in practice
1939 * this case should be rare though and right now nothing
1940 * is done about it :-(
1941 */
1942 if (IV.end() == true ||
1943 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == false)
1944 TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst);
1945 }
b2e465d6
AL
1946 }
1947 }
1948
1949 Fix.InstallProtect();
1950 if (Fix.Resolve(true) == false)
1951 _error->Discard();
1952
1953 // Now we check the state of the packages,
1954 if (Cache->BrokenCount() != 0)
1955 return _error->Error(_("Some broken packages were found while trying to process build-dependencies.\n"
1956 "You might want to run `apt-get -f install' to correct these."));
1957 }
1958
1959 if (InstallPackages(Cache, false, true) == false)
1960 return _error->Error(_("Failed to process build dependencies"));
36375005
AL
1961 return true;
1962}
1963 /*}}}*/
1964
b2e465d6
AL
1965// DoMoo - Never Ask, Never Tell /*{{{*/
1966// ---------------------------------------------------------------------
1967/* */
1968bool DoMoo(CommandLine &CmdL)
1969{
1970 cout <<
1971 " (__) \n"
1972 " (oo) \n"
1973 " /------\\/ \n"
1974 " / | || \n"
1975 " * /\\---/\\ \n"
1976 " ~~ ~~ \n"
1977 "....\"Have you mooed today?\"...\n";
1978
1979 return true;
1980}
1981 /*}}}*/
0a8e3465
AL
1982// ShowHelp - Show a help screen /*{{{*/
1983// ---------------------------------------------------------------------
1984/* */
212ad54a 1985bool ShowHelp(CommandLine &CmdL)
0a8e3465 1986{
b2e465d6
AL
1987 ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
1988 COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
1989
04aa15a8 1990 if (_config->FindB("version") == true)
b2e465d6
AL
1991 {
1992 cout << _("Supported Modules:") << endl;
1993
1994 for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++)
1995 {
1996 pkgVersioningSystem *VS = pkgVersioningSystem::GlobalList[I];
1997 if (_system != 0 && _system->VS == VS)
1998 cout << '*';
1999 else
2000 cout << ' ';
2001 cout << "Ver: " << VS->Label << endl;
2002
2003 /* Print out all the packaging systems that will work with
2004 this VS */
2005 for (unsigned J = 0; J != pkgSystem::GlobalListLen; J++)
2006 {
2007 pkgSystem *Sys = pkgSystem::GlobalList[J];
2008 if (_system == Sys)
2009 cout << '*';
2010 else
2011 cout << ' ';
2012 if (Sys->VS->TestCompatibility(*VS) == true)
2013 cout << "Pkg: " << Sys->Label << " (Priority " << Sys->Score(*_config) << ")" << endl;
2014 }
2015 }
2016
2017 for (unsigned I = 0; I != pkgSourceList::Type::GlobalListLen; I++)
2018 {
2019 pkgSourceList::Type *Type = pkgSourceList::Type::GlobalList[I];
2020 cout << " S.L: '" << Type->Name << "' " << Type->Label << endl;
2021 }
2022
2023 for (unsigned I = 0; I != pkgIndexFile::Type::GlobalListLen; I++)
2024 {
2025 pkgIndexFile::Type *Type = pkgIndexFile::Type::GlobalList[I];
2026 cout << " Idx: " << Type->Label << endl;
2027 }
2028
2029 return true;
2030 }
2031
2032 cout <<
2033 _("Usage: apt-get [options] command\n"
2034 " apt-get [options] install|remove pkg1 [pkg2 ...]\n"
2035 " apt-get [options] source pkg1 [pkg2 ...]\n"
2036 "\n"
2037 "apt-get is a simple command line interface for downloading and\n"
2038 "installing packages. The most frequently used commands are update\n"
2039 "and install.\n"
2040 "\n"
2041 "Commands:\n"
2042 " update - Retrieve new lists of packages\n"
2043 " upgrade - Perform an upgrade\n"
2044 " install - Install new packages (pkg is libc6 not libc6.deb)\n"
2045 " remove - Remove packages\n"
2046 " source - Download source archives\n"
2047 " build-dep - Configure build-dependencies for source packages\n"
2048 " dist-upgrade - Distribution upgrade, see apt-get(8)\n"
2049 " dselect-upgrade - Follow dselect selections\n"
2050 " clean - Erase downloaded archive files\n"
2051 " autoclean - Erase old downloaded archive files\n"
2052 " check - Verify that there are no broken dependencies\n"
2053 "\n"
2054 "Options:\n"
2055 " -h This help text.\n"
2056 " -q Loggable output - no progress indicator\n"
2057 " -qq No output except for errors\n"
2058 " -d Download only - do NOT install or unpack archives\n"
2059 " -s No-act. Perform ordering simulation\n"
2060 " -y Assume Yes to all queries and do not prompt\n"
2061 " -f Attempt to continue if the integrity check fails\n"
2062 " -m Attempt to continue if archives are unlocatable\n"
2063 " -u Show a list of upgraded packages as well\n"
2064 " -b Build the source package after fetching it\n"
2065 " -c=? Read this configuration file\n"
2066 " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp\n"
2067 "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n"
2068 "pages for more information and options.\n"
2069 " This APT has Super Cow Powers.\n");
2070 return true;
0a8e3465
AL
2071}
2072 /*}}}*/
2073// GetInitialize - Initialize things for apt-get /*{{{*/
2074// ---------------------------------------------------------------------
2075/* */
2076void GetInitialize()
2077{
2078 _config->Set("quiet",0);
2079 _config->Set("help",false);
2080 _config->Set("APT::Get::Download-Only",false);
2081 _config->Set("APT::Get::Simulate",false);
2082 _config->Set("APT::Get::Assume-Yes",false);
2083 _config->Set("APT::Get::Fix-Broken",false);
83d89a9f 2084 _config->Set("APT::Get::Force-Yes",false);
9df71a5b 2085 _config->Set("APT::Get::APT::Get::No-List-Cleanup",true);
0a8e3465
AL
2086}
2087 /*}}}*/
d7827aca
AL
2088// SigWinch - Window size change signal handler /*{{{*/
2089// ---------------------------------------------------------------------
2090/* */
2091void SigWinch(int)
2092{
2093 // Riped from GNU ls
2094#ifdef TIOCGWINSZ
2095 struct winsize ws;
2096
2097 if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
2098 ScreenWidth = ws.ws_col - 1;
2099#endif
2100}
2101 /*}}}*/
0a8e3465
AL
2102
2103int main(int argc,const char *argv[])
2104{
2105 CommandLine::Args Args[] = {
2106 {'h',"help","help",0},
04aa15a8 2107 {'v',"version","version",0},
0a8e3465
AL
2108 {'q',"quiet","quiet",CommandLine::IntLevel},
2109 {'q',"silent","quiet",CommandLine::IntLevel},
2110 {'d',"download-only","APT::Get::Download-Only",0},
fb0ee66e
AL
2111 {'b',"compile","APT::Get::Compile",0},
2112 {'b',"build","APT::Get::Compile",0},
d150b09d
AL
2113 {'s',"simulate","APT::Get::Simulate",0},
2114 {'s',"just-print","APT::Get::Simulate",0},
2115 {'s',"recon","APT::Get::Simulate",0},
6df23d2f 2116 {'s',"dry-run","APT::Get::Simulate",0},
d150b09d
AL
2117 {'s',"no-act","APT::Get::Simulate",0},
2118 {'y',"yes","APT::Get::Assume-Yes",0},
0a8e3465
AL
2119 {'y',"assume-yes","APT::Get::Assume-Yes",0},
2120 {'f',"fix-broken","APT::Get::Fix-Broken",0},
2121 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
30e1eab5 2122 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
b2e465d6
AL
2123 {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
2124 {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
2125 {0,"download","APT::Get::Download",0},
30e1eab5 2126 {0,"fix-missing","APT::Get::Fix-Missing",0},
b2e465d6
AL
2127 {0,"ignore-hold","APT::Ignore-Hold",0},
2128 {0,"upgrade","APT::Get::upgrade",0},
83d89a9f 2129 {0,"force-yes","APT::Get::force-yes",0},
f7a08e33 2130 {0,"print-uris","APT::Get::Print-URIs",0},
5fafc0ef
AL
2131 {0,"diff-only","APT::Get::Diff-Only",0},
2132 {0,"tar-only","APT::Get::tar-Only",0},
fc4b5c9f 2133 {0,"purge","APT::Get::Purge",0},
9df71a5b 2134 {0,"list-cleanup","APT::Get::List-Cleanup",0},
d0c59649 2135 {0,"reinstall","APT::Get::ReInstall",0},
d150b09d 2136 {0,"trivial-only","APT::Get::Trivial-Only",0},
b2e465d6
AL
2137 {0,"remove","APT::Get::Remove",0},
2138 {0,"only-source","APT::Get::Only-Source",0},
45430cbf 2139 {0,"arch-only","APT::Get::Arch-Only",0},
0a8e3465
AL
2140 {'c',"config-file",0,CommandLine::ConfigFile},
2141 {'o',"option",0,CommandLine::ArbItem},
2142 {0,0,0,0}};
83d89a9f
AL
2143 CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
2144 {"upgrade",&DoUpgrade},
2145 {"install",&DoInstall},
2146 {"remove",&DoInstall},
2147 {"dist-upgrade",&DoDistUpgrade},
2148 {"dselect-upgrade",&DoDSelectUpgrade},
b2e465d6 2149 {"build-dep",&DoBuildDep},
83d89a9f 2150 {"clean",&DoClean},
1bc849af 2151 {"autoclean",&DoAutoClean},
83d89a9f 2152 {"check",&DoCheck},
67111687 2153 {"source",&DoSource},
b2e465d6 2154 {"moo",&DoMoo},
67111687 2155 {"help",&ShowHelp},
83d89a9f 2156 {0,0}};
67111687
AL
2157
2158 // Set up gettext support
2159 setlocale(LC_ALL,"");
2160 textdomain(PACKAGE);
2161
0a8e3465
AL
2162 // Parse the command line and initialize the package library
2163 CommandLine CmdL(Args,_config);
b2e465d6
AL
2164 if (pkgInitConfig(*_config) == false ||
2165 CmdL.Parse(argc,argv) == false ||
2166 pkgInitSystem(*_config,_system) == false)
0a8e3465 2167 {
b2e465d6
AL
2168 if (_config->FindB("version") == true)
2169 ShowHelp(CmdL);
2170
0a8e3465
AL
2171 _error->DumpErrors();
2172 return 100;
2173 }
2174
2175 // See if the help should be shown
2176 if (_config->FindB("help") == true ||
04aa15a8 2177 _config->FindB("version") == true ||
0a8e3465 2178 CmdL.FileSize() == 0)
b2e465d6
AL
2179 {
2180 ShowHelp(CmdL);
2181 return 0;
2182 }
67ff87bf 2183
a9a5908d
AL
2184 // Deal with stdout not being a tty
2185 if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
2186 _config->Set("quiet","1");
01b64152 2187
0a8e3465
AL
2188 // Setup the output streams
2189 c0out.rdbuf(cout.rdbuf());
2190 c1out.rdbuf(cout.rdbuf());
2191 c2out.rdbuf(cout.rdbuf());
2192 if (_config->FindI("quiet",0) > 0)
2193 c0out.rdbuf(devnull.rdbuf());
2194 if (_config->FindI("quiet",0) > 1)
2195 c1out.rdbuf(devnull.rdbuf());
d7827aca
AL
2196
2197 // Setup the signals
2198 signal(SIGPIPE,SIG_IGN);
2199 signal(SIGWINCH,SigWinch);
2200 SigWinch(0);
b2e465d6 2201
0a8e3465 2202 // Match the operation
83d89a9f 2203 CmdL.DispatchArg(Cmds);
0a8e3465
AL
2204
2205 // Print any errors or warnings found during parsing
2206 if (_error->empty() == false)
2207 {
2208 bool Errors = _error->PendingError();
2209 _error->DumpErrors();
0a8e3465
AL
2210 return Errors == true?100:0;
2211 }
2212
2213 return 0;
2214}