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