#include <termios.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
+#include <sys/statfs.h>
#include <sys/statvfs.h>
#include <signal.h>
#include <unistd.h>
#include <sstream>
/*}}}*/
+#define RAMFS_MAGIC 0x858458f6
+
using namespace std;
ostream c0out(0);
if (DebBytes != FetchBytes)
ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
- else
+ else if (DebBytes != 0)
ioprintf(c1out,_("Need to get %sB of archives.\n"),
SizeToStr(DebBytes).c_str());
// Size delta
if (Cache->UsrSize() >= 0)
- ioprintf(c1out,_("After unpacking %sB of additional disk space will be used.\n"),
+ ioprintf(c1out,_("After this operation, %sB of additional disk space will be used.\n"),
SizeToStr(Cache->UsrSize()).c_str());
else
- ioprintf(c1out,_("After unpacking %sB disk space will be freed.\n"),
+ ioprintf(c1out,_("After this operation, %sB disk space will be freed.\n"),
SizeToStr(-1*Cache->UsrSize()).c_str());
if (_error->PendingError() == true)
return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
OutputDir.c_str());
if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
- return _error->Error(_("You don't have enough free space in %s."),
- OutputDir.c_str());
+ {
+ struct statfs Stat;
+ if (statfs(OutputDir.c_str(),&Stat) != 0 ||
+ unsigned(Stat.f_type) != RAMFS_MAGIC)
+ return _error->Error(_("You don't have enough free space in %s."),
+ OutputDir.c_str());
+ }
}
// Fail safe check
pkgAcquire::UriIterator I = Fetcher.UriBegin();
for (; I != Fetcher.UriEnd(); I++)
cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
- I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+ I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
return true;
}
return _error->Error(_("Unable to lock the list directory"));
}
- // Create the download object
+ // Create the progress
AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
- pkgAcquire Fetcher(&Stat);
-
-
+
// Just print out the uris an exit if the --print-uris flag was used
if (_config->FindB("APT::Get::Print-URIs") == true)
{
+ // get a fetcher
+ pkgAcquire Fetcher(&Stat);
+
// Populate it with the source selection and get all Indexes
// (GetAll=true)
if (List.GetIndexes(&Fetcher,true) == false)
pkgAcquire::UriIterator I = Fetcher.UriBegin();
for (; I != Fetcher.UriEnd(); I++)
cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
- I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+ I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
return true;
}
- // Populate it with the source selection
- if (List.GetIndexes(&Fetcher) == false)
- return false;
-
- // Run it
- if (Fetcher.Run() == pkgAcquire::Failed)
- return false;
-
- bool Failed = 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());
- Failed = true;
- }
-
- // Clean out any old list files
- if (!Failed && _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)
- return false;
- }
-
- // Prepare the cache.
+ // do the work
CacheFile Cache;
+ bool res = ListUpdate(Stat, List);
+
+ // Rebuild the cache.
if (Cache.BuildCaches() == false)
return false;
- if (Failed == true)
- return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
-
return true;
}
/*}}}*/
/* 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)
bool TryInstallTask(pkgDepCache &Cache, pkgProblemResolver &Fix,
bool BrokenFix,
unsigned int& ExpectedInst,
- const char *taskname)
+ const char *taskname,
+ bool Remove)
{
const char *start, *end;
pkgCache::PkgIterator Pkg;
// build regexp for the task
char S[300];
- snprintf(S, sizeof(S), "^Task:.*[^a-z]%s[^a-z].*\n", taskname);
- regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
+ 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;
buf[end-start] = 0x0;
if (regexec(&Pattern,buf,0,0,0) != 0)
continue;
- res &= TryToInstall(Pkg,Cache,Fix,false,BrokenFix,ExpectedInst);
+ res &= TryToInstall(Pkg,Cache,Fix,Remove,false,ExpectedInst);
found = true;
}
if (Cache->BrokenCount() != 0)
BrokenFix = true;
+ unsigned int AutoMarkChanged = 0;
unsigned int ExpectedInst = 0;
unsigned int Packages = 0;
pkgProblemResolver Fix(Cache);
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);
+ _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++)
+ {
+ // 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;
+ // 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;
- }
+ // 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)
- {
- // Handle an optional end tag indicating what to do
- if (Length >= 1 && S[Length - 1] == '-')
+ while (Cache->FindPkg(S).end() == true)
{
- Remove = true;
- 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;
+ }
- if (Length >= 1 && S[Length - 1] == '+')
- {
- Remove = false;
- 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;
- }
+ 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);
+ // 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) &&
+ _config->FindB("APT::Get::ReInstall",false) == false)
+ {
+ ioprintf(c1out,_("%s set to manually 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 */
}
+ // 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);
if (Last == 0)
return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
+ string srec = Last->AsStr();
+ string::size_type pos = srec.find("\nVcs-");
+ while (pos != string::npos)
+ {
+ pos += strlen("\nVcs-");
+ string vcs = srec.substr(pos,srec.find(":",pos)-pos);
+ if(vcs == "Browser")
+ {
+ pos = srec.find("\nVcs-", pos);
+ continue;
+ }
+ pos += vcs.length()+2;
+ string::size_type epos = srec.find("\n", pos);
+ string uri = srec.substr(pos,epos-pos).c_str();
+ ioprintf(c1out, _("NOTICE: '%s' packaging is maintained in "
+ "the '%s' version control system at:\n"
+ "%s\n"),
+ Src.c_str(), vcs.c_str(), uri.c_str());
+ if(vcs == "Bzr")
+ ioprintf(c1out,_("Please use:\n"
+ "bzr get %s\n"
+ "to retrieve the latest (possible unreleased) "
+ "updates to the package.\n"),
+ uri.c_str());
+ break;
+ }
+
// Back track
vector<pkgSrcRecords::File> Lst;
if (Last->Files(Lst) == false)
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())
return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
OutputDir.c_str());
if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
- return _error->Error(_("You don't have enough free space in %s"),
- OutputDir.c_str());
+ {
+ struct statfs Stat;
+ if (statfs(OutputDir.c_str(),&Stat) != 0 ||
+ unsigned(Stat.f_type) != RAMFS_MAGIC)
+ return _error->Error(_("You don't have enough free space in %s"),
+ OutputDir.c_str());
+ }
// Number of bytes
if (DebBytes != FetchBytes)
pkgAcquire::UriIterator I = Fetcher.UriBegin();
for (; I != Fetcher.UriEnd(); I++)
cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
- I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+ I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
return true;
}
break;
}
if (CV.end() == true)
+ {
if (hasAlternatives)
{
continue;
Last->BuildDepType((*D).Type),Src.c_str(),
(*D).Package.c_str());
}
+ }
}
else
{
/* */
bool ShowHelp(CommandLine &CmdL)
{
- ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
- COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+ ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
+ COMMON_ARCH,__DATE__,__TIME__);
if (_config->FindB("version") == true)
{
" upgrade - Perform an upgrade\n"
" install - Install new packages (pkg is libc6 not libc6.deb)\n"
" remove - Remove packages\n"
+ " autoremove - Remove all automatic unused 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"
" -d Download only - do NOT install or unpack archives\n"
" -s No-act. Perform ordering simulation\n"
" -y Assume Yes to all queries and do not prompt\n"
- " -f Attempt to continue if the integrity check fails\n"
+ " -f Attempt to correct a system with broken dependencies in place\n"
" -m Attempt to continue if archives are unlocatable\n"
" -u Show a list of upgraded packages as well\n"
" -b Build the source package after fetching it\n"
{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},
{"upgrade",&DoUpgrade},
{"install",&DoInstall},
{"remove",&DoInstall},
+ {"purge",&DoInstall},
{"autoremove",&DoInstall},
+ {"purge",&DoInstall},
{"dist-upgrade",&DoDistUpgrade},
{"dselect-upgrade",&DoDSelectUpgrade},
{"build-dep",&DoBuildDep},