Working apt-get source build stuff
[ntk/apt.git] / cmdline / apt-get.cc
CommitLineData
0a8e3465
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
54676e1a 3// $Id: apt-get.cc,v 1.55 1999/04/20 05:02:09 jgg Exp $
0a8e3465
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 /*{{{*/
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>
03e39e59 35#include <apt-pkg/dpkgpm.h>
cdcc6d34 36#include <apt-pkg/strutl.h>
1bc849af 37#include <apt-pkg/clean.h>
36375005
AL
38#include <apt-pkg/srcrecords.h>
39#include <apt-pkg/version.h>
2d11135a 40#include <apt-pkg/cachefile.h>
0a8e3465
AL
41
42#include <config.h>
43
0919e3f9
AL
44#include "acqprogress.h"
45
0a8e3465 46#include <fstream.h>
d7827aca
AL
47#include <termios.h>
48#include <sys/ioctl.h>
1bc849af 49#include <sys/stat.h>
138d4b3d 50#include <sys/vfs.h>
d7827aca 51#include <signal.h>
65a1e968 52#include <unistd.h>
3e3221ba 53#include <stdio.h>
54676e1a 54#include <sys/wait.h>
0a8e3465
AL
55 /*}}}*/
56
57ostream c0out;
58ostream c1out;
59ostream c2out;
60ofstream devnull("/dev/null");
61unsigned int ScreenWidth = 80;
62
a6568219
AL
63// YnPrompt - Yes No Prompt. /*{{{*/
64// ---------------------------------------------------------------------
65/* Returns true on a Yes.*/
66bool YnPrompt()
67{
68 if (_config->FindB("APT::Get::Assume-Yes",false) == true)
69 {
738309d6 70 c1out << 'Y' << endl;
a6568219
AL
71 return true;
72 }
73
74 char C = 0;
75 char Jnk = 0;
76 read(STDIN_FILENO,&C,1);
77 while (C != '\n' && Jnk != '\n') read(STDIN_FILENO,&Jnk,1);
78
79 if (!(C == 'Y' || C == 'y' || C == '\n' || C == '\r'))
80 return false;
81 return true;
82}
83 /*}}}*/
6f86c974
AL
84// AnalPrompt - Annoying Yes No Prompt. /*{{{*/
85// ---------------------------------------------------------------------
86/* Returns true on a Yes.*/
87bool AnalPrompt(const char *Text)
88{
89 char Buf[1024];
90 cin.getline(Buf,sizeof(Buf));
91 if (strcmp(Buf,Text) == 0)
92 return true;
93 return false;
94}
95 /*}}}*/
0a8e3465
AL
96// ShowList - Show a list /*{{{*/
97// ---------------------------------------------------------------------
98/* This prints out a string of space seperated words with a title and
99 a two space indent line wraped to the current screen width. */
83d89a9f 100bool ShowList(ostream &out,string Title,string List)
0a8e3465
AL
101{
102 if (List.empty() == true)
83d89a9f 103 return true;
0a8e3465
AL
104
105 // Acount for the leading space
106 int ScreenWidth = ::ScreenWidth - 3;
107
108 out << Title << endl;
109 string::size_type Start = 0;
110 while (Start < List.size())
111 {
112 string::size_type End;
113 if (Start + ScreenWidth >= List.size())
114 End = List.size();
115 else
116 End = List.rfind(' ',Start+ScreenWidth);
117
118 if (End == string::npos || End < Start)
119 End = Start + ScreenWidth;
120 out << " " << string(List,Start,End - Start) << endl;
121 Start = End + 1;
122 }
83d89a9f 123 return false;
0a8e3465
AL
124}
125 /*}}}*/
126// ShowBroken - Debugging aide /*{{{*/
127// ---------------------------------------------------------------------
128/* This prints out the names of all the packages that are broken along
129 with the name of each each broken dependency and a quite version
130 description. */
131void ShowBroken(ostream &out,pkgDepCache &Cache)
132{
30e1eab5 133 out << "Sorry, but the following packages have unmet dependencies:" << endl;
0a8e3465
AL
134 pkgCache::PkgIterator I = Cache.PkgBegin();
135 for (;I.end() != true; I++)
136 {
303a1703
AL
137 if (Cache[I].InstBroken() == false)
138 continue;
139
140 // Print out each package and the failed dependencies
141 out <<" " << I.Name() << ":";
142 int Indent = strlen(I.Name()) + 3;
143 bool First = true;
144 if (Cache[I].InstVerIter(Cache).end() == true)
0a8e3465 145 {
303a1703
AL
146 cout << endl;
147 continue;
148 }
149
30e1eab5 150 for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false;)
303a1703 151 {
30e1eab5
AL
152 // Compute a single dependency element (glob or)
153 pkgCache::DepIterator Start;
154 pkgCache::DepIterator End;
155 D.GlobOr(Start,End);
76fbce56 156
30e1eab5
AL
157 if (Cache.IsImportantDep(End) == false ||
158 (Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
303a1703
AL
159 continue;
160
161 if (First == false)
162 for (int J = 0; J != Indent; J++)
163 out << ' ';
164 First = false;
cc718e9a 165
a65cbe33 166 out << ' ' << End.DepType() << ": " << End.TargetPkg().Name();
303a1703
AL
167
168 // Show a quick summary of the version requirements
30e1eab5
AL
169 if (End.TargetVer() != 0)
170 out << " (" << End.CompType() << " " << End.TargetVer() <<
303a1703
AL
171 ")";
172
173 /* Show a summary of the target package if possible. In the case
174 of virtual packages we show nothing */
175
30e1eab5 176 pkgCache::PkgIterator Targ = End.TargetPkg();
303a1703 177 if (Targ->ProvidesList == 0)
0a8e3465 178 {
303a1703
AL
179 out << " but ";
180 pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
181 if (Ver.end() == false)
182 out << Ver.VerStr() << " is installed";
0a8e3465 183 else
7e798dd7 184 {
303a1703
AL
185 if (Cache[Targ].CandidateVerIter(Cache).end() == true)
186 {
187 if (Targ->ProvidesList == 0)
188 out << "it is not installable";
189 else
190 out << "it is a virtual package";
191 }
7e798dd7
AL
192 else
193 out << "it is not installed";
303a1703
AL
194 }
195 }
196
197 out << endl;
198 }
0a8e3465
AL
199 }
200}
201 /*}}}*/
202// ShowNew - Show packages to newly install /*{{{*/
203// ---------------------------------------------------------------------
204/* */
205void ShowNew(ostream &out,pkgDepCache &Dep)
206{
207 /* Print out a list of packages that are going to be removed extra
208 to what the user asked */
209 pkgCache::PkgIterator I = Dep.PkgBegin();
210 string List;
211 for (;I.end() != true; I++)
212 if (Dep[I].NewInstall() == true)
213 List += string(I.Name()) + " ";
214 ShowList(out,"The following NEW packages will be installed:",List);
215}
216 /*}}}*/
217// ShowDel - Show packages to delete /*{{{*/
218// ---------------------------------------------------------------------
219/* */
220void ShowDel(ostream &out,pkgDepCache &Dep)
221{
222 /* Print out a list of packages that are going to be removed extra
223 to what the user asked */
224 pkgCache::PkgIterator I = Dep.PkgBegin();
225 string List;
226 for (;I.end() != true; I++)
227 if (Dep[I].Delete() == true)
228 List += string(I.Name()) + " ";
3d615484 229
0a8e3465
AL
230 ShowList(out,"The following packages will be REMOVED:",List);
231}
232 /*}}}*/
233// ShowKept - Show kept packages /*{{{*/
234// ---------------------------------------------------------------------
235/* */
236void ShowKept(ostream &out,pkgDepCache &Dep)
237{
238 pkgCache::PkgIterator I = Dep.PkgBegin();
239 string List;
240 for (;I.end() != true; I++)
241 {
242 // Not interesting
243 if (Dep[I].Upgrade() == true || Dep[I].Upgradable() == false ||
244 I->CurrentVer == 0 || Dep[I].Delete() == true)
245 continue;
246
247 List += string(I.Name()) + " ";
248 }
249 ShowList(out,"The following packages have been kept back",List);
250}
251 /*}}}*/
252// ShowUpgraded - Show upgraded packages /*{{{*/
253// ---------------------------------------------------------------------
254/* */
255void ShowUpgraded(ostream &out,pkgDepCache &Dep)
256{
257 pkgCache::PkgIterator I = Dep.PkgBegin();
258 string List;
259 for (;I.end() != true; I++)
260 {
261 // Not interesting
262 if (Dep[I].Upgrade() == false || Dep[I].NewInstall() == true)
263 continue;
264
265 List += string(I.Name()) + " ";
266 }
267 ShowList(out,"The following packages will be upgraded",List);
268}
269 /*}}}*/
270// ShowHold - Show held but changed packages /*{{{*/
271// ---------------------------------------------------------------------
272/* */
83d89a9f 273bool ShowHold(ostream &out,pkgDepCache &Dep)
0a8e3465
AL
274{
275 pkgCache::PkgIterator I = Dep.PkgBegin();
276 string List;
277 for (;I.end() != true; I++)
278 {
279 if (Dep[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
280 I->SelectedState == pkgCache::State::Hold)
281 List += string(I.Name()) + " ";
282 }
283
83d89a9f 284 return ShowList(out,"The following held packages will be changed:",List);
0a8e3465
AL
285}
286 /*}}}*/
287// ShowEssential - Show an essential package warning /*{{{*/
288// ---------------------------------------------------------------------
289/* This prints out a warning message that is not to be ignored. It shows
290 all essential packages and their dependents that are to be removed.
291 It is insanely risky to remove the dependents of an essential package! */
83d89a9f 292bool ShowEssential(ostream &out,pkgDepCache &Dep)
0a8e3465
AL
293{
294 pkgCache::PkgIterator I = Dep.PkgBegin();
295 string List;
296 bool *Added = new bool[Dep.HeaderP->PackageCount];
93641593 297 for (unsigned int I = 0; I != Dep.HeaderP->PackageCount; I++)
0a8e3465
AL
298 Added[I] = false;
299
300 for (;I.end() != true; I++)
301 {
302 if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential)
303 continue;
304
305 // The essential package is being removed
306 if (Dep[I].Delete() == true)
307 {
308 if (Added[I->ID] == false)
309 {
310 Added[I->ID] = true;
311 List += string(I.Name()) + " ";
312 }
313 }
314
315 if (I->CurrentVer == 0)
316 continue;
317
318 // Print out any essential package depenendents that are to be removed
319 for (pkgDepCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; D++)
320 {
3e3221ba
AL
321 // Skip everything but depends
322 if (D->Type != pkgCache::Dep::PreDepends &&
323 D->Type != pkgCache::Dep::Depends)
324 continue;
325
0a8e3465
AL
326 pkgCache::PkgIterator P = D.SmartTargetPkg();
327 if (Dep[P].Delete() == true)
328 {
329 if (Added[P->ID] == true)
330 continue;
331 Added[P->ID] = true;
3e3221ba
AL
332
333 char S[300];
334 sprintf(S,"%s (due to %s) ",P.Name(),I.Name());
335 List += S;
0a8e3465
AL
336 }
337 }
338 }
339
83d89a9f 340 delete [] Added;
0a8e3465
AL
341 if (List.empty() == false)
342 out << "WARNING: The following essential packages will be removed" << endl;
83d89a9f 343 return ShowList(out,"This should NOT be done unless you know exactly what you are doing!",List);
0a8e3465
AL
344}
345 /*}}}*/
346// Stats - Show some statistics /*{{{*/
347// ---------------------------------------------------------------------
348/* */
349void Stats(ostream &out,pkgDepCache &Dep)
350{
351 unsigned long Upgrade = 0;
352 unsigned long Install = 0;
353 for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++)
354 {
355 if (Dep[I].NewInstall() == true)
356 Install++;
357 else
358 if (Dep[I].Upgrade() == true)
359 Upgrade++;
360 }
361
362 out << Upgrade << " packages upgraded, " <<
363 Install << " newly installed, " <<
364 Dep.DelCount() << " to remove and " <<
365 Dep.KeepCount() << " not upgraded." << endl;
366
367 if (Dep.BadCount() != 0)
368 out << Dep.BadCount() << " packages not fully installed or removed." << endl;
369}
370 /*}}}*/
371
372// class CacheFile - Cover class for some dependency cache functions /*{{{*/
373// ---------------------------------------------------------------------
374/* */
2d11135a 375class CacheFile : public pkgCacheFile
0a8e3465
AL
376{
377 public:
378
2d11135a
AL
379 bool CheckDeps(bool AllowBroken = false);
380 bool Open(bool WithLock = true)
0a8e3465 381 {
2d11135a
AL
382 OpTextProgress Prog(*_config);
383 return pkgCacheFile::Open(Prog,WithLock);
384 };
0a8e3465
AL
385};
386 /*}}}*/
387// CacheFile::Open - Open the cache file /*{{{*/
388// ---------------------------------------------------------------------
389/* This routine generates the caches and then opens the dependency cache
390 and verifies that the system is OK. */
2d11135a 391bool CacheFile::CheckDeps(bool AllowBroken)
0a8e3465 392{
d38b7b3d
AL
393 if (_error->PendingError() == true)
394 return false;
0a8e3465 395
0a8e3465
AL
396 // Check that the system is OK
397 if (Cache->DelCount() != 0 || Cache->InstCount() != 0)
398 return _error->Error("Internal Error, non-zero counts");
399
400 // Apply corrections for half-installed packages
401 if (pkgApplyStatus(*Cache) == false)
402 return false;
403
404 // Nothing is broken
7c57fe64 405 if (Cache->BrokenCount() == 0 || AllowBroken == true)
0a8e3465
AL
406 return true;
407
408 // Attempt to fix broken things
409 if (_config->FindB("APT::Get::Fix-Broken",false) == true)
410 {
411 c1out << "Correcting dependencies..." << flush;
412 if (pkgFixBroken(*Cache) == false || Cache->BrokenCount() != 0)
413 {
414 c1out << " failed." << endl;
415 ShowBroken(c1out,*this);
416
417 return _error->Error("Unable to correct dependencies");
418 }
7e798dd7
AL
419 if (pkgMinimizeUpgrade(*Cache) == false)
420 return _error->Error("Unable to minimize the upgrade set");
0a8e3465
AL
421
422 c1out << " Done" << endl;
423 }
424 else
425 {
426 c1out << "You might want to run `apt-get -f install' to correct these." << endl;
427 ShowBroken(c1out,*this);
428
429 return _error->Error("Unmet dependencies. Try using -f.");
430 }
431
432 return true;
433}
434 /*}}}*/
435
436// InstallPackages - Actually download and install the packages /*{{{*/
437// ---------------------------------------------------------------------
438/* This displays the informative messages describing what is going to
439 happen and then calls the download routines */
6f86c974 440bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey = true)
0a8e3465 441{
83d89a9f 442 bool Fail = false;
6f86c974 443 bool Essential = false;
83d89a9f 444
a6568219 445 // Show all the various warning indicators
0a8e3465
AL
446 ShowDel(c1out,Cache);
447 ShowNew(c1out,Cache);
448 if (ShwKept == true)
449 ShowKept(c1out,Cache);
7a215bee 450 Fail |= !ShowHold(c1out,Cache);
0a8e3465
AL
451 if (_config->FindB("APT::Get::Show-Upgraded",false) == true)
452 ShowUpgraded(c1out,Cache);
6f86c974
AL
453 Essential = !ShowEssential(c1out,Cache);
454 Fail |= Essential;
0a8e3465
AL
455 Stats(c1out,Cache);
456
457 // Sanity check
d38b7b3d 458 if (Cache->BrokenCount() != 0)
0a8e3465
AL
459 {
460 ShowBroken(c1out,Cache);
461 return _error->Error("Internal Error, InstallPackages was called with broken packages!");
462 }
463
d38b7b3d
AL
464 if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
465 Cache->BadCount() == 0)
c60d151b 466 return true;
03e39e59
AL
467
468 // Run the simulator ..
469 if (_config->FindB("APT::Get::Simulate") == true)
470 {
471 pkgSimulate PM(Cache);
472 return PM.DoInstall();
473 }
474
475 // Create the text record parser
476 pkgRecords Recs(Cache);
83d89a9f
AL
477 if (_error->PendingError() == true)
478 return false;
479
d38b7b3d 480 // Lock the archive directory
36375005 481 FileFd Lock;
d38b7b3d
AL
482 if (_config->FindB("Debug::NoLocking",false) == false)
483 {
36375005 484 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
d38b7b3d
AL
485 if (_error->PendingError() == true)
486 return _error->Error("Unable to lock the download directory");
487 }
03e39e59
AL
488
489 // Create the download object
490 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
491 pkgAcquire Fetcher(&Stat);
492
493 // Read the source list
494 pkgSourceList List;
495 if (List.ReadMainList() == false)
496 return _error->Error("The list of sources could not be read.");
497
498 // Create the package manager and prepare to download
30e1eab5 499 pkgDPkgPM PM(Cache);
424c3bc0
AL
500 if (PM.GetArchives(&Fetcher,&List,&Recs) == false ||
501 _error->PendingError() == true)
03e39e59
AL
502 return false;
503
7a1b1f8b 504 // Display statistics
a6568219 505 unsigned long FetchBytes = Fetcher.FetchNeeded();
6b1ff003 506 unsigned long FetchPBytes = Fetcher.PartialPresent();
a6568219 507 unsigned long DebBytes = Fetcher.TotalNeeded();
d38b7b3d
AL
508 if (DebBytes != Cache->DebSize())
509 {
510 c0out << DebBytes << ',' << Cache->DebSize() << endl;
a6568219 511 c0out << "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl;
d38b7b3d 512 }
138d4b3d
AL
513
514 // Check for enough free space
515 struct statfs Buf;
516 string OutputDir = _config->FindDir("Dir::Cache::Archives");
517 if (statfs(OutputDir.c_str(),&Buf) != 0)
518 return _error->Errno("statfs","Couldn't determine free space in %s",
519 OutputDir.c_str());
6b1ff003 520 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
138d4b3d
AL
521 return _error->Error("Sorry, you don't have enough free space in %s",
522 OutputDir.c_str());
523
7a1b1f8b 524 // Number of bytes
fc9d4b7b 525 c1out << "Need to get ";
a6568219 526 if (DebBytes != FetchBytes)
fc9d4b7b 527 c1out << SizeToStr(FetchBytes) << "b/" << SizeToStr(DebBytes) << 'b';
a6568219 528 else
fc9d4b7b 529 c1out << SizeToStr(DebBytes) << 'b';
a6568219
AL
530
531 c1out << " of archives. After unpacking ";
532
7a1b1f8b 533 // Size delta
d38b7b3d 534 if (Cache->UsrSize() >= 0)
fc9d4b7b 535 c1out << SizeToStr(Cache->UsrSize()) << "b will be used." << endl;
a6568219 536 else
fc9d4b7b 537 c1out << SizeToStr(-1*Cache->UsrSize()) << "b will be freed." << endl;
a6568219
AL
538
539 if (_error->PendingError() == true)
540 return false;
541
83d89a9f 542 // Fail safe check
0c95c765
AL
543 if (_config->FindI("quiet",0) >= 2 ||
544 _config->FindB("APT::Get::Assume-Yes",false) == true)
83d89a9f
AL
545 {
546 if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
547 return _error->Error("There are problems and -y was used without --force-yes");
548 }
83d89a9f 549
6f86c974
AL
550 if (Essential == true && Saftey == true)
551 {
552 c2out << "You are about to do something potentially harmful" << endl;
36375005 553 c2out << "To continue type in the phrase 'Yes, I understand this may be bad'" << endl;
6f86c974 554 c2out << " ?] " << flush;
36375005 555 if (AnalPrompt("Yes, I understand this may be bad") == false)
6f86c974
AL
556 {
557 c2out << "Abort." << endl;
a6568219 558 exit(1);
6f86c974
AL
559 }
560 }
561 else
562 {
563 // Prompt to continue
38262e68 564 if (Ask == true || Fail == true)
6f86c974 565 {
0c95c765 566 if (_config->FindI("quiet",0) < 2 &&
6f86c974 567 _config->FindB("APT::Get::Assume-Yes",false) == false)
0c95c765 568 {
6f86c974
AL
569 c2out << "Do you want to continue? [Y/n] " << flush;
570
0c95c765
AL
571 if (YnPrompt() == false)
572 {
573 c2out << "Abort." << endl;
574 exit(1);
575 }
576 }
6f86c974
AL
577 }
578 }
579
36375005 580 // Just print out the uris an exit if the --print-uris flag was used
f7a08e33
AL
581 if (_config->FindB("APT::Get::Print-URIs") == true)
582 {
583 pkgAcquire::UriIterator I = Fetcher.UriBegin();
584 for (; I != Fetcher.UriEnd(); I++)
585 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
586 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
587 return true;
588 }
83d89a9f 589
03e39e59
AL
590 // Run it
591 if (Fetcher.Run() == false)
592 return false;
30e1eab5
AL
593
594 // Print out errors
595 bool Failed = false;
f01fe790 596 bool Transient = false;
30e1eab5
AL
597 for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
598 {
599 if ((*I)->Status == pkgAcquire::Item::StatDone &&
600 (*I)->Complete == true)
601 continue;
602
f01fe790
AL
603 if ((*I)->Status == pkgAcquire::Item::StatIdle)
604 {
605 Transient = true;
606 Failed = true;
607 continue;
608 }
609
36375005 610 cerr << "Failed to fetch " << (*I)->DescURI() << endl;
30e1eab5
AL
611 cerr << " " << (*I)->ErrorText << endl;
612 Failed = true;
613 }
45b5fa67
AL
614
615 if (_config->FindB("APT::Get::Download-Only",false) == true)
616 return true;
617
e102791a 618 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
f01fe790
AL
619 {
620 if (Transient == true)
621 {
622 c2out << "Upgrading with disk swapping is not supported in this version." << endl;
623 c2out << "Try running multiple times with --fix-missing" << endl;
624 }
625
30e1eab5 626 return _error->Error("Unable to fetch some archives, maybe try with --fix-missing?");
f01fe790
AL
627 }
628
30e1eab5 629 // Try to deal with missing package files
d38b7b3d 630 if (PM.FixMissing() == false)
30e1eab5
AL
631 {
632 cerr << "Unable to correct missing packages." << endl;
633 return _error->Error("Aborting Install.");
d38b7b3d 634 }
30e1eab5 635
2d11135a 636 Cache.ReleaseLock();
30e1eab5 637 return PM.DoInstall();
0a8e3465
AL
638}
639 /*}}}*/
640
641// DoUpdate - Update the package lists /*{{{*/
642// ---------------------------------------------------------------------
643/* */
0919e3f9 644bool DoUpdate(CommandLine &)
0a8e3465 645{
0919e3f9
AL
646 // Get the source list
647 pkgSourceList List;
648 if (List.ReadMainList() == false)
649 return false;
650
d38b7b3d 651 // Lock the list directory
36375005 652 FileFd Lock;
d38b7b3d
AL
653 if (_config->FindB("Debug::NoLocking",false) == false)
654 {
36375005 655 Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
d38b7b3d
AL
656 if (_error->PendingError() == true)
657 return _error->Error("Unable to lock the list directory");
658 }
659
0919e3f9
AL
660 // Create the download object
661 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
662 pkgAcquire Fetcher(&Stat);
663
664 // Populate it with the source selection
665 pkgSourceList::const_iterator I;
666 for (I = List.begin(); I != List.end(); I++)
667 {
668 new pkgAcqIndex(&Fetcher,I);
669 if (_error->PendingError() == true)
670 return false;
671 }
672
673 // Run it
674 if (Fetcher.Run() == false)
675 return false;
676
7a7fa5f0
AL
677 // Clean out any old list files
678 if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
679 Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
680 return false;
681
0919e3f9
AL
682 // Prepare the cache.
683 CacheFile Cache;
a65cbe33 684 if (Cache.Open() == false)
0919e3f9
AL
685 return false;
686
687 return true;
0a8e3465
AL
688}
689 /*}}}*/
690// DoUpgrade - Upgrade all packages /*{{{*/
691// ---------------------------------------------------------------------
692/* Upgrade all packages without installing new packages or erasing old
693 packages */
694bool DoUpgrade(CommandLine &CmdL)
695{
696 CacheFile Cache;
2d11135a 697 if (Cache.Open() == false || Cache.CheckDeps() == false)
0a8e3465
AL
698 return false;
699
700 // Do the upgrade
0a8e3465
AL
701 if (pkgAllUpgrade(Cache) == false)
702 {
703 ShowBroken(c1out,Cache);
704 return _error->Error("Internal Error, AllUpgrade broke stuff");
705 }
706
707 return InstallPackages(Cache,true);
708}
709 /*}}}*/
710// DoInstall - Install packages from the command line /*{{{*/
711// ---------------------------------------------------------------------
712/* Install named packages */
713bool DoInstall(CommandLine &CmdL)
714{
715 CacheFile Cache;
2d11135a 716 if (Cache.Open() == false || Cache.CheckDeps(CmdL.FileSize() != 1) == false)
0a8e3465
AL
717 return false;
718
7c57fe64
AL
719 // Enter the special broken fixing mode if the user specified arguments
720 bool BrokenFix = false;
721 if (Cache->BrokenCount() != 0)
722 BrokenFix = true;
723
a6568219
AL
724 unsigned int ExpectedInst = 0;
725 unsigned int Packages = 0;
0a8e3465
AL
726 pkgProblemResolver Fix(Cache);
727
303a1703
AL
728 bool DefRemove = false;
729 if (strcasecmp(CmdL.FileList[0],"remove") == 0)
730 DefRemove = true;
731
0a8e3465
AL
732 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
733 {
734 // Duplicate the string
735 unsigned int Length = strlen(*I);
736 char S[300];
737 if (Length >= sizeof(S))
738 continue;
739 strcpy(S,*I);
740
741 // See if we are removing the package
303a1703 742 bool Remove = DefRemove;
2c3bc8bb 743 if (Cache->FindPkg(S).end() == true)
0a8e3465 744 {
2c3bc8bb
AL
745 // Handle an optional end tag indicating what to do
746 if (S[Length - 1] == '-')
747 {
748 Remove = true;
749 S[--Length] = 0;
750 }
751 if (S[Length - 1] == '+')
752 {
753 Remove = false;
754 S[--Length] = 0;
755 }
303a1703 756 }
0a8e3465
AL
757
758 // Locate the package
759 pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
303a1703 760 Packages++;
0a8e3465
AL
761 if (Pkg.end() == true)
762 return _error->Error("Couldn't find package %s",S);
763
2c3bc8bb
AL
764 // Handle the no-upgrade case
765 if (_config->FindB("APT::Get::no-upgrade",false) == true &&
766 Pkg->CurrentVer != 0)
767 {
768 c1out << "Skipping " << Pkg.Name() << ", it is already installed and no-upgrade is set." << endl;
769 continue;
770 }
771
0a8e3465
AL
772 // Check if there is something new to install
773 pkgDepCache::StateCache &State = (*Cache)[Pkg];
774 if (State.CandidateVer == 0)
303a1703
AL
775 {
776 if (Pkg->ProvidesList != 0)
777 {
778 c1out << "Package " << S << " is a virtual package provided by:" << endl;
779
780 pkgCache::PrvIterator I = Pkg.ProvidesList();
781 for (; I.end() == false; I++)
782 {
783 pkgCache::PkgIterator Pkg = I.OwnerPkg();
784
785 if ((*Cache)[Pkg].CandidateVerIter(*Cache) == I.OwnerVer())
be5dbaf2
AL
786 {
787 if ((*Cache)[Pkg].Install() == true && (*Cache)[Pkg].NewInstall() == false)
788 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
789 " [Installed]"<< endl;
790 else
791 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
792 }
303a1703
AL
793 }
794 c1out << "You should explicly select one to install." << endl;
795 }
796 else
797 {
798 c1out << "Package " << S << " has no available version, but exists in the database." << endl;
799 c1out << "This typically means that the package was mentioned in a dependency and " << endl;
800 c1out << "never uploaded, or that it is an obsolete package." << endl;
07801a6d
AL
801
802 string List;
803 pkgCache::DepIterator Dep = Pkg.RevDependsList();
804 for (; Dep.end() == false; Dep++)
805 {
806 if (Dep->Type != pkgCache::Dep::Replaces)
807 continue;
808 List += string(Dep.ParentPkg().Name()) + " ";
809 }
810 ShowList(c1out,"However the following packages replace it:",List);
303a1703
AL
811 }
812
0a8e3465 813 return _error->Error("Package %s has no installation candidate",S);
303a1703 814 }
0a8e3465
AL
815
816 Fix.Protect(Pkg);
817 if (Remove == true)
818 {
303a1703 819 Fix.Remove(Pkg);
0a8e3465
AL
820 Cache->MarkDelete(Pkg);
821 continue;
822 }
823
824 // Install it
825 Cache->MarkInstall(Pkg,false);
826 if (State.Install() == false)
827 c1out << "Sorry, " << S << " is already the newest version" << endl;
828 else
829 ExpectedInst++;
830
831 // Install it with autoinstalling enabled.
7c57fe64 832 if (State.InstBroken() == true && BrokenFix == false)
0a8e3465
AL
833 Cache->MarkInstall(Pkg,true);
834 }
835
7c57fe64
AL
836 /* If we are in the Broken fixing mode we do not attempt to fix the
837 problems. This is if the user invoked install without -f and gave
838 packages */
839 if (BrokenFix == true && Cache->BrokenCount() != 0)
840 {
841 c1out << "You might want to run `apt-get -f install' to correct these." << endl;
842 ShowBroken(c1out,Cache);
843
844 return _error->Error("Unmet dependencies. Try using -f.");
845 }
846
0a8e3465 847 // Call the scored problem resolver
303a1703 848 Fix.InstallProtect();
0a8e3465
AL
849 if (Fix.Resolve(true) == false)
850 _error->Discard();
851
852 // Now we check the state of the packages,
853 if (Cache->BrokenCount() != 0)
854 {
303a1703
AL
855 c1out << "Some packages could not be installed. This may mean that you have" << endl;
856 c1out << "requested an impossible situation or if you are using the unstable" << endl;
857 c1out << "distribution that some required packages have not yet been created" << endl;
858 c1out << "or been moved out of Incoming." << endl;
859 if (Packages == 1)
860 {
861 c1out << endl;
862 c1out << "Since you only requested a single operation it is extremely likely that" << endl;
863 c1out << "the package is simply not installable and a bug report against" << endl;
864 c1out << "that package should be filed." << endl;
865 }
866
867 c1out << "The following information may help to resolve the situation:" << endl;
868 c1out << endl;
0a8e3465
AL
869 ShowBroken(c1out,Cache);
870 return _error->Error("Sorry, broken packages");
871 }
872
873 /* Print out a list of packages that are going to be installed extra
874 to what the user asked */
875 if (Cache->InstCount() != ExpectedInst)
876 {
877 string List;
878 pkgCache::PkgIterator I = Cache->PkgBegin();
879 for (;I.end() != true; I++)
880 {
881 if ((*Cache)[I].Install() == false)
882 continue;
883
884 const char **J;
885 for (J = CmdL.FileList + 1; *J != 0; J++)
886 if (strcmp(*J,I.Name()) == 0)
887 break;
888
889 if (*J == 0)
890 List += string(I.Name()) + " ";
891 }
892
893 ShowList(c1out,"The following extra packages will be installed:",List);
894 }
895
03e39e59 896 // See if we need to prompt
2c3bc8bb 897 if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
2c3bc8bb 898 return InstallPackages(Cache,false,false);
2c3bc8bb 899
03e39e59 900 return InstallPackages(Cache,false);
0a8e3465
AL
901}
902 /*}}}*/
903// DoDistUpgrade - Automatic smart upgrader /*{{{*/
904// ---------------------------------------------------------------------
905/* Intelligent upgrader that will install and remove packages at will */
906bool DoDistUpgrade(CommandLine &CmdL)
907{
908 CacheFile Cache;
2d11135a 909 if (Cache.Open() == false || Cache.CheckDeps() == false)
0a8e3465
AL
910 return false;
911
912 c0out << "Calculating Upgrade... " << flush;
913 if (pkgDistUpgrade(*Cache) == false)
914 {
915 c0out << "Failed" << endl;
916 ShowBroken(c1out,Cache);
917 return false;
918 }
919
920 c0out << "Done" << endl;
921
922 return InstallPackages(Cache,true);
923}
924 /*}}}*/
925// DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
926// ---------------------------------------------------------------------
927/* Follows dselect's selections */
928bool DoDSelectUpgrade(CommandLine &CmdL)
929{
930 CacheFile Cache;
2d11135a 931 if (Cache.Open() == false || Cache.CheckDeps() == false)
0a8e3465
AL
932 return false;
933
934 // Install everything with the install flag set
935 pkgCache::PkgIterator I = Cache->PkgBegin();
936 for (;I.end() != true; I++)
937 {
938 /* Install the package only if it is a new install, the autoupgrader
939 will deal with the rest */
940 if (I->SelectedState == pkgCache::State::Install)
941 Cache->MarkInstall(I,false);
942 }
943
944 /* Now install their deps too, if we do this above then order of
945 the status file is significant for | groups */
946 for (I = Cache->PkgBegin();I.end() != true; I++)
947 {
948 /* Install the package only if it is a new install, the autoupgrader
949 will deal with the rest */
950 if (I->SelectedState == pkgCache::State::Install)
2f45c76a 951 Cache->MarkInstall(I,true);
0a8e3465
AL
952 }
953
954 // Apply erasures now, they override everything else.
955 for (I = Cache->PkgBegin();I.end() != true; I++)
956 {
957 // Remove packages
958 if (I->SelectedState == pkgCache::State::DeInstall ||
959 I->SelectedState == pkgCache::State::Purge)
960 Cache->MarkDelete(I);
961 }
962
2f45c76a
AL
963 /* Resolve any problems that dselect created, allupgrade cannot handle
964 such things. We do so quite agressively too.. */
965 if (Cache->BrokenCount() != 0)
966 {
967 pkgProblemResolver Fix(Cache);
968
969 // Hold back held packages.
970 if (_config->FindB("APT::Ingore-Hold",false) == false)
971 {
972 for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++)
973 {
974 if (I->SelectedState == pkgCache::State::Hold)
975 {
976 Fix.Protect(I);
977 Cache->MarkKeep(I);
978 }
979 }
980 }
981
982 if (Fix.Resolve() == false)
983 {
984 ShowBroken(c1out,Cache);
985 return _error->Error("Internal Error, problem resolver broke stuff");
986 }
987 }
988
989 // Now upgrade everything
0a8e3465
AL
990 if (pkgAllUpgrade(Cache) == false)
991 {
992 ShowBroken(c1out,Cache);
2f45c76a 993 return _error->Error("Internal Error, problem resolver broke stuff");
0a8e3465
AL
994 }
995
996 return InstallPackages(Cache,false);
997}
998 /*}}}*/
999// DoClean - Remove download archives /*{{{*/
1000// ---------------------------------------------------------------------
1001/* */
1002bool DoClean(CommandLine &CmdL)
1003{
7a1b1f8b
AL
1004 pkgAcquire Fetcher;
1005 Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
1006 Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
0a8e3465
AL
1007 return true;
1008}
1009 /*}}}*/
1bc849af
AL
1010// DoAutoClean - Smartly remove downloaded archives /*{{{*/
1011// ---------------------------------------------------------------------
1012/* This is similar to clean but it only purges things that cannot be
1013 downloaded, that is old versions of cached packages. */
65a1e968
AL
1014class LogCleaner : public pkgArchiveCleaner
1015{
1016 protected:
1017 virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St)
1018 {
1019 cout << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "b]" << endl;
1020 };
1021};
1022
1bc849af
AL
1023bool DoAutoClean(CommandLine &CmdL)
1024{
1025 CacheFile Cache;
2d11135a 1026 if (Cache.Open() == false)
1bc849af
AL
1027 return false;
1028
65a1e968 1029 LogCleaner Cleaner;
1bc849af
AL
1030
1031 return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) &&
1032 Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache);
1033}
1034 /*}}}*/
0a8e3465
AL
1035// DoCheck - Perform the check operation /*{{{*/
1036// ---------------------------------------------------------------------
1037/* Opening automatically checks the system, this command is mostly used
1038 for debugging */
1039bool DoCheck(CommandLine &CmdL)
1040{
1041 CacheFile Cache;
1042 Cache.Open();
2d11135a 1043 Cache.CheckDeps();
0a8e3465
AL
1044
1045 return true;
1046}
1047 /*}}}*/
36375005
AL
1048// DoSource - Fetch a source archive /*{{{*/
1049// ---------------------------------------------------------------------
2d11135a 1050/* Fetch souce packages */
fb0ee66e
AL
1051struct DscFile
1052{
1053 string Package;
1054 string Version;
1055 string Dsc;
1056};
1057
36375005
AL
1058bool DoSource(CommandLine &CmdL)
1059{
1060 CacheFile Cache;
2d11135a 1061 if (Cache.Open(false) == false)
36375005
AL
1062 return false;
1063
2d11135a
AL
1064 if (CmdL.FileSize() <= 1)
1065 return _error->Error("Must specify at least one package to fetch source for");
1066
36375005
AL
1067 // Read the source list
1068 pkgSourceList List;
1069 if (List.ReadMainList() == false)
1070 return _error->Error("The list of sources could not be read.");
1071
1072 // Create the text record parsers
1073 pkgRecords Recs(Cache);
1074 pkgSrcRecords SrcRecs(List);
1075 if (_error->PendingError() == true)
1076 return false;
1077
1078 // Create the download object
1079 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1080 pkgAcquire Fetcher(&Stat);
fb0ee66e
AL
1081
1082 DscFile *Dsc = new DscFile[CmdL.FileSize()];
36375005
AL
1083
1084 // Load the requestd sources into the fetcher
fb0ee66e
AL
1085 unsigned J = 0;
1086 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
36375005
AL
1087 {
1088 string Src;
0a8e3465 1089
36375005
AL
1090 /* Lookup the version of the package we would install if we were to
1091 install a version and determine the source package name, then look
1092 in the archive for a source package of the same name. In theory
1093 we could stash the version string as well and match that too but
1094 today there aren't multi source versions in the archive. */
1095 pkgCache::PkgIterator Pkg = Cache->FindPkg(*I);
1096 if (Pkg.end() == false)
1097 {
1098 pkgCache::VerIterator Ver = Cache->GetCandidateVer(Pkg);
1099 if (Ver.end() == false)
1100 {
1101 pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
1102 Src = Parse.SourcePkg();
1103 }
1104 }
1105
1106 // No source package name..
1107 if (Src.empty() == true)
1108 Src = *I;
1109
1110 // The best hit
1111 pkgSrcRecords::Parser *Last = 0;
1112 unsigned long Offset = 0;
1113 string Version;
1114
1115 // Iterate over all of the hits
1116 pkgSrcRecords::Parser *Parse;
1117 SrcRecs.Restart();
1118 while ((Parse = SrcRecs.Find(Src.c_str(),false)) != 0)
1119 {
1120 string Ver = Parse->Version();
1121 if (Last == 0 || pkgVersionCompare(Version,Ver) < 0)
1122 {
1123 Last = Parse;
1124 Offset = Parse->Offset();
1125 Version = Ver;
1126 }
1127 }
1128
1129 if (Last == 0)
1130 return _error->Error("Unable to find a source package for %s",Src.c_str());
1131
1132 // Back track
1133 vector<pkgSrcRecords::File> Lst;
1134 if (Last->Jump(Offset) == false || Last->Files(Lst) == false)
1135 return false;
1136
1137 // Load them into the fetcher
1138 for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
1139 I != Lst.end(); I++)
1140 {
1141 // Try to guess what sort of file it is we are getting.
1142 string Comp;
1143 if (I->Path.find(".dsc") != string::npos)
fb0ee66e 1144 {
36375005 1145 Comp = "dsc";
fb0ee66e
AL
1146 Dsc[J].Package = Last->Package();
1147 Dsc[J].Version = Last->Version();
1148 Dsc[J].Dsc = flNotDir(I->Path);
1149 }
1150
36375005
AL
1151 if (I->Path.find(".tar.gz") != string::npos)
1152 Comp = "tar";
1153 if (I->Path.find(".diff.gz") != string::npos)
1154 Comp = "diff";
1155
1156 new pkgAcqFile(&Fetcher,Last->Source()->ArchiveURI(I->Path),
1157 I->MD5Hash,I->Size,Last->Source()->SourceInfo(Src,
1158 Last->Version(),Comp),Src);
1159 }
1160 }
1161
1162 // Display statistics
1163 unsigned long FetchBytes = Fetcher.FetchNeeded();
1164 unsigned long FetchPBytes = Fetcher.PartialPresent();
1165 unsigned long DebBytes = Fetcher.TotalNeeded();
1166
1167 // Check for enough free space
1168 struct statfs Buf;
1169 string OutputDir = ".";
1170 if (statfs(OutputDir.c_str(),&Buf) != 0)
1171 return _error->Errno("statfs","Couldn't determine free space in %s",
1172 OutputDir.c_str());
1173 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
1174 return _error->Error("Sorry, you don't have enough free space in %s",
1175 OutputDir.c_str());
1176
1177 // Number of bytes
1178 c1out << "Need to get ";
1179 if (DebBytes != FetchBytes)
1180 c1out << SizeToStr(FetchBytes) << "b/" << SizeToStr(DebBytes) << 'b';
1181 else
1182 c1out << SizeToStr(DebBytes) << 'b';
1183 c1out << " of source archives." << endl;
1184
1185 // Just print out the uris an exit if the --print-uris flag was used
1186 if (_config->FindB("APT::Get::Print-URIs") == true)
1187 {
1188 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1189 for (; I != Fetcher.UriEnd(); I++)
1190 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1191 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
1192 return true;
1193 }
1194
1195 // Run it
1196 if (Fetcher.Run() == false)
1197 return false;
1198
1199 // Print error messages
fb0ee66e 1200 bool Failed = false;
36375005
AL
1201 for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
1202 {
1203 if ((*I)->Status == pkgAcquire::Item::StatDone &&
1204 (*I)->Complete == true)
1205 continue;
1206
1207 cerr << "Failed to fetch " << (*I)->DescURI() << endl;
1208 cerr << " " << (*I)->ErrorText << endl;
fb0ee66e 1209 Failed = true;
36375005 1210 }
fb0ee66e
AL
1211 if (Failed == true)
1212 return _error->Error("Failed to fetch some archives.");
1213
1214 if (_config->FindB("APT::Get::Download-only",false) == true)
1215 return true;
36375005 1216
fb0ee66e 1217 // Unpack the sources
54676e1a
AL
1218 pid_t Process = ExecFork();
1219
1220 if (Process == 0)
fb0ee66e 1221 {
54676e1a 1222 for (unsigned I = 0; I != J; I++)
fb0ee66e 1223 {
54676e1a 1224 string Dir = Dsc[I].Package + '-' + pkgBaseVersion(Dsc[I].Version.c_str());
fb0ee66e 1225
54676e1a
AL
1226 // See if the package is already unpacked
1227 struct stat Stat;
1228 if (stat(Dir.c_str(),&Stat) == 0 &&
1229 S_ISDIR(Stat.st_mode) != 0)
1230 {
1231 c0out << "Skipping unpack of already unpacked source in " << Dir << endl;
1232 }
1233 else
1234 {
1235 // Call dpkg-source
1236 char S[500];
1237 snprintf(S,sizeof(S),"%s -x %s",
1238 _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
1239 Dsc[I].Dsc.c_str());
1240 if (system(S) != 0)
1241 {
1242 cerr << "Unpack command '" << S << "' failed." << endl;
1243 _exit(1);
1244 }
1245 }
1246
1247 // Try to compile it with dpkg-buildpackage
1248 if (_config->FindB("APT::Get::Compile",false) == true)
1249 {
1250 // Call dpkg-buildpackage
1251 char S[500];
1252 snprintf(S,sizeof(S),"cd %s && %s %s",
1253 Dir.c_str(),
1254 _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
1255 _config->Find("DPkg::Build-Options","-b -uc").c_str());
1256
1257 if (system(S) != 0)
1258 {
1259 cerr << "Build command '" << S << "' failed." << endl;
1260 _exit(1);
1261 }
1262 }
1263 }
1264
1265 _exit(0);
1266 }
1267
1268 // Wait for the subprocess
1269 int Status = 0;
1270 while (waitpid(Process,&Status,0) != Process)
1271 {
1272 if (errno == EINTR)
1273 continue;
1274 return _error->Errno("waitpid","Couldn't wait for subprocess");
1275 }
1276
1277 if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
1278 return _error->Error("Child process failed");
1279
36375005
AL
1280 return true;
1281}
1282 /*}}}*/
1283
0a8e3465
AL
1284// ShowHelp - Show a help screen /*{{{*/
1285// ---------------------------------------------------------------------
1286/* */
212ad54a 1287bool ShowHelp(CommandLine &CmdL)
0a8e3465
AL
1288{
1289 cout << PACKAGE << ' ' << VERSION << " for " << ARCHITECTURE <<
1290 " compiled on " << __DATE__ << " " << __TIME__ << endl;
04aa15a8
AL
1291 if (_config->FindB("version") == true)
1292 return 100;
1293
0a8e3465
AL
1294 cout << "Usage: apt-get [options] command" << endl;
1295 cout << " apt-get [options] install pkg1 [pkg2 ...]" << endl;
1296 cout << endl;
1297 cout << "apt-get is a simple command line interface for downloading and" << endl;
1298 cout << "installing packages. The most frequently used commands are update" << endl;
1299 cout << "and install." << endl;
1300 cout << endl;
1301 cout << "Commands:" << endl;
1302 cout << " update - Retrieve new lists of packages" << endl;
1303 cout << " upgrade - Perform an upgrade" << endl;
1304 cout << " install - Install new packages (pkg is libc6 not libc6.deb)" << endl;
303a1703 1305 cout << " remove - Remove packages" << endl;
4994560c 1306 cout << " source - Download source archives" << endl;
0a8e3465
AL
1307 cout << " dist-upgrade - Distribution upgrade, see apt-get(8)" << endl;
1308 cout << " dselect-upgrade - Follow dselect selections" << endl;
1309 cout << " clean - Erase downloaded archive files" << endl;
1bc849af 1310 cout << " autoclean - Erase old downloaded archive files" << endl;
0a8e3465
AL
1311 cout << " check - Verify that there are no broken dependencies" << endl;
1312 cout << endl;
1313 cout << "Options:" << endl;
c217f42a
AL
1314 cout << " -h This help text." << endl;
1315 cout << " -q Loggable output - no progress indicator" << endl;
0a8e3465
AL
1316 cout << " -qq No output except for errors" << endl;
1317 cout << " -d Download only - do NOT install or unpack archives" << endl;
1318 cout << " -s No-act. Perform ordering simulation" << endl;
1319 cout << " -y Assume Yes to all queries and do not prompt" << endl;
1320 cout << " -f Attempt to continue if the integrity check fails" << endl;
1321 cout << " -m Attempt to continue if archives are unlocatable" << endl;
1322 cout << " -u Show a list of upgraded packages as well" << endl;
1323 cout << " -c=? Read this configuration file" << endl;
7974b907 1324 cout << " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" << endl;
21ae3cae 1325 cout << "See the apt-get(8), sources.list(5) and apt.conf(5) manual" << endl;
0a8e3465
AL
1326 cout << "pages for more information." << endl;
1327 return 100;
1328}
1329 /*}}}*/
1330// GetInitialize - Initialize things for apt-get /*{{{*/
1331// ---------------------------------------------------------------------
1332/* */
1333void GetInitialize()
1334{
1335 _config->Set("quiet",0);
1336 _config->Set("help",false);
1337 _config->Set("APT::Get::Download-Only",false);
1338 _config->Set("APT::Get::Simulate",false);
1339 _config->Set("APT::Get::Assume-Yes",false);
1340 _config->Set("APT::Get::Fix-Broken",false);
83d89a9f 1341 _config->Set("APT::Get::Force-Yes",false);
0a8e3465
AL
1342}
1343 /*}}}*/
d7827aca
AL
1344// SigWinch - Window size change signal handler /*{{{*/
1345// ---------------------------------------------------------------------
1346/* */
1347void SigWinch(int)
1348{
1349 // Riped from GNU ls
1350#ifdef TIOCGWINSZ
1351 struct winsize ws;
1352
1353 if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
1354 ScreenWidth = ws.ws_col - 1;
1355#endif
1356}
1357 /*}}}*/
0a8e3465
AL
1358
1359int main(int argc,const char *argv[])
1360{
1361 CommandLine::Args Args[] = {
1362 {'h',"help","help",0},
04aa15a8 1363 {'v',"version","version",0},
0a8e3465
AL
1364 {'q',"quiet","quiet",CommandLine::IntLevel},
1365 {'q',"silent","quiet",CommandLine::IntLevel},
1366 {'d',"download-only","APT::Get::Download-Only",0},
fb0ee66e
AL
1367 {'b',"compile","APT::Get::Compile",0},
1368 {'b',"build","APT::Get::Compile",0},
0a8e3465
AL
1369 {'s',"simulate","APT::Get::Simulate",0},
1370 {'s',"just-print","APT::Get::Simulate",0},
1371 {'s',"recon","APT::Get::Simulate",0},
1372 {'s',"no-act","APT::Get::Simulate",0},
1373 {'y',"yes","APT::Get::Assume-Yes",0},
1374 {'y',"assume-yes","APT::Get::Assume-Yes",0},
1375 {'f',"fix-broken","APT::Get::Fix-Broken",0},
1376 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
30e1eab5
AL
1377 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
1378 {0,"fix-missing","APT::Get::Fix-Missing",0},
c88edf1d 1379 {0,"ignore-hold","APT::Ingore-Hold",0},
83d89a9f
AL
1380 {0,"no-upgrade","APT::Get::no-upgrade",0},
1381 {0,"force-yes","APT::Get::force-yes",0},
f7a08e33 1382 {0,"print-uris","APT::Get::Print-URIs",0},
0a8e3465
AL
1383 {'c',"config-file",0,CommandLine::ConfigFile},
1384 {'o',"option",0,CommandLine::ArbItem},
1385 {0,0,0,0}};
83d89a9f
AL
1386 CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
1387 {"upgrade",&DoUpgrade},
1388 {"install",&DoInstall},
1389 {"remove",&DoInstall},
1390 {"dist-upgrade",&DoDistUpgrade},
1391 {"dselect-upgrade",&DoDSelectUpgrade},
1392 {"clean",&DoClean},
1bc849af 1393 {"autoclean",&DoAutoClean},
83d89a9f 1394 {"check",&DoCheck},
36375005 1395 {"source",&DoSource},
3d615484 1396 {"help",&ShowHelp},
83d89a9f 1397 {0,0}};
0a8e3465
AL
1398
1399 // Parse the command line and initialize the package library
1400 CommandLine CmdL(Args,_config);
1401 if (pkgInitialize(*_config) == false ||
1402 CmdL.Parse(argc,argv) == false)
1403 {
1404 _error->DumpErrors();
1405 return 100;
1406 }
1407
1408 // See if the help should be shown
1409 if (_config->FindB("help") == true ||
04aa15a8 1410 _config->FindB("version") == true ||
0a8e3465 1411 CmdL.FileSize() == 0)
3d615484 1412 return ShowHelp(CmdL);
0a8e3465 1413
a9a5908d
AL
1414 // Deal with stdout not being a tty
1415 if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
1416 _config->Set("quiet","1");
1417
0a8e3465
AL
1418 // Setup the output streams
1419 c0out.rdbuf(cout.rdbuf());
1420 c1out.rdbuf(cout.rdbuf());
1421 c2out.rdbuf(cout.rdbuf());
1422 if (_config->FindI("quiet",0) > 0)
1423 c0out.rdbuf(devnull.rdbuf());
1424 if (_config->FindI("quiet",0) > 1)
1425 c1out.rdbuf(devnull.rdbuf());
d7827aca
AL
1426
1427 // Setup the signals
1428 signal(SIGPIPE,SIG_IGN);
1429 signal(SIGWINCH,SigWinch);
1430 SigWinch(0);
0a8e3465
AL
1431
1432 // Match the operation
83d89a9f 1433 CmdL.DispatchArg(Cmds);
0a8e3465
AL
1434
1435 // Print any errors or warnings found during parsing
1436 if (_error->empty() == false)
1437 {
1438 bool Errors = _error->PendingError();
1439 _error->DumpErrors();
0a8e3465
AL
1440 return Errors == true?100:0;
1441 }
1442
1443 return 0;
1444}