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