All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Zaman <jason@perfinion.com>
To: selinux@tycho.nsa.gov
Subject: Re: [PATCH 7/7] sepolicy: update setup.py to remove C module
Date: Fri, 23 Sep 2016 11:14:27 +0800	[thread overview]
Message-ID: <20160923031427.GA3240@meriadoc> (raw)
In-Reply-To: <1474557453-14379-8-git-send-email-jason@perfinion.com>

I've sent a v2 of this patch, somehow I missed that I needed to
remove things from more Makefiles

v2 is only this one, the others in this series should be okay as-is.

-- Jason

On Thu, Sep 22, 2016 at 11:17:33PM +0800, Jason Zaman wrote:
> nt gentoo
> 
> Signed-off-by: Jason Zaman <jason@perfinion.com>
> ---
>  policycoreutils/sepolicy/common.h             |   69 --
>  policycoreutils/sepolicy/info.c               | 1381 -------------------------
>  policycoreutils/sepolicy/policy.c             |  116 ---
>  policycoreutils/sepolicy/policy.h             |    7 -
>  policycoreutils/sepolicy/search.c             | 1029 ------------------
>  policycoreutils/sepolicy/sepolicy/__init__.py |    2 -
>  policycoreutils/sepolicy/setup.py             |   24 +-
>  7 files changed, 17 insertions(+), 2611 deletions(-)
>  delete mode 100644 policycoreutils/sepolicy/common.h
>  delete mode 100644 policycoreutils/sepolicy/info.c
>  delete mode 100644 policycoreutils/sepolicy/policy.c
>  delete mode 100644 policycoreutils/sepolicy/policy.h
>  delete mode 100644 policycoreutils/sepolicy/search.c
> 
> diff --git a/policycoreutils/sepolicy/common.h b/policycoreutils/sepolicy/common.h
> deleted file mode 100644
> index e453def..0000000
> --- a/policycoreutils/sepolicy/common.h
> +++ /dev/null
> @@ -1,69 +0,0 @@
> -#include "Python.h"
> -
> -#ifdef UNUSED
> -#elif defined(__GNUC__)
> -# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
> -#elif defined(__LCLINT__)
> -# define UNUSED(x) /*@unused@*/ x
> -#else
> -# define UNUSED(x) x
> -#endif
> -
> -#define py_decref(x) { if (x) 	Py_DECREF(x); }
> -
> -#if PY_MAJOR_VERSION >= 3
> -#	define PyIntObject                  PyLongObject
> -#	define PyInt_Type                   PyLong_Type
> -#	define PyInt_Check(op)              PyLong_Check(op)
> -#	define PyInt_CheckExact(op)         PyLong_CheckExact(op)
> -#	define PyInt_FromString             PyLong_FromString
> -#	define PyInt_FromUnicode            PyLong_FromUnicode
> -#	define PyInt_FromLong               PyLong_FromLong
> -#	define PyInt_FromSize_t             PyLong_FromSize_t
> -#	define PyInt_FromSsize_t            PyLong_FromSsize_t
> -#	define PyInt_AsLong                 PyLong_AsLong
> -#	define PyInt_AS_LONG                PyLong_AS_LONG
> -#	define PyInt_AsSsize_t              PyLong_AsSsize_t
> -#	define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
> -#	define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
> -#	define PyString_FromString          PyUnicode_FromString
> -#	define PyString_AsString            PyUnicode_AsUTF8
> -#endif
> -
> -static int py_append_string(PyObject *list, const char* value)
> -{
> -	int rt;
> -	PyObject *obj = PyString_FromString(value);
> -	if (!obj) return -1;
> -	rt = PyList_Append(list, obj);
> -	Py_DECREF(obj);
> -	return rt;
> -}
> -
> -static int py_append_obj(PyObject *list, PyObject *obj)
> -{
> -	int rt;
> -	if (!obj) return -1;
> -	rt = PyList_Append(list, obj);
> -	return rt;
> -}
> -
> -static int py_insert_obj(PyObject *dict, const char *name, PyObject *obj)
> -{
> -	int rt;
> -	if (!obj) return -1;
> -	rt = PyDict_SetItemString(dict, name, obj);
> -	return rt;
> -}
> -
> -static int py_insert_string(PyObject *dict, const char *name, const char* value)
> -{
> -	int rt;
> -	PyObject *obj = PyString_FromString(value);
> -	if (!obj) return -1;
> -	rt = PyDict_SetItemString(dict, name, obj);
> -	Py_DECREF(obj);
> -	return rt;
> -}
> -
> -
> diff --git a/policycoreutils/sepolicy/info.c b/policycoreutils/sepolicy/info.c
> deleted file mode 100644
> index bbb6844..0000000
> --- a/policycoreutils/sepolicy/info.c
> +++ /dev/null
> @@ -1,1381 +0,0 @@
> -/**
> - *  @file
> - *  Command line tool to search TE rules.
> - *
> - *  @author Frank Mayer  mayerf@tresys.com
> - *  @author Jeremy A. Mowery jmowery@tresys.com
> - *  @author Paul Rosenfeld  prosenfeld@tresys.com
> - *  @author Thomas Liu  <tliu@redhat.com>
> - *  @author Dan Walsh  <dwalsh@redhat.com>
> - *
> - *  Copyright (C) 2003-2008 Tresys Technology, LLC
> - *
> - *  This program is free software; you can redistribute it and/or modify
> - *  it under the terms of the GNU General Public License as published by
> - *  the Free Software Foundation; either version 2 of the License, or
> - *  (at your option) any later version.
> - *
> - *  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> - */
> -
> -/**
> - * This is a modified version of seinfo to be used as part of a library for
> - * Python bindings.
> - */
> -
> -#include "common.h"
> -#include "policy.h"
> -
> -/* libapol */
> -#include <apol/policy-query.h>
> -#include <apol/render.h>
> -#include <apol/util.h>
> -#include <apol/vector.h>
> -
> -/* libqpol */
> -#include <qpol/policy.h>
> -#include <qpol/util.h>
> -
> -/* other */
> -#include <errno.h>
> -#include <stdlib.h>
> -#include <stdio.h>
> -#include <string.h>
> -#include <assert.h>
> -
> -#define COPYRIGHT_INFO "Copyright (C) 2003-2007 Tresys Technology, LLC"
> -
> -enum input
> -{
> -	TYPE, ATTRIBUTE, ROLE, USER, PORT, BOOLEAN, CLASS, SENS, CATS
> -};
> -
> -static int py_insert_long(PyObject *dict, const char *name, int value)
> -{
> -	int rt;
> -	PyObject *obj = PyLong_FromLong(value);
> -	if (!obj) return -1;
> -	rt = PyDict_SetItemString(dict, name, obj);
> -	Py_DECREF(obj);
> -	return rt;
> -}
> -
> -static int py_insert_bool(PyObject *dict, const char *name, int value)
> -{
> -	int rt;
> -	PyObject *obj = PyBool_FromLong(value);
> -	if (!obj) return -1;
> -	rt = PyDict_SetItemString(dict, name, obj);
> -	Py_DECREF(obj);
> -	return rt;
> -}
> -
> -/**
> - * Get a policy's MLS sensitivities.
> - * If this function is given a name, it will attempt to
> - * get statistics about a particular sensitivity; otherwise
> - * the function gets statistics about all of the policy's
> - * sensitivities.
> - *
> - * @param name Reference to a sensitivity's name; if NULL,
> - * all sensitivities will be considered
> - * @param policydb Reference to a policy
> - *
> - * @return 0 on success, < 0 on error.
> - */
> -static PyObject* get_sens(const char *name, const apol_policy_t * policydb)
> -{
> -	PyObject *dict = NULL;
> -	int error = 0;
> -	int rt = 0;
> -	size_t i;
> -	char *tmp = NULL;
> -	const char *lvl_name = NULL;
> -	apol_level_query_t *query = NULL;
> -	apol_vector_t *v = NULL;
> -	const qpol_level_t *level = NULL;
> -	apol_mls_level_t *ap_mls_lvl = NULL;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -
> -	query = apol_level_query_create();
> -	if (!query)
> -		goto cleanup;
> -	if (apol_level_query_set_sens(policydb, query, name))
> -		goto cleanup;
> -	if (apol_level_get_by_query(policydb, query, &v))
> -		goto cleanup;
> -
> -	dict = PyDict_New();
> -	if (!dict) goto err;
> -	for (i = 0; i < apol_vector_get_size(v); i++) {
> -		level = apol_vector_get_element(v, i);
> -		if (qpol_level_get_name(q, level, &lvl_name))
> -			goto err;
> -		ap_mls_lvl = (apol_mls_level_t *) apol_mls_level_create_from_qpol_level_datum(policydb, level);
> -		tmp = apol_mls_level_render(policydb, ap_mls_lvl);
> -		apol_mls_level_destroy(&ap_mls_lvl);
> -		if (!tmp)
> -			goto cleanup;
> -		if (py_insert_string(dict, lvl_name, tmp))
> -			goto err;
> -		free(tmp); tmp = NULL;
> -		if (rt) goto err;
> -	}
> -
> -	if (name && !apol_vector_get_size(v)) {
> -		goto cleanup;
> -	}
> -
> -	goto cleanup;
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(error));
> -	py_decref(dict); dict = NULL;
> -cleanup:
> -	free(tmp);
> -	apol_level_query_destroy(&query);
> -	apol_vector_destroy(&v);
> -	errno = error;
> -	return dict;
> -}
> -
> -/**
> - * Compare two qpol_cat_datum_t objects.
> - * This function is meant to be passed to apol_vector_compare
> - * as the callback for performing comparisons.
> - *
> - * @param datum1 Reference to a qpol_type_datum_t object
> - * @param datum2 Reference to a qpol_type_datum_t object
> - * @param data Reference to a policy
> - * @return Greater than 0 if the first argument is less than the second argument,
> - * less than 0 if the first argument is greater than the second argument,
> - * 0 if the arguments are equal
> - */
> -static int qpol_cat_datum_compare(const void *datum1, const void *datum2, void *data)
> -{
> -	const qpol_cat_t *cat_datum1 = NULL, *cat_datum2 = NULL;
> -	apol_policy_t *policydb = NULL;
> -	qpol_policy_t *q;
> -	uint32_t val1, val2;
> -
> -	policydb = (apol_policy_t *) data;
> -	q = apol_policy_get_qpol(policydb);
> -	assert(policydb);
> -
> -	if (!datum1 || !datum2)
> -		goto exit_err;
> -	cat_datum1 = datum1;
> -	cat_datum2 = datum2;
> -
> -	if (qpol_cat_get_value(q, cat_datum1, &val1))
> -		goto exit_err;
> -	if (qpol_cat_get_value(q, cat_datum2, &val2))
> -		goto exit_err;
> -
> -	return (val1 > val2) ? 1 : ((val1 == val2) ? 0 : -1);
> -
> -      exit_err:
> -	assert(0);
> -	return 0;
> -}
> -
> -/**
> - * Compare two qpol_level_datum_t objects.
> - * This function is meant to be passed to apol_vector_compare
> - * as the callback for performing comparisons.
> - *
> - * @param datum1 Reference to a qpol_level_datum_t object
> - * @param datum2 Reference to a qpol_level_datum_t object
> - * @param data Reference to a policy
> - * @return Greater than 0 if the first argument is less than the second argument,
> - * less than 0 if the first argument is greater than the second argument,
> - * 0 if the arguments are equal
> - */
> -static int qpol_level_datum_compare(const void *datum1, const void *datum2, void *data)
> -{
> -	const qpol_level_t *lvl_datum1 = NULL, *lvl_datum2 = NULL;
> -	apol_policy_t *policydb = NULL;
> -	qpol_policy_t *q;
> -	uint32_t val1, val2;
> -
> -	policydb = (apol_policy_t *) data;
> -	assert(policydb);
> -	q = apol_policy_get_qpol(policydb);
> -
> -	if (!datum1 || !datum2)
> -		goto exit_err;
> -	lvl_datum1 = datum1;
> -	lvl_datum2 = datum2;
> -
> -	if (qpol_level_get_value(q, lvl_datum1, &val1))
> -		goto exit_err;
> -	if (qpol_level_get_value(q, lvl_datum2, &val2))
> -		goto exit_err;
> -
> -	return (val1 > val2) ? 1 : ((val1 == val2) ? 0 : -1);
> -
> -      exit_err:
> -	assert(0);
> -	return 0;
> -}
> -
> -/**
> - * Gets a textual representation of a MLS category and
> - * all of that category's sensitivies.
> - *
> - * @param type_datum Reference to sepol type_datum
> - * @param policydb Reference to a policy
> - */
> -static PyObject* get_cat_sens(const qpol_cat_t * cat_datum, const apol_policy_t * policydb)
> -{
> -	const char *cat_name, *lvl_name;
> -	apol_level_query_t *query = NULL;
> -	apol_vector_t *v = NULL;
> -	const qpol_level_t *lvl_datum = NULL;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	size_t i, n_sens = 0;
> -	int error = 0;
> -	PyObject *list = NULL;
> -	PyObject *dict = PyDict_New();
> -	if (!dict) goto err;
> -	if (!cat_datum || !policydb)
> -		goto err;
> -
> -	/* get category name for apol query */
> -	if (qpol_cat_get_name(q, cat_datum, &cat_name))
> -		goto cleanup;
> -
> -	query = apol_level_query_create();
> -	if (!query)
> -		goto err;
> -	if (apol_level_query_set_cat(policydb, query, cat_name))
> -		goto err;
> -	if (apol_level_get_by_query(policydb, query, &v))
> -		goto err;
> -	apol_vector_sort(v, &qpol_level_datum_compare, (void *)policydb);
> -	dict = PyDict_New();
> -	if (!dict) goto err;
> -	if (py_insert_string(dict, "name", cat_name))
> -		goto err;
> -	n_sens = apol_vector_get_size(v);
> -	list = PyList_New(0);
> -	if (!list) goto err;
> -	for (i = 0; i < n_sens; i++) {
> -		lvl_datum = (qpol_level_t *) apol_vector_get_element(v, i);
> -		if (!lvl_datum)
> -			goto err;
> -		if (qpol_level_get_name(q, lvl_datum, &lvl_name))
> -			goto err;
> -		if (py_append_string(list, lvl_name))
> -			goto err;
> -	}
> -	if (py_insert_obj(dict, "level", list))
> -		goto err;
> -	Py_DECREF(list);
> -
> -	goto cleanup;
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list = NULL;
> -	py_decref(dict); dict = NULL;
> -cleanup:
> -	apol_level_query_destroy(&query);
> -	apol_vector_destroy(&v);
> -	errno = error;
> -	return dict;
> -}
> -
> -/**
> - * Prints statistics regarding a policy's MLS categories.
> - * If this function is given a name, it will attempt to
> - * get statistics about a particular category; otherwise
> - * the function gets statistics about all of the policy's
> - * categories.
> - *
> - * @param name Reference to a MLS category's name; if NULL,
> - * all categories will be considered
> - * @param policydb Reference to a policy
> - *
> - * @return 0 on success, < 0 on error.
> - */
> -static PyObject* get_cats(const char *name, const apol_policy_t * policydb)
> -{
> -	PyObject *obj = NULL;
> -	apol_cat_query_t *query = NULL;
> -	apol_vector_t *v = NULL;
> -	const qpol_cat_t *cat_datum = NULL;
> -	size_t i, n_cats;
> -	int error = 0;
> -	int rt;
> -	PyObject *list = PyList_New(0);
> -	if (!list) goto err;
> -
> -	query = apol_cat_query_create();
> -	if (!query)
> -		goto err;
> -	if (apol_cat_query_set_cat(policydb, query, name))
> -		goto err;
> -	if (apol_cat_get_by_query(policydb, query, &v))
> -		goto err;
> -	n_cats = apol_vector_get_size(v);
> -	apol_vector_sort(v, &qpol_cat_datum_compare, (void *)policydb);
> -
> -	for (i = 0; i < n_cats; i++) {
> -		cat_datum = apol_vector_get_element(v, i);
> -		if (!cat_datum)
> -			goto err;
> -		obj = get_cat_sens(cat_datum, policydb);
> -		if (!obj)
> -			goto err;
> -		rt = py_append_obj(list, obj);
> -		Py_DECREF(obj);
> -		if (rt) goto err;
> -	}
> -
> -	if (name && !n_cats) {
> -		goto err;
> -	}
> -
> -	goto cleanup;
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list = NULL;
> -cleanup:
> -	apol_cat_query_destroy(&query);
> -	apol_vector_destroy(&v);
> -	errno = error;
> -	return list;
> -}
> -
> -/**
> - * Get the alias of a type.
> - *
> - * @param type_datum Reference to sepol type_datum
> - * @param policydb Reference to a policy
> - * attributes
> - */
> -static PyObject* get_type_aliases(const qpol_type_t * type_datum, const apol_policy_t * policydb)
> -{
> -	qpol_iterator_t *iter = NULL;
> -	size_t alias_size;
> -	unsigned char isattr, isalias;
> -	const char *type_name = NULL;
> -	const char *alias_name;
> -	int error = 0;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	PyObject *list = PyList_New(0);
> -	if (!list) goto err;
> -
> -	if (qpol_type_get_name(q, type_datum, &type_name))
> -		goto cleanup;
> -	if (qpol_type_get_isattr(q, type_datum, &isattr))
> -		goto cleanup;
> -	if (qpol_type_get_isalias(q, type_datum, &isalias))
> -		goto cleanup;
> -
> -	if (qpol_type_get_alias_iter(q, type_datum, &iter))
> -		goto cleanup;
> -	if (qpol_iterator_get_size(iter, &alias_size))
> -		goto cleanup;
> -	if (alias_size >  0) {
> -		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -			if (qpol_iterator_get_item(iter, (void **)&alias_name))
> -				goto err;
> -			if (py_append_string(list, alias_name))
> -				goto err;
> -		}
> -	}
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list = NULL;
> -
> -cleanup:
> -	qpol_iterator_destroy(&iter);
> -	errno = error;
> -	return list;
> -}
> -
> -/**
> - * Gets a textual representation of an attribute, and 
> - * all of that attribute's types.
> - *
> - * @param type_datum Reference to sepol type_datum
> - * @param policydb Reference to a policy
> - */
> -static PyObject* get_attr(const qpol_type_t * type_datum, const apol_policy_t * policydb)
> -{
> -	PyObject *list = NULL;
> -	const qpol_type_t *attr_datum = NULL;
> -	qpol_iterator_t *iter = NULL;
> -	const char *attr_name = NULL, *type_name = NULL;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	unsigned char isattr;
> -	int error = 0;
> -	int rt = 0;
> -	PyObject *dict = PyDict_New(); 
> -	if (!dict) goto err;
> -
> -	if (qpol_type_get_name(q, type_datum, &attr_name))
> -		goto err;
> -
> -	if (py_insert_string(dict, "name", attr_name))
> -		goto err;
> -
> -	/* get an iterator over all types this attribute has */
> -	if (qpol_type_get_isattr(q, type_datum, &isattr))
> -		goto err;
> -
> -	if (isattr) {	       /* sanity check */
> -		if (qpol_type_get_type_iter(q, type_datum, &iter))
> -			goto err;
> -		list = PyList_New(0);
> -		if (!list) goto err;
> -		
> -		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -			if (qpol_iterator_get_item(iter, (void **)&attr_datum))
> -				goto err;
> -			if (qpol_type_get_name(q, attr_datum, &type_name))
> -				goto err;
> -			if (py_append_string(list, type_name))
> -				goto err;
> -		}
> -		qpol_iterator_destroy(&iter);
> -		rt = PyDict_SetItemString(dict, "types", list);
> -		Py_DECREF(list); list = NULL;
> -		if (rt) goto err;
> -	} else		       /* this should never happen */
> -		goto err;
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(dict); dict = NULL;
> -	py_decref(list);
> -
> -cleanup:
> -	qpol_iterator_destroy(&iter);
> -	errno =	error;
> -	return dict;
> -}
> -
> -/**
> - * Gets statistics regarding a policy's attributes.
> - * If this function is given a name, it will attempt to
> - * get statistics about a particular attribute; otherwise
> - * the function gets statistics about all of the policy's
> - * attributes.
> - *
> - * @param name Reference to an attribute's name; if NULL,
> - * all object classes will be considered
> - * @param policydb Reference to a policy
> - *
> - * @return 0 on success, < 0 on error.
> - */
> -static PyObject* get_attribs(const char *name, const apol_policy_t * policydb)
> -{
> -	PyObject *obj;
> -	apol_attr_query_t *attr_query = NULL;
> -	apol_vector_t *v = NULL;
> -	const qpol_type_t *type_datum = NULL;
> -	size_t n_attrs, i;
> -	int error = 0;
> -	int rt = 0;
> -	PyObject *list = PyList_New(0);
> -	if (!list) goto err;
> -
> -	/* we are only getting information about 1 attribute */
> -	if (name != NULL) {
> -		attr_query = apol_attr_query_create();
> -		if (!attr_query)
> -			goto err;
> -		if (apol_attr_query_set_attr(policydb, attr_query, name))
> -			goto err;
> -		if (apol_attr_get_by_query(policydb, attr_query, &v))
> -			goto err;
> -		apol_attr_query_destroy(&attr_query);
> -		if (apol_vector_get_size(v) == 0) {
> -			apol_vector_destroy(&v);
> -			errno = EINVAL;
> -			goto err;
> -		}
> -
> -		type_datum = apol_vector_get_element(v, (size_t) 0);
> -		obj = get_attr(type_datum, policydb);
> -		rt = py_append_obj(list, obj);
> -		Py_DECREF(obj);
> -		if (rt) goto err;
> -	} else {
> -		attr_query = apol_attr_query_create();
> -		if (!attr_query)
> -			goto err;
> -		if (apol_attr_get_by_query(policydb, attr_query, &v))
> -			goto err;
> -		apol_attr_query_destroy(&attr_query);
> -		n_attrs = apol_vector_get_size(v);
> -
> -		for (i = 0; i < n_attrs; i++) {
> -			/* get qpol_type_t* item from vector */
> -			type_datum = (qpol_type_t *) apol_vector_get_element(v, (size_t) i);
> -			if (!type_datum)
> -				goto err;
> -			obj = get_attr(type_datum, policydb);
> -			rt = py_append_obj(list, obj);
> -			Py_DECREF(obj);
> -			if (rt) goto err;
> -		}
> -	}
> -	apol_vector_destroy(&v);
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list = NULL;
> -
> -cleanup:
> -	apol_attr_query_destroy(&attr_query);
> -	apol_vector_destroy(&v);
> -	errno = error;
> -	return list;
> -}
> -
> -/**
> - * Get a textual representation of a type, and
> - * all of that type's attributes.
> - *
> - * @param type_datum Reference to sepol type_datum
> - * @param policydb Reference to a policy
> - */
> -static PyObject* get_type_attrs(const qpol_type_t * type_datum, const apol_policy_t * policydb)
> -{
> -	qpol_iterator_t *iter = NULL;
> -	const char *attr_name = NULL;
> -	const qpol_type_t *attr_datum = NULL;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	int error = 0;
> -	PyObject *list = PyList_New(0);
> -	if (!list) goto err;
> -
> -	if (qpol_type_get_attr_iter(q, type_datum, &iter))
> -		goto err;
> -
> -	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -		if (qpol_iterator_get_item(iter, (void **)&attr_datum))
> -			goto err;
> -		if (qpol_type_get_name(q, attr_datum, &attr_name))
> -			goto err;
> -		if (py_append_string(list, attr_name))
> -			goto err;
> -	}
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list = NULL;
> -
> -cleanup:
> -	qpol_iterator_destroy(&iter);
> -	errno = error;
> -	return list;
> -}
> -
> -static PyObject* get_type(const qpol_type_t * type_datum, const apol_policy_t * policydb) {
> -
> -	PyObject *obj;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	const char *type_name = NULL;
> -	int error = 0;
> -	int rt;
> -	unsigned char isalias, ispermissive, isattr;
> -	PyObject *dict = PyDict_New(); 
> -	if (!dict) goto err;
> -
> -	if (qpol_type_get_name(q, type_datum, &type_name))
> -		goto err;
> -	if (qpol_type_get_isalias(q, type_datum, &isalias))
> -		goto err;
> -	if (qpol_type_get_isattr(q, type_datum, &isattr))
> -		goto err;
> -	if (qpol_type_get_ispermissive(q, type_datum, &ispermissive))
> -		goto err;
> -
> -	if (py_insert_string(dict, "name", type_name))
> -		goto err;
> -
> -	if (py_insert_bool(dict, "permissive", ispermissive))
> -		goto err;
> -
> -	if (!isattr && !isalias) {
> -		obj = get_type_attrs(type_datum, policydb);
> -		rt = py_insert_obj(dict, "attributes", obj);
> -		Py_DECREF(obj);
> -		if (rt) goto err;
> -	}
> -
> -	obj = get_type_aliases(type_datum, policydb);
> -	rt = py_insert_obj(dict, "aliases", obj);
> -	Py_DECREF(obj);
> -	if (rt) goto err;
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(error));
> -	py_decref(dict); dict = NULL;
> -
> -cleanup:
> -	errno = error; 
> -	return dict;
> -}
> -
> -/**
> - * Gets statistics regarding a policy's booleans.
> - * If this function is given a name, it will attempt to
> - * get statistics about a particular boolean; otherwise
> - * the function gets statistics about all of the policy's booleans.
> - *
> - * @param name Reference to a boolean's name; if NULL,
> - * all booleans will be considered
> - * @param policydb Reference to a policy
> - *
> - * @return new reference, or NULL (setting an exception)
> - */
> -static PyObject* get_booleans(const char *name, const apol_policy_t * policydb)
> -{
> -	PyObject *dict = NULL;
> -	int error = 0;
> -	int rt = 0;
> -	const char *bool_name = NULL;
> -	int state;
> -	qpol_bool_t *bool_datum = NULL;
> -	qpol_iterator_t *iter = NULL;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	size_t n_bools = 0;
> -	PyObject *list = PyList_New(0);
> -	if (!list) goto err;
> -
> -	if (name != NULL) {
> -		if (qpol_policy_get_bool_by_name(q, name, &bool_datum))
> -			goto err;
> -		if (qpol_bool_get_state(q, bool_datum, &state))
> -			goto err;
> -
> -		dict = PyDict_New(); 
> -		if (!dict) goto err;
> -		if (py_insert_string(dict, "name", name))
> -			goto err;
> -		if (py_insert_bool(dict, "name", state))
> -			goto err;
> -		rt = py_append_obj(list, dict);
> -		Py_DECREF(dict); dict = NULL;
> -		if (rt) goto err;
> -	} else {
> -		if (qpol_policy_get_bool_iter(q, &iter))
> -			goto err;
> -		if (qpol_iterator_get_size(iter, &n_bools))
> -			goto err;
> -		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -			if (qpol_iterator_get_item(iter, (void **)&bool_datum))
> -				goto err;
> -			if (qpol_bool_get_name(q, bool_datum, &bool_name))
> -				goto err;
> -			if (qpol_bool_get_state(q, bool_datum, &state))
> -				goto err;
> -
> -			dict = PyDict_New(); 
> -			if (!dict) goto err;
> -			if (py_insert_string(dict, "name", bool_name))
> -				goto err;
> -			if (py_insert_bool(dict, "state", state))
> -				goto err;
> -			rt = py_append_obj(list, dict);
> -			Py_DECREF(dict); dict = NULL;
> -			if (rt) goto err;
> -		}
> -		qpol_iterator_destroy(&iter);
> -	}
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(error));
> -	py_decref(list); list = NULL;
> -	py_decref(dict); dict = NULL;
> -
> -cleanup:
> -	qpol_iterator_destroy(&iter);
> -	errno = error; 
> -	return list;
> -}
> -
> -/**
> - * Gets a textual representation of a user, and
> - * all of that user's roles.
> - *
> - * @param type_datum Reference to sepol type_datum
> - * @param policydb Reference to a policy
> - * roles
> - */
> -static PyObject* get_user(const qpol_user_t * user_datum, const apol_policy_t * policydb)
> -{
> -	int error = 0;
> -	int rt;
> -	const qpol_role_t *role_datum = NULL;
> -	qpol_iterator_t *iter = NULL;
> -	const qpol_mls_range_t *range = NULL;
> -	const qpol_mls_level_t *dflt_level = NULL;
> -	apol_mls_level_t *ap_lvl = NULL;
> -	apol_mls_range_t *ap_range = NULL;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	char *tmp = NULL;
> -	const char *user_name, *role_name;
> -	PyObject *dict = NULL;
> -	PyObject *list = PyList_New(0);
> -	if (!list) goto err;
> -
> -	if (qpol_user_get_name(q, user_datum, &user_name))
> -		goto err;
> -
> -	dict = PyDict_New(); 
> -	if (!dict) goto err;
> -
> -	if (py_insert_string(dict, "name", user_name))
> -		goto err;
> -
> -	if (qpol_policy_has_capability(q, QPOL_CAP_MLS)) {
> -		if (qpol_user_get_dfltlevel(q, user_datum, &dflt_level))
> -			goto err;
> -		ap_lvl = apol_mls_level_create_from_qpol_mls_level(policydb, dflt_level);
> -		tmp = apol_mls_level_render(policydb, ap_lvl);
> -		if (!tmp) goto err;
> -		if (py_insert_string(dict, "level", tmp))
> -		    goto err;
> -		free(tmp); tmp = NULL;
> -
> -		if (qpol_user_get_range(q, user_datum, &range))
> -			goto err;
> -		ap_range = apol_mls_range_create_from_qpol_mls_range(policydb, range);
> -		tmp = apol_mls_range_render(policydb, ap_range);
> -		if (!tmp) goto err;
> -		if (py_insert_string(dict, "range", tmp))
> -		    goto err;
> -		free(tmp); tmp=NULL;
> -	}
> -	
> -	if (qpol_user_get_role_iter(q, user_datum, &iter))
> -		goto err;
> -	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -		if (qpol_iterator_get_item(iter, (void **)&role_datum))
> -			goto err;
> -		if (qpol_role_get_name(q, role_datum, &role_name))
> -			goto err;
> -		if (py_append_string(list, role_name))
> -			goto err;
> -	}
> -
> -	rt = py_insert_obj(dict, "roles", list);
> -	Py_DECREF(list); list=NULL;
> -	if (rt) goto err;
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list=NULL;
> -	py_decref(dict); dict=NULL;
> -
> -cleanup:
> -	free(tmp);
> -	qpol_iterator_destroy(&iter);
> -	apol_mls_level_destroy(&ap_lvl);
> -	apol_mls_range_destroy(&ap_range);
> -	errno = error;
> -	return dict;
> -}
> -
> -/**
> - * Prints a textual representation of an object class and possibly
> - * all of that object class' permissions.
> - *
> - * @param type_datum Reference to sepol type_datum
> - * @param policydb Reference to a policy
> - */
> -static PyObject* get_class(const qpol_class_t * class_datum, const apol_policy_t * policydb)
> -{
> -	const char *class_name = NULL, *perm_name = NULL;
> -	qpol_iterator_t *iter = NULL;
> -	const qpol_common_t *common_datum = NULL;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	int error = 0;
> -	int rt;
> -	PyObject *list = NULL;
> -	PyObject *dict = PyDict_New();
> -	if (!dict) goto err;
> -
> -	if (!class_datum)
> -		goto err;
> -
> -	if (qpol_class_get_name(q, class_datum, &class_name))
> -		goto err;
> -
> -	if (py_insert_string(dict, "name", class_name))
> -		goto err;
> -	/* get commons for this class */
> -	if (qpol_class_get_common(q, class_datum, &common_datum))
> -		goto err;
> -
> -	list = PyList_New(0);
> -	if (!list) goto err;
> -
> -	if (common_datum) {
> -		if (qpol_common_get_perm_iter(q, common_datum, &iter))
> -			goto err;
> -		/* print perms for the common */
> -		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -			if (qpol_iterator_get_item(iter, (void **)&perm_name))
> -				goto err;
> -			if (py_append_string(list, perm_name))
> -				goto err;
> -		}
> -	}
> -	/* print unique perms for this class */
> -	if (qpol_class_get_perm_iter(q, class_datum, &iter))
> -		goto err;
> -	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -		if (qpol_iterator_get_item(iter, (void **)&perm_name))
> -			goto err;
> -		if (py_append_string(list, perm_name))
> -			goto err;
> -	}
> -	rt = py_insert_obj(dict, "permlist", list);
> -	Py_DECREF(list); list = NULL;
> -	if (rt) goto err;
> -	qpol_iterator_destroy(&iter);
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list=NULL;
> -	py_decref(dict); dict=NULL;
> -
> -cleanup:
> -	errno = error;
> -	qpol_iterator_destroy(&iter);
> -	return dict;
> -}
> -
> -/**
> - * Get statistics regarding a policy's object classes.
> - * If this function is given a name, it will attempt to
> - * print statistics about a particular object class; otherwise
> - * the function prints statistics about all of the policy's object
> - * classes.
> - *
> - * @param name Reference to an object class' name; if NULL,
> - * all object classes will be considered
> - * @param policydb Reference to a policy
> - *
> - * @return 0 on success, < 0 on error.
> - */
> -static PyObject*  get_classes(const char *name, const apol_policy_t * policydb)
> -{
> -	qpol_iterator_t *iter = NULL;
> -	size_t n_classes = 0;
> -	const qpol_class_t *class_datum = NULL;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	int error = 0;
> -	int rt;
> -	PyObject *obj;
> -	PyObject *list = PyList_New(0);
> -	if (!list) goto err;
> -
> -	if (name != NULL) {
> -		if (qpol_policy_get_class_by_name(q, name, &class_datum))
> -			goto err;
> -		obj = get_class(class_datum, policydb);
> -		rt = py_append_obj(list, obj);
> -		Py_DECREF(obj);
> -		if (rt) goto err;
> -	} else {
> -		if (qpol_policy_get_class_iter(q, &iter))
> -			goto err;
> -		if (qpol_iterator_get_size(iter, &n_classes))
> -			goto err;
> -
> -		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -			if (qpol_iterator_get_item(iter, (void **)&class_datum))
> -				goto err;
> -			obj = get_class(class_datum, policydb);
> -			rt = py_append_obj(list, obj);
> -			Py_DECREF(obj);
> -			if (rt) goto err;
> -		}
> -		qpol_iterator_destroy(&iter);
> -	}
> -	goto cleanup;
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list = NULL;
> -
> -cleanup:
> -	qpol_iterator_destroy(&iter);
> -	errno = error;
> -	return list;
> -}
> -
> -/**
> - * Gets statistics regarding a policy's users.
> - * If this function is given a name, it will attempt to
> - * get statistics about a particular user; otherwise
> - * the function gets statistics about all of the policy's
> - * users.
> - *
> - * @param name Reference to a user's name; if NULL,
> - * all users will be considered
> - * @param policydb Reference to a policy
> - *
> - * @return 0 on success, < 0 on error.
> - */
> -static PyObject*  get_users(const char *name, const apol_policy_t * policydb)
> -{
> -	qpol_iterator_t *iter = NULL;
> -	const qpol_user_t *user_datum = NULL;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	int error = 0;
> -	int rt;
> -	PyObject *obj;
> -	PyObject *list = PyList_New(0);
> -	if (!list) goto err;
> -
> -	if (name != NULL) {
> -		if (qpol_policy_get_user_by_name(q, name, &user_datum)) {
> -			errno = EINVAL;
> -			goto err;
> -		}
> -		obj = get_user(user_datum, policydb);
> -		rt = py_append_obj(list, obj);
> -		Py_DECREF(obj);
> -		if (rt) goto err;
> -	} else {
> -		if (qpol_policy_get_user_iter(q, &iter))
> -			goto err;
> -
> -		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -			if (qpol_iterator_get_item(iter, (void **)&user_datum))
> -				goto err;
> -			obj = get_user(user_datum, policydb);
> -			rt = py_append_obj(list, obj);
> -			Py_DECREF(obj);
> -			if (rt) goto err;
> -		}
> -		qpol_iterator_destroy(&iter);
> -	}
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list = NULL;
> -
> -cleanup:
> -	qpol_iterator_destroy(&iter);
> -	errno = error;
> -	return list;
> -}
> -
> -/**
> - * get a textual representation of a role, and 
> - * all of that role's types.
> - *
> - * @param type_datum Reference to sepol type_datum
> - * @param policydb Reference to a policy
> - * types
> - */
> -static PyObject* get_role(const qpol_role_t * role_datum, const apol_policy_t * policydb)
> -{
> -	const char *role_name = NULL, *type_name = NULL;
> -	const qpol_role_t *dom_datum = NULL;
> -	const qpol_type_t *type_datum = NULL;
> -	qpol_iterator_t *iter = NULL;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	size_t n_dom = 0, n_types = 0;
> -	int error = 0;
> -	int rt;
> -	PyObject *list = NULL;
> -	PyObject *dict = PyDict_New();
> -	if (!dict) goto err;
> -
> -	if (qpol_role_get_name(q, role_datum, &role_name))
> -		goto err;
> -	if (py_insert_string(dict, "name", role_name))
> -		goto err;
> -
> -	if (qpol_role_get_dominate_iter(q, role_datum, &iter))
> -		goto err;
> -	if (qpol_iterator_get_size(iter, &n_dom))
> -		goto err;
> -	if ((int)n_dom > 0) {
> -		list = PyList_New(0);
> -		if (!list) goto err;
> -		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -			if (qpol_iterator_get_item(iter, (void **)&dom_datum))
> -				goto err;
> -			if (qpol_role_get_name(q, dom_datum, &role_name))
> -				goto err;
> -			if (py_append_string(list, role_name))
> -				goto err;
> -		}
> -		rt = py_insert_obj(dict, "roles", list);
> -		Py_DECREF(list); list = NULL;
> -		if (rt) goto err;
> -	}
> -	qpol_iterator_destroy(&iter);
> -	
> -	if (qpol_role_get_type_iter(q, role_datum, &iter))
> -		goto err;
> -	if (qpol_iterator_get_size(iter, &n_types))
> -		goto err;
> -	if ((int)n_types > 0) {
> -		list = PyList_New(0);
> -		if (!list) goto err;
> -		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -			if (qpol_iterator_get_item(iter, (void **)&type_datum))
> -				goto err;
> -			if (qpol_type_get_name(q, type_datum, &type_name))
> -				goto err;
> -			if (py_append_string(list, type_name))
> -				goto err;
> -		}
> -		rt = py_insert_obj(dict, "types", list);
> -		Py_DECREF(list); list = NULL;
> -		if (rt) goto err;
> -	}
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list = NULL;
> -	py_decref(dict); dict = NULL;
> -
> -cleanup:
> -	qpol_iterator_destroy(&iter);
> -	errno =	error;
> -	return dict;
> -}
> -
> -/**
> - * Get statistics regarding a policy's ports.
> - * If this function is given a name, it will attempt to
> - * get statistics about a particular port; otherwise
> - * the function get statistics about all of the policy's ports.
> - *
> - * @param name Reference to an port's name; if NULL,
> - * all ports will be considered
> - * @param policydb Reference to a policy
> - *
> - * @return 0 on success, < 0 on error.
> - */
> -static PyObject*  get_ports(const char *num, const apol_policy_t * policydb)
> -{
> -	const qpol_portcon_t *portcon = NULL;
> -	qpol_iterator_t *iter = NULL;
> -	uint16_t low_port, high_port;
> -	uint8_t ocon_proto;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	const qpol_context_t *ctxt = NULL;
> -	const char *proto_str = NULL;
> -	const char *type = NULL;
> -	const apol_mls_range_t *range = NULL;
> -	char *range_str = NULL;
> -	apol_context_t *c = NULL;
> -	int error = 0;
> -	int rt = 0;
> -	PyObject *dict = NULL;
> -	PyObject *list = PyList_New(0);
> -	if (!list) goto err;
> -
> -	if (qpol_policy_get_portcon_iter(q, &iter))
> -		goto err;
> -
> -	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -		if (qpol_iterator_get_item(iter, (void **)&portcon))
> -			goto err;
> -		if (qpol_portcon_get_low_port(q, portcon, &low_port))
> -			goto err;
> -		if (qpol_portcon_get_high_port(q, portcon, &high_port))
> -			goto err;
> -		if (qpol_portcon_get_protocol(q, portcon, &ocon_proto))
> -			goto err;
> -		if (num) {
> -			if (atoi(num) < low_port || atoi(num) > high_port)
> -				continue;
> -		}
> -
> -		if ((ocon_proto != IPPROTO_TCP) &&
> -		    (ocon_proto != IPPROTO_UDP)) 
> -			goto err;
> -
> -		if (qpol_portcon_get_context(q, portcon, &ctxt)) {
> -			PyErr_SetString(PyExc_RuntimeError, "Could not get for port context.");
> -			goto err;
> -		}
> -
> -		if ((proto_str = apol_protocol_to_str(ocon_proto)) == NULL) {
> -			PyErr_SetString(PyExc_RuntimeError, "Invalid protocol for port");
> -			goto err;
> -		}
> -
> -		if ((c = apol_context_create_from_qpol_context(policydb, ctxt)) == NULL) {
> -			goto err;
> -		}
> -		
> -		if((type = apol_context_get_type(c)) == NULL) {
> -			apol_context_destroy(&c);
> -			goto err;
> -		}
> -			
> -		dict = PyDict_New(); 
> -		if (!dict) goto err;
> -		if (py_insert_string(dict, "type", type))
> -			goto err;
> -
> -		if((range = apol_context_get_range(c)) != NULL) {
> -			range_str = apol_mls_range_render(policydb, range);
> -			if (range_str == NULL) {
> -				goto err;
> -			}
> -			if (py_insert_string(dict, "range", range_str))
> -				goto err;
> -		}
> -
> -		if (py_insert_string(dict, "protocol", proto_str))
> -			goto err;
> -
> -		if (py_insert_long(dict, "high", high_port))
> -			goto err;
> -
> -		if (py_insert_long(dict, "low", low_port))
> -			goto err;
> -
> -		rt = py_append_obj(list, dict);
> -		Py_DECREF(dict); dict = NULL;
> -		if (rt) goto err;
> -	}
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list = NULL;
> -	py_decref(dict); dict = NULL;
> -
> -cleanup:
> -	free(range_str);
> -	apol_context_destroy(&c);
> -	qpol_iterator_destroy(&iter);
> -	errno = error;
> -	return list;
> -}
> -
> -/**
> - * Get statistics regarding a policy's roles.
> - * If this function is given a name, it will attempt to
> - * get statistics about a particular role; otherwise
> - * the function get statistics about all of the policy's roles.
> - *
> - * @param name Reference to an role's name; if NULL,
> - * all roles will be considered
> - * @param policydb Reference to a policy
> - *
> - * @return 0 on success, < 0 on error.
> - */
> -static PyObject*  get_roles(const char *name, const apol_policy_t * policydb)
> -{
> -	const qpol_role_t *role_datum = NULL;
> -	qpol_iterator_t *iter = NULL;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	int error = 0;
> -	int rt;
> -	PyObject *obj;
> -	PyObject *list = PyList_New(0);
> -	if (!list) goto err;
> -
> -	if (name != NULL) {
> -		if (qpol_policy_get_role_by_name(q, name, &role_datum)) {
> -			errno = EINVAL;
> -			goto err;
> -		}
> -		obj = get_role(role_datum, policydb);
> -		rt = py_append_obj(list, obj);
> -		Py_DECREF(obj); 
> -		if (rt) goto err;
> -	} else {
> -		if (qpol_policy_get_role_iter(q, &iter))
> -			goto err;
> -
> -		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -			if (qpol_iterator_get_item(iter, (void **)&role_datum))
> -				goto err;
> -			obj = get_role(role_datum, policydb);
> -			rt = py_append_obj(list, obj);
> -			Py_DECREF(obj); 
> -			if (rt) goto err;
> -		}
> -		qpol_iterator_destroy(&iter);
> -	}
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list = NULL;
> -
> -cleanup:
> -	qpol_iterator_destroy(&iter);
> -	errno = error;
> -	return list;
> -}
> -
> -/**
> - * Get statistics regarding a policy's types.
> - * If this function is given a name, it will attempt to
> - * print statistics about a particular type; otherwise
> - * the function prints statistics about all of the policy's types.
> - *
> - * @param name Reference to a type's name; if NULL,
> - * all object classes will be considered
> - * @param policydb Reference to a policy
> - *
> - * @return 0 on success, < 0 on error.
> - */
> -static PyObject* get_types(const char *name, const apol_policy_t * policydb)
> -{
> -	const qpol_type_t *type_datum = NULL;
> -	qpol_iterator_t *iter = NULL;
> -	qpol_policy_t *q = apol_policy_get_qpol(policydb);
> -	int error = 0;
> -	int rt;
> -	PyObject *obj;
> -	PyObject *list = PyList_New(0);
> -	if (!list) goto err;
> -	/* if name was provided, only print that name */
> -	if (name != NULL) {
> -		if (qpol_policy_get_type_by_name(q, name, &type_datum)) {
> -			errno = EINVAL;
> -			goto err;
> -		}
> -		obj = get_type(type_datum, policydb);
> -		rt = py_append_obj(list, obj);
> -		Py_DECREF(obj); 
> -		if (rt) goto err;
> -	} else {
> -		if (qpol_policy_get_type_iter(q, &iter))
> -			goto err;
> -
> -		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -			if (qpol_iterator_get_item(iter, (void **)&type_datum))
> -				goto err;
> -			obj = get_type(type_datum, policydb);
> -			rt = py_append_obj(list, obj);
> -			Py_DECREF(obj); 
> -			if (rt) goto err;
> -		}
> -	}
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(list); list = NULL;
> -
> -cleanup:
> -	qpol_iterator_destroy(&iter);
> -	errno =	error;
> -	return list;
> -}
> -
> -PyObject* info( int type, const char *name)
> -{
> -	PyObject* output = NULL;
> -
> -	switch(type) {
> -	/* display requested info */
> -	case TYPE:
> -		output = get_types(name, global_policy);
> -		break;
> -	case ATTRIBUTE:
> -		output = get_attribs(name, global_policy);
> -		break;
> -	case ROLE:
> -		output = get_roles(name, global_policy);
> -		break;
> -	case USER:
> -		output = get_users(name, global_policy);
> -		break;
> -	case CLASS:
> -		output = get_classes(name, global_policy);
> -		break;
> -	case BOOLEAN:
> -		output = get_booleans(name, global_policy);
> -		break;
> -	case PORT:
> -		output = get_ports(name, global_policy);
> -		break;
> -	case SENS:
> -		output = get_sens(name, global_policy);
> -		break;
> -	case CATS:
> -		output = get_cats(name, global_policy);
> -		break;
> -	default:
> -		errno = EINVAL;
> -		PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -		break;
> -	}
> -
> -	return output;
> -}
> -
> -PyObject *wrap_info(PyObject *UNUSED(self), PyObject *args){
> -    int type;
> -    const char *name;
> -    
> -    if (!global_policy) {
> -	    PyErr_SetString(PyExc_RuntimeError,"Policy not loaded");
> -	    return NULL;
> -    }
> -
> -    if (!PyArg_ParseTuple(args, "iz", &type, &name))
> -        return NULL;
> -
> -    return info(type, name);
> -}
> -
> -void init_info (PyObject *m) {
> -    PyModule_AddIntConstant(m, "ATTRIBUTE", ATTRIBUTE);
> -    PyModule_AddIntConstant(m, "PORT", PORT);
> -    PyModule_AddIntConstant(m, "ROLE", ROLE);
> -    PyModule_AddIntConstant(m, "TYPE", TYPE);
> -    PyModule_AddIntConstant(m, "USER", USER);
> -    PyModule_AddIntConstant(m, "CLASS", CLASS);
> -    PyModule_AddIntConstant(m, "BOOLEAN", BOOLEAN);
> -    PyModule_AddIntConstant(m, "SENS", SENS);
> -    PyModule_AddIntConstant(m, "CATS", CATS);
> -}
> diff --git a/policycoreutils/sepolicy/policy.c b/policycoreutils/sepolicy/policy.c
> deleted file mode 100644
> index 423a926..0000000
> --- a/policycoreutils/sepolicy/policy.c
> +++ /dev/null
> @@ -1,116 +0,0 @@
> -/**
> - *  @file
> - *  Python bindings to search SELinux Policy rules.
> - *
> - *  @author Dan Walsh  <dwalsh@redhat.com>
> - *
> - *  Copyright (C) 2012 Red Hat, INC
> - *
> - *  This program is free software; you can redistribute it and/or modify
> - *  it under the terms of the GNU General Public License as published by
> - *  the Free Software Foundation; either version 2 of the License, or
> - *  (at your option) any later version.
> - *
> - *  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> - */
> -
> -#include "Python.h"
> -
> -#ifdef UNUSED
> -#elif defined(__GNUC__)
> -# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
> -#elif defined(__LCLINT__)
> -# define UNUSED(x) /*@unused@*/ x
> -#else
> -# define UNUSED(x) x
> -#endif
> -
> -#include "policy.h"
> -apol_policy_t *global_policy = NULL;
> -
> -/* other */
> -#include <errno.h>
> -#include <stdlib.h>
> -#include <stdio.h>
> -#include <string.h>
> -#include <assert.h>
> -
> -#define COPYRIGHT_INFO "Copyright (C) 2003-2007 Tresys Technology, LLC"
> -
> -PyObject *wrap_policy(PyObject *UNUSED(self), PyObject *args){
> -    const char *policy_file;
> -    apol_vector_t *mod_paths = NULL;
> -    apol_policy_path_type_e path_type = APOL_POLICY_PATH_TYPE_MONOLITHIC;
> -    apol_policy_path_t *pol_path = NULL;
> -    
> -    if (!PyArg_ParseTuple(args, "z", &policy_file))
> -	    return NULL;
> -
> -    if (global_policy)
> -	    apol_policy_destroy(&global_policy);
> -
> -    int policy_load_options = 0;
> -	    
> -    pol_path = apol_policy_path_create(path_type, policy_file, mod_paths);
> -    if (!pol_path) {
> -	    apol_vector_destroy(&mod_paths);
> -	    PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM));
> -	    return NULL;
> -    }
> -    apol_vector_destroy(&mod_paths);
> -    
> -    global_policy = apol_policy_create_from_policy_path(pol_path, policy_load_options, NULL, NULL);
> -    apol_policy_path_destroy(&pol_path);
> -    if (!global_policy) {
> -	    PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	    return NULL;
> -    }
> -
> -    return Py_None;
> -}
> -
> -static PyMethodDef methods[] = {
> -	{"policy", (PyCFunction) wrap_policy, METH_VARARGS,
> -		 "Initialize SELinux policy for use with search and info"},
> -	{"info", (PyCFunction) wrap_info, METH_VARARGS,
> -		 "Return SELinux policy info about types, attributes, roles, users"},
> -	{"search", (PyCFunction) wrap_search, METH_VARARGS,
> -	"Search SELinux Policy for allow, neverallow, auditallow, dontaudit and transition records"},
> -	{NULL, NULL, 0, NULL}	/* sentinel */
> -};
> -
> -#if PY_MAJOR_VERSION >= 3
> -
> -static struct PyModuleDef module_def =
> -{
> -	PyModuleDef_HEAD_INIT,
> -	"_policy", /* name of module */
> -	"", /* module documentation, may be NULL */
> -	-1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
> -	(PyMethodDef*)&methods,
> -};
> -
> -PyMODINIT_FUNC PyInit__policy(void)
> -{
> -	PyObject *m;
> -	m = PyModule_Create(&module_def);
> -	init_info(m);
> -	return m;
> -}
> -
> -#else // python 2
> -
> -void init_policy(void) {
> -	PyObject *m;
> -	m = Py_InitModule("_policy", methods);
> -	init_info(m);
> -}
> -
> -#endif
> diff --git a/policycoreutils/sepolicy/policy.h b/policycoreutils/sepolicy/policy.h
> deleted file mode 100644
> index ffac497..0000000
> --- a/policycoreutils/sepolicy/policy.h
> +++ /dev/null
> @@ -1,7 +0,0 @@
> -#include <apol/policy.h>
> -extern apol_policy_t *global_policy;
> -extern PyObject *wrap_info(PyObject *self, PyObject *args);
> -extern void init_info (PyObject *m);
> -extern PyObject *wrap_search(PyObject *self, PyObject *args);
> -
> -
> diff --git a/policycoreutils/sepolicy/search.c b/policycoreutils/sepolicy/search.c
> deleted file mode 100644
> index d608006..0000000
> --- a/policycoreutils/sepolicy/search.c
> +++ /dev/null
> @@ -1,1029 +0,0 @@
> -// Author: Thomas Liu <tliu@redhat.com>
> -
> -/**
> - *  @file
> - *  Python bindings used to search TE rules.
> - *
> - *  @author Thomas Liu  <tliu@redhat.com>
> - *  @author Dan Walsh  <dwalsh@redhat.com>
> - *  Copyright (C) 2012-2013 Red Hat, inc
> - *
> - *  Sections copied from sesearch.c in setools package
> - *  @author Frank Mayer  mayerf@tresys.com
> - *  @author Jeremy A. Mowery jmowery@tresys.com
> - *  @author Paul Rosenfeld  prosenfeld@tresys.com
> - *  Copyright (C) 2003-2008 Tresys Technology, LLC
> - *
> - *  This program is free software; you can redistribute it and/or modify
> - *  it under the terms of the GNU General Public License as published by
> - *  the Free Software Foundation; either version 2 of the License, or
> - *  (at your option) any later version.
> - *
> - *  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> - */
> -
> -/**
> - * This is a modified version of sesearch to be used as part of a sepython library for
> - * Python bindings.
> - */
> -
> -#include "common.h"
> -#include "policy.h"
> -
> -/* libapol */
> -#include <apol/policy-query.h>
> -#include <apol/render.h>
> -#include <apol/util.h>
> -#include <apol/vector.h>
> -
> -/* libqpol*/
> -#include <qpol/policy.h>
> -#include <qpol/policy_extend.h>
> -#include <qpol/syn_rule_query.h>
> -#include <qpol/util.h>
> -
> -/* other */
> -#include <errno.h>
> -#include <stdlib.h>
> -#include <stdio.h>
> -#include <assert.h>
> -#include <getopt.h>
> -#include <string.h>
> -#include <stdbool.h>
> -
> -#define COPYRIGHT_INFO "Copyright (C) 2012 Red Hat, Inc, Tresys Technology, LLC"
> -
> -enum opt_values
> -{
> -	RULE_NEVERALLOW = 256, RULE_AUDIT, RULE_AUDITALLOW, RULE_DONTAUDIT,
> -	RULE_ROLE_ALLOW, RULE_ROLE_TRANS, RULE_RANGE_TRANS, RULE_ALL,
> -	EXPR_ROLE_SOURCE, EXPR_ROLE_TARGET
> -};
> -
> -;
> -
> -typedef struct options
> -{
> -	char *src_name;
> -	char *tgt_name;
> -	char *src_role_name;
> -	char *tgt_role_name;
> -	char *class_name;
> -	char *permlist;
> -	char *bool_name;
> -	apol_vector_t *class_vector;
> -	bool all;
> -	bool lineno;
> -	bool semantic;
> -	bool indirect;
> -	bool allow;
> -	bool nallow;
> -	bool auditallow;
> -	bool dontaudit;
> -	bool type;
> -	bool rtrans;
> -	bool role_allow;
> -	bool role_trans;
> -	bool useregex;
> -	bool show_cond;
> -	apol_vector_t *perm_vector;
> -} options_t;
> -
> -static int py_tuple_insert_obj(PyObject *tuple, int pos, PyObject *obj)
> -{
> -	int rt;
> -	if (!obj) return -1;
> -	rt = PyTuple_SetItem(tuple, pos, obj);
> -	return rt;
> -}
> -
> -static int perform_ra_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v)
> -{
> -	apol_role_allow_query_t *raq = NULL;
> -	int error = 0;
> -
> -	if (!policy || !opt || !v) {
> -		ERR(policy, "%s", strerror(EINVAL));
> -		errno = EINVAL;
> -		return -1;
> -	}
> -
> -	if (!opt->role_allow && !opt->all) {
> -		*v = NULL;
> -		return 0;	       /* no search to do */
> -	}
> -
> -	raq = apol_role_allow_query_create();
> -	if (!raq) {
> -		ERR(policy, "%s", strerror(ENOMEM));
> -		errno = ENOMEM;
> -		return -1;
> -	}
> -
> -	apol_role_allow_query_set_regex(policy, raq, opt->useregex);
> -	if (opt->src_role_name) {
> -		if (apol_role_allow_query_set_source(policy, raq, opt->src_role_name)) {
> -			error = errno;
> -			goto err;
> -		}
> -	}
> -	if (opt->tgt_role_name)
> -		if (apol_role_allow_query_set_target(policy, raq, opt->tgt_role_name)) {
> -			error = errno;
> -			goto err;
> -		}
> -
> -	if (apol_role_allow_get_by_query(policy, raq, v)) {
> -		error = errno;
> -		goto err;
> -	}
> -	apol_role_allow_query_destroy(&raq);
> -	return 0;
> -
> -      err:
> -	apol_vector_destroy(v);
> -	apol_role_allow_query_destroy(&raq);
> -	ERR(policy, "%s", strerror(error));
> -	errno = error;
> -	return -1;
> -}
> -
> -static PyObject* get_ra_results(const apol_policy_t * policy, const apol_vector_t * v, PyObject *output)
> -{
> -	size_t i, num_rules = 0;
> -	qpol_policy_t *q;
> -	const qpol_role_allow_t *rule = NULL;
> -	const char *tmp;
> -	PyObject *obj, *dict=NULL;
> -	const qpol_role_t *role = NULL;
> -	int error = 0;
> -	errno = EINVAL;
> -	int rt;
> -
> -	if (!policy || !v) {
> -		errno = EINVAL;
> -		goto err;
> -	}
> -
> -	if (!(num_rules = apol_vector_get_size(v)))
> -		return NULL;
> -
> -	q = apol_policy_get_qpol(policy);
> -
> -	for (i = 0; i < num_rules; i++) {
> -		dict = PyDict_New();
> -		if (!dict) goto err;
> -		if (!(rule = apol_vector_get_element(v, i)))
> -			goto err;
> -
> -		if (qpol_role_allow_get_source_role(q, rule, &role)) {
> -			goto err;
> -		}
> -		if (qpol_role_get_name(q, role, &tmp)) {
> -			goto err;
> -		}
> -		obj = PyString_FromString(tmp);
> -		if (py_insert_obj(dict, "source", obj))
> -			goto err;
> -
> -		if (qpol_role_allow_get_target_role(q, rule, &role)) {
> -			goto err;
> -		}
> -		if (qpol_role_get_name(q, role, &tmp)) {
> -			goto err;
> -		}
> -		obj = PyString_FromString(tmp);
> -		if (py_insert_obj(dict, "target", obj))
> -			goto err;
> -
> -		rt = py_append_obj(output, dict);
> -		if (rt) goto err;
> -		py_decref(dict); dict=NULL;
> -	}
> -	goto cleanup;
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(error));
> -	py_decref(dict);
> -
> -cleanup:
> -	errno = error;
> -	return output;
> -}
> -
> -static int perform_te_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v)
> -{
> -	apol_terule_query_t *teq = NULL;
> -	unsigned int rules = 0;
> -	int error = 0;
> -	size_t i;
> -
> -	if (!policy || !opt || !v) {
> -		PyErr_SetString(PyExc_RuntimeError,strerror(EINVAL));
> -		errno = EINVAL;
> -		return -1;
> -	}
> -
> -	if (opt->all || opt->type) {
> -		rules = (QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER);
> -	} else {
> -		*v = NULL;
> -		return 0;	       /* no search to do */
> -	}
> -
> -	teq = apol_terule_query_create();
> -	if (!teq) {
> -		PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM));
> -		errno = ENOMEM;
> -		return -1;
> -	}
> -
> -	apol_terule_query_set_rules(policy, teq, rules);
> -	apol_terule_query_set_regex(policy, teq, opt->useregex);
> -
> -	if (opt->src_name)
> -		apol_terule_query_set_source(policy, teq, opt->src_name, opt->indirect);
> -	if (opt->tgt_name)
> -		apol_terule_query_set_target(policy, teq, opt->tgt_name, opt->indirect);
> -	if (opt->bool_name)
> -		apol_terule_query_set_bool(policy, teq, opt->bool_name);
> -	if (opt->class_name) {
> -		if (opt->class_vector == NULL) {
> -			if (apol_terule_query_append_class(policy, teq, opt->class_name)) {
> -				error = errno;
> -				goto err;
> -			}
> -		} else {
> -			for (i = 0; i < apol_vector_get_size(opt->class_vector); ++i) {
> -				char *class_name;
> -				class_name = apol_vector_get_element(opt->class_vector, i);
> -				if (!class_name)
> -					continue;
> -				if (apol_terule_query_append_class(policy, teq, class_name)) {
> -					error = errno;
> -					goto err;
> -				}
> -			}
> -		}
> -	}
> -
> -	if (!(opt->semantic) && qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) {
> -		if (apol_syn_terule_get_by_query(policy, teq, v)) {
> -			goto err;
> -		}
> -	} else {
> -		if (apol_terule_get_by_query(policy, teq, v)) {
> -			goto err;
> -		}
> -	}
> -
> -	apol_terule_query_destroy(&teq);
> -	return 0;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(error));
> -	apol_vector_destroy(v);
> -	apol_terule_query_destroy(&teq);
> -	errno = error;
> -	return -1;
> -}
> -
> -static PyObject* get_bool(const qpol_policy_t *q, const qpol_cond_t * cond, int enabled)
> -{
> -	qpol_iterator_t *iter = NULL;
> -	qpol_cond_expr_node_t *expr = NULL;
> -	char *tmp = NULL;
> -	const char *bool_name = NULL;
> -	int error = 0;
> -	uint32_t expr_type = 0;
> -	qpol_bool_t *cond_bool = NULL;
> -	PyObject *obj, *tuple = NULL;
> -	PyObject *boollist = NULL;
> -
> -	if (!q || !cond) {
> -		errno = EINVAL;
> -		return NULL;
> -	}
> -	if (qpol_cond_get_expr_node_iter(q, cond, &iter) < 0) {
> -		goto err;
> -	}
> -
> -	boollist = PyList_New(0);
> -	if (! boollist) goto err;
> -
> -	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -		if (qpol_iterator_get_item(iter, (void **)&expr)) {
> -			goto err;
> -		}
> -		if (qpol_cond_expr_node_get_expr_type(q, expr, &expr_type)) {
> -			goto err;
> -		}
> -		if (expr_type != QPOL_COND_EXPR_BOOL) {
> -			obj = PyString_FromString(apol_cond_expr_type_to_str(expr_type));
> -			if (!obj) goto err;
> -			if (py_append_obj(boollist, obj))
> -				goto err;
> -		} else {
> -			tuple = PyTuple_New(2);
> -			if (!tuple) goto err;
> -
> -			if (qpol_cond_expr_node_get_bool(q, expr, &cond_bool)) {
> -				goto err;
> -			}
> -			if (qpol_bool_get_name(q, cond_bool, &bool_name)) {
> -				goto err;
> -			}
> -			obj = PyString_FromString(bool_name);
> -			if (py_tuple_insert_obj(tuple, 0, obj))
> -				goto err;
> -			obj = PyBool_FromLong(enabled);
> -			if (py_tuple_insert_obj(tuple, 1, obj))
> -				goto err;
> -			if (py_append_obj(boollist, tuple)) 
> -				goto err;
> -			tuple=NULL;
> -		}
> -	}
> -
> -	qpol_iterator_destroy(&iter);
> -	return boollist;
> -
> -      err:
> -	error = errno;
> -	qpol_iterator_destroy(&iter);
> -	py_decref(tuple);
> -	py_decref(boollist);
> -	free(tmp);
> -	errno = error;
> -	return NULL;
> -}
> -
> -static PyObject* get_te_results(const apol_policy_t * policy, const apol_vector_t * v, PyObject *output)
> -{
> -	int error = 0;
> -	int rt = 0;
> -	PyObject *obj, *dict=NULL, *tuple = NULL;
> -	qpol_policy_t *q;
> -	uint32_t rule_type = 0;
> -	const qpol_type_t *type;
> -	size_t i, num_rules = 0;
> -	const qpol_terule_t *rule = NULL;
> -	char *tmp = NULL, *rule_str = NULL, *expr = NULL;
> -	const qpol_cond_t *cond = NULL;
> -	uint32_t enabled = 0;
> -	const char *tmp_name;
> -	const qpol_class_t *obj_class = NULL;
> -
> -	if (!policy || !v) {
> -		errno = EINVAL;
> -		goto err;
> -	}
> -
> -	if (!(num_rules = apol_vector_get_size(v)))
> -		return NULL;
> -
> -	q = apol_policy_get_qpol(policy);
> -
> -	for (i = 0; i < num_rules; i++) {
> -		dict = PyDict_New();
> -		if (!dict) goto err;
> -		if (!(rule = apol_vector_get_element(v, i)))
> -			goto err;
> -		if (qpol_terule_get_cond(q, rule, &cond))
> -			goto err;
> -		if (qpol_terule_get_is_enabled(q, rule, &enabled))
> -			goto err;
> -
> -		if (cond) {
> -			obj = get_bool(q, cond, enabled);
> -			if (!obj) goto err;
> -			rt = PyDict_SetItemString(dict, "boolean", obj);
> -			py_decref(obj);
> -		}
> -
> -		if (qpol_terule_get_rule_type(q, rule, &rule_type))
> -			goto err;
> -
> -		if (!(rule_type &= (QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER))) {
> -			PyErr_SetString(PyExc_RuntimeError,"Invalid TE rule type");
> -			errno = EINVAL;
> -			goto err;
> -		}
> -		if (!(tmp_name = apol_rule_type_to_str(rule_type))) {
> -			PyErr_SetString(PyExc_RuntimeError, "Could not get TE rule type's string");
> -			errno = EINVAL;
> -			goto err;
> -		}
> -
> -		if (py_insert_string(dict, "type", tmp_name))
> -			goto err;
> -
> -		if (qpol_terule_get_source_type(q, rule, &type))
> -			goto err;
> -		if (qpol_type_get_name(q, type, &tmp_name))
> -			goto err;
> -		if (py_insert_string(dict, "source", tmp_name))
> -			goto err;
> -
> -		if (qpol_terule_get_target_type(q, rule, &type))
> -			goto err;
> -		if (qpol_type_get_name(q, type, &tmp_name))
> -			goto err;
> -		if (py_insert_string(dict, "target", tmp_name))
> -			goto err;
> -
> -		if (qpol_terule_get_object_class(q, rule, &obj_class))
> -			goto err;
> -		if (qpol_class_get_name(q, obj_class, &tmp_name))
> -			goto err;
> -		if (py_insert_string(dict, "class", tmp_name))
> -			goto err;
> -
> -		if (qpol_terule_get_default_type(q, rule, &type))
> -			goto err;
> -		if (qpol_type_get_name(q, type, &tmp_name))
> -			goto err;
> -		if (py_insert_string(dict, "transtype", tmp_name))
> -			goto err;
> -
> -		rt = py_append_obj(output, dict);
> -		dict = NULL;
> -		if(rt) goto err;
> -
> -		free(rule_str);	rule_str = NULL;
> -		free(expr); expr = NULL;
> -	}
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	py_decref(dict);
> -	py_decref(tuple);
> -	PyErr_SetString(PyExc_RuntimeError,strerror(error));
> -cleanup:
> -	free(tmp);
> -	free(rule_str);
> -	free(expr);
> -	errno = error;
> -	return output;
> -}
> -
> -static int perform_ft_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v)
> -{
> -	apol_filename_trans_query_t *ftq = NULL;
> -	size_t i;
> -	int error = 0;
> -
> -	if (!policy || !opt || !v) {
> -		PyErr_SetString(PyExc_RuntimeError,strerror(EINVAL));
> -		errno = EINVAL;
> -		return -1;
> -	}
> -
> -	if (!opt->type && !opt->all) {
> -		*v = NULL;
> -		return 0;	       /* no search to do */
> -	}
> -
> -	ftq = apol_filename_trans_query_create();
> -	if (!ftq) {
> -		PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM));
> -		errno = ENOMEM;
> -		return -1;
> -	}
> -
> -	apol_filename_trans_query_set_regex(policy, ftq, opt->useregex);
> -	if (opt->src_name) {
> -		if (apol_filename_trans_query_set_source(policy, ftq, opt->src_name, opt->indirect)) {
> -			goto err;
> -		}
> -	}
> -
> -	if (opt->tgt_name) {
> -		if (apol_filename_trans_query_set_target(policy, ftq, opt->tgt_name, opt->indirect)) {
> -			goto err;
> -		}
> -	}
> -	if (opt->class_name) {
> -		if (opt->class_vector == NULL) {
> -			if (apol_filename_trans_query_append_class(policy, ftq, opt->class_name)) {
> -				goto err;
> -			}
> -		} else {
> -			for (i = 0; i < apol_vector_get_size(opt->class_vector); ++i) {
> -				char *class_name;
> -				class_name = apol_vector_get_element(opt->class_vector, i);
> -				if (!class_name)
> -					continue;
> -				if (apol_filename_trans_query_append_class(policy, ftq, class_name)) {
> -					goto err;
> -				}
> -			}
> -		}
> -	}
> -
> -	if (apol_filename_trans_get_by_query(policy, ftq, v))
> -		goto err;
> -
> -	apol_filename_trans_query_destroy(&ftq);
> -	return 0;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	apol_vector_destroy(v);
> -	apol_filename_trans_query_destroy(&ftq);
> -	errno = error;
> -	return -1;
> -}
> -
> -static PyObject* get_ft_results(const apol_policy_t * policy, const apol_vector_t * v, PyObject *list)
> -{
> -	PyObject *dict = NULL;
> -	size_t i, num_filename_trans = 0;
> -	const char *tmp_name;
> -	int error = 0;
> -	int rt;
> -	const qpol_filename_trans_t *filename_trans = NULL;
> -	const qpol_class_t *obj_class = NULL;
> -	char *tmp = NULL, *filename_trans_str = NULL, *expr = NULL;
> -	qpol_policy_t *q;
> -	const qpol_type_t *type = NULL;
> -
> -	if (!policy || !v) {
> -		errno = EINVAL;
> -		goto err;
> -	}
> -
> -	if (!(num_filename_trans = apol_vector_get_size(v)))
> -		return NULL;
> -
> -	q = apol_policy_get_qpol(policy);
> -
> -	for (i = 0; i < num_filename_trans; i++) {
> -		if (!(filename_trans = apol_vector_get_element(v, i)))
> -			goto err;
> -
> -		dict = PyDict_New();
> -		if (!dict) goto err;
> -
> -		if (py_insert_string(dict, "type", "type_transition"))
> -			goto err;
> -
> -		/* source type */
> -		if (qpol_filename_trans_get_source_type(q, filename_trans, &type)) {
> -			goto err;
> -		}
> -		if (qpol_type_get_name(q, type, &tmp_name)) {
> -			goto err;
> -		}
> -
> -		if (py_insert_string(dict, "source", tmp_name))
> -			goto err;
> -
> -		if (qpol_filename_trans_get_target_type(q, filename_trans, &type))
> -			goto err;
> -
> -		if (qpol_type_get_name(q, type, &tmp_name))
> -			goto err;
> -
> -		if (py_insert_string(dict, "target", tmp_name))
> -			goto err;
> -
> -		if (qpol_filename_trans_get_object_class(q, filename_trans, &obj_class))
> -			goto err;
> -
> -		if (qpol_class_get_name(q, obj_class, &tmp_name))
> -			goto err;
> -
> -		if (py_insert_string(dict, "class", tmp_name))
> -			goto err;
> -
> -		if (qpol_filename_trans_get_default_type(q, filename_trans, &type))
> -			goto err;
> -		if (qpol_type_get_name(q, type, &tmp_name))
> -			goto err;
> -		if (py_insert_string(dict, "transtype", tmp_name))
> -			goto err;
> -
> -		if (! qpol_filename_trans_get_filename(q, filename_trans, &tmp_name)) {
> -			if (py_insert_string(dict, "filename", tmp_name))
> -				goto err;
> -		}
> -
> -		rt = py_append_obj(list, dict);
> -		dict = NULL;
> -		if (rt) goto err;
> -
> -		free(filename_trans_str); filename_trans_str = NULL;
> -		free(expr); expr = NULL;
> -	}
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(dict);
> -cleanup:
> -	free(tmp);
> -	free(filename_trans_str);
> -	free(expr);
> -	errno = error;
> -	return list;
> -}
> -
> -static int perform_av_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v)
> -{
> -	apol_avrule_query_t *avq = NULL;
> -	unsigned int rules = 0;
> -	int error = 0;
> -	char *tmp = NULL, *tok = NULL, *s = NULL;
> -
> -	if (!policy || !opt || !v) {
> -		PyErr_SetString(PyExc_RuntimeError,strerror(EINVAL));
> -		errno = EINVAL;
> -		return -1;
> -	}
> -
> -	if (!opt->all && !opt->allow && !opt->nallow && !opt->auditallow && !opt->dontaudit) {
> -		*v = NULL;
> -		return 0;	       /* no search to do */
> -	}
> -
> -	avq = apol_avrule_query_create();
> -	if (!avq) {
> -		PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM));
> -		errno = ENOMEM;
> -		return -1;
> -	}
> -
> -	if (opt->allow || opt->all)
> -		rules |= QPOL_RULE_ALLOW;
> -	if (opt->nallow || opt->all)	// Add this regardless of policy capabilities
> -		rules |= QPOL_RULE_NEVERALLOW;
> -	if (opt->auditallow || opt->all)
> -		rules |= QPOL_RULE_AUDITALLOW;
> -	if (opt->dontaudit || opt->all)
> -		rules |= QPOL_RULE_DONTAUDIT;
> -	if (rules != 0)	// Setting rules = 0 means you want all the rules
> -		apol_avrule_query_set_rules(policy, avq, rules);
> -	apol_avrule_query_set_regex(policy, avq, opt->useregex);
> -	if (opt->src_name)
> -		apol_avrule_query_set_source(policy, avq, opt->src_name, opt->indirect);
> -	if (opt->tgt_name)
> -		apol_avrule_query_set_target(policy, avq, opt->tgt_name, opt->indirect);
> -	if (opt->bool_name)
> -		apol_avrule_query_set_bool(policy, avq, opt->bool_name);
> -	if (opt->class_name) {
> -		if (opt->class_vector == NULL) {
> -			if (apol_avrule_query_append_class(policy, avq, opt->class_name)) {
> -				goto err;
> -			}
> -		} else {
> -			size_t i;
> -	    for (i = 0; i < apol_vector_get_size(opt->class_vector); ++i) {
> -				char *class_name;
> -				class_name = apol_vector_get_element(opt->class_vector, i);
> -				if (!class_name)
> -					continue;
> -				if (apol_avrule_query_append_class(policy, avq, class_name)) {
> -					goto err;
> -				}
> -			}
> -		}
> -	}
> -
> -	if (opt->permlist) {
> -		tmp = strdup(opt->permlist);
> -		for (tok = strtok(tmp, ","); tok; tok = strtok(NULL, ",")) {
> -			if (apol_avrule_query_append_perm(policy, avq, tok)) {
> -				goto err;
> -			}
> -			if ((s = strdup(tok)) == NULL || apol_vector_append(opt->perm_vector, s) < 0) {
> -				goto err;
> -			}
> -			s = NULL;
> -		}
> -		free(tmp);
> -		tmp = NULL;
> -	}
> -
> -	if (!(opt->semantic) && qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) {
> -		if (apol_syn_avrule_get_by_query(policy, avq, v)) {
> -			goto err;
> -		}
> -	} else {
> -		if (apol_avrule_get_by_query(policy, avq, v)) {
> -			goto err;
> -		}
> -	}
> -
> -	apol_avrule_query_destroy(&avq);
> -	return 0;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(error));
> -	apol_vector_destroy(v);
> -	apol_avrule_query_destroy(&avq);
> -	free(tmp);
> -	free(s);
> -	errno = error;
> -	return -1;
> -}
> -
> -static PyObject* get_av_results(const apol_policy_t * policy, const apol_vector_t * v, PyObject *output)
> -{
> -	PyObject *obj, *dict=NULL;
> -	PyObject *permlist = NULL;
> -	PyObject *boollist = NULL;
> -	uint32_t rule_type = 0;
> -	int rt;
> -	int error = 0;
> -	qpol_policy_t *q;
> -	size_t i, num_rules = 0;
> -	const qpol_avrule_t *rule = NULL;
> -	char *tmp = NULL, *rule_str = NULL;
> -	qpol_cond_expr_node_t *expr = NULL;
> -	qpol_iterator_t *iter = NULL;
> -	const qpol_cond_t *cond = NULL;
> -	uint32_t enabled = 0;
> -	const qpol_type_t *type;
> -	const char *tmp_name;
> -	const qpol_class_t *obj_class = NULL;
> -
> -	if (!policy || !v) {
> -		errno = EINVAL;
> -		goto err;
> -	}
> -
> -	if (!(num_rules = apol_vector_get_size(v)))
> -		return NULL;
> -
> -	q = apol_policy_get_qpol(policy);
> -
> -	for (i = 0; i < num_rules; i++) {
> -		if (!(rule = apol_vector_get_element(v, i)))
> -			goto err;
> -
> -		dict = PyDict_New();
> -		if (!dict) goto err;
> -
> -		if (qpol_avrule_get_rule_type(q, rule, &rule_type))
> -			goto err;
> -
> -		if (!(tmp_name = apol_rule_type_to_str(rule_type))) {
> -			PyErr_SetString(PyExc_RuntimeError, "Could not get TE rule type's string");
> -			errno = EINVAL;
> -			goto err;
> -		}
> -
> -		if (py_insert_string(dict, "type", tmp_name))
> -			goto err;
> -
> -		if (qpol_avrule_get_source_type(q, rule, &type)) {
> -			goto err;
> -		}
> -
> -		if (qpol_type_get_name(q, type, &tmp_name)) {
> -			goto err;
> -		}
> -
> -		if (py_insert_string(dict, "source", tmp_name))
> -			goto err;
> -
> -		if (qpol_avrule_get_target_type(q, rule, &type)) {
> -			goto err;
> -		}
> -		if (qpol_type_get_name(q, type, &tmp_name)) {
> -			goto err;
> -		}
> -
> -		if (py_insert_string(dict, "target", tmp_name))
> -			goto err;
> -
> -		if (qpol_avrule_get_object_class(q, rule, &obj_class)) {
> -			goto err;
> -		}
> -		if (qpol_class_get_name(q, obj_class, &tmp_name)) {
> -			goto err;
> -		}
> -
> -		if (py_insert_string(dict, "class", tmp_name))
> -			goto err;
> -
> -		if (qpol_avrule_get_perm_iter(q, rule, &iter)) {
> -			goto err;
> -		}
> -
> -		permlist = PyList_New(0);
> -		if (! permlist) goto err;
> -
> -		for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
> -			const char *perm_name = NULL;
> -			if (qpol_iterator_get_item(iter, (void **)&perm_name))
> -				goto err;
> -			if (py_append_string(permlist, perm_name))
> -				goto err;
> -		}
> -
> -		rt = PyDict_SetItemString(dict, "permlist", permlist);
> -		py_decref(permlist); permlist=NULL;
> -		if (rt) goto err;
> -
> -		if (qpol_avrule_get_cond(q, rule, &cond))
> -			goto err;
> -		if (qpol_avrule_get_is_enabled(q, rule, &enabled))
> -			goto err;
> -
> -		obj = PyBool_FromLong(enabled);
> -		rt = PyDict_SetItemString(dict, "enabled", obj);
> -		py_decref(obj);
> -
> -		if (cond) {
> -			obj = get_bool(q, cond, enabled);
> -			if (!obj) goto err;
> -			rt = PyDict_SetItemString(dict, "boolean", obj);
> -			py_decref(obj);
> -		}
> -
> -		rt = py_append_obj(output, dict);
> -		py_decref(dict); dict=NULL;
> -		if (rt) goto err;
> -
> -		free(rule_str);	rule_str = NULL;
> -		free(expr); expr = NULL;
> -	}
> -	goto cleanup;
> -
> -err:
> -	error = errno;
> -	PyErr_SetString(PyExc_RuntimeError,strerror(errno));
> -	py_decref(dict);
> -	py_decref(permlist);
> -	py_decref(boollist);
> -
> -cleanup:
> -	free(tmp);
> -	free(rule_str);
> -	free(expr);
> -	errno = error;
> -	return output;
> -}
> -
> -PyObject* search(bool allow,
> -		 bool neverallow,
> -		 bool auditallow,
> -		 bool dontaudit,
> -		 bool transition,
> -		 bool role_allow,
> -		 const char *src_name,
> -		 const char *tgt_name,
> -		 const char *class_name,
> -		 const char *permlist
> -	)
> -{
> -	options_t cmd_opts;
> -	PyObject *output = NULL;
> -	apol_vector_t *v = NULL;
> -
> -	memset(&cmd_opts, 0, sizeof(cmd_opts));
> -	cmd_opts.indirect = true;
> -	cmd_opts.show_cond = true;
> -	cmd_opts.allow = allow;
> -	cmd_opts.nallow = neverallow;
> -	cmd_opts.auditallow = auditallow;
> -	cmd_opts.dontaudit = dontaudit;
> -	cmd_opts.type = transition;
> -	cmd_opts.role_allow = role_allow;
> -	if (src_name)
> -		cmd_opts.src_name = strdup(src_name);
> -	if (tgt_name)
> -		cmd_opts.tgt_name = strdup(tgt_name);
> -	if (class_name)
> -		cmd_opts.class_name = strdup(class_name);
> -	if (permlist){
> -		cmd_opts.perm_vector = apol_vector_create(free);
> -		cmd_opts.permlist = strdup(permlist);
> -	}
> -	if (!cmd_opts.semantic && qpol_policy_has_capability(apol_policy_get_qpol(global_policy), QPOL_CAP_SYN_RULES)) {
> -		if (qpol_policy_build_syn_rule_table(apol_policy_get_qpol(global_policy))) {
> -			PyErr_SetString(PyExc_RuntimeError,"Query failed");
> -			goto cleanup;
> -		}
> -	}
> -
> -	/* if syntactic rules are not available always do semantic search */
> -	if (!qpol_policy_has_capability(apol_policy_get_qpol(global_policy), QPOL_CAP_SYN_RULES)) {
> -		cmd_opts.semantic = 1;
> -	}
> -
> -	/* supress line numbers if doing semantic search or not available */
> -	if (cmd_opts.semantic || !qpol_policy_has_capability(apol_policy_get_qpol(global_policy), QPOL_CAP_LINE_NUMBERS)) {
> -		cmd_opts.lineno = 0;
> -	}
> -	if (perform_av_query(global_policy, &cmd_opts, &v)) {
> -		goto cleanup;
> -	}
> -	output = PyList_New(0);
> -	if (!output)
> -		goto cleanup;
> -
> -	if (v) {
> -		get_av_results(global_policy, v, output);
> -	}
> -
> -	apol_vector_destroy(&v);
> -	if (perform_te_query(global_policy, &cmd_opts, &v)) {
> -		goto cleanup;
> -	}
> -	if (v) {
> -		get_te_results(global_policy, v, output);
> -	}
> -
> -	if (cmd_opts.all || cmd_opts.type) {
> -		apol_vector_destroy(&v);
> -		if (perform_ft_query(global_policy, &cmd_opts, &v)) {
> -			goto cleanup;
> -		}
> -
> -		if (v) {
> -			get_ft_results(global_policy, v, output);
> -		}
> -	}
> -
> -	if (cmd_opts.all || cmd_opts.role_allow) {
> -		apol_vector_destroy(&v);
> -		if (perform_ra_query(global_policy, &cmd_opts, &v)) {
> -			goto cleanup;
> -		}
> -
> -		if (v) {
> -			get_ra_results(global_policy, v, output);
> -		}
> -	}
> -
> -	apol_vector_destroy(&v);
> -
> -      cleanup:
> -	free(cmd_opts.src_name);
> -	free(cmd_opts.tgt_name);
> -	free(cmd_opts.class_name);
> -	free(cmd_opts.permlist);
> -	free(cmd_opts.bool_name);
> -	free(cmd_opts.src_role_name);
> -	free(cmd_opts.tgt_role_name);
> -	apol_vector_destroy(&cmd_opts.perm_vector);
> -	apol_vector_destroy(&cmd_opts.class_vector);
> -
> -	if (output && PyList_GET_SIZE(output) == 0) {
> -		py_decref(output);
> -		return Py_None;
> -	}
> -	return output;
> -}
> -
> -static int Dict_ContainsInt(PyObject *dict, const char *key){
> -    PyObject *item = PyDict_GetItemString(dict, key);
> -    if (item)
> -	return PyInt_AsLong(item);
> -    return false;
> -}
> -
> -static const char *Dict_ContainsString(PyObject *dict, const char *key){
> -    PyObject *item = PyDict_GetItemString(dict, key);
> -    if (item)
> -	return PyString_AsString(item);
> -    return NULL;
> -}
> -
> -PyObject *wrap_search(PyObject *UNUSED(self), PyObject *args){
> -    PyObject *dict;
> -    if (!PyArg_ParseTuple(args, "O", &dict))
> -	return NULL;
> -    int allow = Dict_ContainsInt(dict, "allow");
> -    int neverallow = Dict_ContainsInt(dict, "neverallow");
> -    int auditallow = Dict_ContainsInt(dict, "auditallow");
> -    int dontaudit = Dict_ContainsInt(dict, "dontaudit");
> -    int transition = Dict_ContainsInt(dict, "transition");
> -    int role_allow = Dict_ContainsInt(dict, "role_allow");
> -
> -    if (!global_policy) {
> -	    PyErr_SetString(PyExc_RuntimeError,"Policy not loaded");
> -	    return NULL;
> -    }
> -    const char *src_name = Dict_ContainsString(dict, "source");
> -    const char *tgt_name = Dict_ContainsString(dict, "target");
> -    const char *class_name = Dict_ContainsString(dict, "class");
> -    const char *permlist = Dict_ContainsString(dict, "permlist");
> -
> -    return search(allow, neverallow, auditallow, dontaudit, transition, role_allow, src_name, tgt_name, class_name, permlist);
> -}
> diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py
> index b00ec81..8fbd5b4 100644
> --- a/policycoreutils/sepolicy/sepolicy/__init__.py
> +++ b/policycoreutils/sepolicy/sepolicy/__init__.py
> @@ -4,7 +4,6 @@
>  # Author: Ryan Hallisey <rhallise@redhat.com>
>  # Author: Jason Zaman <perfinion@gentoo.org>
>  
> -from . import _policy
>  import selinux
>  import setools
>  import glob
> @@ -149,7 +148,6 @@ def policy(policy_file):
>      global _pol
>  
>      try:
> -        _policy.policy(policy_file)
>          _pol = setools.SELinuxPolicy(policy_file)
>      except:
>          raise ValueError(_("Failed to read %s policy file") % policy_file)
> diff --git a/policycoreutils/sepolicy/setup.py b/policycoreutils/sepolicy/setup.py
> index e74e68d..4bd8353 100644
> --- a/policycoreutils/sepolicy/setup.py
> +++ b/policycoreutils/sepolicy/setup.py
> @@ -2,11 +2,21 @@
>  
>  # Author: Thomas Liu <tliu@redhat.com>
>  # Author: Dan Walsh <dwalsh@redhat.com>
> -import os
> -from distutils.core import setup, Extension
> -policy = Extension("sepolicy._policy",
> -                   libraries=["apol", "qpol"],
> -                   sources=["policy.c", "info.c", "search.c"]
> -                   )
> +from distutils.core import setup
>  
> -setup(name="sepolicy", version="1.1", description="Python SELinux Policy Analyses bindings", author="Daniel Walsh", author_email="dwalsh@redhat.com", ext_modules=[policy], packages=["sepolicy", "sepolicy.templates", "sepolicy.help"], package_data={'sepolicy': ['*.glade'], 'sepolicy.help': ['*.txt', '*.png']})
> +setup(
> +    name="sepolicy",
> +    version="1.1",
> +    description="Python SELinux Policy Analyses bindings",
> +    author="Daniel Walsh",
> +    author_email="dwalsh@redhat.com",
> +    packages=[
> +        "sepolicy",
> +        "sepolicy.templates",
> +        "sepolicy.help"
> +    ],
> +    package_data={
> +        'sepolicy': ['*.glade'],
> +        'sepolicy.help': ['*.txt', '*.png']
> +    }
> +)

  reply	other threads:[~2016-09-23  3:15 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-22 15:17 setools4 support Jason Zaman
2016-09-22 15:17 ` [PATCH 1/7] sepolicy: rearrange vars together at the top Jason Zaman
2016-09-22 15:17 ` [PATCH 2/7] sepolicy: initialize setools4 Jason Zaman
2016-09-22 15:17 ` [PATCH 3/7] sepolicy: update some users of search() to use setools directly Jason Zaman
2016-09-22 15:17 ` [PATCH 4/7] sepolicy: info() and search() will return generators Jason Zaman
2016-09-22 15:17 ` [PATCH 5/7] sepolicy: make info() use setools4 api Jason Zaman
2016-09-22 15:17 ` [PATCH 6/7] sepolicy: make search() " Jason Zaman
2016-09-22 15:17 ` [PATCH 7/7] sepolicy: update setup.py to remove C module Jason Zaman
2016-09-23  3:14   ` Jason Zaman [this message]
2016-09-23 17:07 ` setools4 support Stephen Smalley
2016-09-23 17:11   ` Petr Lautrbach
2016-09-23 17:44     ` Jason Zaman
2016-09-23 17:47   ` Jason Zaman
2016-09-23 18:15     ` Stephen Smalley
2016-09-23 19:23       ` Stephen Smalley
2016-09-23 20:39 ` Stephen Smalley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160923031427.GA3240@meriadoc \
    --to=jason@perfinion.com \
    --cc=selinux@tycho.nsa.gov \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.