From c98fb5e00d4b8a7e0c372e9cbc857046dec3b3dd Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 21 Apr 2011 16:46:28 +0200 Subject: * cmdline/apt-mark.cc: - reimplement apt-mark in c++ --- cmdline/apt-mark.cc | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 cmdline/apt-mark.cc (limited to 'cmdline/apt-mark.cc') diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc new file mode 100644 index 000000000..a5dc45a10 --- /dev/null +++ b/cmdline/apt-mark.cc @@ -0,0 +1,257 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ##################################################################### + apt-mark - show and change auto-installed bit information + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + /*}}}*/ +using namespace std; + +ostream c0out(0); +ostream c1out(0); +ostream c2out(0); +ofstream devnull("/dev/null"); +/* DoAuto - mark packages as automatically/manually installed {{{*/ +bool DoAuto(CommandLine &CmdL) +{ + pkgCacheFile CacheFile; + pkgCache *Cache = CacheFile.GetPkgCache(); + pkgDepCache *DepCache = CacheFile.GetDepCache(); + if (unlikely(Cache == NULL || DepCache == NULL)) + return false; + + APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1); + if (pkgset.empty() == true) + return _error->Error(_("No packages found")); + + bool MarkAuto = strcasecmp(CmdL.FileList[0],"auto") == 0; + int AutoMarkChanged = 0; + + for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) + { + if (Pkg->CurrentVer == 0) + { + ioprintf(c1out,_("%s can not be marked as it is not installed.\n"), Pkg.FullName(true).c_str()); + continue; + } + else if ((((*DepCache)[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) == MarkAuto) + { + if (MarkAuto == false) + ioprintf(c1out,_("%s was already set to manually installed.\n"), Pkg.FullName(true).c_str()); + else + ioprintf(c1out,_("%s was already set to automatically installed.\n"), Pkg.FullName(true).c_str()); + continue; + } + + if (MarkAuto == false) + ioprintf(c1out,_("%s set to manually installed.\n"), Pkg.FullName(true).c_str()); + else + ioprintf(c1out,_("%s set to automatically installed.\n"), Pkg.FullName(true).c_str()); + + DepCache->MarkAuto(Pkg, MarkAuto); + ++AutoMarkChanged; + } + if (AutoMarkChanged > 0 && _config->FindB("APT::Mark::Simulate", false) == false) + return DepCache->writeStateFile(NULL); + return true; +} + /*}}}*/ +/* DoMarkAuto - mark packages as automatically/manually installed {{{*/ +/* Does the same as DoAuto but tries to do it exactly the same why as + the python implementation did it so it can be a drop-in replacement */ +bool DoMarkAuto(CommandLine &CmdL) +{ + pkgCacheFile CacheFile; + pkgCache *Cache = CacheFile.GetPkgCache(); + pkgDepCache *DepCache = CacheFile.GetDepCache(); + if (unlikely(Cache == NULL || DepCache == NULL)) + return false; + + APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1); + if (pkgset.empty() == true) + return _error->Error(_("No packages found")); + + bool const MarkAuto = strcasecmp(CmdL.FileList[0],"markauto") == 0; + bool const Verbose = _config->FindB("APT::MarkAuto::Verbose", false); + int AutoMarkChanged = 0; + + for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) + { + if (Pkg->CurrentVer == 0 || + (((*DepCache)[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) == MarkAuto) + continue; + + if (Verbose == true) + ioprintf(c1out, "changing %s to %d\n", Pkg.Name(), (MarkAuto == false) ? 0 : 1); + + DepCache->MarkAuto(Pkg, MarkAuto); + ++AutoMarkChanged; + } + if (AutoMarkChanged > 0 && _config->FindB("APT::Mark::Simulate", false) == false) + return DepCache->writeStateFile(NULL); + + _error->Notice(_("This command is deprecated. Please use 'apt-mark auto' and 'apt-mark manual' instead.")); + + return true; +} + /*}}}*/ +/* ShowAuto - show automatically installed packages (sorted) {{{*/ +bool ShowAuto(CommandLine &CmdL) +{ + pkgCacheFile CacheFile; + pkgCache *Cache = CacheFile.GetPkgCache(); + pkgDepCache *DepCache = CacheFile.GetDepCache(); + if (unlikely(Cache == NULL || DepCache == NULL)) + return false; + + std::vector packages; + + bool const ShowAuto = strcasecmp(CmdL.FileList[0],"showauto") == 0; + + if (CmdL.FileList[1] == 0) + { + packages.reserve(Cache->HeaderP->PackageCount / 3); + for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P) + if (P->CurrentVer != 0 && + (((*DepCache)[P].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) == ShowAuto) + packages.push_back(P.FullName(true)); + } + else + { + APT::CacheSetHelper helper(false); // do not show errors + APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1, helper); + packages.reserve(pkgset.size()); + for (APT::PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P) + if (P->CurrentVer != 0 && + (((*DepCache)[P].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) == ShowAuto) + packages.push_back(P.FullName(true)); + } + + std::sort(packages.begin(), packages.end()); + + for (vector::const_iterator I = packages.begin(); I != packages.end(); ++I) + std::cout << *I << std::endl; + + return true; +} + /*}}}*/ +// ShowHelp - Show a help screen /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool ShowHelp(CommandLine &CmdL) +{ + ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION, + COMMON_ARCH,__DATE__,__TIME__); + + cout << + _("Usage: apt-mark [options] {auto|manual} pkg1 [pkg2 ...]\n" + "\n" + "apt-mark is a simple command line interface for marking packages\n" + "as manual or automatical installed. It can also list marks.\n" + "\n" + "Commands:\n" + " auto - Mark the given packages as automatically installed\n" + " manual - Mark the given packages as manually installed\n" + "\n" + "Options:\n" + " -h This help text.\n" + " -q Loggable output - no progress indicator\n" + " -qq No output except for errors\n" + " -s No-act. Just prints what would be done.\n" + " -f read/write auto/manual marking in the given file\n" + " -c=? Read this configuration file\n" + " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n" + "See the apt-mark(8) and apt.conf(5) manual pages for more information.") + << std::endl; + return true; +} + /*}}}*/ +int main(int argc,const char *argv[]) /*{{{*/ +{ + CommandLine::Args Args[] = { + {'h',"help","help",0}, + {0,"version","version",0}, + {'q',"quiet","quiet",CommandLine::IntLevel}, + {'q',"silent","quiet",CommandLine::IntLevel}, + {'v',"verbose","APT::MarkAuto::Verbose",0}, + {'s',"simulate","APT::Mark::Simulate",0}, + {'s',"just-print","APT::Mark::Simulate",0}, + {'s',"recon","APT::Mark::Simulate",0}, + {'s',"dry-run","APT::Mark::Simulate",0}, + {'s',"no-act","APT::Mark::Simulate",0}, + {'f',"file","Dir::State::extended_states",CommandLine::HasArg}, + {'c',"config-file",0,CommandLine::ConfigFile}, + {'o',"option",0,CommandLine::ArbItem}, + {0,0,0,0}}; + CommandLine::Dispatch Cmds[] = {{"help",&ShowHelp}, + {"auto",&DoAuto}, + {"manual",&DoAuto}, + {"showauto",&ShowAuto}, + {"showmanual",&ShowAuto}, + // obsolete commands for compatibility + {"markauto", &DoMarkAuto}, + {"unmarkauto", &DoMarkAuto}, + {0,0}}; + + // Set up gettext support + setlocale(LC_ALL,""); + textdomain(PACKAGE); + + // Parse the command line and initialize the package library + CommandLine CmdL(Args,_config); + if (pkgInitConfig(*_config) == false || + CmdL.Parse(argc,argv) == false || + pkgInitSystem(*_config,_system) == false) + { + if (_config->FindB("version") == true) + ShowHelp(CmdL); + _error->DumpErrors(); + return 100; + } + + // See if the help should be shown + if (_config->FindB("help") == true || + _config->FindB("version") == true || + CmdL.FileSize() == 0) + { + ShowHelp(CmdL); + return 0; + } + + // Deal with stdout not being a tty + if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) + _config->Set("quiet","1"); + + // Setup the output streams + c0out.rdbuf(cout.rdbuf()); + c1out.rdbuf(cout.rdbuf()); + c2out.rdbuf(cout.rdbuf()); + if (_config->FindI("quiet",0) > 0) + c0out.rdbuf(devnull.rdbuf()); + if (_config->FindI("quiet",0) > 1) + c1out.rdbuf(devnull.rdbuf()); + + // Match the operation + CmdL.DispatchArg(Cmds); + + // Print any errors or warnings found during parsing + bool const Errors = _error->PendingError(); + if (_config->FindI("quiet",0) > 0) + _error->DumpErrors(); + else + _error->DumpErrors(GlobalError::DEBUG); + return Errors == true ? 100 : 0; +} + /*}}}*/ -- cgit v1.2.3