|
|
@@ -1408,31 +1408,47 @@ 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");
|
|
|
+ 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;
|
|
|
+
|
|
|
+ autoremovelist += string(Pkg.Name()) + " ";
|
|
|
+ autoremoveversions += string(Cache[Pkg].CandVersion) + " ";
|
|
|
+ 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);
|
|
|
- }
|
|
|
- }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+ ShowList(c1out, _("The following packages were automatically installed and are no longer required:"), autoremovelist, autoremoveversions);
|
|
|
+ if (!doAutoRemove && autoremovelist.size() > 0)
|
|
|
+ c1out << _("Use 'apt-get autoremove' to remove them.") << std::endl;
|
|
|
|
|
|
// Now see if we destroyed anything
|
|
|
if (Cache->BrokenCount() != 0)
|
|
|
@@ -1537,175 +1553,164 @@ bool DoInstall(CommandLine &CmdL)
|
|
|
if (strcasecmp(CmdL.FileList[0],"remove") == 0)
|
|
|
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;
|
|
|
-
|
|
|
- // 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);
|
|
|
- continue;
|
|
|
- }
|
|
|
+ _config->Set("APT::Get::AutomaticRemove", "true");
|
|
|
+ DefRemove = true;
|
|
|
+ }
|
|
|
|
|
|
- while (Cache->FindPkg(S).end() == 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;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if (Length >= 1 && S[Length - 1] == '+')
|
|
|
- {
|
|
|
- Remove = false;
|
|
|
- S[--Length] = 0;
|
|
|
+ // Duplicate the string
|
|
|
+ unsigned int Length = strlen(*I);
|
|
|
+ char S[300];
|
|
|
+ if (Length >= sizeof(S))
|
|
|
continue;
|
|
|
- }
|
|
|
-
|
|
|
- char *Slash = strchr(S,'=');
|
|
|
- if (Slash != 0)
|
|
|
+ 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)
|
|
|
{
|
|
|
- VerIsRel = false;
|
|
|
- *Slash = 0;
|
|
|
- VerTag = Slash + 1;
|
|
|
- }
|
|
|
+ // Handle an optional end tag indicating what to do
|
|
|
+ if (Length >= 1 && S[Length - 1] == '-')
|
|
|
+ {
|
|
|
+ Remove = true;
|
|
|
+ S[--Length] = 0;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- Slash = strchr(S,'/');
|
|
|
- if (Slash != 0)
|
|
|
- {
|
|
|
- VerIsRel = true;
|
|
|
- *Slash = 0;
|
|
|
- VerTag = Slash + 1;
|
|
|
- }
|
|
|
+ if (Length >= 1 && S[Length - 1] == '+')
|
|
|
+ {
|
|
|
+ Remove = false;
|
|
|
+ S[--Length] = 0;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- break;
|
|
|
- }
|
|
|
+ char *Slash = strchr(S,'=');
|
|
|
+ if (Slash != 0)
|
|
|
+ {
|
|
|
+ VerIsRel = false;
|
|
|
+ *Slash = 0;
|
|
|
+ VerTag = Slash + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ Slash = strchr(S,'/');
|
|
|
+ if (Slash != 0)
|
|
|
+ {
|
|
|
+ VerIsRel = true;
|
|
|
+ *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);
|
|
|
+ // 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;
|
|
|
+ // 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);
|
|
|
- }
|
|
|
+ // 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;
|
|
|
+ // 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);
|
|
|
+ /* 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)."));
|
|
|
- }
|
|
|
+ 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 */
|