util.c File Reference


Detailed Description

Implementation of utility functions.

Author:
Jeremy A. Mowery jmowery@tresys.com

Jason Tang jtang@tresys.com

Copyright (C) 2001-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 util.c.

#include <config.h>
#include <apol/util.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <qpol/nodecon_query.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

Go to the source code of this file.


Defines

#define APOL_LINE_SZ   8192
#define APOL_ENVIRON_VAR_NAME   "APOL_INSTALL_DIR"

Functions

const char * libapol_get_version (void)
 Return an immutable string describing this library's version.
int apol_str_to_internal_ip (const char *str, uint32_t ip[4])
 Given a string representing and IP value (mask or address, IPv4 or IPv6), write to an array that value in the same bit order that qpol uses.
const char * apol_objclass_to_str (uint32_t objclass)
 Given a genfscon object class, return a read-only string that describes that class.
uint32_t apol_str_to_objclass (const char *objclass)
 Given a string representing a genfscon object class, return its numeric identifier.
const char * apol_protocol_to_str (uint8_t protocol)
 Given a portcon protocol, return a read-only string that describes that protocol.
uint8_t apol_str_to_protocol (const char *protocol_str)
 Given the name of a portcon protocol, return its numeric value.
const char * apol_fs_use_behavior_to_str (uint32_t behavior)
 Given a fs_use behavior type, return a read-only string that describes that fs_use behavior.
int apol_str_to_fs_use_behavior (const char *behavior)
 Given a fs_use behavior string, return its numeric value.
const char * apol_rule_type_to_str (uint32_t rule_type)
 Given a rule type, return a read-only string that describes that rule.
const char * apol_cond_expr_type_to_str (uint32_t expr_type)
 Given a conditional expression type, return a read-only string that describes that operator.
char * apol_file_find (const char *file_name)
 Given a file name, search and return that file's path on the running system.
char * apol_file_find_path (const char *file_name)
 Given a file name, search and return that file's full path (directory + file name) on the running system.
char * apol_file_find_user_config (const char *file_name)
 Given a file name for a user configuration, search and return that file's path + file name in the user's home directory.
int apol_file_read_to_buffer (const char *fname, char **buf, size_t *len)
 Given a file name, read the file's contents into a newly allocated buffer.
char * apol_config_get_var (const char *var, FILE *fp)
 Given a file pointer into a config file, read and return the value for the given config var.
apol_vector_tapol_str_split (const char *s, const char *delim)
 Given a string of tokens, allocate and return a vector of strings initialized to those tokens.
char * apol_str_join (const apol_vector_t *list, const char *delim)
 Given a vector of strings, allocate and return a string that joins the vector using the given separator.
void trim_leading_whitespace (char *str)
 Given a string, if the string begins with whitespace then allocate a new string that does not contain those whitespaces.
void trim_trailing_whitespace (char *str)
 Given a mutable string, replace trailing whitespace characters with null characters.
void apol_str_trim (char *str)
 Given a mutable string, modify the string by removing both starting and trailing whitespace characters.
int apol_str_append (char **tgt, size_t *tgt_sz, const char *str)
 Append a string to an existing dynamic mutable string, expanding the target string if necessary.
int apol_str_appendf (char **tgt, size_t *tgt_sz, const char *fmt,...)
 Append a string to an existing dynamic mutable string, expanding the target string if necessary.
int apol_str_is_only_white_space (const char *str)
 Test whether a given string is only white space.
int apol_str_strcmp (const void *a, const void *b, void *unused __attribute__((unused)))
 Wrapper around strcmp for use in vector and BST comparison functions.
void * apol_str_strdup (const void *elem, void *unused __attribute__((unused)))
 Wrapper around strdup for use in vector and BST cloning functions.

Define Documentation

#define APOL_LINE_SZ   8192
 

Definition at line 46 of file util.c.

#define APOL_ENVIRON_VAR_NAME   "APOL_INSTALL_DIR"
 

Definition at line 47 of file util.c.

Referenced by apol_file_find(), and apol_file_find_path().


Function Documentation

const char* libapol_get_version void   ) 
 

Return an immutable string describing this library's version.

Returns:
String describing this library.

Definition at line 49 of file util.c.

00050 {
00051         return LIBAPOL_VERSION_STRING;
00052 }

int apol_str_to_internal_ip const char *  str,
uint32_t  ip[4]
 

Given a string representing and IP value (mask or address, IPv4 or IPv6), write to an array that value in the same bit order that qpol uses.

If the IP was in IPv4 format, only write to the first element and zero the remainder.

Parameters:
str A string representing and IP value, either in IPv4 or IPv6 format.
ip Array to which write converted value.
Returns:
QPOL_IPV4 if the string is in IPv4 format, QPOL_IPV6 if in IPv6, < 0 on error.

Definition at line 54 of file util.c.

References QPOL_IPV4.

Referenced by print_nodecon().

00055 {
00056         bool ipv4 = false;
00057         bool ipv6 = false;
00058 
00059         if (!str || !ip) {
00060                 errno = EINVAL;
00061                 return -1;
00062         }
00063 
00064         ip[0] = ip[1] = ip[2] = ip[3] = 0;
00065 
00066         if (strchr(str, '.'))
00067                 ipv4 = true;
00068 
00069         if (strchr(str, ':'))
00070                 ipv6 = true;
00071 
00072         if (ipv4 == ipv6) {
00073                 errno = EINVAL;
00074                 return -1;
00075         }
00076 
00077         if (ipv4) {
00078                 unsigned char *p = (unsigned char *)&(ip[0]);
00079                 int seg = 0;
00080                 uint32_t val = 0;      /* value of current segment of address */
00081                 size_t len = strlen(str), i;
00082                 for (i = 0; i <= len; i++) {
00083                         if (str[i] == '.' || str[i] == '\0') {
00084                                 if (val > 255) {
00085                                         errno = EINVAL;
00086                                         return -1;
00087                                 }
00088 
00089                                 p[seg] = (unsigned char)(0xff & val);
00090                                 seg++;
00091                                 val = 0;
00092                                 if (seg == 4)
00093                                         break;
00094                         } else if (isdigit(str[i])) {
00095                                 char tmp[2] = { str[i], 0 };
00096                                 val = val * 10 + atoi(tmp);
00097                         } else {
00098                                 errno = EINVAL;
00099                                 return -1;
00100                         }
00101                 }
00102         } else {
00103                 struct in6_addr addr;
00104                 if (inet_pton(AF_INET6, str, &addr) <= 0) {
00105                         return -1;
00106                 }
00107                 memcpy(ip, addr.s6_addr32, 16);
00108         }
00109 
00110         return ipv4 ? QPOL_IPV4 : QPOL_IPV6;
00111 }

const char* apol_objclass_to_str uint32_t  objclass  ) 
 

Given a genfscon object class, return a read-only string that describes that class.

Parameters:
objclass Object class, one of QPOL_CLASS_BLK_FILE, QPOL_CLASS_CHR_FILE, etc.
Returns:
A string that describes the object class, or NULL if the object class is invalid. Do not free() this string.
See also:
<qpol/genfscon_query.h> for a list of valid object classes.

Definition at line 113 of file util.c.

References QPOL_CLASS_ALL, QPOL_CLASS_BLK_FILE, QPOL_CLASS_CHR_FILE, QPOL_CLASS_DIR, QPOL_CLASS_FIFO_FILE, QPOL_CLASS_FILE, QPOL_CLASS_LNK_FILE, and QPOL_CLASS_SOCK_FILE.

00114 {
00115         switch (objclass) {
00116         case QPOL_CLASS_BLK_FILE:
00117                 return "block";
00118         case QPOL_CLASS_CHR_FILE:
00119                 return "char";
00120         case QPOL_CLASS_DIR:
00121                 return "dir";
00122         case QPOL_CLASS_FIFO_FILE:
00123                 return "fifo";
00124         case QPOL_CLASS_FILE:
00125                 return "file";
00126         case QPOL_CLASS_LNK_FILE:
00127                 return "link";
00128         case QPOL_CLASS_SOCK_FILE:
00129                 return "sock";
00130         case QPOL_CLASS_ALL:
00131                 return "any";
00132         }
00133         return NULL;
00134 }

uint32_t apol_str_to_objclass const char *  objclass  ) 
 

Given a string representing a genfscon object class, return its numeric identifier.

Valid strings may be obtained by calling apol_objclass_to_str().

Parameters:
objclass Object class, one of "any", "file", etc.
Returns:
Numeric identifier for object class, or 0 if unknown.
See also:
<qpol/genfscon_query.h> for a list of valid object classes.

Definition at line 136 of file util.c.

Referenced by sefs_query::objectClass().

00137 {
00138         if (objclass == NULL) {
00139                 errno = EINVAL;
00140                 return 0;
00141         }
00142         if (strcmp(objclass, "block") == 0) {
00143                 return QPOL_CLASS_BLK_FILE;
00144         }
00145         if (strcmp(objclass, "char") == 0) {
00146                 return QPOL_CLASS_CHR_FILE;
00147         }
00148         if (strcmp(objclass, "dir") == 0) {
00149                 return QPOL_CLASS_DIR;
00150         }
00151         if (strcmp(objclass, "fifo") == 0) {
00152                 return QPOL_CLASS_FIFO_FILE;
00153         }
00154         if (strcmp(objclass, "file") == 0) {
00155                 return QPOL_CLASS_FILE;
00156         }
00157         if (strcmp(objclass, "link") == 0) {
00158                 return QPOL_CLASS_LNK_FILE;
00159         }
00160         if (strcmp(objclass, "sock") == 0) {
00161                 return QPOL_CLASS_SOCK_FILE;
00162         }
00163         if (strcmp(objclass, "any") == 0) {
00164                 return QPOL_CLASS_ALL;
00165         }
00166         return 0;
00167 }

const char* apol_protocol_to_str uint8_t  protocol  ) 
 

Given a portcon protocol, return a read-only string that describes that protocol.

Parameters:
protocol Portcon protocol, one of IPPROTO_TCP or IPPROTO_UDP from netinet/in.h.
Returns:
A string that describes the protocol, or NULL if the protocol is invalid. Do not free() this string.

Definition at line 169 of file util.c.

Referenced by apol_portcon_render().

00170 {
00171         switch (protocol) {
00172         case IPPROTO_TCP:
00173                 return "tcp";
00174         case IPPROTO_UDP:
00175                 return "udp";
00176         default:
00177                 errno = EPROTONOSUPPORT;
00178                 return NULL;
00179         }
00180 }

uint8_t apol_str_to_protocol const char *  protocol_str  ) 
 

Given the name of a portcon protocol, return its numeric value.

Parameters:
protocol_str Portcon protocol, one of "tcp", "TCP", "udp", or "UDP".
Returns:
Numeric value for the protocol, one of IPPROTO_TCP or IPPROTO_UDP from netinet/in.h. Upon error return 0.

Definition at line 182 of file util.c.

00183 {
00184         if (protocol_str == NULL) {
00185                 errno = EINVAL;
00186                 return 0;
00187         }
00188         if (strcmp(protocol_str, "tcp") == 0 || strcmp(protocol_str, "TCP") == 0) {
00189                 return IPPROTO_TCP;
00190         }
00191         if (strcmp(protocol_str, "udp") == 0 || strcmp(protocol_str, "UDP") == 0) {
00192                 return IPPROTO_UDP;
00193         }
00194         errno = EPROTONOSUPPORT;
00195         return 0;
00196 }

const char* apol_fs_use_behavior_to_str uint32_t  behavior  ) 
 

Given a fs_use behavior type, return a read-only string that describes that fs_use behavior.

Parameters:
behavior A fs_use behavior, one of QPOL_FS_USE_PSID, QPOL_FS_USE_XATTR, etc.
Returns:
A string that describes the behavior, or NULL if the behavior is invalid. Do not free() this string.

Definition at line 198 of file util.c.

References QPOL_FS_USE_GENFS, QPOL_FS_USE_NONE, QPOL_FS_USE_PSID, QPOL_FS_USE_TASK, QPOL_FS_USE_TRANS, and QPOL_FS_USE_XATTR.

Referenced by apol_fs_use_render().

00199 {
00200         switch (behavior) {
00201         case QPOL_FS_USE_XATTR:
00202                 return "fs_use_xattr";
00203         case QPOL_FS_USE_TASK:
00204                 return "fs_use_task";
00205         case QPOL_FS_USE_TRANS:
00206                 return "fs_use_trans";
00207         case QPOL_FS_USE_GENFS:
00208                 return "fs_use_genfs";
00209         case QPOL_FS_USE_NONE:
00210                 return "fs_use_none";
00211         case QPOL_FS_USE_PSID:
00212                 return "fs_use_psid";
00213         }
00214         return NULL;
00215 }

int apol_str_to_fs_use_behavior const char *  behavior  ) 
 

Given a fs_use behavior string, return its numeric value.

Parameters:
behavior A fs_use behavior, one of "fs_use_psid", "fs_use_xattr", etc.
Returns:
A numeric representation for the behavior, one of QPOL_FS_USE_PSID, QPOL_FS_USE_XATTR, etc, or < 0 if the string is invalid.

Definition at line 217 of file util.c.

00218 {
00219         if (strcmp(behavior, "fs_use_xattr") == 0) {
00220                 return QPOL_FS_USE_XATTR;
00221         } else if (strcmp(behavior, "fs_use_task") == 0) {
00222                 return QPOL_FS_USE_TASK;
00223         } else if (strcmp(behavior, "fs_use_trans") == 0) {
00224                 return QPOL_FS_USE_TRANS;
00225         } else if (strcmp(behavior, "fs_use_genfs") == 0) {
00226                 return QPOL_FS_USE_GENFS;
00227         } else if (strcmp(behavior, "fs_use_none") == 0) {
00228                 return QPOL_FS_USE_NONE;
00229         } else if (strcmp(behavior, "fs_use_psid") == 0) {
00230                 return QPOL_FS_USE_PSID;
00231         }
00232         return -1;
00233 }

const char* apol_rule_type_to_str uint32_t  rule_type  ) 
 

Given a rule type, return a read-only string that describes that rule.

Parameters:
rule_type A policy rule type, one of QPOL_RULE_ALLOW, QPOL_RULE_TYPE_CHANGE, etc.
Returns:
A string that describes the rule, or NULL if the rule_type is invalid. Do not free() this string.

Definition at line 235 of file util.c.

References QPOL_RULE_ALLOW, QPOL_RULE_AUDITALLOW, QPOL_RULE_DONTAUDIT, QPOL_RULE_NEVERALLOW, QPOL_RULE_TYPE_CHANGE, QPOL_RULE_TYPE_MEMBER, and QPOL_RULE_TYPE_TRANS.

Referenced by apol_avrule_render(), apol_syn_avrule_render(), apol_syn_terule_render(), apol_terule_render(), avrule_to_string(), poldiff_avrule_cmp(), poldiff_avrule_to_string(), poldiff_terule_cmp(), poldiff_terule_to_string(), terule_bst_comp(), and terule_to_string().

00236 {
00237         switch (rule_type) {
00238         case QPOL_RULE_ALLOW:
00239                 return "allow";
00240         case QPOL_RULE_NEVERALLOW:
00241                 return "neverallow";
00242         case QPOL_RULE_AUDITALLOW:
00243                 return "auditallow";
00244         case QPOL_RULE_DONTAUDIT:
00245                 return "dontaudit";
00246         case QPOL_RULE_TYPE_TRANS:
00247                 return "type_transition";
00248         case QPOL_RULE_TYPE_CHANGE:
00249                 return "type_change";
00250         case QPOL_RULE_TYPE_MEMBER:
00251                 return "type_member";
00252         }
00253         return NULL;
00254 }

const char* apol_cond_expr_type_to_str uint32_t  expr_type  ) 
 

Given a conditional expression type, return a read-only string that describes that operator.

Parameters:
expr_type An expression type, one of QPOL_COND_EXPR_BOOL, QPOL_COND_EXPR_NOT, etc.
Returns:
A string that describes the expression, or NULL if the expr_type is invalid. Do not free() this string.

Definition at line 256 of file util.c.

References QPOL_COND_EXPR_AND, QPOL_COND_EXPR_BOOL, QPOL_COND_EXPR_EQ, QPOL_COND_EXPR_NEQ, QPOL_COND_EXPR_NOT, QPOL_COND_EXPR_OR, and QPOL_COND_EXPR_XOR.

Referenced by apol_cond_expr_render().

00257 {
00258         switch (expr_type) {
00259         case QPOL_COND_EXPR_BOOL:
00260                 return "";
00261         case QPOL_COND_EXPR_NOT:
00262                 return "!";
00263         case QPOL_COND_EXPR_OR:
00264                 return "||";
00265         case QPOL_COND_EXPR_AND:
00266                 return "&&";
00267         case QPOL_COND_EXPR_XOR:
00268                 return "^";
00269         case QPOL_COND_EXPR_EQ:
00270                 return "==";
00271         case QPOL_COND_EXPR_NEQ:
00272                 return "!=";
00273         }
00274         return NULL;
00275 }

char* apol_file_find const char *  file_name  ) 
 

Given a file name, search and return that file's path on the running system.

First search the present working directory, then the directory at APOL_INSTALL_DIR (an environment variable), then apol's install dir.

Parameters:
file_name File to find.
Returns:
File's path, or NULL if not found. Caller must free() this string afterwards.

Definition at line 277 of file util.c.

References APOL_ENVIRON_VAR_NAME.

Referenced by report_set_default_configuration(), report_set_default_stylesheet(), and sechk_lib_load_profile().

00278 {
00279         char *file = NULL, *var = NULL, *dirs[3];
00280         size_t i;
00281         int rt;
00282 
00283         if (file_name == NULL) {
00284                 errno = EINVAL;
00285                 return NULL;
00286         }
00287 
00288         /* check current directory, environment variable, and then
00289          * installed directory */
00290         dirs[0] = ".";
00291         dirs[1] = getenv(APOL_ENVIRON_VAR_NAME);
00292         dirs[2] = APOL_INSTALL_DIR;
00293         for (i = 0; i < 3; i++) {
00294                 if ((var = dirs[i]) != NULL) {
00295                         if (asprintf(&file, "%s/%s", var, file_name) < 0) {
00296                                 return NULL;
00297                         }
00298                         rt = access(file, R_OK);
00299                         free(file);
00300                         if (rt == 0) {
00301                                 return strdup(var);
00302                         }
00303                 }
00304         }
00305 
00306         /* didn't find it */
00307         return NULL;
00308 }

char* apol_file_find_path const char *  file_name  ) 
 

Given a file name, search and return that file's full path (directory + file name) on the running system.

First search the present working directory, then the directory at APOL_INSTALL_DIR (an environment variable), then apol's install dir.

Parameters:
file_name File to find.
Returns:
File's path + file name, or NULL if not found. Caller must free() this string afterwards.

Definition at line 310 of file util.c.

References APOL_ENVIRON_VAR_NAME.

Referenced by init_icons(), preferences_create(), toplevel_create(), and toplevel_on_help_activate().

00311 {
00312         char *file = NULL, *var = NULL, *dirs[3];
00313         size_t i;
00314         int rt;
00315 
00316         if (file_name == NULL) {
00317                 errno = EINVAL;
00318                 return NULL;
00319         }
00320 
00321         /* check current directory, environment variable, and then
00322          * installed directory */
00323         dirs[0] = ".";
00324         dirs[1] = getenv(APOL_ENVIRON_VAR_NAME);
00325         dirs[2] = APOL_INSTALL_DIR;
00326         for (i = 0; i < 3; i++) {
00327                 if ((var = dirs[i]) != NULL) {
00328                         if (asprintf(&file, "%s/%s", var, file_name) < 0) {
00329                                 return NULL;
00330                         }
00331                         rt = access(file, R_OK);
00332                         if (rt == 0) {
00333                                 return file;
00334                         }
00335                         free(file);
00336                 }
00337         }
00338 
00339         /* didn't find it */
00340         return NULL;
00341 }

char* apol_file_find_user_config const char *  file_name  ) 
 

Given a file name for a user configuration, search and return that file's path + file name in the user's home directory.

Parameters:
file_name File to find.
Returns:
File's path + file name, or NULL if not found. Caller must free() this string afterwards.

Definition at line 343 of file util.c.

Referenced by preferences_create().

00344 {
00345         char *file, *var;
00346         int rt;
00347 
00348         if (file_name == NULL) {
00349                 errno = EINVAL;
00350                 return NULL;
00351         }
00352         var = getenv("HOME");
00353         if (var) {
00354                 if (asprintf(&file, "%s/%s", var, file_name) < 0) {
00355                         return NULL;
00356                 }
00357                 rt = access(file, R_OK);
00358                 if (rt == 0) {
00359                         return file;
00360                 } else {
00361                         free(file);
00362                         return NULL;
00363                 }
00364         }
00365         return NULL;
00366 }

int apol_file_read_to_buffer const char *  fname,
char **  buf,
size_t *  len
 

Given a file name, read the file's contents into a newly allocated buffer.

The caller must free() this buffer afterwards.

Parameters:
fname Name of file to read.
buf Reference to a newly allocated buffer.
len Reference to the number of bytes read.
Returns:
0 on success, < 0 on error.

Definition at line 368 of file util.c.

Referenced by toplevel_on_help_activate().

00369 {
00370         FILE *file = NULL;
00371         const size_t BUF_SIZE = 1024;
00372         size_t size = 0, r;
00373         char *bufp, *b;
00374 
00375         assert(*buf == NULL);
00376         assert(len);
00377         *len = 0;
00378         while (1) {
00379                 size += BUF_SIZE;
00380                 r = 0;
00381                 b = (char *)realloc(*buf, size * sizeof(char));
00382                 if (b == NULL) {
00383                         free(*buf);
00384                         *buf = NULL;
00385                         *len = 0;
00386                         if (file)
00387                                 fclose(file);
00388                         return -1;
00389                 }
00390                 *buf = b;
00391                 if (!file) {
00392                         file = fopen(fname, "rb");
00393                         if (!file) {
00394                                 free(*buf);
00395                                 *buf = NULL;
00396                                 *len = 0;
00397                                 return -1;
00398                         }
00399                 }
00400                 bufp = &((*buf)[size - BUF_SIZE]);
00401                 r = fread(bufp, sizeof(char), BUF_SIZE, file);
00402                 *len += r;
00403                 if (r < BUF_SIZE) {
00404                         if (feof(file)) {
00405                                 fclose(file);
00406                                 break;
00407                         } else {
00408                                 free(*buf);
00409                                 *buf = NULL;
00410                                 *len = 0;
00411                                 fclose(file);
00412                                 return -1;
00413                         }
00414                 }
00415         }
00416         return 0;
00417 }

char* apol_config_get_var const char *  var,
FILE *  fp
 

Given a file pointer into a config file, read and return the value for the given config var.

The caller must free() the returned string afterwards.

Parameters:
var Name of configuration variable to obtain.
fp An open file pointer into a configuration file. This function will not maintain the pointer's current location.
Returns:
A newly allocated string containing the variable's value, or NULL if not found or error.

Definition at line 419 of file util.c.

References APOL_LINE_SZ, and apol_str_trim().

Referenced by preferences_create(), and preferences_parse_new_recent_files().

00420 {
00421         char line[APOL_LINE_SZ], t1[APOL_LINE_SZ], t2[APOL_LINE_SZ];
00422         char *line_ptr = NULL;
00423 
00424         if (var == NULL || fp == NULL) {
00425                 errno = EINVAL;
00426                 return NULL;
00427         }
00428 
00429         rewind(fp);
00430         while (fgets(line, APOL_LINE_SZ, fp) != NULL) {
00431                 if ((line_ptr = strdup(line)) == NULL) {
00432                         return NULL;
00433                 }
00434                 apol_str_trim(line_ptr);
00435                 if (line_ptr[0] == '#' || sscanf(line_ptr, "%s %[^\n]", t1, t2) != 2 || strcasecmp(var, t1) != 0) {
00436                         free(line_ptr);
00437                         continue;
00438                 } else {
00439                         free(line_ptr);
00440                         return strdup(t2);
00441                 }
00442         }
00443         return NULL;
00444 }

apol_vector_t* apol_str_split const char *  s,
const char *  delim
 

Given a string of tokens, allocate and return a vector of strings initialized to those tokens.

Parameters:
s String to split.
delim Delimiter for tokens, as per strsep(3).
Returns:
A newly allocated vector of strings containing the variable's values, or NULL if not found or error. Note that the vector could be empty if the config var does not exist or has an empty value. The caller must call apol_vector_destroy() afterwards.

Definition at line 446 of file util.c.

References apol_str_is_only_white_space(), apol_vector_append(), apol_vector_create(), apol_vector_destroy(), and apol_vector_t.

Referenced by apol_policy_path_create_from_file(), apol_policy_path_create_from_string(), filters_simple(), preferences_create(), preferences_parse_old_recent_files(), and remap_types_on_add_click().

00447 {
00448         char *orig_s = NULL, *dup_s = NULL, *v, *token;
00449         apol_vector_t *list = NULL;
00450         int error = 0;
00451 
00452         if (s == NULL || delim == NULL) {
00453                 error = EINVAL;
00454                 goto cleanup;
00455         }
00456         if ((list = apol_vector_create(free)) == NULL || (orig_s = strdup(s)) == NULL) {
00457                 error = errno;
00458                 goto cleanup;
00459         }
00460         v = orig_s;
00461         while ((token = strsep(&v, delim)) != NULL) {
00462                 if (strcmp(token, "") != 0 && !apol_str_is_only_white_space(token)) {
00463                         if ((dup_s = strdup(token)) == NULL || apol_vector_append(list, dup_s) < 0) {
00464                                 error = errno;
00465                                 free(dup_s);
00466                                 goto cleanup;
00467                         }
00468                 }
00469         }
00470       cleanup:
00471         free(orig_s);
00472         if (error != 0) {
00473                 apol_vector_destroy(&list);
00474                 errno = error;
00475                 return NULL;
00476         }
00477         return list;
00478 }

char* apol_str_join const apol_vector_t list,
const char *  delim
 

Given a vector of strings, allocate and return a string that joins the vector using the given separator.

The caller is responsible for free()ing the string afterwards.

Parameters:
list Vector of strings to join.
delim Delimiter character(s) for the concatenated string.
Returns:
An allocated concatenated string, or NULL upon error. If the list is empty then return an empty string. The caller is responsible for calling free() upon the return value.

Definition at line 480 of file util.c.

References apol_str_appendf(), apol_vector_get_element(), apol_vector_get_size(), and apol_vector_t.

Referenced by preferences_write_to_conf_file(), remap_types_update_view(), toplevel_set_recent_policies_submenu(), and util_policy_path_to_full_string().

00481 {
00482         char *val, *s;
00483         size_t i, len;
00484 
00485         if (list == NULL || delim == NULL) {
00486                 errno = EINVAL;
00487                 return NULL;
00488         }
00489         if (apol_vector_get_size(list) == 0) {
00490                 return strdup("");
00491         }
00492         s = apol_vector_get_element(list, 0);
00493         if ((val = strdup(s)) == NULL) {
00494                 return NULL;
00495         }
00496         len = strlen(val) + 1;
00497         for (i = 1; i < apol_vector_get_size(list); i++) {
00498                 s = apol_vector_get_element(list, i);
00499                 if (apol_str_appendf(&val, &len, "%s%s", delim, s) < 0) {
00500                         return NULL;
00501                 }
00502         }
00503         return val;
00504 }

void trim_leading_whitespace char *  str  )  [static]
 

Given a string, if the string begins with whitespace then allocate a new string that does not contain those whitespaces.

Parameters:
str String to modify.

Definition at line 512 of file util.c.

Referenced by apol_str_trim().

00513 {
00514         size_t i, len;
00515         for (i = 0; str[i] != '\0' && isspace(str[i]); i++) ;
00516         len = strlen(str + i);
00517         memmove(str, str + i, len + 1);
00518 }

void trim_trailing_whitespace char *  str  )  [static]
 

Given a mutable string, replace trailing whitespace characters with null characters.

Parameters:
str String to modify.

Definition at line 526 of file util.c.

Referenced by apol_str_trim().

00527 {
00528         size_t length;
00529         length = strlen(str);
00530         while (length > 0 && isspace(str[length - 1])) {
00531                 str[length - 1] = '\0';
00532                 length--;
00533         }
00534 }

void apol_str_trim char *  str  ) 
 

Given a mutable string, modify the string by removing both starting and trailing whitespace characters.

Parameters:
str String to modify.

Definition at line 536 of file util.c.

References trim_leading_whitespace(), and trim_trailing_whitespace().

Referenced by apol_config_get_var(), apol_file_is_policy_path_list(), apol_mls_level_create_from_literal(), apol_policy_path_create_from_file(), build_nomls_vecs(), compare_str(), filter_view_on_entry_focus_out(), level_to_string(), modified_mls_range_to_string(), sefs_fcfile::parse_line(), parse_permmap(), parse_permmap_class(), report_import_html_stylesheet(), seaudit_log_parse(), seaudit_log_parse_buffer(), and vector_to_string().

00537 {
00538         if (str == NULL) {
00539                 errno = EINVAL;
00540                 return;
00541         }
00542         trim_leading_whitespace(str);
00543         trim_trailing_whitespace(str);
00544 }

int apol_str_append char **  tgt,
size_t *  tgt_sz,
const char *  str
 

Append a string to an existing dynamic mutable string, expanding the target string if necessary.

The caller must free() the target string. If tgt is NULL then initially allocate the resulting string.

Parameters:
tgt Reference to a string to modify, or NULL to create a new string.
tgt_sz Pointer to number of bytes currently allocated to tgt. This will be updated with the new string size. If *tgt is NULL then this existing value is ignored. (It will still be updated afterwards).
str String to append.
Returns:
0 on success. On error, return < 0 and set errno; tgt will be free()d and set to NULL, tgt_sz will be set to 0.

Definition at line 546 of file util.c.

Referenced by apol_avrule_render(), apol_cond_expr_render(), apol_context_render(), apol_mls_level_render(), apol_mls_range_render(), apol_range_trans_render(), apol_syn_avrule_render(), apol_syn_terule_render(), apol_terule_render(), avc_message_to_string(), avc_message_to_string_html(), bool_message_to_string(), build_dtd_path(), components_types_tests(), find_assoc_types_run(), find_netif_types_run(), find_node_types_run(), find_port_types_run(), generate_common_only_proof_text(), generate_tcp_proof_text(), generate_udp_recv_proof_text(), generate_udp_send_proof_text(), poldiff_attrib_to_string(), poldiff_avrule_to_string(), poldiff_class_to_string(), poldiff_common_to_string(), poldiff_level_to_string(), poldiff_level_to_string_brief(), poldiff_range_to_string_brief(), poldiff_role_allow_to_string(), poldiff_role_to_string(), poldiff_terule_to_string(), poldiff_type_to_string(), sefs_db::runQueryMap(), spurious_audit_run(), type_get_name(), and user_to_modified_string().

00547 {
00548         size_t str_len;
00549         if (str == NULL || (str_len = strlen(str)) == 0)
00550                 return 0;
00551         if (tgt == NULL) {
00552                 errno = EINVAL;
00553                 return -1;
00554         }
00555         str_len++;
00556         /* target is currently empty */
00557         if (*tgt == NULL || *tgt_sz == 0) {
00558                 *tgt = (char *)malloc(str_len);
00559                 if (*tgt == NULL) {
00560                         *tgt_sz = 0;
00561                         return -1;
00562                 }
00563                 *tgt_sz = str_len;
00564                 strcpy(*tgt, str);
00565                 return 0;
00566         } else {
00567                 /* tgt has some memory */
00568                 char *t = (char *)realloc(*tgt, *tgt_sz + str_len);
00569                 if (t == NULL) {
00570                         int error = errno;
00571                         free(*tgt);
00572                         *tgt = NULL;
00573                         *tgt_sz = 0;
00574                         errno = error;
00575                         return -1;
00576                 }
00577                 *tgt = t;
00578                 *tgt_sz += str_len;
00579                 strcat(*tgt, str);
00580                 return 0;
00581         }
00582 }

int apol_str_appendf char **  tgt,
size_t *  tgt_sz,
const char *  fmt,
  ...
 

Append a string to an existing dynamic mutable string, expanding the target string if necessary.

The string to append is computed using the format string, as per printf(3). The caller must free() the target string. If tgt is NULL then initially allocate the resulting string.

Parameters:
tgt Reference to a string to modify, or NULL to create a new string.
tgt_sz Pointer to number of bytes currently allocated to tgt. This will be updated with the new string size. If *tgt is NULL then the existing value is ignored. (It will still be updated afterwards).
fmt Format for the string with which append, as per printf(3).
Returns:
0 on success. On error, return < 0 and set errno; tgt will be free()d and set to NULL, tgt_sz will be set to 0.

Definition at line 584 of file util.c.

References fmt.

Referenced by apol_context_render(), apol_mls_level_render(), apol_mls_range_render(), apol_policy_path_to_string(), apol_str_join(), avc_message_get_misc_string(), avc_message_to_misc_string(), avc_message_to_string(), avc_message_to_string_html(), avrule_to_string(), bool_message_to_misc_string(), bool_message_to_string(), bool_message_to_string_html(), build_component_vecs(), build_nomls_vecs(), components_types_tests(), fclist_sefs_node_make_string(), get_rule_modification_str(), level_to_string(), message_view_store_get_value(), mls_user_to_string(), modified_mls_range_to_string(), poldiff_attrib_to_string(), poldiff_avrule_to_string(), poldiff_bool_to_string(), poldiff_cat_to_string(), poldiff_class_to_string(), poldiff_common_to_string(), poldiff_level_to_string(), poldiff_level_to_string_brief(), poldiff_range_to_string_brief(), poldiff_range_trans_to_string(), poldiff_role_allow_to_string(), poldiff_role_to_string(), poldiff_terule_to_string(), poldiff_type_to_string(), poldiff_user_to_string(), rangetrans_to_string(), replace_entry(), roleallow_to_string(), roletrans_to_string(), sefs_db::runQueryMap(), terule_to_string(), type_get_name(), user_to_modified_string(), util_policy_path_to_full_string(), and vector_to_string().

00585 {
00586         va_list ap;
00587         int error;
00588         if (fmt == NULL || strlen(fmt) == 0)
00589                 return 0;
00590         if (tgt == NULL) {
00591                 errno = EINVAL;
00592                 return -1;
00593         }
00594         va_start(ap, fmt);
00595         /* target is currently empty */
00596         if (*tgt == NULL || *tgt_sz == 0) {
00597                 if (vasprintf(tgt, fmt, ap) < 0) {
00598                         error = errno;
00599                         *tgt = NULL;
00600                         *tgt_sz = 0;
00601                         va_end(ap);
00602                         errno = error;
00603                         return -1;
00604                 }
00605                 *tgt_sz = strlen(*tgt) + 1;
00606                 va_end(ap);
00607                 return 0;
00608         } else {
00609                 /* tgt has some memory */
00610                 char *t, *u;
00611                 size_t str_len;
00612                 if (vasprintf(&t, fmt, ap) < 0) {
00613                         error = errno;
00614                         free(*tgt);
00615                         *tgt_sz = 0;
00616                         va_end(ap);
00617                         errno = error;
00618                         return -1;
00619                 }
00620                 va_end(ap);
00621                 str_len = strlen(t);
00622                 if ((u = (char *)realloc(*tgt, *tgt_sz + str_len)) == NULL) {
00623                         error = errno;
00624                         free(t);
00625                         free(*tgt);
00626                         *tgt_sz = 0;
00627                         errno = error;
00628                         return -1;
00629                 }
00630                 *tgt = u;
00631                 *tgt_sz += str_len;
00632                 strcat(*tgt, t);
00633                 free(t);
00634                 return 0;
00635         }
00636 }

int apol_str_is_only_white_space const char *  str  ) 
 

Test whether a given string is only white space.

Parameters:
str String to test.
Returns:
1 if string is either NULL or only whitespace, 0 otherwise.

Definition at line 638 of file util.c.

Referenced by apol_str_split(), get_tokens(), parse_permmap_class(), and report_import_html_stylesheet().

00639 {
00640         size_t len, i;
00641         if (str == NULL)
00642                 return 0;
00643         len = strlen(str);
00644         for (i = 0; i < len; i++) {
00645                 if (!isspace(str[i]))
00646                         return 0;
00647         }
00648         return 1;
00649 }

int apol_str_strcmp const void *  a,
const void *  b,
void *unused   __attribute__((unused))
 

Wrapper around strcmp for use in vector and BST comparison functions.

Parameters:
a String to compare.
b The other string to compare.
unused Not used. (exists to match expected function signature)
Returns:
Less than, equal to, or greater than 0 if string a is found to be less than, identical to, or greater than string b respectively.

Definition at line 651 of file util.c.

Referenced by apol_avrule_list_to_syn_avrules(), apol_avrule_to_syn_avrules(), apol_infoflow_graph_check_class_perms(), apol_mls_level_append_cats(), apol_obj_perm_append_perm(), apol_perm_get_by_query(), apol_policy_path_compare(), apol_policy_path_create(), apol_policy_path_create_from_string(), attrib_deep_diff(), avrule_deep_diff(), avrule_new_diff(), class_deep_diff(), common_deep_diff(), components_types_tests(), db_type_compare(), filter_src_role_accept(), filter_src_type_accept(), filter_src_user_accept(), filter_tgt_class_accept(), filter_tgt_role_accept(), filter_tgt_type_accept(), filter_tgt_user_accept(), filter_view_get_policy_classes(), filter_view_get_policy_roles(), filter_view_get_policy_types(), filter_view_get_policy_users(), in_def_ctx(), sefs_filesystem::isQueryMatch(), level_deep_diff(), poldiff_build_bsts(), poldiff_type_remap_create(), policy_components_view_init_lists(), policy_components_view_on_to_exc_click(), policy_components_view_on_to_inc_click(), policy_view_find_terules(), policy_view_populate_combo_boxes(), prefs_add_recent_vector(), remap_types_highlight_entries(), remap_types_on_add_click(), remap_types_update_view(), report_print_enforce_toggles(), role_allow_deep_diff(), role_allow_get_items(), role_deep_diff(), sefs_fcfile::runQueryMap(), seaudit_log_clear(), seaudit_log_create(), sefs_fclist::sefs_fclist(), shallow_copy_str_vec_and_sort(), sort_perm_comp(), spurious_audit_run(), type_deep_diff(), type_get_attrib_names(), type_map_prim_aliases_comp(), and user_deep_diff_roles().

00652 {
00653         return strcmp((const char *)a, (const char *)b);
00654 }

void* apol_str_strdup const void *  elem,
void *unused   __attribute__((unused))
 

Wrapper around strdup for use in vector and BST cloning functions.

Parameters:
elem String to duplicate.
unused Not used. (exists to match expected function signature)
Returns:
A new string that is a duplicate of elem, or NULL upon error.

Definition at line 656 of file util.c.

Referenced by apol_mls_level_create_from_mls_level(), apol_mls_level_render(), apol_policy_path_create(), filter_set_vector(), filter_view_init_context(), level_create_from_apol_mls_level(), level_deep_diff(), level_deep_diff_apol_mls_levels(), level_new_diff(), policy_components_view_run(), range_create(), seaudit_filter_create_from_filter(), and user_new_diff().

00657 {
00658         return strdup((const char *)elem);
00659 }