/*
* Copyright 2013 Red Hat Inc., Durham, North Carolina.
* All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Authors:
* Šimon Lukašík
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "public/oval_definitions.h"
#include "public/oval_system_characteristics.h"
#include "oval_system_characteristics_impl.h"
#include "oval_probe_impl.h"
#include "_oval_probe_session.h"
static int _oval_probe_hint_criteria(oval_probe_session_t *sess, struct oval_criteria_node *cnode, int variable_instance_hint);
static int _oval_probe_hint_object(oval_probe_session_t *psess, struct oval_object *object, int variable_instance_hint);
/**
* Finds all the oval_syschars (collected objects) assigned with a given definition
* and sets the variable_instance_hint attribute thereof. That is to mark these
* collected objects with the hint that a new round of collection might be needed
* when these objects are again probed by @ref oval_probe_query_object. That is
* usefull when a new variable instance is injected into the oval_agent_session.
* @param variable_instance_hint new hint to set
* @returns 0 on success; -1 on error; 1 on warning
*/
int oval_probe_hint_definition(oval_probe_session_t *sess, struct oval_definition *definition, int variable_instance_hint)
{
if (definition == NULL)
return -1;
struct oval_criteria_node *cnode = oval_definition_get_criteria(definition);
if (cnode == NULL)
return -1;
return _oval_probe_hint_criteria(sess, cnode, variable_instance_hint);
}
int _oval_probe_hint_criteria(oval_probe_session_t *sess, struct oval_criteria_node *cnode, int variable_instance_hint)
{
switch (oval_criteria_node_get_type(cnode)) {
case OVAL_NODETYPE_CRITERION:{
struct oval_test *test = oval_criteria_node_get_test(cnode);
if (test == NULL)
return 0;
struct oval_object *object = oval_test_get_object(test);
if (object == NULL)
return 0;
// TODO: Do we need to similarly hint all the object refereced like: test->state->variable->object?
return _oval_probe_hint_object(sess, object, variable_instance_hint);
}
case OVAL_NODETYPE_CRITERIA:{
struct oval_criteria_node_iterator *cnode_it = oval_criteria_node_get_subnodes(cnode);
if (cnode_it == NULL)
return 0;
int ret = 0;
while (ret == 0 && oval_criteria_node_iterator_has_more(cnode_it)) {
struct oval_criteria_node *node = oval_criteria_node_iterator_next(cnode_it);
ret = _oval_probe_hint_criteria(sess, node, variable_instance_hint);
}
oval_criteria_node_iterator_free(cnode_it);
return ret;
}
case OVAL_NODETYPE_EXTENDDEF:{
struct oval_definition *oval_def = oval_criteria_node_get_definition(cnode);
return oval_probe_hint_definition(sess, oval_def, variable_instance_hint);
}
case OVAL_NODETYPE_UNKNOWN:{
assert(false);
return -1;
}
}
return -1;
}
int _oval_probe_hint_object(oval_probe_session_t *psess, struct oval_object *object, int variable_instance_hint)
{
const char *oid = oval_object_get_id(object);
struct oval_syschar *syschar = oval_syschar_model_get_syschar(psess->sys_model, oid);
if (syschar != NULL) {
oval_syschar_set_variable_instance_hint(syschar, variable_instance_hint);
}
return 0;
}