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