]>
git.saurik.com Git - apt.git/blob - cmdline/apt-get.cc
6353adf33518f017ca53b010030d50a77aabfa82
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>
17 #include "acqprogress.h"
21 #include <sys/ioctl.h>
34 ofstream
devnull("/dev/null");
35 unsigned int ScreenWidth
= 80;
37 // class CacheFile - Cover class for some dependency cache functions /*{{{*/
38 // ---------------------------------------------------------------------
40 class CacheFile
: public pkgCacheFile
42 static pkgCache
*SortCache
;
43 static int NameComp(const void *a
,const void *b
);
46 pkgCache::Package
**List
;
49 bool CheckDeps(bool AllowBroken
= false);
50 bool Open(bool WithLock
= true)
52 OpTextProgress
Prog(*_config
);
53 if (pkgCacheFile::Open(Prog
,WithLock
) == false)
58 CacheFile() : List(0) {};
62 // YnPrompt - Yes No Prompt. /*{{{*/
63 // ---------------------------------------------------------------------
64 /* Returns true on a Yes.*/
67 if (_config
->FindB("APT::Get::Assume-Yes",false) == true)
75 read(STDIN_FILENO
,&C
,1);
76 while (C
!= '\n' && Jnk
!= '\n') read(STDIN_FILENO
,&Jnk
,1);
78 if (!(C
== 'Y' || C
== 'y' || C
== '\n' || C
== '\r'))
83 // AnalPrompt - Annoying Yes No Prompt. /*{{{*/
84 // ---------------------------------------------------------------------
85 /* Returns true on a Yes.*/
86 bool AnalPrompt(const char *Text
)
89 cin
.getline(Buf
,sizeof(Buf
));
90 if (strcmp(Buf
,Text
) == 0)
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. */
99 bool ShowList(ostream
&out
,string Title
,string List
)
101 if (List
.empty() == true)
104 // Acount for the leading space
105 int ScreenWidth
= ::ScreenWidth
- 3;
107 out
<< Title
<< endl
;
108 string::size_type Start
= 0;
109 while (Start
< List
.size())
111 string::size_type End
;
112 if (Start
+ ScreenWidth
>= List
.size())
115 End
= List
.rfind(' ',Start
+ScreenWidth
);
117 if (End
== string::npos
|| End
< Start
)
118 End
= Start
+ ScreenWidth
;
119 out
<< " " << string(List
,Start
,End
- Start
) << endl
;
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
130 void ShowBroken(ostream
&out
,CacheFile
&Cache
,bool Now
)
132 out
<< "Sorry, but the following packages have unmet dependencies:" << endl
;
133 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
135 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
137 if (Cache
[I
].InstBroken() == false)
140 // Print out each package and the failed dependencies
141 out
<<" " << I
.Name() << ":";
142 int Indent
= strlen(I
.Name()) + 3;
144 if (Cache
[I
].InstVerIter(Cache
).end() == true)
150 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
152 // Compute a single dependency element (glob or)
153 pkgCache::DepIterator Start
;
154 pkgCache::DepIterator End
;
157 if (Cache
->IsImportantDep(End
) == false ||
158 (Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
162 for (int J
= 0; J
!= Indent
; J
++)
166 out
<< ' ' << End
.DepType() << ": " << End
.TargetPkg().Name();
168 // Show a quick summary of the version requirements
169 if (End
.TargetVer() != 0)
170 out
<< " (" << End
.CompType() << " " << End
.TargetVer() <<
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)
179 pkgCache::VerIterator Ver
= Cache
[Targ
].InstVerIter(Cache
);
180 if (Ver
.end() == false)
181 out
<< Ver
.VerStr() << (Now
?" is installed":" is to be installed");
184 if (Cache
[Targ
].CandidateVerIter(Cache
).end() == true)
186 if (Targ
->ProvidesList
== 0)
187 out
<< "it is not installable";
189 out
<< "it is a virtual package";
192 out
<< (Now
?"it is not installed":"it is not going to be installed");
201 // ShowNew - Show packages to newly install /*{{{*/
202 // ---------------------------------------------------------------------
204 void ShowNew(ostream
&out
,CacheFile
&Cache
)
206 /* Print out a list of packages that are going to be removed extra
207 to what the user asked */
209 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
211 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
212 if (Cache
[I
].NewInstall() == true)
213 List
+= string(I
.Name()) + " ";
216 ShowList(out
,"The following NEW packages will be installed:",List
);
219 // ShowDel - Show packages to delete /*{{{*/
220 // ---------------------------------------------------------------------
222 void ShowDel(ostream
&out
,CacheFile
&Cache
)
224 /* Print out a list of packages that are going to be removed extra
225 to what the user asked */
227 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
229 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
230 if (Cache
[I
].Delete() == true)
232 if ((Cache
[I
].iFlags
& pkgDepCache::Purge
) == pkgDepCache::Purge
)
233 List
+= string(I
.Name()) + "* ";
235 List
+= string(I
.Name()) + " ";
239 ShowList(out
,"The following packages will be REMOVED:",List
);
242 // ShowKept - Show kept packages /*{{{*/
243 // ---------------------------------------------------------------------
245 void ShowKept(ostream
&out
,CacheFile
&Cache
)
248 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
250 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
253 if (Cache
[I
].Upgrade() == true || Cache
[I
].Upgradable() == false ||
254 I
->CurrentVer
== 0 || Cache
[I
].Delete() == true)
257 List
+= string(I
.Name()) + " ";
259 ShowList(out
,"The following packages have been kept back",List
);
262 // ShowUpgraded - Show upgraded packages /*{{{*/
263 // ---------------------------------------------------------------------
265 void ShowUpgraded(ostream
&out
,CacheFile
&Cache
)
268 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
270 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
273 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
276 List
+= string(I
.Name()) + " ";
278 ShowList(out
,"The following packages will be upgraded",List
);
281 // ShowHold - Show held but changed packages /*{{{*/
282 // ---------------------------------------------------------------------
284 bool ShowHold(ostream
&out
,CacheFile
&Cache
)
287 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
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()) + " ";
295 return ShowList(out
,"The following held packages will be changed:",List
);
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! */
303 bool ShowEssential(ostream
&out
,CacheFile
&Cache
)
306 bool *Added
= new bool[Cache
->HeaderP
->PackageCount
];
307 for (unsigned int I
= 0; I
!= Cache
->HeaderP
->PackageCount
; I
++)
310 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
312 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
313 if ((I
->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
316 // The essential package is being removed
317 if (Cache
[I
].Delete() == true)
319 if (Added
[I
->ID
] == false)
322 List
+= string(I
.Name()) + " ";
326 if (I
->CurrentVer
== 0)
329 // Print out any essential package depenendents that are to be removed
330 for (pkgDepCache::DepIterator D
= I
.CurrentVer().DependsList(); D
.end() == false; D
++)
332 // Skip everything but depends
333 if (D
->Type
!= pkgCache::Dep::PreDepends
&&
334 D
->Type
!= pkgCache::Dep::Depends
)
337 pkgCache::PkgIterator P
= D
.SmartTargetPkg();
338 if (Cache
[P
].Delete() == true)
340 if (Added
[P
->ID
] == true)
345 sprintf(S
,"%s (due to %s) ",P
.Name(),I
.Name());
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
);
357 // Stats - Show some statistics /*{{{*/
358 // ---------------------------------------------------------------------
360 void Stats(ostream
&out
,pkgDepCache
&Dep
)
362 unsigned long Upgrade
= 0;
363 unsigned long Install
= 0;
364 for (pkgCache::PkgIterator I
= Dep
.PkgBegin(); I
.end() == false; I
++)
366 if (Dep
[I
].NewInstall() == true)
369 if (Dep
[I
].Upgrade() == true)
373 out
<< Upgrade
<< " packages upgraded, " <<
374 Install
<< " newly installed, " <<
375 Dep
.DelCount() << " to remove and " <<
376 Dep
.KeepCount() << " not upgraded." << endl
;
378 if (Dep
.BadCount() != 0)
379 out
<< Dep
.BadCount() << " packages not fully installed or removed." << endl
;
383 // CacheFile::NameComp - QSort compare by name /*{{{*/
384 // ---------------------------------------------------------------------
386 pkgCache
*CacheFile::SortCache
= 0;
387 int CacheFile::NameComp(const void *a
,const void *b
)
389 if (*(pkgCache::Package
**)a
== 0 || *(pkgCache::Package
**)b
== 0)
390 return *(pkgCache::Package
**)a
- *(pkgCache::Package
**)b
;
392 const pkgCache::Package
&A
= **(pkgCache::Package
**)a
;
393 const pkgCache::Package
&B
= **(pkgCache::Package
**)b
;
395 return strcmp(SortCache
->StrP
+ A
.Name
,SortCache
->StrP
+ B
.Name
);
398 // CacheFile::Sort - Sort by name /*{{{*/
399 // ---------------------------------------------------------------------
401 void CacheFile::Sort()
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
++)
411 qsort(List
,Cache
->Head().PackageCount
,sizeof(*List
),NameComp
);
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. */
418 bool CacheFile::CheckDeps(bool AllowBroken
)
420 if (_error
->PendingError() == true)
423 // Check that the system is OK
424 if (Cache
->DelCount() != 0 || Cache
->InstCount() != 0)
425 return _error
->Error("Internal Error, non-zero counts");
427 // Apply corrections for half-installed packages
428 if (pkgApplyStatus(*Cache
) == false)
432 if (Cache
->BrokenCount() == 0 || AllowBroken
== true)
435 // Attempt to fix broken things
436 if (_config
->FindB("APT::Get::Fix-Broken",false) == true)
438 c1out
<< "Correcting dependencies..." << flush
;
439 if (pkgFixBroken(*Cache
) == false || Cache
->BrokenCount() != 0)
441 c1out
<< " failed." << endl
;
442 ShowBroken(c1out
,*this,true);
444 return _error
->Error("Unable to correct dependencies");
446 if (pkgMinimizeUpgrade(*Cache
) == false)
447 return _error
->Error("Unable to minimize the upgrade set");
449 c1out
<< " Done" << endl
;
453 c1out
<< "You might want to run `apt-get -f install' to correct these." << endl
;
454 ShowBroken(c1out
,*this,true);
456 return _error
->Error("Unmet dependencies. Try using -f.");
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 */
467 bool InstallPackages(CacheFile
&Cache
,bool ShwKept
,bool Ask
= true,bool Saftey
= true)
469 if (_config
->FindB("APT::Get::Purge",false) == true)
471 pkgCache::PkgIterator I
= Cache
->PkgBegin();
472 for (; I
.end() == false; I
++)
474 if (I
.Purge() == false && Cache
[I
].Mode
== pkgDepCache::ModeDelete
)
475 Cache
->MarkDelete(I
,true);
480 bool Essential
= false;
482 // Show all the various warning indicators
483 ShowDel(c1out
,Cache
);
484 ShowNew(c1out
,Cache
);
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
);
495 if (Cache
->BrokenCount() != 0)
497 ShowBroken(c1out
,Cache
,false);
498 return _error
->Error("Internal Error, InstallPackages was called with broken packages!");
501 if (Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
502 Cache
->BadCount() == 0)
505 // Run the simulator ..
506 if (_config
->FindB("APT::Get::Simulate") == true)
508 pkgSimulate
PM(Cache
);
509 pkgPackageManager::OrderResult Res
= PM
.DoInstall();
510 if (Res
== pkgPackageManager::Failed
)
512 if (Res
!= pkgPackageManager::Completed
)
513 return _error
->Error("Internal Error, Ordering didn't finish");
517 // Create the text record parser
518 pkgRecords
Recs(Cache
);
519 if (_error
->PendingError() == true)
522 // Lock the archive directory
524 if (_config
->FindB("Debug::NoLocking",false) == false)
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");
531 // Create the download object
532 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
533 pkgAcquire
Fetcher(&Stat
);
535 // Read the source list
537 if (List
.ReadMainList() == false)
538 return _error
->Error("The list of sources could not be read.");
540 // Create the package manager and prepare to download
542 if (PM
.GetArchives(&Fetcher
,&List
,&Recs
) == false ||
543 _error
->PendingError() == true)
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())
552 c0out
<< DebBytes
<< ',' << Cache
->DebSize() << endl
;
553 c0out
<< "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl
;
557 c1out
<< "Need to get ";
558 if (DebBytes
!= FetchBytes
)
559 c1out
<< SizeToStr(FetchBytes
) << "B/" << SizeToStr(DebBytes
) << 'B';
561 c1out
<< SizeToStr(DebBytes
) << 'B';
563 c1out
<< " of archives. After unpacking ";
565 // Check for enough free space
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",
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.",
576 if (Cache
->UsrSize() >= 0)
577 c1out
<< SizeToStr(Cache
->UsrSize()) << "B will be used." << endl
;
579 c1out
<< SizeToStr(-1*Cache
->UsrSize()) << "B will be freed." << endl
;
581 if (_error
->PendingError() == true)
585 if (_config
->FindI("quiet",0) >= 2 ||
586 _config
->FindB("APT::Get::Assume-Yes",false) == true)
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");
592 if (Essential
== true && Saftey
== true)
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)
599 c2out
<< "Abort." << endl
;
605 // Prompt to continue
606 if (Ask
== true || Fail
== true)
608 if (_config
->FindI("quiet",0) < 2 &&
609 _config
->FindB("APT::Get::Assume-Yes",false) == false)
611 c2out
<< "Do you want to continue? [Y/n] " << flush
;
613 if (YnPrompt() == false)
615 c2out
<< "Abort." << endl
;
622 // Just print out the uris an exit if the --print-uris flag was used
623 if (_config
->FindB("APT::Get::Print-URIs") == true)
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
;
635 if (_config
->FindB("APT::Get::No-Download",false) == false)
636 if( Fetcher
.Run() == pkgAcquire::Failed
)
641 bool Transient
= false;
642 for (pkgAcquire::Item
**I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); I
++)
644 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
645 (*I
)->Complete
== true)
650 if ((*I
)->Status
== pkgAcquire::Item::StatIdle
)
657 cerr
<< "Failed to fetch " << (*I
)->DescURI() << endl
;
658 cerr
<< " " << (*I
)->ErrorText
<< endl
;
662 if (_config
->FindB("APT::Get::Download-Only",false) == true)
664 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
665 return _error
->Error("Some files failed to download");
669 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
671 /*if (Transient == true)
673 c2out << "Upgrading with disk swapping is not supported in this version." << endl;
674 c2out << "Try running multiple times with --fix-missing" << endl;
677 return _error
->Error("Unable to fetch some archives, maybe try with --fix-missing?");
680 if (Transient
== true && Failed
== true)
681 return _error
->Error("--fix-missing and media swapping is not currently supported");
683 // Try to deal with missing package files
684 if (Failed
== true && PM
.FixMissing() == false)
686 cerr
<< "Unable to correct missing packages." << endl
;
687 return _error
->Error("Aborting Install.");
691 pkgPackageManager::OrderResult Res
= PM
.DoInstall();
692 if (Res
== pkgPackageManager::Failed
|| _error
->PendingError() == true)
694 if (Res
== pkgPackageManager::Completed
)
697 // Reload the fetcher object and loop again for media swapping
699 if (PM
.GetArchives(&Fetcher
,&List
,&Recs
) == false)
705 // DoUpdate - Update the package lists /*{{{*/
706 // ---------------------------------------------------------------------
708 bool DoUpdate(CommandLine
&)
710 // Get the source list
712 if (List
.ReadMainList() == false)
715 // Lock the list directory
717 if (_config
->FindB("Debug::NoLocking",false) == false)
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");
724 // Create the download object
725 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
726 pkgAcquire
Fetcher(&Stat
);
728 // Populate it with the source selection
729 pkgSourceList::const_iterator I
;
730 for (I
= List
.begin(); I
!= List
.end(); I
++)
732 new pkgAcqIndex(&Fetcher
,I
);
733 if (_error
->PendingError() == true)
738 if (Fetcher
.Run() == pkgAcquire::Failed
)
742 for (pkgAcquire::Item
**I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); I
++)
744 if ((*I
)->Status
== pkgAcquire::Item::StatDone
)
749 cerr
<< "Failed to fetch " << (*I
)->DescURI() << endl
;
750 cerr
<< " " << (*I
)->ErrorText
<< endl
;
754 // Clean out any old list files
755 if (_config
->FindB("APT::Get::List-Cleanup",false) == false)
757 if (Fetcher
.Clean(_config
->FindDir("Dir::State::lists")) == false ||
758 Fetcher
.Clean(_config
->FindDir("Dir::State::lists") + "partial/") == false)
762 // Prepare the cache.
764 if (Cache
.Open() == false)
768 return _error
->Error("Some index files failed to download, they have been ignored, or old ones used instead.");
772 // DoUpgrade - Upgrade all packages /*{{{*/
773 // ---------------------------------------------------------------------
774 /* Upgrade all packages without installing new packages or erasing old
776 bool DoUpgrade(CommandLine
&CmdL
)
779 if (Cache
.Open() == false || Cache
.CheckDeps() == false)
783 if (pkgAllUpgrade(Cache
) == false)
785 ShowBroken(c1out
,Cache
,false);
786 return _error
->Error("Internal Error, AllUpgrade broke stuff");
789 return InstallPackages(Cache
,true);
792 // DoInstall - Install packages from the command line /*{{{*/
793 // ---------------------------------------------------------------------
794 /* Install named packages */
795 bool DoInstall(CommandLine
&CmdL
)
798 if (Cache
.Open() == false || Cache
.CheckDeps(CmdL
.FileSize() != 1) == false)
801 // Enter the special broken fixing mode if the user specified arguments
802 bool BrokenFix
= false;
803 if (Cache
->BrokenCount() != 0)
806 unsigned int ExpectedInst
= 0;
807 unsigned int Packages
= 0;
808 pkgProblemResolver
Fix(Cache
);
810 bool DefRemove
= false;
811 if (strcasecmp(CmdL
.FileList
[0],"remove") == 0)
814 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
816 // Duplicate the string
817 unsigned int Length
= strlen(*I
);
819 if (Length
>= sizeof(S
))
823 // See if we are removing the package
824 bool Remove
= DefRemove
;
825 while (Cache
->FindPkg(S
).end() == true)
827 // Handle an optional end tag indicating what to do
828 if (S
[Length
- 1] == '-')
835 if (S
[Length
- 1] == '+')
844 // Locate the package
845 pkgCache::PkgIterator Pkg
= Cache
->FindPkg(S
);
847 if (Pkg
.end() == true)
848 return _error
->Error("Couldn't find package %s",S
);
850 // Handle the no-upgrade case
851 if (_config
->FindB("APT::Get::no-upgrade",false) == true &&
852 Pkg
->CurrentVer
!= 0)
854 c1out
<< "Skipping " << Pkg
.Name() << ", it is already installed and no-upgrade is set." << endl
;
858 // Check if there is something new to install
859 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
860 if (State
.CandidateVer
== 0)
862 if (Pkg
->ProvidesList
!= 0)
864 c1out
<< "Package " << S
<< " is a virtual package provided by:" << endl
;
866 pkgCache::PrvIterator I
= Pkg
.ProvidesList();
867 for (; I
.end() == false; I
++)
869 pkgCache::PkgIterator Pkg
= I
.OwnerPkg();
871 if ((*Cache
)[Pkg
].CandidateVerIter(*Cache
) == I
.OwnerVer())
873 if ((*Cache
)[Pkg
].Install() == true && (*Cache
)[Pkg
].NewInstall() == false)
874 c1out
<< " " << Pkg
.Name() << " " << I
.OwnerVer().VerStr() <<
875 " [Installed]"<< endl
;
877 c1out
<< " " << Pkg
.Name() << " " << I
.OwnerVer().VerStr() << endl
;
880 c1out
<< "You should explicly select one to install." << endl
;
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
;
889 pkgCache::DepIterator Dep
= Pkg
.RevDependsList();
890 for (; Dep
.end() == false; Dep
++)
892 if (Dep
->Type
!= pkgCache::Dep::Replaces
)
894 List
+= string(Dep
.ParentPkg().Name()) + " ";
896 ShowList(c1out
,"However the following packages replace it:",List
);
899 return _error
->Error("Package %s has no installation candidate",S
);
906 Cache
->MarkDelete(Pkg
,_config
->FindB("APT::Get::Purge",false));
911 Cache
->MarkInstall(Pkg
,false);
912 if (State
.Install() == false)
913 c1out
<< "Sorry, " << S
<< " is already the newest version" << endl
;
917 // Install it with autoinstalling enabled.
918 if (State
.InstBroken() == true && BrokenFix
== false)
919 Cache
->MarkInstall(Pkg
,true);
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
925 if (BrokenFix
== true && Cache
->BrokenCount() != 0)
927 c1out
<< "You might want to run `apt-get -f install' to correct these:" << endl
;
928 ShowBroken(c1out
,Cache
,false);
930 return _error
->Error("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).");
933 // Call the scored problem resolver
934 Fix
.InstallProtect();
935 if (Fix
.Resolve(true) == false)
938 // Now we check the state of the packages,
939 if (Cache
->BrokenCount() != 0)
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
;
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
;
953 c1out
<< "The following information may help to resolve the situation:" << endl
;
955 ShowBroken(c1out
,Cache
,false);
956 return _error
->Error("Sorry, broken packages");
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
)
964 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
966 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
967 if ((*Cache
)[I
].Install() == false)
971 for (J
= CmdL
.FileList
+ 1; *J
!= 0; J
++)
972 if (strcmp(*J
,I
.Name()) == 0)
976 List
+= string(I
.Name()) + " ";
979 ShowList(c1out
,"The following extra packages will be installed:",List
);
982 // See if we need to prompt
983 if (Cache
->InstCount() == ExpectedInst
&& Cache
->DelCount() == 0)
984 return InstallPackages(Cache
,false,false);
986 return InstallPackages(Cache
,false);
989 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
990 // ---------------------------------------------------------------------
991 /* Intelligent upgrader that will install and remove packages at will */
992 bool DoDistUpgrade(CommandLine
&CmdL
)
995 if (Cache
.Open() == false || Cache
.CheckDeps() == false)
998 c0out
<< "Calculating Upgrade... " << flush
;
999 if (pkgDistUpgrade(*Cache
) == false)
1001 c0out
<< "Failed" << endl
;
1002 ShowBroken(c1out
,Cache
,false);
1006 c0out
<< "Done" << endl
;
1008 return InstallPackages(Cache
,true);
1011 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
1012 // ---------------------------------------------------------------------
1013 /* Follows dselect's selections */
1014 bool DoDSelectUpgrade(CommandLine
&CmdL
)
1017 if (Cache
.Open() == false || Cache
.CheckDeps() == false)
1020 // Install everything with the install flag set
1021 pkgCache::PkgIterator I
= Cache
->PkgBegin();
1022 for (;I
.end() != true; I
++)
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);
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
++)
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);
1040 // Apply erasures now, they override everything else.
1041 for (I
= Cache
->PkgBegin();I
.end() != true; I
++)
1044 if (I
->SelectedState
== pkgCache::State::DeInstall
||
1045 I
->SelectedState
== pkgCache::State::Purge
)
1046 Cache
->MarkDelete(I
,I
->SelectedState
== pkgCache::State::Purge
);
1049 /* Resolve any problems that dselect created, allupgrade cannot handle
1050 such things. We do so quite agressively too.. */
1051 if (Cache
->BrokenCount() != 0)
1053 pkgProblemResolver
Fix(Cache
);
1055 // Hold back held packages.
1056 if (_config
->FindB("APT::Ingore-Hold",false) == false)
1058 for (pkgCache::PkgIterator I
= Cache
->PkgBegin(); I
.end() == false; I
++)
1060 if (I
->SelectedState
== pkgCache::State::Hold
)
1068 if (Fix
.Resolve() == false)
1070 ShowBroken(c1out
,Cache
,false);
1071 return _error
->Error("Internal Error, problem resolver broke stuff");
1075 // Now upgrade everything
1076 if (pkgAllUpgrade(Cache
) == false)
1078 ShowBroken(c1out
,Cache
,false);
1079 return _error
->Error("Internal Error, problem resolver broke stuff");
1082 return InstallPackages(Cache
,false);
1085 // DoClean - Remove download archives /*{{{*/
1086 // ---------------------------------------------------------------------
1088 bool DoClean(CommandLine
&CmdL
)
1091 Fetcher
.Clean(_config
->FindDir("Dir::Cache::archives"));
1092 Fetcher
.Clean(_config
->FindDir("Dir::Cache::archives") + "partial/");
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. */
1100 class LogCleaner
: public pkgArchiveCleaner
1103 virtual void Erase(const char *File
,string Pkg
,string Ver
,struct stat
&St
)
1105 cout
<< "Del " << Pkg
<< " " << Ver
<< " [" << SizeToStr(St
.st_size
) << "B]" << endl
;
1107 if (_config
->FindB("APT::Get::Simulate") == false)
1112 bool DoAutoClean(CommandLine
&CmdL
)
1115 if (Cache
.Open() == false)
1120 return Cleaner
.Go(_config
->FindDir("Dir::Cache::archives"),*Cache
) &&
1121 Cleaner
.Go(_config
->FindDir("Dir::Cache::archives") + "partial/",*Cache
);
1124 // DoCheck - Perform the check operation /*{{{*/
1125 // ---------------------------------------------------------------------
1126 /* Opening automatically checks the system, this command is mostly used
1128 bool DoCheck(CommandLine
&CmdL
)
1137 // DoSource - Fetch a source archive /*{{{*/
1138 // ---------------------------------------------------------------------
1139 /* Fetch souce packages */
1147 bool DoSource(CommandLine
&CmdL
)
1150 if (Cache
.Open(false) == false)
1153 if (CmdL
.FileSize() <= 1)
1154 return _error
->Error("Must specify at least one package to fetch source for");
1156 // Read the source list
1158 if (List
.ReadMainList() == false)
1159 return _error
->Error("The list of sources could not be read.");
1161 // Create the text record parsers
1162 pkgRecords
Recs(Cache
);
1163 pkgSrcRecords
SrcRecs(List
);
1164 if (_error
->PendingError() == true)
1167 // Create the download object
1168 AcqTextStatus
Stat(ScreenWidth
,_config
->FindI("quiet",0));
1169 pkgAcquire
Fetcher(&Stat
);
1171 DscFile
*Dsc
= new DscFile
[CmdL
.FileSize()];
1173 // Load the requestd sources into the fetcher
1175 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++, J
++)
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)
1187 pkgCache::VerIterator Ver
= Cache
->GetCandidateVer(Pkg
);
1188 if (Ver
.end() == false)
1190 pkgRecords::Parser
&Parse
= Recs
.Lookup(Ver
.FileList());
1191 Src
= Parse
.SourcePkg();
1195 // No source package name..
1196 if (Src
.empty() == true)
1200 pkgSrcRecords::Parser
*Last
= 0;
1201 unsigned long Offset
= 0;
1203 bool IsMatch
= false;
1205 // Iterate over all of the hits
1206 pkgSrcRecords::Parser
*Parse
;
1208 while ((Parse
= SrcRecs
.Find(Src
.c_str(),false)) != 0)
1210 string Ver
= Parse
->Version();
1212 // Skip name mismatches
1213 if (IsMatch
== true && Parse
->Package() != Src
)
1216 // Newer version or an exact match
1217 if (Last
== 0 || pkgVersionCompare(Version
,Ver
) < 0 ||
1218 (Parse
->Package() == Src
&& IsMatch
== false))
1220 IsMatch
= Parse
->Package() == Src
;
1222 Offset
= Parse
->Offset();
1228 return _error
->Error("Unable to find a source package for %s",Src
.c_str());
1231 vector
<pkgSrcRecords::File
> Lst
;
1232 if (Last
->Jump(Offset
) == false || Last
->Files(Lst
) == false)
1235 // Load them into the fetcher
1236 for (vector
<pkgSrcRecords::File
>::const_iterator I
= Lst
.begin();
1237 I
!= Lst
.end(); I
++)
1239 // Try to guess what sort of file it is we are getting.
1241 if (I
->Path
.find(".dsc") != string::npos
)
1244 Dsc
[J
].Package
= Last
->Package();
1245 Dsc
[J
].Version
= Last
->Version();
1246 Dsc
[J
].Dsc
= flNotDir(I
->Path
);
1249 if (I
->Path
.find(".tar.gz") != string::npos
)
1251 if (I
->Path
.find(".diff.gz") != string::npos
)
1254 // Diff only mode only fetches .diff files
1255 if (_config
->FindB("APT::Get::Diff-Only",false) == true &&
1259 // Tar only mode only fetches .tar files
1260 if (_config
->FindB("APT::Get::Tar-Only",false) == true &&
1264 new pkgAcqFile(&Fetcher
,Last
->Source()->ArchiveURI(I
->Path
),
1265 I
->MD5Hash
,I
->Size
,Last
->Source()->SourceInfo(Src
,
1266 Last
->Version(),Comp
),Src
);
1270 // Display statistics
1271 unsigned long FetchBytes
= Fetcher
.FetchNeeded();
1272 unsigned long FetchPBytes
= Fetcher
.PartialPresent();
1273 unsigned long DebBytes
= Fetcher
.TotalNeeded();
1275 // Check for enough free space
1277 string OutputDir
= ".";
1278 if (statfs(OutputDir
.c_str(),&Buf
) != 0)
1279 return _error
->Errno("statfs","Couldn't determine free space in %s",
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",
1286 c1out
<< "Need to get ";
1287 if (DebBytes
!= FetchBytes
)
1288 c1out
<< SizeToStr(FetchBytes
) << "B/" << SizeToStr(DebBytes
) << 'B';
1290 c1out
<< SizeToStr(DebBytes
) << 'B';
1291 c1out
<< " of source archives." << endl
;
1293 if (_config
->FindB("APT::Get::Simulate",false) == true)
1295 for (unsigned I
= 0; I
!= J
; I
++)
1296 cout
<< "Fetch Source " << Dsc
[I
].Package
<< endl
;
1300 // Just print out the uris an exit if the --print-uris flag was used
1301 if (_config
->FindB("APT::Get::Print-URIs") == true)
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
;
1311 if (Fetcher
.Run() == pkgAcquire::Failed
)
1314 // Print error messages
1315 bool Failed
= false;
1316 for (pkgAcquire::Item
**I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); I
++)
1318 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
1319 (*I
)->Complete
== true)
1322 cerr
<< "Failed to fetch " << (*I
)->DescURI() << endl
;
1323 cerr
<< " " << (*I
)->ErrorText
<< endl
;
1327 return _error
->Error("Failed to fetch some archives.");
1329 if (_config
->FindB("APT::Get::Download-only",false) == true)
1332 // Unpack the sources
1333 pid_t Process
= ExecFork();
1337 for (unsigned I
= 0; I
!= J
; I
++)
1339 string Dir
= Dsc
[I
].Package
+ '-' + pkgBaseVersion(Dsc
[I
].Version
.c_str());
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)
1346 // See if the package is already unpacked
1348 if (stat(Dir
.c_str(),&Stat
) == 0 &&
1349 S_ISDIR(Stat
.st_mode
) != 0)
1351 c0out
<< "Skipping unpack of already unpacked source in " << Dir
<< endl
;
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());
1362 cerr
<< "Unpack command '" << S
<< "' failed." << endl
;
1367 // Try to compile it with dpkg-buildpackage
1368 if (_config
->FindB("APT::Get::Compile",false) == true)
1370 // Call dpkg-buildpackage
1372 snprintf(S
,sizeof(S
),"cd %s && %s %s",
1374 _config
->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
1375 _config
->Find("DPkg::Build-Options","-b -uc").c_str());
1379 cerr
<< "Build command '" << S
<< "' failed." << endl
;
1388 // Wait for the subprocess
1390 while (waitpid(Process
,&Status
,0) != Process
)
1394 return _error
->Errno("waitpid","Couldn't wait for subprocess");
1397 if (WIFEXITED(Status
) == 0 || WEXITSTATUS(Status
) != 0)
1398 return _error
->Error("Child process failed");
1404 // ShowHelp - Show a help screen /*{{{*/
1405 // ---------------------------------------------------------------------
1407 bool ShowHelp(CommandLine
&CmdL
)
1409 cout
<< PACKAGE
<< ' ' << VERSION
<< " for " << ARCHITECTURE
<<
1410 " compiled on " << __DATE__
<< " " << __TIME__
<< endl
;
1411 if (_config
->FindB("version") == true)
1414 cout
<< "Usage: apt-get [options] command" << endl
;
1415 cout
<< " apt-get [options] install pkg1 [pkg2 ...]" << 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
;
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
;
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
;
1451 // GetInitialize - Initialize things for apt-get /*{{{*/
1452 // ---------------------------------------------------------------------
1454 void GetInitialize()
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);
1466 // SigWinch - Window size change signal handler /*{{{*/
1467 // ---------------------------------------------------------------------
1471 // Riped from GNU ls
1475 if (ioctl(1, TIOCGWINSZ
, &ws
) != -1 && ws
.ws_col
>= 5)
1476 ScreenWidth
= ws
.ws_col
- 1;
1481 int main(int argc
,const char *argv
[])
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
},
1513 CommandLine::Dispatch Cmds
[] = {{"update",&DoUpdate
},
1514 {"upgrade",&DoUpgrade
},
1515 {"install",&DoInstall
},
1516 {"remove",&DoInstall
},
1517 {"dist-upgrade",&DoDistUpgrade
},
1518 {"dselect-upgrade",&DoDSelectUpgrade
},
1520 {"autoclean",&DoAutoClean
},
1522 {"source",&DoSource
},
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)
1531 _error
->DumpErrors();
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
);
1541 // Deal with stdout not being a tty
1542 if (ttyname(STDOUT_FILENO
) == 0 && _config
->FindI("quiet",0) < 1)
1543 _config
->Set("quiet","1");
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());
1554 // Setup the signals
1555 signal(SIGPIPE
,SIG_IGN
);
1556 signal(SIGWINCH
,SigWinch
);
1559 // Match the operation
1560 CmdL
.DispatchArg(Cmds
);
1562 // Print any errors or warnings found during parsing
1563 if (_error
->empty() == false)
1565 bool Errors
= _error
->PendingError();
1566 _error
->DumpErrors();
1567 return Errors
== true?100:0;