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