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