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