From d00cb4b73a41fce2ffaa5c6313b6752dfc9ad046 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Wed, 31 Aug 2016 11:11:31 +0000
Subject: [PATCH 1/6] New option '-r' to select a report plugin

---
 src/main.c | 69 +++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 41 insertions(+), 28 deletions(-)

diff --git a/src/main.c b/src/main.c
index 8593c17..5bb16c9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -283,8 +283,7 @@ static bool _show_version = false;
 static bool skip_update = false;
 static gchar *nvds = NULL;
 static gchar *forced_type = NULL;
-static bool no_html = false;
-static bool csv_mode = false;
+static gchar *report_type = NULL;
 static char *modified_stamp = NULL;
 static gchar *mapping_file = NULL;
 static gchar *output_file = NULL;
@@ -297,10 +296,9 @@ static GOptionEntry _entries[] = {
         { "nvd-dir", 'd', 0, G_OPTION_ARG_STRING, &nvds, "NVD directory in filesystem", NULL },
         { "version", 'v', 0, G_OPTION_ARG_NONE, &_show_version, "Show version", NULL },
         { "type", 't', 0, G_OPTION_ARG_STRING, &forced_type, "Set package type to T", "T" },
-        { "no-html", 'N', 0, G_OPTION_ARG_NONE, &no_html, "Disable HTML report", NULL },
+        { "report", 'r', 0, G_OPTION_ARG_STRING, &report_type, "Set report type to R", "R" },
         { "modified", 'm', 0, G_OPTION_ARG_STRING, &modified_stamp, "Ignore reports after modification date", "D" },
         { "srpm-dir", 's', 0, G_OPTION_ARG_STRING, &srpm_dir, "Source RPM directory", "S" },
-        { "csv", 'c', 0, G_OPTION_ARG_NONE, &csv_mode, "Output CSV formatted data only", NULL },
         { "mapping", 'M', 0, G_OPTION_ARG_STRING, &mapping_file, "Path to a mapping file", NULL},
         { "output-file", 'o', 0, G_OPTION_ARG_STRING, &output_file, "Path to the output file (output plugin specific)", NULL},
         { "use-fractional-compare", 'f', 0, G_OPTION_ARG_NONE, &use_frac_compare, "CVE version string fractional compare", NULL },
@@ -387,7 +385,7 @@ end:
         return ret;
 }
 
-static gchar *supported_packages(GList *plugins)
+static gchar *supported_plugins(GList *plugins)
 {
         uint len;
         CvePlugin *plugin = NULL;
@@ -400,7 +398,7 @@ static gchar *supported_packages(GList *plugins)
         plugin = g_list_nth_data(plugins, 0);
 
         if (!asprintf(&r, "%s", plugin->name)) {
-                fprintf(stderr, "supported_packages(): Out of memory\n");
+                fprintf(stderr, "supported_plugins(): Out of memory\n");
                 abort();
         }
 
@@ -409,7 +407,7 @@ static gchar *supported_packages(GList *plugins)
 
                 plugin = g_list_nth_data(plugins, i);
                 if (!asprintf(&t, "%s, %s", r, plugin->name)) {
-                        fprintf(stderr, "supported_packages(): Out of memory\n");
+                        fprintf(stderr, "supported_plugins(): Out of memory\n");
                         abort();
                 }
                 free(r);
@@ -479,6 +477,7 @@ int main(int argc, char **argv)
         autofree(cve_string) *db_path = NULL;
         autofree(CveDB) *cve_db = NULL;
         GList *pkg_plugins = NULL;
+        GList *report_plugins = NULL;
         int ret = EXIT_FAILURE;
         CveToolInstance instance = { .pkg_plugin = NULL };
         time_t ti;
@@ -501,13 +500,10 @@ int main(int argc, char **argv)
                 goto cleanup_no_lock;
         }
 
-        quiet = csv_mode || !no_html;
         self->output_file = output_file;
         self->cacert_file = cacert_file;
 
-        if (!csv_mode && self->output_file) {
-                quiet = false;
-        }
+        quiet = !self->output_file;
 
         if (_show_version) {
                 show_version();
@@ -569,6 +565,12 @@ int main(int argc, char **argv)
                 goto cleanup;
         }
 
+        report_plugins = cve_plugin_get_by_cap(PLUGIN_TYPE_REPORT);
+        if (!report_plugins || g_list_length(report_plugins) < 1) {
+                fprintf(stderr, "Cannot find any reporting plugins on this system.\n");
+                goto cleanup;
+        }
+
         if (srpm_dir) {
                 if (!cve_is_dir(srpm_dir)) {
                         fprintf(stderr, "srpm directory does not exist or is not a directory\n");
@@ -581,7 +583,7 @@ int main(int argc, char **argv)
         if (forced_type) {
                 if (g_str_equal(forced_type, "list")) {
                         /* Print a list of 'em */
-                        autofree(gchar) *list = supported_packages(pkg_plugins);
+                        autofree(gchar) *list = supported_plugins(pkg_plugins);
                         printf("Currently supported package types: %s\n", list);
                         goto cleanup;
                 } else {
@@ -599,6 +601,30 @@ int main(int argc, char **argv)
                 }
         }
 
+        if (!report_type) {
+                report_type = "html";
+        }
+        if (g_str_equal(report_type, "list")) {
+                /* Print a list of 'em */
+                autofree(gchar) *list = supported_plugins(report_plugins);
+                printf("Currently supported report types: %s\n", list);
+                goto cleanup;
+        } else {
+                report = cve_plugin_get_by_name(report_type);
+                if (!report) {
+                        fprintf(stderr, "Plugin \'%s\' not found.\n", report_type);
+                        goto cleanup;
+                }
+                if (!(report->flags & PLUGIN_TYPE_REPORT)) {
+                        fprintf(stderr, "Plugin \'%s\' is not a PLUGIN_TYPE_REPORT.\n", report_type);
+                        goto cleanup;
+                }
+                if (!report->report) {
+                        fprintf(stderr, "No usable output module\n");
+                        goto cleanup;
+                }
+        }
+
         if (argc != 2) {
                 fprintf(stderr, "Usage: %s [path-to-source-spec|path-to-source-list-file]\n", argv[0]);
                 goto cleanup;
@@ -787,22 +813,6 @@ clean:
                 fprintf(stderr, "Scanned %d source file%s\n", size, size > 1 ? "s" : "");
         }
 
-        /* TODO: Switch to single output mode, with a report type set in
-         * config and/or flags, i.e. -r html (preserve csv option though)
-         */
-        if (csv_mode) {
-                report = cve_plugin_get_by_name("csv");
-        } else if (!no_html) {
-                report = cve_plugin_get_by_name("html");
-        } else {
-                report = cve_plugin_get_by_name("cli");
-        }
-
-        if (!report || !report->report) {
-                fprintf(stderr, "No usable output module\n");
-                goto cleanup;
-        }
-
         if (!report->report(self)) {
                 fprintf(stderr, "Report generation failed\n");
                 goto cleanup;
@@ -817,6 +827,9 @@ cleanup_no_lock:
         if (pkg_plugins) {
                 g_list_free(pkg_plugins);
         }
+        if (report_plugins) {
+                g_list_free(report_plugins);
+        }
         if (self->db) {
                 g_hash_table_unref(self->db);
         }
-- 
2.10.1