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