aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Fernando J. Pereda <ferdy@ferdyx.org> 2006-11-29 12:54:41 +0000
committerAvatar Fernando J. Pereda <ferdy@ferdyx.org> 2006-11-29 12:54:41 +0000
commita0839a01948ede23772dea993f0f4aa797ab448c (patch)
tree84d9fce017ab9dd6033f1143a3d0dcd5dc95d5a5
parentb43f39919c06e471bac3e34f99c0c0ad8e05de7b (diff)
downloadpaludis-a0839a01948ede23772dea993f0f4aa797ab448c.tar.gz
paludis-a0839a01948ede23772dea993f0f4aa797ab448c.tar.xz
Add --report action to report the current state of the system.
-rw-r--r--paludis/tasks/Makefile.am6
-rw-r--r--paludis/tasks/report_task.cc227
-rw-r--r--paludis/tasks/report_task.hh83
-rw-r--r--src/paludis/Makefile.am1
-rw-r--r--src/paludis/command_line.cc2
-rw-r--r--src/paludis/command_line.hh3
-rw-r--r--src/paludis/paludis.cc9
-rw-r--r--src/paludis/report.cc164
-rw-r--r--src/paludis/report.hh33
9 files changed, 526 insertions, 2 deletions
diff --git a/paludis/tasks/Makefile.am b/paludis/tasks/Makefile.am
index 76c8b41..b03694a 100644
--- a/paludis/tasks/Makefile.am
+++ b/paludis/tasks/Makefile.am
@@ -23,12 +23,14 @@ paludis_tasks_includedir = $(includedir)/paludis/tasks
paludis_tasks_include_HEADERS = \
install_task.hh \
uninstall_task.hh \
- sync_task.hh
+ sync_task.hh \
+ report_task.hh
libpaludistasks_a_SOURCES = $(paludis_tasks_include_HEADERS) \
install_task.cc \
uninstall_task.cc \
- sync_task.cc
+ sync_task.cc \
+ report_task.cc
built-sources : $(BUILT_SOURCES)
for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
diff --git a/paludis/tasks/report_task.cc b/paludis/tasks/report_task.cc
new file mode 100644
index 0000000..57809ec
--- /dev/null
+++ b/paludis/tasks/report_task.cc
@@ -0,0 +1,227 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Fernando J. Pereda <ferdy@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "report_task.hh"
+#include <paludis/environment.hh>
+
+using namespace paludis;
+
+namespace
+{
+ class VulnerableChecker :
+ public DepAtomVisitorTypes::ConstVisitor
+ {
+ private:
+ std::multimap<PackageDatabaseEntry, DepTag::ConstPointer> _found;
+ const Environment & _env;
+
+ public:
+ typedef std::multimap<PackageDatabaseEntry, DepTag::ConstPointer>::const_iterator ConstIterator;
+
+ /**
+ * Constructor.
+ */
+ VulnerableChecker(const Environment & e) :
+ _env(e)
+ {
+ }
+
+ /// \name Visit functions
+ ///{
+ void visit(const AllDepAtom * const);
+
+ void visit(const AnyDepAtom * const);
+
+ void visit(const UseDepAtom * const);
+
+ void visit(const PackageDepAtom * const);
+
+ void visit(const PlainTextDepAtom * const)
+ {
+ }
+
+ void visit(const BlockDepAtom * const)
+ {
+ }
+ ///}
+
+ /**
+ * Return whether a PDE is insecure or not
+ */
+ std::pair<ConstIterator, ConstIterator> insecure_tags(const PackageDatabaseEntry & pde) const
+ {
+ return _found.equal_range(pde);
+ }
+ };
+
+ void
+ VulnerableChecker::visit(const AllDepAtom * const a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+
+ void
+ VulnerableChecker::visit(const AnyDepAtom * const a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+
+ void
+ VulnerableChecker::visit(const UseDepAtom * const a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+
+ void
+ VulnerableChecker::visit(const PackageDepAtom * const a)
+ {
+ PackageDatabaseEntryCollection::ConstPointer insecure(
+ _env.package_database()->query(*a, is_either));
+ for (PackageDatabaseEntryCollection::Iterator i(insecure->begin()),
+ i_end(insecure->end()) ; i != i_end ; ++i)
+ if (a->tag())
+ _found.insert(std::make_pair(*i, a->tag()));
+ else
+ throw InternalError(PALUDIS_HERE, "didn't get a tag");
+ }
+}
+
+namespace paludis
+{
+ template<>
+ struct Implementation<ReportTask> :
+ InternalCounted<Implementation<ReportTask> >
+ {
+ Environment * const env;
+
+ Implementation(Environment * const e) :
+ env(e)
+ {
+ }
+ };
+}
+
+ReportTask::ReportTask(Environment * const env) :
+ PrivateImplementationPattern<ReportTask>(new Implementation<ReportTask>(env))
+{
+}
+
+ReportTask::~ReportTask()
+{
+}
+
+void
+ReportTask::execute()
+{
+ Context context("When executing report task:");
+
+ on_report_all_pre();
+
+ paludis::Environment * const e(_imp->env);
+
+ VulnerableChecker vuln(*e);
+ for (PackageDatabase::RepositoryIterator r(e->package_database()->begin_repositories()),
+ r_end(e->package_database()->end_repositories()) ; r != r_end ; ++r)
+ {
+ Repository::ConstPointer rr(e->package_database()->fetch_repository((*r)->name()));
+ if (! rr->sets_interface)
+ continue;
+
+ DepAtom::ConstPointer insecure(rr->sets_interface->package_set(SetName("insecurity")));
+ if (! insecure)
+ continue;
+ insecure->accept(&vuln);
+ }
+
+ for (PackageDatabase::RepositoryIterator r(e->package_database()->begin_repositories()),
+ r_end(e->package_database()->end_repositories()) ; r != r_end ; ++r)
+ {
+ Repository::ConstPointer rr(e->package_database()->fetch_repository((*r)->name()));
+ if (! rr->installed_interface)
+ continue;
+
+ CategoryNamePartCollection::ConstPointer cat_names(rr->category_names());
+ for (CategoryNamePartCollection::Iterator c(cat_names->begin()), c_end(cat_names->end()) ;
+ c != c_end ; ++c)
+ {
+ QualifiedPackageNameCollection::ConstPointer packages(rr->package_names(*c));
+ for (QualifiedPackageNameCollection::Iterator p(packages->begin()), p_end(packages->end()) ;
+ p != p_end ; ++p)
+ {
+ on_report_check_package_pre(*p);
+
+ VersionSpecCollection::ConstPointer vers(rr->version_specs(*p));
+ for (VersionSpecCollection::Iterator v(vers->begin()), v_end(vers->end()) ;
+ v != v_end ; ++v)
+ {
+ PackageDatabaseEntry pde(*p, *v, rr->name());
+ bool is_masked(false);
+ bool is_vulnerable(false);
+ bool is_missing(false);
+
+ MaskReasons mr;
+ try
+ {
+ VersionMetadata::ConstPointer m(rr->version_metadata(pde.name, pde.version));
+
+ if (m->origins.source)
+ {
+ mr = e->mask_reasons(*(m->origins.source));
+ if (mr.any())
+ is_masked = true;
+ }
+ }
+ catch (const NoSuchPackageError &)
+ {
+ is_missing = true;
+ }
+
+ std::pair<VulnerableChecker::ConstIterator, VulnerableChecker::ConstIterator> pi(
+ vuln.insecure_tags(pde));
+ if (pi.first != pi.second)
+ is_vulnerable = true;
+
+ if (is_masked || is_vulnerable || is_missing)
+ {
+ on_report_package_failure_pre(pde);
+ if (is_masked)
+ on_report_package_is_masked(pde, mr);
+ if (is_vulnerable)
+ {
+ on_report_package_is_vulnerable_pre(pde);
+ for (VulnerableChecker::ConstIterator itag(pi.first) ; itag != pi.second ; ++itag)
+ on_report_package_is_vulnerable(pde, itag->second->short_text());
+ on_report_package_is_vulnerable_post(pde);
+ }
+ if (is_missing)
+ on_report_package_is_missing(pde);
+ on_report_package_failure_post(pde);
+ }
+ else
+ on_report_package_success(pde);
+
+ }
+
+ on_report_check_package_post(*p);
+ }
+ }
+ }
+
+ on_report_all_post();
+}
diff --git a/paludis/tasks/report_task.hh b/paludis/tasks/report_task.hh
new file mode 100644
index 0000000..16a701c
--- /dev/null
+++ b/paludis/tasks/report_task.hh
@@ -0,0 +1,83 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Fernando J. Pereda <ferdy@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_TASKS_REPORT_TASK_HH
+#define PALUDIS_GUARD_PALUDIS_TASKS_REPORT_TASK_HH 1
+
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/repository.hh>
+#include <paludis/mask_reasons.hh>
+
+namespace paludis
+{
+ class Environment;
+
+ /**
+ * Task to report the current state of the system.
+ *
+ * \ingroup grptasks
+ * \nosubgrouping
+ */
+ class PALUDIS_VISIBLE ReportTask :
+ PrivateImplementationPattern<ReportTask>,
+ InstantiationPolicy<ReportTask, instantiation_method::NonCopyableTag>
+ {
+ protected:
+ ///\name Basic operations
+ ///\{
+
+ ReportTask(Environment * const env);
+
+ ///\}
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ virtual ~ReportTask();
+
+ ///\}
+
+ ///\name Event callbacks
+ ///\{
+
+ virtual void on_report_all_pre() = 0;
+ virtual void on_report_check_package_pre(const QualifiedPackageName & p) = 0;
+ virtual void on_report_package_success(const PackageDatabaseEntry & pde) = 0;
+ virtual void on_report_package_failure_pre(const PackageDatabaseEntry & pde) = 0;
+ virtual void on_report_package_is_masked(const PackageDatabaseEntry & pde, const MaskReasons & mr) = 0;
+ virtual void on_report_package_is_vulnerable_pre(const PackageDatabaseEntry & pde) = 0;
+ virtual void on_report_package_is_vulnerable(const PackageDatabaseEntry & pde, const std::string & tag) = 0;
+ virtual void on_report_package_is_vulnerable_post(const PackageDatabaseEntry & pde) = 0;
+ virtual void on_report_package_is_missing(const PackageDatabaseEntry & pde) = 0;
+ virtual void on_report_package_failure_post(const PackageDatabaseEntry & pde) = 0;
+ virtual void on_report_check_package_post(const QualifiedPackageName & p) = 0;
+ virtual void on_report_all_post() = 0;
+
+ ///\}
+
+ /**
+ * Run the task.
+ */
+ void execute();
+ };
+}
+
+#endif
diff --git a/src/paludis/Makefile.am b/src/paludis/Makefile.am
index bee0464..3b1f37c 100644
--- a/src/paludis/Makefile.am
+++ b/src/paludis/Makefile.am
@@ -39,6 +39,7 @@ paludis_SOURCES = \
contents.hh contents.cc \
owner.hh owner.cc \
news.hh news.cc \
+ report.hh report.cc \
paludis.cc
paludis_LDADD = \
diff --git a/src/paludis/command_line.cc b/src/paludis/command_line.cc
index 63ac0b8..a913224 100644
--- a/src/paludis/command_line.cc
+++ b/src/paludis/command_line.cc
@@ -30,6 +30,7 @@ CommandLine::CommandLine() :
a_uninstall(&action_args, "uninstall", 'u', "Uninstall one or more packages"),
a_uninstall_unused(&action_args, "uninstall-unused", '\0', "Uninstall unused packages"),
a_sync(&action_args, "sync", 's', "Sync all or specified repositories"),
+ a_report(&action_args, "report", 'r', "Report the current state of the system"),
a_contents(&action_args, "contents", 'k', "Display contents of a package"),
a_owner(&action_args, "owner", 'o', "Display the owner of a file"),
a_version(&action_args, "version", 'V', "Display program version"),
@@ -202,6 +203,7 @@ CommandLine::CommandLine() :
add_usage_line("--query [query options] target ...");
add_usage_line("--install [install options] target ...");
add_usage_line("--sync [target (leave blank for all)]");
+ add_usage_line("--report");
add_usage_line("--contents target ...");
add_usage_line("--owner [owner options] files ...");
add_usage_line("--version");
diff --git a/src/paludis/command_line.hh b/src/paludis/command_line.hh
index 81d0f8e..5df2387 100644
--- a/src/paludis/command_line.hh
+++ b/src/paludis/command_line.hh
@@ -74,6 +74,9 @@ class CommandLine :
/// --sync
paludis::args::SwitchArg a_sync;
+ /// --report
+ paludis::args::SwitchArg a_report;
+
/// --contents
paludis::args::SwitchArg a_contents;
diff --git a/src/paludis/paludis.cc b/src/paludis/paludis.cc
index fafb8b3..1ef1e5d 100644
--- a/src/paludis/paludis.cc
+++ b/src/paludis/paludis.cc
@@ -26,6 +26,7 @@
#include "news.hh"
#include "owner.hh"
#include "query.hh"
+#include "report.hh"
#include "sync.hh"
#include "uninstall.hh"
#include "config.h"
@@ -194,6 +195,7 @@ main(int argc, char *argv[])
CommandLine::get_instance()->a_uninstall.specified() +
CommandLine::get_instance()->a_uninstall_unused.specified() +
CommandLine::get_instance()->a_sync.specified() +
+ CommandLine::get_instance()->a_report.specified() +
CommandLine::get_instance()->a_list_repositories.specified() +
CommandLine::get_instance()->a_list_categories.specified() +
CommandLine::get_instance()->a_list_packages.specified() +
@@ -337,6 +339,13 @@ main(int argc, char *argv[])
return do_sync();
}
+ if (CommandLine::get_instance()->a_report.specified())
+ {
+ if (! CommandLine::get_instance()->empty())
+ throw DoHelp("report action takes no parameters");
+ return do_report();
+ }
+
if (CommandLine::get_instance()->a_list_repositories.specified())
{
if (! CommandLine::get_instance()->empty())
diff --git a/src/paludis/report.cc b/src/paludis/report.cc
new file mode 100644
index 0000000..7fb250b
--- /dev/null
+++ b/src/paludis/report.cc
@@ -0,0 +1,164 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Fernando J. Pereda <ferdy@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "report.hh"
+#include "colour.hh"
+#include <paludis/tasks/report_task.hh>
+#include <paludis/environment/default/default_environment.hh>
+#include <iostream>
+
+/** \file
+ * Handle the --report action for the main paludis program.
+ */
+
+using namespace paludis;
+using std::cout;
+using std::endl;
+
+namespace
+{
+ class OurReportTask :
+ public ReportTask
+ {
+ private:
+ int _n_packages;
+ int _n_errors;
+
+ public:
+ OurReportTask() :
+ ReportTask(DefaultEnvironment::get_instance()),
+ _n_packages(0),
+ _n_errors(0)
+ {
+ }
+
+ virtual void on_report_all_pre();
+ virtual void on_report_check_package_pre(const QualifiedPackageName & p);
+ virtual void on_report_package_success(const PackageDatabaseEntry & pde);
+ virtual void on_report_package_failure_pre(const PackageDatabaseEntry & pde);
+ virtual void on_report_package_is_masked(const PackageDatabaseEntry & pde, const MaskReasons & mr);
+ virtual void on_report_package_is_vulnerable_pre(const PackageDatabaseEntry & pde);
+ virtual void on_report_package_is_vulnerable(const PackageDatabaseEntry & pde, const std::string & tag);
+ virtual void on_report_package_is_vulnerable_post(const PackageDatabaseEntry & pde);
+ virtual void on_report_package_is_missing(const PackageDatabaseEntry & pde);
+ virtual void on_report_package_failure_post(const PackageDatabaseEntry & pde);
+ virtual void on_report_check_package_post(const QualifiedPackageName & p);
+ virtual void on_report_all_post();
+
+ int return_code() const
+ {
+ return _n_errors ? 1 : 0;
+ }
+ };
+
+ void
+ OurReportTask::on_report_all_pre()
+ {
+ cout << colour(cl_heading, "Current state of the system") << endl << endl;
+ }
+
+ void
+ OurReportTask::on_report_check_package_pre(const QualifiedPackageName &)
+ {
+ }
+
+ void
+ OurReportTask::on_report_package_success(const PackageDatabaseEntry &)
+ {
+ }
+
+ void
+ OurReportTask::on_report_package_failure_pre(const PackageDatabaseEntry & pde)
+ {
+ cout << "* " << colour(cl_package_name, pde) << " NOT OK";
+ }
+
+ void
+ OurReportTask::on_report_package_is_masked(const PackageDatabaseEntry &, const MaskReasons & mr)
+ {
+ cout << endl << " Masked by: ";
+
+ bool comma(false);
+ for (unsigned i(0), i_end(mr.size()); i != i_end; ++i)
+ if (mr.test(i))
+ {
+ if (comma)
+ cout << ", ";
+ cout << colour(cl_masked, MaskReason(i));
+ comma = true;
+ }
+ ++_n_errors;
+ }
+
+ void
+ OurReportTask::on_report_package_is_vulnerable_pre(const PackageDatabaseEntry &)
+ {
+ cout << endl << " Affected by:";
+ }
+
+ void
+ OurReportTask::on_report_package_is_vulnerable(const PackageDatabaseEntry &, const std::string & tag)
+ {
+ cout << " " << colour(cl_tag, tag);
+ ++_n_errors;
+ }
+
+ void
+ OurReportTask::on_report_package_is_vulnerable_post(const PackageDatabaseEntry &)
+ {
+ }
+
+ void
+ OurReportTask::on_report_package_is_missing(const PackageDatabaseEntry &)
+ {
+ cout << endl << " No longer exists in its original repository";
+ ++_n_errors;
+ }
+
+ void
+ OurReportTask::on_report_package_failure_post(const PackageDatabaseEntry &)
+ {
+ cout << endl << endl;
+ }
+
+ void
+ OurReportTask::on_report_check_package_post(const QualifiedPackageName &)
+ {
+ ++_n_packages;
+ }
+
+ void
+ OurReportTask::on_report_all_post()
+ {
+ cout << endl <<
+ "Finished processing " <<
+ _n_packages << " " << (_n_packages != 1 ? "packages" : "package") << ". " <<
+ _n_errors << " " << (_n_errors != 1 ? "errors" : "error") << "." << endl;
+ }
+}
+
+int do_report()
+{
+ Context context("When performing report action from command line:");
+
+ OurReportTask task;
+ task.execute();
+
+ return task.return_code();
+}
diff --git a/src/paludis/report.hh b/src/paludis/report.hh
new file mode 100644
index 0000000..761a200
--- /dev/null
+++ b/src/paludis/report.hh
@@ -0,0 +1,33 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Fernando J. Pereda <ferdy@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_SRC_REPORT_HH
+#define PALUDIS_GUARD_SRC_REPORT_HH 1
+
+#include "command_line.hh"
+
+/** \file
+ * Declaration for the do_report function.
+ */
+
+/// Handle --report.
+int do_report();
+
+#endif
+