diff options
author | Ashlee Young <ashlee@wildernessvoice.com> | 2015-11-29 08:22:13 -0800 |
---|---|---|
committer | Ashlee Young <ashlee@wildernessvoice.com> | 2015-11-29 08:22:13 -0800 |
commit | df5afa4fcd9725380f94ca6476248d4cc24f889a (patch) | |
tree | 65456f62397305febf7f40778c5a413a35d094ef /framework/src/audit/auparse/data_buf.c | |
parent | 76f6bf922552c00546e6e85ca471eab28f56986c (diff) |
v2.4.4 audit sources
Change-Id: I9315a7408817db51edf084fb4d27fbb492785084
Signed-off-by: Ashlee Young <ashlee@wildernessvoice.com>
Diffstat (limited to 'framework/src/audit/auparse/data_buf.c')
-rw-r--r-- | framework/src/audit/auparse/data_buf.c | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/framework/src/audit/auparse/data_buf.c b/framework/src/audit/auparse/data_buf.c new file mode 100644 index 00000000..43b5999e --- /dev/null +++ b/framework/src/audit/auparse/data_buf.c @@ -0,0 +1,394 @@ +/* data_buf.c -- + * Copyright 2007,2011 Red Hat Inc., Durham, North Carolina. + * All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * John Dennis <jdennis@redhat.com> + */ + +/* + * gcc -DTEST -g data_buf.c -o data_buf + * gcc -DTEST -g data_buf.c -o data_buf && valgrind --leak-check=yes ./data_buf + */ + +/*****************************************************************************/ +/******************************** Documentation ******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/******************************* Include Files *******************************/ +/*****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <stdarg.h> +#include <errno.h> +#include "data_buf.h" + +/*****************************************************************************/ +/****************************** Internal Defines *****************************/ +/*****************************************************************************/ + +#ifndef MIN +#define MIN(a,b) (((a)<=(b))?(a):(b)) +#endif + +#ifndef MAX +#define MAX(a,b) (((a)>=(b))?(a):(b)) +#endif + +//#define DEBUG 1 + +#ifdef DEBUG +#define DATABUF_VALIDATE(db) \ +{ \ + if (db->alloc_ptr == NULL || db->alloc_size == 0) { \ + assert(db->alloc_ptr == NULL); \ + assert(db->alloc_size == 0); \ + assert(db->len == 0); \ + } else { \ + assert(db->offset <= db->alloc_size); \ + assert(db->len <= db->alloc_size); \ + assert(db->offset+db->len <= db->alloc_size); \ + } \ +} +#else +#define DATABUF_VALIDATE(db) +#endif + +/*****************************************************************************/ +/************************** Internal Type Definitions ************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/********************** External Function Declarations *********************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/********************** Internal Function Declarations *********************/ +/*****************************************************************************/ + +static int databuf_shift_data_to_beginning(DataBuf *db); +static int databuf_strcat(DataBuf *db, const char *str); + +/*****************************************************************************/ +/************************* External Global Variables ***********************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/************************* Internal Global Variables ***********************/ +/*****************************************************************************/ + +#ifdef DEBUG +static int debug = 0; +#endif + +/*****************************************************************************/ +/**************************** Inline Functions *****************************/ +/*****************************************************************************/ +static inline char *databuf_end(DataBuf *db) +{return (db->alloc_ptr == NULL) ? NULL : db->alloc_ptr+db->offset+db->len;} + +static inline char *databuf_alloc_end(DataBuf *db) +{return (db->alloc_ptr == NULL) ? NULL : db->alloc_ptr+db->alloc_size;} + +static inline int databuf_tail_size(DataBuf *db) +{return db->alloc_size - (db->offset+db->len);} + +static inline int databuf_tail_available(DataBuf *db, size_t append_len) +{return append_len <= databuf_tail_size(db);} + +static inline size_t databuf_free_size(DataBuf *db) +{return db->alloc_size-db->len;} + +/*****************************************************************************/ +/*************************** Internal Functions ****************************/ +/*****************************************************************************/ + +static int databuf_shift_data_to_beginning(DataBuf *db) +{ + DATABUF_VALIDATE(db); + if (db->flags & DATABUF_FLAG_PRESERVE_HEAD) return -1; + if (databuf_beg(db) == NULL) return 1; + if (db->offset) { + memmove(db->alloc_ptr, databuf_beg(db), db->len); + db->offset = 0; + } + DATABUF_VALIDATE(db); + return 1; +} + +/*****************************************************************************/ +/**************************** Exported Functions ***************************/ +/*****************************************************************************/ + +void databuf_print(DataBuf *db, int print_data, char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (fmt) { + vprintf(fmt, ap); + } + printf("%salloc_size=%zu alloc_ptr=%p offset=%zu beg=%p len=%zu max_len=%zu flags=[", + fmt?" ":"", db->alloc_size, db->alloc_ptr, db->offset, databuf_beg(db), db->len, db->max_len); + + if (db->flags & DATABUF_FLAG_PRESERVE_HEAD) printf("PRESERVE_HEAD "); + if (db->flags & DATABUF_FLAG_STRING) printf("STRING "); + printf("]"); + + if (print_data) { + printf(" ["); + fwrite(databuf_beg(db), 1, db->len, stdout); + printf("]"); + } + printf("\n"); + va_end(ap); +} + +int databuf_init(DataBuf *db, size_t size, unsigned flags) +{ + db->alloc_ptr = NULL; + db->alloc_size = 0; + db->offset = 0; + db->len = 0; + db->max_len = 0; + db->flags = flags; + + if (size) { + if ((db->alloc_ptr = malloc(size))) { + db->alloc_size = size; + return 1; + } else { + return -1; + } + } + + // For strings intialize with initial NULL terminator + if (flags & DATABUF_FLAG_STRING) databuf_strcat(db, ""); + + return 1; +} + +void databuf_free(DataBuf *db) +{ + DATABUF_VALIDATE(db); + + if (db->alloc_ptr != NULL) { + free(db->alloc_ptr); + } + + db->alloc_ptr = NULL; + db->alloc_size = 0; + db->offset = 0; + db->len = 0; + db->max_len = 0; + + DATABUF_VALIDATE(db); +} + +int databuf_append(DataBuf *db, const char *src, size_t src_size) +{ + size_t new_size; + + DATABUF_VALIDATE(db); + + if (src == NULL || src_size == 0) return 0; + + new_size = db->len+src_size; + +#ifdef DEBUG + if (debug) databuf_print(db, 1, "databuf_append() size=%zd", src_size); +#endif + if ((new_size > db->alloc_size) || + ((db->flags & DATABUF_FLAG_PRESERVE_HEAD) && !databuf_tail_available(db, src_size))) { + /* not enough room, we must realloc */ + void *new_alloc; + + databuf_shift_data_to_beginning(db); + if ((new_alloc = realloc(db->alloc_ptr, new_size))) { + db->alloc_ptr = new_alloc; + db->alloc_size = new_size; + } else { + return -1; /* realloc failed */ + } + } else { + /* we can fit within current allocation, but can we append? */ + if (!databuf_tail_available(db, src_size)) { + /* we can't append in place, must create room at tail by shifting + data forward to the beginning of the allocation block */ + databuf_shift_data_to_beginning(db); + } + } +#ifdef DEBUG + if (debug) databuf_print(db, 1, "databuf_append() about to memmove()"); +#endif + /* pointers all set up and room availble, move the data and update */ + memmove(databuf_end(db), src, src_size); + db->len = new_size; + db->max_len = MAX(db->max_len, new_size); +#ifdef DEBUG + if (debug) databuf_print(db, 1, "databuf_append() conclusion"); +#endif + DATABUF_VALIDATE(db); + return 1; +} + +static int databuf_strcat(DataBuf *db, const char *str) +{ + size_t str_len; + + DATABUF_VALIDATE(db); + + if (str == NULL) return 0; + + // +1 so the data append also copies the NULL terminator + str_len = strlen(str) + 1; + + // If there is a NULL terminator exclude it so the subsequent + // data append produces a proper string concatenation + if (db->len > 0) { + char *last_char = databuf_end(db) - 1; + if (*last_char == 0) { + db->len--; // backup over NULL terminator + } + } + + // Copy string and NULL terminator + databuf_append(db, str, str_len); + + DATABUF_VALIDATE(db); + return 1; +} + +int databuf_advance(DataBuf *db, size_t advance) +{ + size_t actual_advance; + DATABUF_VALIDATE(db); + +#ifdef DEBUG + if (debug) databuf_print(db, 1, "databuf_advance() enter, advance=%zd", advance); +#endif + actual_advance = MIN(advance, db->len); + db->offset += actual_advance; + db->len -= actual_advance; + +#ifdef DEBUG + if (debug) databuf_print(db, 1, "databuf_advance() leave, actual_advance=%zd", actual_advance); +#endif + DATABUF_VALIDATE(db); + if (advance == actual_advance) { + return 1; + } else { + errno = ESPIPE; // Illegal seek + return -1; + } +} + +int databuf_reset(DataBuf *db) +{ +#ifdef DEBUG + if (debug) databuf_print(db, 1, "databuf_reset() entry"); +#endif + if (!(db->flags & DATABUF_FLAG_PRESERVE_HEAD)) return -1; + db->offset = 0; + db->len = MIN(db->alloc_size, db->max_len); +#ifdef DEBUG + if (debug) databuf_print(db, 1, "databuf_reset() exit"); +#endif + return 1; +} + +/*****************************************************************************/ +/******************************* Test Program ******************************/ +/*****************************************************************************/ + +#ifdef TEST +static char *make_data(size_t size, const char *fill) { + int n=0; + char *data = malloc(size); + + if (data == NULL) { + fprintf(stderr, "ERROR: make_data malloc failed\n"); + exit(1); + } + + n += snprintf(data, size, "%d", size); + while (n < size) { + n += snprintf(data+n, size-n, "%s", fill); + } + return data; +} + +int main(int argc, char **argv) +{ + size_t size = 0; + DataBuf buf; + char *data; + + assert(databuf_init(&buf, size, DATABUF_FLAG_STRING)); + databuf_print(&buf, 1, "after init size=%d", size); + +#if 1 + data = "a"; + assert(databuf_strcat(&buf, data)); + databuf_print(&buf, 1, "after strcat(%s)", data); + + data = "bb"; + assert(databuf_strcat(&buf, data)); + databuf_print(&buf, 1, "after strcat(%s)", data); + + data = "ccc"; + assert(databuf_strcat(&buf, data)); + databuf_print(&buf, 1, "after strcat(%s)", data); + +#endif + + databuf_free(&buf); + +#if 0 + assert(databuf_init(&buf, size, 0)); + databuf_print(&buf, 1, "after init size=%d", size); + + size = 8; + data = make_data(size, "a"); + assert(databuf_append(&buf, data, size)); + databuf_print(&buf, 1, "after append size=%d", size); + assert(databuf_append(&buf, data, size)); + free(data); + databuf_print(&buf, 1, "after append size=%d", size); + + assert(databuf_advance(&buf, 4)); + databuf_print(&buf, 1, "after databuf_advance(%d", 4); + + size = 5; + data = make_data(size, "b"); + assert(databuf_append(&buf, data, size)); + free(data); + databuf_print(&buf, 1, "after append size=%d", size); + size = 7; + data = make_data(size, "c"); + assert(databuf_append(&buf, data, size)); + free(data); + databuf_print(&buf, 1, "after append size=%d", size); + + databuf_free(&buf); +#endif + exit(0); +} +#endif |