bool_diff.c File Reference


Detailed Description

Implementation for computing semantic differences in booleans.

Author:
Jeremy A. Mowery jmowery@tresys.com

Jason Tang jtang@tresys.com

Randy Wicks rwicks@tresys.com

Copyright (C) 2006-2007 Tresys Technology, LLC

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Definition in file bool_diff.c.

#include <config.h>
#include "poldiff_internal.h"
#include <apol/util.h>
#include <apol/vector.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

Go to the source code of this file.


Classes

struct  poldiff_bool_summary
struct  poldiff_bool

Functions

void poldiff_bool_get_stats (const poldiff_t *diff, size_t stats[5])
 Get an array of statistics for the number of differences of each form for bools.
char * poldiff_bool_to_string (const poldiff_t *diff, const void *boolean)
 Obtain a newly allocated string representation of a difference in a bool.
const apol_vector_tpoldiff_get_bool_vector (const poldiff_t *diff)
 Get the vector of bool differences from the boolean difference summary.
const char * poldiff_bool_get_name (const poldiff_bool_t *boolean)
 Get the name of the bool from a bool diff.
poldiff_form_e poldiff_bool_get_form (const void *boolean)
 Get the form of difference from a bool diff.
void bool_free (void *elem)
poldiff_bool_summary_tbool_create (void)
 Allocate and return a new poldiff_bool_summary_t object.
void bool_destroy (poldiff_bool_summary_t **bs)
 Deallocate all space associated with a poldiff_bool_summary_t object, including the pointer itself.
int bool_reset (poldiff_t *diff)
 Reset the state of all boolean differences.
int bool_name_comp (const void *x, const void *y, void *arg)
 Comparison function for two bools from the same policy.
apol_vector_tbool_get_items (poldiff_t *diff, const apol_policy_t *policy)
 Get a vector of all bools from the given policy, sorted by name.
int bool_comp (const void *x, const void *y, const poldiff_t *diff)
 Compare two qpol_bool_t objects, determining if they have the same name or not.
poldiff_bool_tmake_diff (const poldiff_t *diff, poldiff_form_e form, const char *name)
 Allocate and return a new bool difference object.
int bool_new_diff (poldiff_t *diff, poldiff_form_e form, const void *item)
 Create, initialize, and insert a new semantic difference entry for a bool.
int bool_deep_diff (poldiff_t *diff, const void *x, const void *y)
 Compute the semantic difference of two bools for which the compare callback returns 0.

Function Documentation

void poldiff_bool_get_stats const poldiff_t diff,
size_t  stats[5]
 

Get an array of statistics for the number of differences of each form for bools.

Parameters:
diff The policy difference structure from which to get the stats.
stats Array into which to write the numbers (array must be pre-allocated). The order of the values written to the array is as follows: number of items of form POLDIFF_FORM_ADDED, number of POLDIFF_FORM_REMOVED, number of POLDIFF_FORM_MODIFIED, number of form POLDIFF_FORM_ADD_TYPE, and number of POLDIFF_FORM_REMOVE_TYPE.

Definition at line 52 of file bool_diff.c.

References poldiff::bool_diffs, diff, ERR, poldiff_bool_summary::num_added, poldiff_bool_summary::num_modified, poldiff_bool_summary::num_removed, and poldiff_t.

00053 {
00054         if (diff == NULL || stats == NULL) {
00055                 ERR(diff, "%s", strerror(EINVAL));
00056                 errno = EINVAL;
00057                 return;
00058         }
00059         stats[0] = diff->bool_diffs->num_added;
00060         stats[1] = diff->bool_diffs->num_removed;
00061         stats[2] = diff->bool_diffs->num_modified;
00062         stats[3] = 0;
00063         stats[4] = 0;
00064 }

char* poldiff_bool_to_string const poldiff_t diff,
const void *  boolean
 

Obtain a newly allocated string representation of a difference in a bool.

Parameters:
diff The policy difference structure associated with the bool.
item The bool from which to generate the string.
Returns:
A string representation of bool difference; the caller is responsible for free()ing this string. On error, return NULL and set errno.

Definition at line 66 of file bool_diff.c.

References apol_str_appendf(), diff, ERR, poldiff_bool::form, poldiff_bool::name, poldiff_bool_t, POLDIFF_FORM_ADDED, POLDIFF_FORM_MODIFIED, POLDIFF_FORM_REMOVED, poldiff_t, and poldiff_bool::state.

00067 {
00068         poldiff_bool_t *b = (poldiff_bool_t *) boolean;
00069         size_t len = 0;
00070         char *s = NULL;
00071         if (diff == NULL || boolean == NULL) {
00072                 ERR(diff, "%s", strerror(EINVAL));
00073                 errno = EINVAL;
00074                 return NULL;
00075         }
00076         switch (b->form) {
00077         case POLDIFF_FORM_ADDED:
00078         {
00079                 if (apol_str_appendf(&s, &len, "+ %s", b->name) < 0) {
00080                         break;
00081                 }
00082                 return s;
00083         }
00084         case POLDIFF_FORM_REMOVED:
00085         {
00086                 if (apol_str_appendf(&s, &len, "- %s", b->name) < 0) {
00087                         break;
00088                 }
00089                 return s;
00090         }
00091         case POLDIFF_FORM_MODIFIED:
00092         {
00093                 if (apol_str_appendf
00094                     (&s, &len, "* %s (changed from %s)", b->name, (b->state ? "false to true" : "true to false")) < 0) {
00095                         break;
00096                 }
00097                 return s;
00098         }
00099         default:
00100         {
00101                 ERR(diff, "%s", strerror(ENOTSUP));
00102                 errno = ENOTSUP;
00103                 return NULL;
00104         }
00105         }
00106         errno = ENOMEM;
00107         return NULL;
00108 }

const apol_vector_t* poldiff_get_bool_vector const poldiff_t diff  ) 
 

Get the vector of bool differences from the boolean difference summary.

Parameters:
diff The policy difference structure associated with the bool difference summary.
Returns:
A vector of elements of type poldiff_bool_t, or NULL on error. The caller should not destroy the vector returned. If the call fails, errno will be set.

Definition at line 110 of file bool_diff.c.

References apol_vector_t, poldiff::bool_diffs, diff, poldiff_bool_summary::diffs, and poldiff_t.

Referenced by components_bools_tests().

00111 {
00112         if (diff == NULL) {
00113                 errno = EINVAL;
00114                 return NULL;
00115         }
00116         return diff->bool_diffs->diffs;
00117 }

const char* poldiff_bool_get_name const poldiff_bool_t boolean  ) 
 

Get the name of the bool from a bool diff.

Parameters:
diff The policy difference structure associated with the bool diff.
cls The bool from which to get the name.
Returns:
Name of the bool on success and NULL on failure; if the call fails, errno will be set. The caller should not free the returned string.

Definition at line 119 of file bool_diff.c.

References poldiff_bool_t.

00120 {
00121         if (boolean == NULL) {
00122                 errno = EINVAL;
00123                 return NULL;
00124         }
00125         return boolean->name;
00126 }

poldiff_form_e poldiff_bool_get_form const void *  boolean  ) 
 

Get the form of difference from a bool diff.

Parameters:
diff The policy difference structure associated with the bool diff.
cls The bool from which to get the difference form.
Returns:
The form of difference (one of POLDIFF_FORM_*) or POLDIFF_FORM_NONE on error. If the call fails, errno will be set.

Definition at line 128 of file bool_diff.c.

References poldiff_bool_t, and poldiff_form_e.

Referenced by components_bools_tests().

00129 {
00130         if (boolean == NULL) {
00131                 errno = EINVAL;
00132                 return 0;
00133         }
00134         return ((const poldiff_bool_t *)boolean)->form;
00135 }

void bool_free void *  elem  )  [static]
 

Definition at line 139 of file bool_diff.c.

References poldiff_bool::name, and poldiff_bool_t.

Referenced by bool_create(), bool_new_diff(), and make_diff().

00140 {
00141         if (elem != NULL) {
00142                 poldiff_bool_t *b = (poldiff_bool_t *) elem;
00143                 free(b->name);
00144                 free(b);
00145         }
00146 }

poldiff_bool_summary_t* bool_create void   ) 
 

Allocate and return a new poldiff_bool_summary_t object.

Returns:
A new bool summary. The caller must call bool_destroy() afterwards. On error, return NULL and set errno.

Definition at line 148 of file bool_diff.c.

References apol_vector_create(), bool_destroy(), bool_free(), and poldiff_bool_summary_t.

Referenced by bool_reset(), and poldiff_create().

00149 {
00150         poldiff_bool_summary_t *bs = calloc(1, sizeof(*bs));
00151         if (bs == NULL) {
00152                 return NULL;
00153         }
00154         if ((bs->diffs = apol_vector_create(bool_free)) == NULL) {
00155                 bool_destroy(&bs);
00156                 return NULL;
00157         }
00158         return bs;
00159 }

void bool_destroy poldiff_bool_summary_t **  bs  ) 
 

Deallocate all space associated with a poldiff_bool_summary_t object, including the pointer itself.

If the pointer is already NULL then do nothing.

Parameters:
bs Reference to a bool summary to destroy. The pointer will be set to NULL afterwards.

Definition at line 161 of file bool_diff.c.

References apol_vector_destroy(), and poldiff_bool_summary_t.

Referenced by bool_create(), bool_reset(), and poldiff_destroy().

00162 {
00163         if (bs != NULL && *bs != NULL) {
00164                 apol_vector_destroy(&(*bs)->diffs);
00165                 free(*bs);
00166                 *bs = NULL;
00167         }
00168 }

int bool_reset poldiff_t diff  ) 
 

Reset the state of all boolean differences.

Parameters:
diff The policy difference structure containing the differences to reset.
Returns:
0 on success and < 0 on error; if the call fails, errno will be set and the user should call poldiff_destroy() on diff.

Definition at line 170 of file bool_diff.c.

References bool_create(), bool_destroy(), poldiff::bool_diffs, diff, ERR, and poldiff_t.

00171 {
00172         int error = 0;
00173 
00174         if (diff == NULL) {
00175                 ERR(diff, "%s", strerror(EINVAL));
00176                 errno = EINVAL;
00177                 return -1;
00178         }
00179 
00180         bool_destroy(&diff->bool_diffs);
00181         diff->bool_diffs = bool_create();
00182         if (diff->bool_diffs == NULL) {
00183                 error = errno;
00184                 ERR(diff, "%s", strerror(error));
00185                 errno = error;
00186                 return -1;
00187         }
00188 
00189         return 0;
00190 }

int bool_name_comp const void *  x,
const void *  y,
void *  arg
[static]
 

Comparison function for two bools from the same policy.

Definition at line 195 of file bool_diff.c.

References apol_policy_get_qpol(), apol_policy_t, qpol_bool_get_name(), qpol_bool_t, and qpol_policy_t.

Referenced by bool_get_items().

00196 {
00197         qpol_bool_t *c1 = (qpol_bool_t *) x;
00198         qpol_bool_t *c2 = (qpol_bool_t *) y;
00199         apol_policy_t *p = (apol_policy_t *) arg;
00200         qpol_policy_t *q = apol_policy_get_qpol(p);
00201         const char *name1, *name2;
00202         if (qpol_bool_get_name(q, c1, &name1) < 0 || qpol_bool_get_name(q, c2, &name2) < 0) {
00203                 return 0;
00204         }
00205         return strcmp(name1, name2);
00206 }

apol_vector_t* bool_get_items poldiff_t diff,
const apol_policy_t policy
 

Get a vector of all bools from the given policy, sorted by name.

Parameters:
diff Policy diff error handler.
policy The policy from which to get the items.
Returns:
a newly allocated vector of all bools. The caller is responsible for calling apol_vector_destroy() afterwards. On error, return NULL and set errno.

Definition at line 208 of file bool_diff.c.

References apol_policy_get_qpol(), apol_policy_t, apol_vector_create_from_iter(), apol_vector_sort(), apol_vector_t, bool_name_comp(), diff, ERR, poldiff_t, qpol_iterator_destroy(), qpol_iterator_t, qpol_policy_get_bool_iter(), and qpol_policy_t.

00209 {
00210         qpol_iterator_t *iter = NULL;
00211         apol_vector_t *v = NULL;
00212         qpol_policy_t *q = apol_policy_get_qpol(policy);
00213         int error = 0;
00214         if (qpol_policy_get_bool_iter(q, &iter) < 0) {
00215                 return NULL;
00216         }
00217         v = apol_vector_create_from_iter(iter, NULL);
00218         if (v == NULL) {
00219                 error = errno;
00220                 ERR(diff, "%s", strerror(error));
00221                 qpol_iterator_destroy(&iter);
00222                 errno = error;
00223                 return NULL;
00224         }
00225         qpol_iterator_destroy(&iter);
00226         apol_vector_sort(v, bool_name_comp, (void *)policy);
00227         return v;
00228 }

int bool_comp const void *  x,
const void *  y,
const poldiff_t diff
 

Compare two qpol_bool_t objects, determining if they have the same name or not.

Parameters:
x The bool from the original policy.
y The bool from the modified policy.
diff The policy difference structure associated with both policies.
Returns:
< 0, 0, or > 0 if bool x is respectively less than, equal to, or greater than bool y.

Definition at line 230 of file bool_diff.c.

References diff, poldiff::mod_qpol, poldiff::orig_qpol, poldiff_t, qpol_bool_get_name(), and qpol_bool_t.

00231 {
00232         qpol_bool_t *c1 = (qpol_bool_t *) x;
00233         qpol_bool_t *c2 = (qpol_bool_t *) y;
00234         const char *name1, *name2;
00235         if (qpol_bool_get_name(diff->orig_qpol, c1, &name1) < 0 || qpol_bool_get_name(diff->mod_qpol, c2, &name2) < 0) {
00236                 return 0;
00237         }
00238         return strcmp(name1, name2);
00239 }

poldiff_bool_t* make_diff const poldiff_t diff,
poldiff_form_e  form,
const char *  name
[static]
 

Allocate and return a new bool difference object.

Parameters:
diff Policy diff error handler.
form Form of the difference.
name Name of the bool that is different.
Returns:
A newly allocated and initialized diff, or NULL upon error. The caller is responsible for calling bool_free() upon the returned value.

Definition at line 252 of file bool_diff.c.

References bool_free(), diff, ERR, poldiff_user::form, poldiff_bool_t, and poldiff_t.

00253 {
00254         poldiff_bool_t *pb;
00255         int error;
00256         if ((pb = calloc(1, sizeof(*pb))) == NULL || (pb->name = strdup(name)) == NULL) {
00257                 error = errno;
00258                 bool_free(pb);
00259                 ERR(diff, "%s", strerror(error));
00260                 errno = error;
00261                 return NULL;
00262         }
00263         pb->form = form;
00264         return pb;
00265 }

int bool_new_diff poldiff_t diff,
poldiff_form_e  form,
const void *  item
 

Create, initialize, and insert a new semantic difference entry for a bool.

Parameters:
diff The policy difference structure to which to add the entry.
form The form of the difference.
item Item for which the entry is being created.
Returns:
0 on success and < 0 on error; if the call fails, set errno and leave the policy difference structure unchanged.

Definition at line 267 of file bool_diff.c.

References apol_vector_append(), poldiff::bool_diffs, bool_free(), diff, poldiff_bool_summary::diffs, ERR, make_diff(), poldiff::mod_qpol, poldiff_bool_summary::num_added, poldiff_bool_summary::num_removed, poldiff::orig_qpol, poldiff_bool_t, POLDIFF_FORM_ADDED, POLDIFF_FORM_REMOVED, poldiff_t, qpol_bool_get_name(), and qpol_bool_t.

00268 {
00269         qpol_bool_t *c = (qpol_bool_t *) item;
00270         const char *name = NULL;
00271         poldiff_bool_t *pb;
00272         int error;
00273         if ((form == POLDIFF_FORM_ADDED &&
00274              qpol_bool_get_name(diff->mod_qpol, c, &name) < 0) ||
00275             ((form == POLDIFF_FORM_REMOVED || form == POLDIFF_FORM_MODIFIED) && qpol_bool_get_name(diff->orig_qpol, c, &name) < 0))
00276         {
00277                 return -1;
00278         }
00279         pb = make_diff(diff, form, name);
00280         if (pb == NULL) {
00281                 return -1;
00282         }
00283         if (apol_vector_append(diff->bool_diffs->diffs, pb) < 0) {
00284                 error = errno;
00285                 ERR(diff, "%s", strerror(error));
00286                 bool_free(pb);
00287                 errno = error;
00288                 return -1;
00289         }
00290         if (form == POLDIFF_FORM_ADDED)
00291                 diff->bool_diffs->num_added++;
00292         else
00293                 diff->bool_diffs->num_removed++;
00294         return 0;
00295 }

int bool_deep_diff poldiff_t diff,
const void *  x,
const void *  y
 

Compute the semantic difference of two bools for which the compare callback returns 0.

If a difference is found then allocate, initialize, and insert an new semantic difference entry for that bool.

Parameters:
diff The policy difference structure associated with both bools and to which to add an entry if needed.
x The bool from the original policy.
y The bool from the modified policy.
Returns:
0 on success and < 0 on error; if the call fails, set errno and leave the policy difference structure unchanged.

Definition at line 297 of file bool_diff.c.

References apol_vector_append(), poldiff::bool_diffs, diff, poldiff_bool_summary::diffs, ERR, make_diff(), poldiff::mod_qpol, poldiff_bool_summary::num_modified, poldiff::orig_qpol, poldiff_bool_t, POLDIFF_FORM_MODIFIED, poldiff_t, qpol_bool_get_name(), qpol_bool_get_state(), qpol_bool_t, and poldiff_bool::state.

00298 {
00299         qpol_bool_t *b1 = (qpol_bool_t *) x;
00300         qpol_bool_t *b2 = (qpol_bool_t *) y;
00301         const char *name;
00302         int s1, s2;
00303         poldiff_bool_t *b = NULL;
00304         int retval = -1, error = 0;
00305 
00306         if (qpol_bool_get_name(diff->orig_qpol, b1, &name) < 0 ||
00307             qpol_bool_get_state(diff->orig_qpol, b1, &s1) < 0 || qpol_bool_get_state(diff->mod_qpol, b2, &s2) < 0) {
00308                 error = errno;
00309                 goto cleanup;
00310         }
00311         if (s1 != s2) {
00312                 if ((b = make_diff(diff, POLDIFF_FORM_MODIFIED, name)) == NULL) {
00313                         error = errno;
00314                         goto cleanup;
00315                 }
00316                 if (s2)
00317                         b->state = true;
00318                 else
00319                         b->state = false;
00320         }
00321         if (b != NULL) {
00322                 if (apol_vector_append(diff->bool_diffs->diffs, b) < 0) {
00323                         error = errno;
00324                         ERR(diff, "%s", strerror(error));
00325                         goto cleanup;
00326                 }
00327                 diff->bool_diffs->num_modified++;
00328         }
00329         retval = 0;
00330       cleanup:
00331         errno = error;
00332         return retval;
00333 }