X-Git-Url: https://git.hcoop.net/ntk/apt.git/blobdiff_plain/b28fffc2825b807a26513f2ac5f34cb6e064acbf..394eadc8e13784162fee87c8059bcc214275f4b5:/cmdline/apt-get.cc diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 8b3c6857..df041407 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -629,6 +629,8 @@ void CacheFile::Sort() and verifies that the system is OK. */ bool CacheFile::CheckDeps(bool AllowBroken) { + bool FixBroken = _config->FindB("APT::Get::Fix-Broken",false); + if (_error->PendingError() == true) return false; @@ -640,12 +642,24 @@ bool CacheFile::CheckDeps(bool AllowBroken) if (pkgApplyStatus(*DCache) == false) return false; + if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true) + { + FixBroken = true; + if ((DCache->PolicyBrokenCount() > 0)) + { + // upgrade all policy-broken packages with ForceImportantDeps=True + for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); I++) + if ((*DCache)[I].NowPolicyBroken() == true) + DCache->MarkInstall(I,true,0, false, true); + } + } + // Nothing is broken if (DCache->BrokenCount() == 0 || AllowBroken == true) return true; // Attempt to fix broken things - if (_config->FindB("APT::Get::Fix-Broken",false) == true) + if (FixBroken == true) { c1out << _("Correcting dependencies...") << flush; if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0) @@ -1146,9 +1160,11 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, else ExpectedInst++; - // Install it with autoinstalling enabled. - if (State.InstBroken() == true && BrokenFix == false) + // Install it with autoinstalling enabled (if we not respect the minial + // required deps or the policy) + if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && BrokenFix == false) Cache.MarkInstall(Pkg,true); + return true; } /*}}}*/ @@ -1356,20 +1372,29 @@ bool DoUpdate(CommandLine &CmdL) return false; bool Failed = false; + bool TransientNetworkFailure = false; for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++) { if ((*I)->Status == pkgAcquire::Item::StatDone) continue; (*I)->Finished(); - + fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(), (*I)->ErrorText.c_str()); + + if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError) + { + TransientNetworkFailure = true; + continue; + } + Failed = true; } // Clean out any old list files - if (!Failed && _config->FindB("APT::Get::List-Cleanup",true) == true) + if (!TransientNetworkFailure && + _config->FindB("APT::Get::List-Cleanup",true) == true) { if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false || Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false) @@ -1381,9 +1406,11 @@ bool DoUpdate(CommandLine &CmdL) if (Cache.BuildCaches() == false) return false; - if (Failed == true) + if (TransientNetworkFailure == true) + _error->Warning(_("Some index files failed to download, they have been ignored, or old ones used instead.")); + else if (Failed == true) return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead.")); - + return true; } /*}}}*/ @@ -1392,31 +1419,52 @@ bool DoUpdate(CommandLine &CmdL) /* Remove unused automatic packages */ bool DoAutomaticRemove(CacheFile &Cache) { - if(_config->FindI("Debug::pkgAutoRemove",false)) - std::cout << "DoAutomaticRemove()" << std::endl; + bool Debug = _config->FindI("Debug::pkgAutoRemove",false); + bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false); + bool hideAutoRemove = _config->FindB("APT::Get::HideAutoRemove"); + pkgDepCache::ActionGroup group(*Cache); - if (_config->FindB("APT::Get::Remove",true) == false) - return _error->Error(_("We are not supposed to delete stuff, can't " - "start AutoRemover")); + if(Debug) + std::cout << "DoAutomaticRemove()" << std::endl; + if (_config->FindB("APT::Get::Remove",true) == false && + doAutoRemove == true) { - pkgDepCache::ActionGroup group(*Cache); - - // look over the cache to see what can be removed - for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg) - { - if (Cache[Pkg].Garbage) - { - if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install()) - fprintf(stdout,"We could delete %s\n", Pkg.Name()); + c1out << _("We are not supposed to delete stuff, can't start " + "AutoRemover") << std::endl; + doAutoRemove = false; + } - if(Pkg.CurrentVer() != 0 && Pkg->CurrentState != pkgCache::State::ConfigFiles) + string autoremovelist, autoremoveversions; + // look over the cache to see what can be removed + for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg) + { + if (Cache[Pkg].Garbage) + { + if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install()) + if(Debug) + std::cout << "We could delete %s" << Pkg.Name() << std::endl; + + // only show stuff in the list that is not yet marked for removal + if(Cache[Pkg].Delete() == false) + { + autoremovelist += string(Pkg.Name()) + " "; + autoremoveversions += string(Cache[Pkg].CandVersion) + "\n"; + } + if (doAutoRemove) + { + if(Pkg.CurrentVer() != 0 && + Pkg->CurrentState != pkgCache::State::ConfigFiles) Cache->MarkDelete(Pkg, _config->FindB("APT::Get::Purge", false)); - else + else Cache->MarkKeep(Pkg, false, false); - } - } + } + } } + if (!hideAutoRemove) + ShowList(c1out, _("The following packages were automatically installed and are no longer required:"), autoremovelist, autoremoveversions); + if (!doAutoRemove && !hideAutoRemove && autoremovelist.size() > 0) + c1out << _("Use 'apt-get autoremove' to remove them.") << std::endl; // Now see if we destroyed anything if (Cache->BrokenCount() != 0) @@ -1453,6 +1501,53 @@ bool DoUpgrade(CommandLine &CmdL) return InstallPackages(Cache,true); } /*}}}*/ +// DoInstallTask - Install task from the command line /*{{{*/ +// --------------------------------------------------------------------- +/* Install named task */ +bool TryInstallTask(pkgDepCache &Cache, pkgProblemResolver &Fix, + bool BrokenFix, + unsigned int& ExpectedInst, + const char *taskname, + bool Remove) +{ + const char *start, *end; + pkgCache::PkgIterator Pkg; + char buf[64*1024]; + regex_t Pattern; + + // get the records + pkgRecords Recs(Cache); + + // build regexp for the task + char S[300]; + snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", taskname); + if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0) + return _error->Error("Failed to compile task regexp"); + + bool found = false; + bool res = true; + for (Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) + { + pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache); + if(ver.end()) + continue; + pkgRecords::Parser &parser = Recs.Lookup(ver.FileList()); + parser.GetRec(start,end); + strncpy(buf, start, end-start); + buf[end-start] = 0x0; + if (regexec(&Pattern,buf,0,0,0) != 0) + continue; + res &= TryToInstall(Pkg,Cache,Fix,Remove,true,ExpectedInst); + found = true; + } + + if(!found) + _error->Error(_("Couldn't find task %s"),taskname); + + regfree(&Pattern); + return res; +} + // DoInstall - Install packages from the command line /*{{{*/ // --------------------------------------------------------------------- /* Install named packages */ @@ -1468,6 +1563,7 @@ bool DoInstall(CommandLine &CmdL) if (Cache->BrokenCount() != 0) BrokenFix = true; + unsigned int AutoMarkChanged = 0; unsigned int ExpectedInst = 0; unsigned int Packages = 0; pkgProblemResolver Fix(Cache); @@ -1475,164 +1571,194 @@ bool DoInstall(CommandLine &CmdL) bool DefRemove = false; if (strcasecmp(CmdL.FileList[0],"remove") == 0) DefRemove = true; + else if (strcasecmp(CmdL.FileList[0], "purge") == 0) + { + _config->Set("APT::Get::Purge", true); + DefRemove = true; + } else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0) - { - _config->Set("APT::Get::AutomaticRemove", "true"); - DefRemove = true; - } - - for (const char **I = CmdL.FileList + 1; *I != 0; I++) { - // Duplicate the string - unsigned int Length = strlen(*I); - char S[300]; - if (Length >= sizeof(S)) - continue; - strcpy(S,*I); - - // See if we are removing and special indicators.. - bool Remove = DefRemove; - char *VerTag = 0; - bool VerIsRel = false; - while (Cache->FindPkg(S).end() == true) + _config->Set("APT::Get::AutomaticRemove", "true"); + DefRemove = true; + } + // new scope for the ActionGroup + { + pkgDepCache::ActionGroup group(Cache); + for (const char **I = CmdL.FileList + 1; *I != 0; I++) { - // Handle an optional end tag indicating what to do - if (Length >= 1 && S[Length - 1] == '-') - { - Remove = true; - S[--Length] = 0; + // Duplicate the string + unsigned int Length = strlen(*I); + char S[300]; + if (Length >= sizeof(S)) continue; - } - - if (Length >= 1 && S[Length - 1] == '+') + strcpy(S,*I); + + // See if we are removing and special indicators.. + bool Remove = DefRemove; + char *VerTag = 0; + bool VerIsRel = false; + + // this is a task! + if (Length >= 1 && S[Length - 1] == '^') + { + S[--Length] = 0; + // tasks must always be confirmed + ExpectedInst += 1000; + // see if we can install it + TryInstallTask(Cache, Fix, BrokenFix, ExpectedInst, S, Remove); + continue; + } + + while (Cache->FindPkg(S).end() == true) { - Remove = false; - S[--Length] = 0; - continue; - } + // Handle an optional end tag indicating what to do + if (Length >= 1 && S[Length - 1] == '-') + { + Remove = true; + S[--Length] = 0; + continue; + } - char *Slash = strchr(S,'='); - if (Slash != 0) - { - VerIsRel = false; - *Slash = 0; - VerTag = Slash + 1; - } + if (Length >= 1 && S[Length - 1] == '+') + { + Remove = false; + S[--Length] = 0; + continue; + } - Slash = strchr(S,'/'); - if (Slash != 0) - { - VerIsRel = true; - *Slash = 0; - VerTag = Slash + 1; - } + char *Slash = strchr(S,'='); + if (Slash != 0) + { + VerIsRel = false; + *Slash = 0; + VerTag = Slash + 1; + } - break; - } - - // Locate the package - pkgCache::PkgIterator Pkg = Cache->FindPkg(S); - Packages++; - if (Pkg.end() == true) - { - // Check if the name is a regex - const char *I; - for (I = S; *I != 0; I++) - if (*I == '?' || *I == '*' || *I == '|' || - *I == '[' || *I == '^' || *I == '$') - break; - if (*I == 0) - return _error->Error(_("Couldn't find package %s"),S); - - // Regexs must always be confirmed - ExpectedInst += 1000; + Slash = strchr(S,'/'); + if (Slash != 0) + { + VerIsRel = true; + *Slash = 0; + VerTag = Slash + 1; + } - // Compile the regex pattern - regex_t Pattern; - int Res; - if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE | - REG_NOSUB)) != 0) - { - char Error[300]; - regerror(Res,&Pattern,Error,sizeof(Error)); - return _error->Error(_("Regex compilation error - %s"),Error); + break; } - - // Run over the matches - bool Hit = false; - for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++) + + // Locate the package + pkgCache::PkgIterator Pkg = Cache->FindPkg(S); + Packages++; + if (Pkg.end() == true) { - if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0) - continue; + // Check if the name is a regex + const char *I; + for (I = S; *I != 0; I++) + if (*I == '?' || *I == '*' || *I == '|' || + *I == '[' || *I == '^' || *I == '$') + break; + if (*I == 0) + return _error->Error(_("Couldn't find package %s"),S); + + // Regexs must always be confirmed + ExpectedInst += 1000; + + // Compile the regex pattern + regex_t Pattern; + int Res; + if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE | + REG_NOSUB)) != 0) + { + char Error[300]; + regerror(Res,&Pattern,Error,sizeof(Error)); + return _error->Error(_("Regex compilation error - %s"),Error); + } + + // Run over the matches + bool Hit = false; + for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++) + { + if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0) + continue; - ioprintf(c1out,_("Note, selecting %s for regex '%s'\n"), - Pkg.Name(),S); + ioprintf(c1out,_("Note, selecting %s for regex '%s'\n"), + Pkg.Name(),S); + if (VerTag != 0) + if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false) + return false; + + Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix, + ExpectedInst,false); + } + regfree(&Pattern); + + if (Hit == false) + return _error->Error(_("Couldn't find package %s"),S); + } + else + { if (VerTag != 0) if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false) return false; - - Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix, - ExpectedInst,false); - } - regfree(&Pattern); - - if (Hit == false) - return _error->Error(_("Couldn't find package %s"),S); - } - else - { - if (VerTag != 0) - if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false) + if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false) return false; - if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false) - return false; - } - } - /* If we are in the Broken fixing mode we do not attempt to fix the - problems. This is if the user invoked install without -f and gave - packages */ - if (BrokenFix == true && Cache->BrokenCount() != 0) - { - c1out << _("You might want to run `apt-get -f install' to correct these:") << endl; - ShowBroken(c1out,Cache,false); + // see if we need to fix the auto-mark flag + // e.g. apt-get install foo + // where foo is marked automatic + if(!Remove && + Cache[Pkg].Install() == false && + (Cache[Pkg].Flags & pkgCache::Flag::Auto)) + { + ioprintf(c1out,_("%s set to manual installed.\n"), + Pkg.Name()); + Cache->MarkAuto(Pkg,false); + AutoMarkChanged++; + } + } + } - return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).")); - } + /* If we are in the Broken fixing mode we do not attempt to fix the + problems. This is if the user invoked install without -f and gave + packages */ + if (BrokenFix == true && Cache->BrokenCount() != 0) + { + c1out << _("You might want to run `apt-get -f install' to correct these:") << endl; + ShowBroken(c1out,Cache,false); + + return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).")); + } - // Call the scored problem resolver - Fix.InstallProtect(); - if (Fix.Resolve(true) == false) - _error->Discard(); + // Call the scored problem resolver + Fix.InstallProtect(); + if (Fix.Resolve(true) == false) + _error->Discard(); - // Now we check the state of the packages, - if (Cache->BrokenCount() != 0) - { - c1out << - _("Some packages could not be installed. This may mean that you have\n" - "requested an impossible situation or if you are using the unstable\n" - "distribution that some required packages have not yet been created\n" - "or been moved out of Incoming.") << endl; - if (Packages == 1) + // Now we check the state of the packages, + if (Cache->BrokenCount() != 0) { - c1out << endl; c1out << - _("Since you only requested a single operation it is extremely likely that\n" - "the package is simply not installable and a bug report against\n" - "that package should be filed.") << endl; - } + _("Some packages could not be installed. This may mean that you have\n" + "requested an impossible situation or if you are using the unstable\n" + "distribution that some required packages have not yet been created\n" + "or been moved out of Incoming.") << endl; + if (Packages == 1) + { + c1out << endl; + c1out << + _("Since you only requested a single operation it is extremely likely that\n" + "the package is simply not installable and a bug report against\n" + "that package should be filed.") << endl; + } - c1out << _("The following information may help to resolve the situation:") << endl; - c1out << endl; - ShowBroken(c1out,Cache,false); - return _error->Error(_("Broken packages")); - } - - if (_config->FindB("APT::Get::AutomaticRemove")) { - if (!DoAutomaticRemove(Cache)) - return false; + c1out << _("The following information may help to resolve the situation:") << endl; + c1out << endl; + ShowBroken(c1out,Cache,false); + return _error->Error(_("Broken packages")); + } } + if (!DoAutomaticRemove(Cache)) + return false; /* Print out a list of packages that are going to be installed extra to what the user asked */ @@ -1666,73 +1792,99 @@ bool DoInstall(CommandLine &CmdL) string SuggestsVersions, RecommendsVersions; for (unsigned J = 0; J < Cache->Head().PackageCount; J++) { - pkgCache::PkgIterator I(Cache,Cache.List[J]); + pkgCache::PkgIterator Pkg(Cache,Cache.List[J]); /* Just look at the ones we want to install */ - if ((*Cache)[I].Install() == false) + if ((*Cache)[Pkg].Install() == false) continue; - for (pkgCache::VerIterator V = I.VersionList(); V.end() == false; V++) - { - for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ) - { - pkgCache::DepIterator Start; - pkgCache::DepIterator End; - D.GlobOr(Start,End); // advances D - - /* - * If this is a virtual package, we need to check the list of - * packages that provide it and see if any of those are - * installed - */ - - bool providedBySomething = false; - for (pkgCache::PrvIterator Prv = Start.TargetPkg().ProvidesList(); - Prv.end() != true; - Prv++) - if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false) - { - providedBySomething = true; - break; - } - - if (providedBySomething) continue; - - for(;;) - { - /* Skip if package is installed already, or is about to be */ - string target = string(Start.TargetPkg().Name()) + " "; - - if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install - || Cache[Start.TargetPkg()].Install()) - break; - - /* Skip if we already saw it */ - if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1) - break; - - if (Start->Type == pkgCache::Dep::Suggests) { - SuggestsList += target; - SuggestsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n"; - } - - if (Start->Type == pkgCache::Dep::Recommends) { - RecommendsList += target; - RecommendsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n"; - } - - if (Start >= End) - break; - Start++; - } - } - } + // get the recommends/suggests for the candidate ver + pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache); + for (pkgCache::DepIterator D = CV.DependsList(); D.end() == false; ) + { + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); // advances D + + // FIXME: we really should display a or-group as a or-group to the user + // the problem is that ShowList is incapable of doing this + string RecommendsOrList,RecommendsOrVersions; + string SuggestsOrList,SuggestsOrVersions; + bool foundInstalledInOrGroup = false; + for(;;) + { + /* Skip if package is installed already, or is about to be */ + string target = string(Start.TargetPkg().Name()) + " "; + + if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install + || Cache[Start.TargetPkg()].Install()) + { + foundInstalledInOrGroup=true; + break; + } + + /* Skip if we already saw it */ + if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1) + { + foundInstalledInOrGroup=true; + break; + } + + // this is a dep on a virtual pkg, check if any package that provides it + // should be installed + if(Start.TargetPkg().ProvidesList() != 0) + { + pkgCache::PrvIterator I = Start.TargetPkg().ProvidesList(); + for (; I.end() == false; I++) + { + pkgCache::PkgIterator Pkg = I.OwnerPkg(); + if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer() && + Pkg.CurrentVer() != 0) + foundInstalledInOrGroup=true; + } + } + + if (Start->Type == pkgCache::Dep::Suggests) + { + SuggestsOrList += target; + SuggestsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n"; + } + + if (Start->Type == pkgCache::Dep::Recommends) + { + RecommendsOrList += target; + RecommendsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n"; + } + + if (Start >= End) + break; + Start++; + } + + if(foundInstalledInOrGroup == false) + { + RecommendsList += RecommendsOrList; + RecommendsVersions += RecommendsOrVersions; + SuggestsList += SuggestsOrList; + SuggestsVersions += SuggestsOrVersions; + } + + } } + ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions); ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions); } + // if nothing changed in the cache, but only the automark information + // we write the StateFile here, otherwise it will be written in + // cache.commit() + if (AutoMarkChanged > 0 && + Cache->DelCount() == 0 && Cache->InstCount() == 0 && + Cache->BadCount() == 0) + Cache->writeStateFile(NULL); + // See if we need to prompt if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0) return InstallPackages(Cache,false,false); @@ -1991,6 +2143,11 @@ bool DoSource(CommandLine &CmdL) I->Type != "tar") continue; + // Dsc only mode only fetches .dsc files + if (_config->FindB("APT::Get::Dsc-Only",false) == true && + I->Type != "dsc") + continue; + // don't download the same uri twice (should this be moved to // the fetcher interface itself?) if(queued.find(Last->Index().ArchiveURI(I->Path)) != queued.end()) @@ -2484,6 +2641,7 @@ bool ShowHelp(CommandLine &CmdL) " upgrade - Perform an upgrade\n" " install - Install new packages (pkg is libc6 not libc6.deb)\n" " remove - Remove packages\n" + " purge - Remove and purge packages\n" " source - Download source archives\n" " build-dep - Configure build-dependencies for source packages\n" " dist-upgrade - Distribution upgrade, see apt-get(8)\n" @@ -2573,7 +2731,8 @@ int main(int argc,const char *argv[]) {0,"force-yes","APT::Get::force-yes",0}, {0,"print-uris","APT::Get::Print-URIs",0}, {0,"diff-only","APT::Get::Diff-Only",0}, - {0,"tar-only","APT::Get::tar-Only",0}, + {0,"tar-only","APT::Get::Tar-Only",0}, + {0,"dsc-only","APT::Get::Dsc-Only",0}, {0,"purge","APT::Get::Purge",0}, {0,"list-cleanup","APT::Get::List-Cleanup",0}, {0,"reinstall","APT::Get::ReInstall",0}, @@ -2583,6 +2742,8 @@ int main(int argc,const char *argv[]) {0,"arch-only","APT::Get::Arch-Only",0}, {0,"auto-remove","APT::Get::AutomaticRemove",0}, {0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0}, + {0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean}, + {0,"fix-policy","APT::Get::Fix-Policy-Broken",0}, {'c',"config-file",0,CommandLine::ConfigFile}, {'o',"option",0,CommandLine::ArbItem}, {0,0,0,0}};