summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2011-04-21 16:46:28 +0200
committerDavid Kalnischkies <kalnischkies@gmail.com>2011-04-21 16:46:28 +0200
commitc98fb5e00d4b8a7e0c372e9cbc857046dec3b3dd (patch)
tree537581e193868c935fc5a22ee49d2f380c4de17d
parente1a279fb9b1580d69f5aac5d2c7191eb6ee59947 (diff)
* cmdline/apt-mark.cc:
- reimplement apt-mark in c++
-rwxr-xr-xcmdline/apt-mark101
-rw-r--r--cmdline/apt-mark.cc257
-rw-r--r--cmdline/makefile9
-rw-r--r--debian/apt.lintian-overrides3
-rw-r--r--debian/changelog6
-rw-r--r--test/integration/framework2
6 files changed, 266 insertions, 112 deletions
diff --git a/cmdline/apt-mark b/cmdline/apt-mark
deleted file mode 100755
index c64d4356c..000000000
--- a/cmdline/apt-mark
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/python
-
-from optparse import OptionParser
-
-import sys
-import os.path
-
-try:
- import apt_pkg
-except ImportError:
- print >> sys.stderr, "Error importing apt_pkg, is python-apt installed?"
- sys.exit(1)
-
-actions = { "markauto" : 1,
- "unmarkauto": 0
- }
-
-def show_automatic(filename):
- if not os.path.exists(STATE_FILE):
- return
- auto = set()
- tagfile = apt_pkg.TagFile(open(STATE_FILE))
- for section in tagfile:
- pkgname = section.get("Package")
- autoInst = section.get("Auto-Installed")
- if int(autoInst):
- auto.add(pkgname)
- print "\n".join(sorted(auto))
-
-
-def mark_unmark_automatic(filename, action, pkgs):
- " mark or unmark automatic flag"
- # open the statefile
- if os.path.exists(STATE_FILE):
- try:
- tagfile = apt_pkg.TagFile(open(STATE_FILE))
- outfile = open(STATE_FILE+".tmp","w")
- except IOError, msg:
- print "%s, are you root?" % (msg)
- sys.exit(1)
- for section in tagfile:
- pkgname = section.get("Package")
- autoInst = section.get("Auto-Installed")
- if pkgname in pkgs:
- if options.verbose:
- print "changing %s to %s" % (pkgname,action)
- newsec = apt_pkg.rewrite_section(section,
- [],
- [ ("Auto-Installed",str(action)) ])
- pkgs.remove(pkgname)
- outfile.write(newsec+"\n")
- else:
- outfile.write(str(section)+"\n")
- if action == 1:
- for pkgname in pkgs:
- if options.verbose:
- print "changing %s to %s" % (pkgname,action)
- outfile.write("Package: %s\nAuto-Installed: %d\n\n" % (pkgname, action))
- # all done, rename the tmpfile
- os.chmod(outfile.name, 0644)
- os.rename(outfile.name, STATE_FILE)
- os.chmod(STATE_FILE, 0644)
-
-
-if __name__ == "__main__":
- apt_pkg.init()
-
- # option parsing
- parser = OptionParser()
- parser.usage = "%prog [options] {markauto|unmarkauto} packages..."
- parser.epilog = "apt-mark is deprecated, use apt-get markauto/unmarkauto."
- parser.add_option("-f", "--file", action="store", type="string",
- dest="filename",
- help="read/write a different file")
- parser.add_option("-v", "--verbose",
- action="store_true", dest="verbose", default=False,
- help="print verbose status messages to stdout")
- (options, args) = parser.parse_args()
-
- if not args:
- parser.print_help()
- sys.exit(1)
-
- # get the state-file
- if not options.filename:
- STATE_FILE = apt_pkg.config.find_dir("Dir::State") + "extended_states"
- else:
- STATE_FILE=options.filename
-
- if len(args) == 0:
- parser.error("first argument must be 'markauto', 'unmarkauto' or 'showauto'")
-
- if args[0] == "showauto":
- show_automatic(STATE_FILE)
- else:
- # get pkgs to change
- if args[0] not in actions.keys():
- parser.error("first argument must be 'markauto', 'unmarkauto' or 'showauto'")
- pkgs = args[1:]
- action = actions[args[0]]
- mark_unmark_automatic(STATE_FILE, action, pkgs)
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 <apt-pkg/cachefile.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/strutl.h>
+
+#include <config.h>
+#include <apti18n.h>
+
+#include <algorithm>
+ /*}}}*/
+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<string> 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<string>::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;
+}
+ /*}}}*/
diff --git a/cmdline/makefile b/cmdline/makefile
index 917ccc96a..e867dae73 100644
--- a/cmdline/makefile
+++ b/cmdline/makefile
@@ -54,10 +54,11 @@ TARGET=program
include $(COPY_H)
# The apt-mark program
-SOURCE=apt-mark
-TO=$(BIN)
-TARGET=program
-include $(COPY_H)
+PROGRAM=apt-mark
+SLIBS = -lapt-pkg $(INTLLIBS)
+LIB_MAKES = apt-pkg/makefile
+SOURCE = apt-mark.cc
+include $(PROGRAM_H)
# The apt-report-mirror-failure program
#SOURCE=apt-report-mirror-failure
diff --git a/debian/apt.lintian-overrides b/debian/apt.lintian-overrides
deleted file mode 100644
index 828b36905..000000000
--- a/debian/apt.lintian-overrides
+++ /dev/null
@@ -1,3 +0,0 @@
-# apt-mark is rarely used auxiliary script, we don't want to depend on
-# python-apt only for it.
-apt binary: python-script-but-no-python-dep usr/bin/apt-mark
diff --git a/debian/changelog b/debian/changelog
index 762688386..1658bd094 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -19,12 +19,12 @@ apt (0.8.14.2) UNRELEASED; urgency=low
- replace obsolete usleep with nanosleep
* debian/apt{,-utils}.symbols:
- update both experimental symbol-files to reflect 0.8.14 state
- * debian/apt.lintian-overrides:
- - update the missing-python-dep override to the lintian 2.5 way
* debian/rules:
- remove unused embedded jquery by doxygen from libapt-pkg-doc
+ * cmdline/apt-mark.cc:
+ - reimplement apt-mark in c++
- -- David Kalnischkies <kalnischkies@gmail.com> Tue, 19 Apr 2011 20:57:52 +0200
+ -- David Kalnischkies <kalnischkies@gmail.com> Thu, 21 Apr 2011 16:43:16 +0200
apt (0.8.14.1) unstable; urgency=low
diff --git a/test/integration/framework b/test/integration/framework
index 50c5157e9..b257738e7 100644
--- a/test/integration/framework
+++ b/test/integration/framework
@@ -695,7 +695,7 @@ testmarkedauto() {
while [ -n "$1" ]; do echo "$1"; shift; done | sort > $COMPAREFILE
else
msgtest 'Test for correctly marked as auto-installed' 'no package'
- echo > $COMPAREFILE
+ echo -n > $COMPAREFILE
fi
aptmark showauto 2>&1 | checkdiff $COMPAREFILE - && msgpass || msgfail
}