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