text: /**
   * @file   entcmp.c
   * @author "Tomas Heinrich" <theinric@redhat.com>
   *
   * @addtogroup PROBEAPI
   * @{
   */
  /*
   * Copyright 2009 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   *
   * Authors:
   *      Tomas Heinrich <theinric@redhat.com>
   */
  
  #ifdef HAVE_CONFIG_H
  #include <config.h>
  #endif
  
  #include <sexp.h>
  #include <assert.h>
  #include <string.h>
  #include <stdarg.h>
  #include <errno.h>
  #if defined USE_REGEX_PCRE
  #include <pcre.h>
  #elif defined USE_REGEX_POSIX
  #include <regex.h>
  #endif
  #include <arpa/inet.h>
  
  #include "common/debug_priv.h"
  #include "entcmp.h"
  #include "../_probe-api.h"
  #include "../../results/oval_cmp_basic_impl.h"
  #include "../../results/oval_cmp_evr_string_impl.h"
  #include "../../results/oval_cmp_ip_address_impl.h"
  
  oval_result_t probe_ent_cmp_binary(SEXP_t * val1, SEXP_t * val2, oval_operation_t op)
  {
  	oval_result_t result = OVAL_RESULT_ERROR;
  	char *s1, *s2;
  
  	s1 = SEXP_string_cstr(val1);
  	s2 = SEXP_string_cstr(val2);
  
  	result = oval_binary_cmp(s1, s2, op);
  
          oscap_free(s1);
          oscap_free(s2);
  
  	return result;
  }
  
  oval_result_t probe_ent_cmp_bool(SEXP_t * val1, SEXP_t * val2, oval_operation_t op)
  {
  	int v1, v2;
  
  	v1 = SEXP_number_geti_32(val1);
  	v2 = SEXP_number_geti_32(val2);
  
  	return oval_boolean_cmp(v1, v2, op);
  }
  
  oval_result_t probe_ent_cmp_evr(SEXP_t * val1, SEXP_t * val2, oval_operation_t op)
  {
  	oval_result_t result = OVAL_RESULT_ERROR;
  	char *s1 = SEXP_string_cstr(val1);
  	char *s2 = SEXP_string_cstr(val2);
  
  	result = oval_evr_string_cmp(s1, s2, op);
  
  	oscap_free(s1);
  	oscap_free(s2);
  	return result;
  }
  
  oval_result_t probe_ent_cmp_filesetrev(SEXP_t * val1, SEXP_t * val2, oval_operation_t op)
  {
  	oval_result_t result = OVAL_RESULT_ERROR;
  
  	// todo:
  
  	return result;
  }
  
  oval_result_t probe_ent_cmp_float(SEXP_t * val1, SEXP_t * val2, oval_operation_t op)
  {
  	double v1, v2;
  
  	v1 = SEXP_number_getf(val1);
  	v2 = SEXP_number_getf(val2);
  
  	return oval_float_cmp(v1, v2, op);
  }
  
  oval_result_t probe_ent_cmp_int(SEXP_t * val1, SEXP_t * val2, oval_operation_t op)
  {
  	oval_result_t result = OVAL_RESULT_ERROR;
  	int64_t v1, v2;
  
  	v1 = SEXP_number_geti_64(val1);
  	v2 = SEXP_number_geti_64(val2);
  
  	result = oval_int_cmp(v1, v2, op);
  
  	return result;
  }
  
  oval_result_t probe_ent_cmp_ios(SEXP_t * val1, SEXP_t * val2, oval_operation_t op)
  {
  	oval_result_t result = OVAL_RESULT_ERROR;
  
  	// todo:
  
  	return result;
  }
  
  oval_result_t probe_ent_cmp_version(SEXP_t * val1, SEXP_t * val2, oval_operation_t op)
  {
  	const char *state_version = SEXP_string_cstr(val1);
  	const char *sys_version = SEXP_string_cstr(val2);
  
  	oval_result_t result = oval_versiontype_cmp(state_version, sys_version, op);
  
  	oscap_free(state_version);
  	oscap_free(sys_version);
  	return result;
  }
  
  oval_result_t probe_ent_cmp_string(SEXP_t * val1, SEXP_t * val2, oval_operation_t op)
  {
  	oval_result_t result = OVAL_RESULT_ERROR;
  	char *s1, *s2;
  
  	s1 = SEXP_string_cstr(val1);
  	s2 = SEXP_string_cstr(val2);
  
  	result = oval_string_cmp(s1, s2, op);
  
          oscap_free(s1);
          oscap_free(s2);
  
  	return result;
  }
  
  static oval_result_t probe_ent_cmp_ipaddr(int af, SEXP_t *val1, SEXP_t *val2, oval_operation_t op)
  {
  	oval_result_t result = OVAL_RESULT_ERROR;
  	char *addr1 = SEXP_string_cstr(val1);
  	char *addr2 = SEXP_string_cstr(val2);
  
  	result = oval_ipaddr_cmp(af, addr1, addr2, op);
  
  	oscap_free(addr1);
  	oscap_free(addr2);
  	return result;
  }
  
  static inline oval_result_t probe_ent_cmp_single(SEXP_t *state_ent, oval_datatype_t state_data_type, SEXP_t *sysent, oval_operation_t op)
  {
  	// This compares a single entity of a state with a single entity of a sysitem
  	// This is very similar to oval_ent_cmp_str, we hope to get a rid of this soon
  
  	switch (state_data_type) {
  	case OVAL_DATATYPE_BINARY:
  		return probe_ent_cmp_binary(state_ent, sysent, op);
  	case OVAL_DATATYPE_BOOLEAN:
  		return probe_ent_cmp_bool(state_ent, sysent, op);
  	case OVAL_DATATYPE_EVR_STRING:
  		return probe_ent_cmp_evr(state_ent, sysent, op);
  	case OVAL_DATATYPE_FILESET_REVISION:
  		return probe_ent_cmp_filesetrev(state_ent, sysent, op);
  	case OVAL_DATATYPE_FLOAT:
  		return probe_ent_cmp_float(state_ent, sysent, op);
  	case OVAL_DATATYPE_IOS_VERSION:
  		return probe_ent_cmp_ios(state_ent, sysent, op);
  	case OVAL_DATATYPE_VERSION:
  		return probe_ent_cmp_version(state_ent, sysent, op);
  	case OVAL_DATATYPE_INTEGER:
  		return probe_ent_cmp_int(state_ent, sysent, op);
  	case OVAL_DATATYPE_STRING:
  		return probe_ent_cmp_string(state_ent, sysent, op);
  	case OVAL_DATATYPE_IPV4ADDR:
  		return probe_ent_cmp_ipaddr(AF_INET, state_ent, sysent, op);
  	case OVAL_DATATYPE_IPV6ADDR:
  		return probe_ent_cmp_ipaddr(AF_INET6, state_ent, sysent, op);
  	default:
  		dI("Unexpected data type: %d\n", state_data_type);
  		break;
  	}
  
  	return OVAL_RESULT_ERROR;
  }
  
  static oval_result_t probe_ent_cmp(SEXP_t * ent, SEXP_t * val2)
  {
  	oval_operation_t op;
  	oval_datatype_t dtype;
  	SEXP_t *stmp, *val1, *vals, *res_lst, *r0;
  	int val_cnt, is_var;
  	oval_check_t ochk;
  	oval_result_t ores, result;
  
  	ores = OVAL_RESULT_ERROR;
  	result = OVAL_RESULT_ERROR;
          vals = NULL;
  	val_cnt = probe_ent_getvals(ent, &vals);
  
  	if (probe_ent_attrexists(ent, "var_ref")) {
  		is_var = 1;
  	} else {
  		if (val_cnt != 1) {
                          SEXP_free(vals);
  			return OVAL_RESULT_ERROR;
                  }
  
  		is_var = 0;
  	}
  
  	dtype = probe_ent_getdatatype(ent);
  	stmp = probe_ent_getattrval(ent, "operation");
  	if (stmp == NULL)
  		op = OVAL_OPERATION_EQUALS;
  	else
  		op = SEXP_number_geti_32(stmp);
          SEXP_free(stmp);
  	res_lst = SEXP_list_new(NULL);
  
  	SEXP_list_foreach(val1, vals) {
  		if (SEXP_typeof(val1) != SEXP_typeof(val2)) {
  			dI("Types of values to compare don't match: val1: %d, val2: %d\n",
  			   SEXP_typeof(val1), SEXP_typeof(val2));
  
                          SEXP_free(vals);
                          SEXP_free(val1);
                          SEXP_free(res_lst);
  
  			return OVAL_RESULT_ERROR;
  		}
  
  		ores = probe_ent_cmp_single(val1, dtype, val2, op);
  
  		SEXP_list_add(res_lst, r0 = SEXP_number_newi_32(ores));
                  SEXP_free(r0);
  	}
  
  	if (is_var) {
  		stmp = probe_ent_getattrval(ent, "var_check");
  		if (stmp == NULL) {
  			ochk = OVAL_CHECK_ALL;
  		} else {
  			ochk = SEXP_number_geti_32(stmp);
  			SEXP_free(stmp);
  		}
  
  		result = probe_ent_result_bychk(res_lst, ochk);
  	} else {
  		result = ores;
  	}
  
  	SEXP_free(res_lst);
          SEXP_free(vals);
  
  	return result;
  }
  
  static oval_result_t _probe_entste_cmp_record(SEXP_t *ent_ste, SEXP_t *ent_itm)
  {
  	oval_result_t res;
  	oval_operation_t op;
  	oval_check_t ochk;
  	SEXP_t *stmp, *ste_res, *ste_record_fields, *ste_rf, *itm_record_fields;
  	int val_cnt;
  
  	stmp = probe_ent_getattrval(ent_ste, "operation");
  	if (stmp == NULL) {
  		op = OVAL_OPERATION_EQUALS;
  	} else {
  		op = SEXP_number_getu(stmp);
  		SEXP_free(stmp);
  		if (op != OVAL_OPERATION_EQUALS)
  			return OVAL_RESULT_ERROR;
  	}
  
  	val_cnt = probe_ent_getvals(ent_ste, &ste_record_fields);
  	if (val_cnt <= 0) {
  		SEXP_free(ste_record_fields);
  		return OVAL_RESULT_ERROR;
  	}
  	val_cnt = probe_ent_getvals(ent_itm, &itm_record_fields);
  	if (val_cnt <= 0) {
  		SEXP_free(ste_record_fields);
  		SEXP_free(itm_record_fields);
  		return OVAL_RESULT_ERROR;
  	}
  
  	ste_res = SEXP_list_new(NULL);
  
  	SEXP_list_foreach(ste_rf, ste_record_fields) {
  		SEXP_t *itm_rf, *itm_res;
  		const char *sname;
  		bool matched;
  
  		sname = probe_ent_getname(ste_rf);
  		itm_res = SEXP_list_new(NULL);
  		matched = false;
  
  		SEXP_list_foreach(itm_rf, itm_record_fields) {
  			const char *iname;
  
  			iname = probe_ent_getname(itm_rf);
  			if (strcmp(sname, iname)) {
  				oscap_free(iname);
  				continue;
  			}
  			oscap_free(iname);
  			matched = true;
  
  			res = probe_entste_cmp(ste_rf, itm_rf);
  			/* todo: _oval_result_to_sexp() */
  			stmp = SEXP_number_newu(res);
  			SEXP_list_add(itm_res, stmp);
  			SEXP_free(stmp);
  		}
  
  		oscap_free(sname);
  
  		if (!matched) {
  			stmp = SEXP_number_newu(OVAL_RESULT_ERROR);
  			SEXP_list_add(itm_res, stmp);
  			SEXP_free(stmp);
  		}
  
  		stmp = probe_ent_getattrval(ste_rf, "entity_check");
  		if (stmp == NULL) {
  			ochk = OVAL_CHECK_ALL;
  		} else {
  			ochk = SEXP_number_getu(stmp);
  			SEXP_free(stmp);
  		}
  
  		res = probe_ent_result_bychk(itm_res, ochk);
  		SEXP_free(itm_res);
  		stmp = SEXP_number_newu(res);
  		SEXP_list_add(ste_res, stmp);
  		SEXP_free(stmp);
  	}
  
  	SEXP_free(ste_record_fields);
  	SEXP_free(itm_record_fields);
  
  	stmp = probe_ent_getattrval(ent_ste, "entity_check");
  	if (stmp == NULL) {
  		ochk = OVAL_CHECK_ALL;
  	} else {
  		ochk = SEXP_number_getu(stmp);
  		SEXP_free(stmp);
  	}
  
  	res = probe_ent_result_bychk(ste_res, ochk);
  	SEXP_free(ste_res);
  
  	return res;
  }
  
  oval_result_t probe_entste_cmp(SEXP_t * ent_ste, SEXP_t * ent_itm)
  {
  	oval_datatype_t ste_dt;
  	oval_syschar_status_t item_status;
  	oval_result_t ores;
  	SEXP_t *val2;
  	int valcnt;
  
  	item_status = probe_ent_getstatus(ent_itm);
  	switch (item_status) {
  	case SYSCHAR_STATUS_DOES_NOT_EXIST:
  		return OVAL_RESULT_FALSE;
  	case SYSCHAR_STATUS_ERROR:
  	case SYSCHAR_STATUS_NOT_COLLECTED:
  		return OVAL_RESULT_ERROR;
  	default:
  		break;
  	}
  
  	ste_dt = probe_ent_getdatatype(ent_ste);
  	if (ste_dt != probe_ent_getdatatype(ent_itm))
  		return OVAL_RESULT_ERROR;
  
  	if (ste_dt == OVAL_DATATYPE_RECORD)
  		/* records require special handling */
  		return _probe_entste_cmp_record(ent_ste, ent_itm);
  
  	valcnt = probe_ent_getvals(ent_ste, NULL);
  	if (valcnt == 0)
  		return OVAL_RESULT_ERROR;
  
  	val2 = probe_ent_getval(ent_itm);
  	ores = probe_ent_cmp(ent_ste, val2);
          SEXP_free(val2);
  
  	if (ores == OVAL_RESULT_NOT_EVALUATED)
  		return OVAL_RESULT_ERROR;
  	return ores;
  }
  
  oval_result_t probe_entobj_cmp(SEXP_t * ent_obj, SEXP_t * val)
  {
  	oval_result_t ores;
  	SEXP_t *r0 = NULL;
  	int valcnt;
  
  	valcnt = probe_ent_getvals(ent_obj, &r0);
  	SEXP_free(r0);
  	if (valcnt == 0) {
  		dI("valcnt == 0.\n");
  		return OVAL_RESULT_FALSE;
  	}
  
  	ores = probe_ent_cmp(ent_obj, val);
  #if defined(OSCAP_VERBOSE_DEBUG)
  	dI("Result of entobj comparison: %s.\n", oval_result_get_text(ores));
  #endif
  	if (ores == OVAL_RESULT_NOT_EVALUATED)
  		return OVAL_RESULT_FALSE;
  	return ores;
  }
  
  struct _oresults {
  	int true_cnt, false_cnt, unknown_cnt, error_cnt, noteval_cnt, notappl_cnt;
  };
  
  static int results_parser(SEXP_t * res_lst, struct _oresults *ores)
  {
  	oval_result_t r;
  	SEXP_t *res;
  
  	memset(ores, 0, sizeof(struct _oresults));
  
  	SEXP_list_foreach(res, res_lst) {
  		r = SEXP_number_geti_32(res);
  		switch (r) {
  		case OVAL_RESULT_TRUE:
  			++(ores->true_cnt);
  			break;
  		case OVAL_RESULT_FALSE:
  			++(ores->false_cnt);
  			break;
  		case OVAL_RESULT_UNKNOWN:
  			++(ores->unknown_cnt);
  			break;
  		case OVAL_RESULT_ERROR:
  			++(ores->error_cnt);
  			break;
  		case OVAL_RESULT_NOT_EVALUATED:
  			++(ores->noteval_cnt);
  			break;
  		case OVAL_RESULT_NOT_APPLICABLE:
  			++(ores->notappl_cnt);
  			break;
  		default:
  			return -1;
  		}
  	}
  
  	return 0;
  }
  
  // todo: already implemented elsewhere; consolidate
  oval_result_t probe_ent_result_bychk(SEXP_t * res_lst, oval_check_t check)
  {
  	oval_result_t result = OVAL_RESULT_UNKNOWN;
  	struct _oresults ores;
  
  	if (SEXP_list_length(res_lst) == 0)
  		return OVAL_RESULT_UNKNOWN;
  
  	if (results_parser(res_lst, &ores) != 0) {
  		return OVAL_RESULT_ERROR;
  	}
  
  	if (ores.notappl_cnt > 0 &&
  	    ores.noteval_cnt == 0 &&
  	    ores.false_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.true_cnt == 0)
  		return OVAL_RESULT_NOT_APPLICABLE;
  
  	switch (check) {
  	case OVAL_CHECK_ALL:
  		if (ores.true_cnt > 0 &&
  		    ores.false_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt == 0) {
  			result = OVAL_RESULT_TRUE;
  		} else if (ores.false_cnt > 0) {
  			result = OVAL_RESULT_FALSE;
  		} else if (ores.false_cnt == 0 && ores.error_cnt > 0) {
  			result = OVAL_RESULT_ERROR;
  		} else if (ores.false_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt > 0) {
  			result = OVAL_RESULT_UNKNOWN;
  		} else if (ores.false_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt > 0) {
  			result = OVAL_RESULT_NOT_EVALUATED;
  		}
  		break;
  	case OVAL_CHECK_AT_LEAST_ONE:
  		if (ores.true_cnt > 0) {
  			result = OVAL_RESULT_TRUE;
  		} else if (ores.false_cnt > 0 &&
  			   ores.true_cnt == 0 &&
  			   ores.unknown_cnt == 0 && ores.error_cnt == 0 && ores.noteval_cnt == 0) {
  			result = OVAL_RESULT_FALSE;
  		} else if (ores.true_cnt == 0 && ores.error_cnt > 0) {
  			result = OVAL_RESULT_ERROR;
  		} else if (ores.false_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt > 0) {
  			result = OVAL_RESULT_UNKNOWN;
  		} else if (ores.false_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt > 0) {
  			result = OVAL_RESULT_NOT_EVALUATED;
  		}
  		break;
  	case OVAL_CHECK_NONE_EXIST:
  		dW("The 'none exist' CheckEnumeration value has been deprecated. "
  		   "Converted to check='none satisfy'.\n");
  		/* FALLTHROUGH */
  	case OVAL_CHECK_NONE_SATISFY:
  		if (ores.true_cnt > 0) {
  			result = OVAL_RESULT_FALSE;
  		} else if (ores.true_cnt == 0 && ores.error_cnt > 0) {
  			result = OVAL_RESULT_ERROR;
  		} else if (ores.true_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt > 0) {
  			result = OVAL_RESULT_UNKNOWN;
  		} else if (ores.true_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt > 0) {
  			result = OVAL_RESULT_NOT_EVALUATED;
  		} else if (ores.false_cnt > 0 &&
  			   ores.error_cnt == 0 &&
  			   ores.unknown_cnt == 0 && ores.noteval_cnt == 0 && ores.true_cnt == 0) {
  			result = OVAL_RESULT_TRUE;
  		}
  		break;
  	case OVAL_CHECK_ONLY_ONE:
  		if (ores.true_cnt == 1 && ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt == 0) {
  			result = OVAL_RESULT_TRUE;
  		} else if (ores.true_cnt > 1) {
  			result = OVAL_RESULT_FALSE;
  		} else if (ores.true_cnt < 2 && ores.error_cnt > 0) {
  			result = OVAL_RESULT_ERROR;
  		} else if (ores.true_cnt < 2 && ores.error_cnt == 0 && ores.unknown_cnt > 0) {
  			result = OVAL_RESULT_UNKNOWN;
  		} else if (ores.true_cnt < 2 && ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt > 0) {
  			result = OVAL_RESULT_NOT_EVALUATED;
  		} else if (ores.true_cnt != 1 && ores.false_cnt > 0) {
  			result = OVAL_RESULT_FALSE;
  		}
  		break;
  	default:
  		break;
  	}
  
  	return result;
  }
  
  // todo: already implemented elsewhere; consolidate
  oval_result_t probe_ent_result_byopr(SEXP_t * res_lst, oval_operator_t operator)
  {
  	oval_result_t result = OVAL_RESULT_UNKNOWN;
  	struct _oresults ores;
  
  	if (SEXP_list_length(res_lst) == 0)
  		return OVAL_RESULT_UNKNOWN;
  
  	if (results_parser(res_lst, &ores) != 0) {
  		return OVAL_RESULT_ERROR;
  	}
  
  	if (ores.notappl_cnt > 0 &&
  	    ores.noteval_cnt == 0 &&
  	    ores.false_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.true_cnt == 0)
  		return OVAL_RESULT_NOT_APPLICABLE;
  
  	switch (operator) {
  	case OVAL_OPERATOR_AND:
  		if (ores.true_cnt > 0 &&
  		    ores.false_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt == 0) {
  			result = OVAL_RESULT_TRUE;
  		} else if (ores.false_cnt > 0) {
  			result = OVAL_RESULT_FALSE;
  		} else if (ores.false_cnt == 0 && ores.error_cnt > 0) {
  			result = OVAL_RESULT_ERROR;
  		} else if (ores.false_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt > 0) {
  			result = OVAL_RESULT_UNKNOWN;
  		} else if (ores.false_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt > 0) {
  			result = OVAL_RESULT_NOT_EVALUATED;
  		}
  		break;
  	case OVAL_OPERATOR_ONE:
  		if (ores.true_cnt == 1 &&
  		    ores.false_cnt >= 0 &&
  		    ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt == 0 && ores.notappl_cnt >= 0) {
  			result = OVAL_RESULT_TRUE;
  		} else if (ores.true_cnt >= 2 &&
  			   ores.false_cnt >= 0 &&
  			   ores.error_cnt >= 0 &&
  			   ores.unknown_cnt >= 0 && ores.noteval_cnt >= 0 && ores.notappl_cnt >= 0) {
  			result = OVAL_RESULT_FALSE;
  		} else if (ores.true_cnt == 0 &&
  			   ores.false_cnt >= 0 &&
  			   ores.error_cnt == 0 &&
  			   ores.unknown_cnt == 0 && ores.noteval_cnt == 0 && ores.notappl_cnt >= 0) {
  			result = OVAL_RESULT_FALSE;
  		} else if (ores.true_cnt < 2 &&
  			   ores.false_cnt >= 0 &&
  			   ores.error_cnt > 0 &&
  			   ores.unknown_cnt >= 0 && ores.noteval_cnt >= 0 && ores.notappl_cnt >= 0) {
  			result = OVAL_RESULT_ERROR;
  		} else if (ores.true_cnt < 2 &&
  			   ores.false_cnt >= 0 &&
  			   ores.error_cnt == 0 &&
  			   ores.unknown_cnt >= 1 && ores.noteval_cnt >= 0 && ores.notappl_cnt >= 0) {
  			result = OVAL_RESULT_UNKNOWN;
  		} else if (ores.true_cnt < 2 &&
  			   ores.false_cnt >= 0 &&
  			   ores.error_cnt == 0 &&
  			   ores.unknown_cnt == 0 && ores.noteval_cnt > 0 && ores.notappl_cnt >= 0) {
  			result = OVAL_RESULT_NOT_EVALUATED;
  		}
  		break;
  	case OVAL_OPERATOR_OR:
  		if (ores.true_cnt > 0) {
  			result = OVAL_RESULT_TRUE;
  		} else if (ores.true_cnt == 0 &&
  			   ores.false_cnt > 0 &&
  			   ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt == 0) {
  			result = OVAL_RESULT_FALSE;
  		} else if (ores.true_cnt == 0 && ores.error_cnt > 0) {
  			result = OVAL_RESULT_ERROR;
  		} else if (ores.true_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt > 0) {
  			result = OVAL_RESULT_UNKNOWN;
  		} else if (ores.true_cnt == 0 && ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt > 0) {
  			result = OVAL_RESULT_NOT_EVALUATED;
  		}
  		break;
  	case OVAL_OPERATOR_XOR:
  		if ((ores.true_cnt % 2) == 1 && ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt == 0) {
  			result = OVAL_RESULT_TRUE;
  		} else if ((ores.true_cnt % 2) == 0 &&
  			   ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt == 0) {
  			result = OVAL_RESULT_FALSE;
  		} else if (ores.error_cnt > 0) {
  			result = OVAL_RESULT_ERROR;
  		} else if (ores.error_cnt == 0 && ores.unknown_cnt > 0) {
  			result = OVAL_RESULT_UNKNOWN;
  		} else if (ores.error_cnt == 0 && ores.unknown_cnt == 0 && ores.noteval_cnt > 0) {
  			result = OVAL_RESULT_NOT_EVALUATED;
  		}
  		break;
  	default:
  		break;
  	}
  
  	return result;
  }
  
  /// @}
  