📄 prefs_plugins_tree.c
字号:
/* NessusClient * Copyright (C) 1998, 2005 Renaud Deraison * * This program 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. * * This program 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., 675 Mass Ave, Cambridge, MA 02139, USA. * * In addition, as a special exception, Renaud Deraison * gives permission to link the code of this program with any * version of the OpenSSL library which is distributed under a * license identical to that listed in the included COPYING.OpenSSL * file, and distribute linked combinations including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * this file, you may extend this exception to your version of the * file, but you are not obligated to do so. If you do not wish to * do so, delete this exception statement from your version. */#include <time.h>#include <includes.h>#include "comm.h"#include "nessus_i18n.h"#ifdef USE_GTK#include <gtk/gtk.h>#include "../nessus_plugin.h"#include "../plugin_infos.h"#include "../families.h"#include "../error_dialog.h"#include "../xpm/warning_small.xpm"#include "filter.h"#include "context.h"#include "prefs_help.h"#include "prefs_plugins_tree.h"/* The columns of the tree store we use */enum { /* The name of the family/plugin */ COL_NAME, /* struct arglist * of the plugin. For a family the value is NULL. */ COL_PLUGIN, /* Number of columns */ NUM_COLS};/* Define a new signal, "statistics-changed", to be emitted when the * plugin tree changes in a way that may have changed the statistics * (number of plugins, number of enabled plugins, number of filtered * plugins) tree view. * * the signal handlers have the following signature: * * void statistics_changed_handler(GtkWidget* tree_view, gpointer user_data) *//* the id of the signal */static gint statistics_changed_signal = 0;/* register the "statistics-changed" signal with glib. This function * must be called before the signal is used for the first time in any * way. It may be called multiple times as it only registers the signal * on the first call. */static voidcreate_statistics_changed_signal(){ if (statistics_changed_signal == 0) { statistics_changed_signal = g_signal_new("statistics-changed", GTK_TYPE_TREE_VIEW, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, GTK_TYPE_NONE, 0); }}/* Emit the "statistics-changed" signal with the tree_view as the * instance */static voidemit_statistics_changed(tree_view) GtkWidget *tree_view;{ g_signal_emit(tree_view, statistics_changed_signal, 0);} /* Handler for the tree model's "row-changed" signal. Emit the * "statistics-changed" signal on the tree model */static voidemit_statistics_when_row_changed(treemodel, arg1, arg2, user_data) GtkTreeModel *treemodel; GtkTreePath *arg1; GtkTreeIter *arg2; gpointer user_data;{ emit_statistics_changed(GTK_WIDGET(user_data));}/* Handler for the tree model's "row-deleted" signal. Emit the * "statistics-changed" signal on the tree model */static voidemit_statistics_when_row_deleted(treemodel, arg1, user_data) GtkTreeModel *treemodel; GtkTreePath *arg1; gpointer user_data;{ emit_statistics_changed(GTK_WIDGET(user_data));}/* Return whether the family given by the model and iter is enabled. * * The iter argument must be the iter pointing to the family row. * A family is enabled when at least one of it's plugins is enabled as * determined by plug_get_launch. */static gbooleanis_family_enabled(model, iter) GtkTreeModel* model; GtkTreeIter * iter;{ GtkTreeIter child_iter; if (gtk_tree_model_iter_children(model, &child_iter, iter)) { do { struct nessus_plugin *plugin; gtk_tree_model_get(model, &child_iter, COL_PLUGIN, &plugin, -1); if ( plugin->enabled ) return TRUE; } while (gtk_tree_model_iter_next(model, &child_iter)); } return FALSE;}/* Determine whether a warning should be shown for the given row * * Some plugins are dangerous and a warning sign is shown for the them * in the tree view. This function determines whether a warning is * necessary for a particular row of the tree model. The row can be * specified either with a path or an iter. If an iter is given, * i.e. the iter parameter is not NULL, the iter is used to retrieve the * plugin information and the path argument is ignored. If iter is * NULL, the path argument must be the GtkTreePath for the row and it is * used to determine the iter needed to access the row data. * * The return value is true if the category of the plugin is one of * "denial", "kill_host", "flood" or "destructive_attack" and false * otherwise. */static intshould_show_warning(model, path, iter) GtkTreeModel *model; GtkTreePath *path; GtkTreeIter *iter;{ GtkTreeIter real_iter; struct nessus_plugin *plugin; char *cat; int warning = FALSE; if (!iter) { gtk_tree_model_get_iter(model, &real_iter, path); iter = &real_iter; } gtk_tree_model_get(model, iter, COL_PLUGIN, &plugin, -1); if (plugin) { cat = plugin->category; warning = cat ? (!strcmp(cat, "denial") || !strcmp(cat, "kill_host") || !strcmp(cat, "flood") || !strcmp(cat, "destructive_attack")) : 0; } return warning;}/* Trigger a row update in any view of the given model * * The iter should be an iter for the row in question. This function is * needed because some information shown in the plugin tree is not * directly stored in the tree store. When that information is changed * the update is not automatically noted by the tree views because the * model doesn't send any signals. */static voidtrigger_row_update(model, iter) GtkTreeModel *model; GtkTreeIter *iter;{ GtkTreePath *path = gtk_tree_model_get_path(model, iter); gtk_tree_model_row_changed(model, path, iter); gtk_tree_path_free(path);}/* Toggle the active/launch flag of a plugin * * This function is called when the checkbox in the tree view widget has * been toggled by the user. There are two cases: The row on which it * happens is a family, in which case all plugins of the family are * activated/deactivated depending on the state of the family checkbox, * or the row is a single plugin in which case on that plugins flag is * changed. * * This function expects the tree view in the data parameter. The * path_str must describe the path in the model of that tree view. * * The changes are always made on the actual plugins, that is the * arglists, with the function plug_set_launch. To update the view, the * appropriate signal is emitted for the rows on the model that are * modified. If a plugin is modified, a signal is also emitted for it's * parent family. */static voidactive_toggled(cell, path_str, data) GtkCellRendererToggle *cell; gchar *path_str; gpointer data;{ GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(data)); GtkTreeIter iter; struct nessus_plugin *plugin; gtk_tree_model_get_iter_from_string(model, &iter, path_str); /* if the item is a family instead of a plugin, toggle the state of * all the children as well. Since only families have children, we * can determine whether the iter points to a family by checking * whether we can get an iterator for its children. */ if (gtk_tree_model_iter_has_child(model, &iter)) { GtkTreeIter child_iter; gboolean launch = !is_family_enabled(model, &iter); gtk_tree_model_iter_children(model, &child_iter, &iter); do { gtk_tree_model_get(model, &child_iter, COL_PLUGIN, &plugin, -1); plugin->enabled = launch; trigger_row_update(model, &child_iter); } while (gtk_tree_model_iter_next(model, &child_iter)); } else { GtkTreeIter parent_iter; gtk_tree_model_get(model, &iter, COL_PLUGIN, &plugin, -1); plugin->enabled = ! plugin->enabled; trigger_row_update(model, &iter); /* update the parent too because the active flag of the family * depends on the active flags of all of its children */ gtk_tree_model_iter_parent(model, &parent_iter, &iter); trigger_row_update(model, &parent_iter); }}/* Called when the user double clicks on a row of the tree view. Pop up * the plugin info dialog if the row is a plugin, not a family. */static voidrow_activated(treeview, path, column, user_data) GtkTreeView *treeview; GtkTreePath *path; GtkTreeViewColumn *column; gpointer user_data;{ GtkTreeModel * model = gtk_tree_view_get_model(treeview); int depth = gtk_tree_path_get_depth(path); if (depth > 1) { GtkTreeIter iter; struct nessus_plugin *plugin; gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get(model, &iter, COL_PLUGIN, &plugin, -1); plugin_info_window_setup(plugin, plugin->name); }}/* Make the check boxes and warning "buttons" work on the first mouse click * * Normally, the tree view only selects a line on the first click with * the mouse button. Only clicks on a selected row will toggle a check * box. To work around that, we handle button clicks ourselves in some * cases. Any click on in the column with the check box will call * gtk_tree_view_set_cursor for the row/column which will lead to the * corresponding check box being toggled. Also, a click on a warning * sign will pop up the warning dialog. * * When the event was handled, i.e. one of the two cases above occurred, * the function returns TRUE to indicate that the event was handled. * Otherwise FALSE is returned to indicate that the event wasn't handled * yet so that we get the default behavior of the tree view widget in * all other cases. */static gbooleanbutton_press_event(tree, event, user_data) GtkTreeView *tree; GdkEventButton *event; gpointer user_data;{ GtkTreePath * path;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -