summaryrefslogtreecommitdiff
path: root/src/openvpn/buffer.c
diff options
context:
space:
mode:
authorAlberto Gonzalez Iniesta <agi@inittab.org>2016-12-27 18:25:47 +0100
committerAlberto Gonzalez Iniesta <agi@inittab.org>2016-12-27 18:25:47 +0100
commit3a2bbdb05ca6a6996e424c9fb225cb0d53804125 (patch)
treef29063da5bec4caf3853d49a22a09c8619eebd21 /src/openvpn/buffer.c
parentd53dba59e78da865c4fe820386ff2f4f76925f3b (diff)
New upstream version 2.4.0upstream/2.4.0
Diffstat (limited to 'src/openvpn/buffer.c')
-rw-r--r--src/openvpn/buffer.c1451
1 files changed, 806 insertions, 645 deletions
diff --git a/src/openvpn/buffer.c b/src/openvpn/buffer.c
index 6af8dbb..2defd18 100644
--- a/src/openvpn/buffer.c
+++ b/src/openvpn/buffer.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -39,216 +39,230 @@
#include "memdbg.h"
size_t
-array_mult_safe (const size_t m1, const size_t m2, const size_t extra)
+array_mult_safe(const size_t m1, const size_t m2, const size_t extra)
{
- const size_t limit = 0xFFFFFFFF;
- unsigned long long res = (unsigned long long)m1 * (unsigned long long)m2 + (unsigned long long)extra;
- if (unlikely(m1 > limit) || unlikely(m2 > limit) || unlikely(extra > limit) || unlikely(res > (unsigned long long)limit))
- msg (M_FATAL, "attemped allocation of excessively large array");
- return (size_t) res;
+ const size_t limit = 0xFFFFFFFF;
+ unsigned long long res = (unsigned long long)m1 * (unsigned long long)m2 + (unsigned long long)extra;
+ if (unlikely(m1 > limit) || unlikely(m2 > limit) || unlikely(extra > limit) || unlikely(res > (unsigned long long)limit))
+ {
+ msg(M_FATAL, "attemped allocation of excessively large array");
+ }
+ return (size_t) res;
}
void
-buf_size_error (const size_t size)
+buf_size_error(const size_t size)
{
- msg (M_FATAL, "fatal buffer size error, size=%lu", (unsigned long)size);
+ msg(M_FATAL, "fatal buffer size error, size=%lu", (unsigned long)size);
}
struct buffer
#ifdef DMALLOC
-alloc_buf_debug (size_t size, const char *file, int line)
+alloc_buf_debug(size_t size, const char *file, int line)
#else
-alloc_buf (size_t size)
+alloc_buf(size_t size)
#endif
{
- struct buffer buf;
+ struct buffer buf;
- if (!buf_size_valid (size))
- buf_size_error (size);
- buf.capacity = (int)size;
- buf.offset = 0;
- buf.len = 0;
+ if (!buf_size_valid(size))
+ {
+ buf_size_error(size);
+ }
+ buf.capacity = (int)size;
+ buf.offset = 0;
+ buf.len = 0;
#ifdef DMALLOC
- buf.data = openvpn_dmalloc (file, line, size);
+ buf.data = openvpn_dmalloc(file, line, size);
#else
- buf.data = calloc (1, size);
+ buf.data = calloc(1, size);
#endif
- check_malloc_return(buf.data);
+ check_malloc_return(buf.data);
- return buf;
+ return buf;
}
struct buffer
#ifdef DMALLOC
-alloc_buf_gc_debug (size_t size, struct gc_arena *gc, const char *file, int line)
+alloc_buf_gc_debug(size_t size, struct gc_arena *gc, const char *file, int line)
#else
-alloc_buf_gc (size_t size, struct gc_arena *gc)
+alloc_buf_gc(size_t size, struct gc_arena *gc)
#endif
{
- struct buffer buf;
- if (!buf_size_valid (size))
- buf_size_error (size);
- buf.capacity = (int)size;
- buf.offset = 0;
- buf.len = 0;
+ struct buffer buf;
+ if (!buf_size_valid(size))
+ {
+ buf_size_error(size);
+ }
+ buf.capacity = (int)size;
+ buf.offset = 0;
+ buf.len = 0;
#ifdef DMALLOC
- buf.data = (uint8_t *) gc_malloc_debug (size, false, gc, file, line);
+ buf.data = (uint8_t *) gc_malloc_debug(size, false, gc, file, line);
#else
- buf.data = (uint8_t *) gc_malloc (size, false, gc);
+ buf.data = (uint8_t *) gc_malloc(size, false, gc);
#endif
- if (size)
- *buf.data = 0;
- return buf;
+ if (size)
+ {
+ *buf.data = 0;
+ }
+ return buf;
}
struct buffer
#ifdef DMALLOC
-clone_buf_debug (const struct buffer* buf, const char *file, int line)
+clone_buf_debug(const struct buffer *buf, const char *file, int line)
#else
-clone_buf (const struct buffer* buf)
+clone_buf(const struct buffer *buf)
#endif
{
- struct buffer ret;
- ret.capacity = buf->capacity;
- ret.offset = buf->offset;
- ret.len = buf->len;
+ struct buffer ret;
+ ret.capacity = buf->capacity;
+ ret.offset = buf->offset;
+ ret.len = buf->len;
#ifdef DMALLOC
- ret.data = (uint8_t *) openvpn_dmalloc (file, line, buf->capacity);
+ ret.data = (uint8_t *) openvpn_dmalloc(file, line, buf->capacity);
#else
- ret.data = (uint8_t *) malloc (buf->capacity);
+ ret.data = (uint8_t *) malloc(buf->capacity);
#endif
- check_malloc_return (ret.data);
- memcpy (BPTR (&ret), BPTR (buf), BLEN (buf));
- return ret;
+ check_malloc_return(ret.data);
+ memcpy(BPTR(&ret), BPTR(buf), BLEN(buf));
+ return ret;
}
#ifdef BUF_INIT_TRACKING
bool
-buf_init_debug (struct buffer *buf, int offset, const char *file, int line)
+buf_init_debug(struct buffer *buf, int offset, const char *file, int line)
{
- buf->debug_file = file;
- buf->debug_line = line;
- return buf_init_dowork (buf, offset);
+ buf->debug_file = file;
+ buf->debug_line = line;
+ return buf_init_dowork(buf, offset);
}
static inline int
-buf_debug_line (const struct buffer *buf)
+buf_debug_line(const struct buffer *buf)
{
- return buf->debug_line;
+ return buf->debug_line;
}
static const char *
-buf_debug_file (const struct buffer *buf)
+buf_debug_file(const struct buffer *buf)
{
- return buf->debug_file;
+ return buf->debug_file;
}
-#else
+#else /* ifdef BUF_INIT_TRACKING */
#define buf_debug_line(buf) 0
#define buf_debug_file(buf) "[UNDEF]"
-#endif
+#endif /* ifdef BUF_INIT_TRACKING */
void
-buf_clear (struct buffer *buf)
+buf_clear(struct buffer *buf)
{
- if (buf->capacity > 0)
+ if (buf->capacity > 0)
{
- secure_memzero (buf->data, buf->capacity);
+ secure_memzero(buf->data, buf->capacity);
}
- buf->len = 0;
- buf->offset = 0;
+ buf->len = 0;
+ buf->offset = 0;
}
bool
-buf_assign (struct buffer *dest, const struct buffer *src)
+buf_assign(struct buffer *dest, const struct buffer *src)
{
- if (!buf_init (dest, src->offset))
- return false;
- return buf_write (dest, BPTR (src), BLEN (src));
+ if (!buf_init(dest, src->offset))
+ {
+ return false;
+ }
+ return buf_write(dest, BPTR(src), BLEN(src));
}
struct buffer
-clear_buf ()
+clear_buf()
{
- struct buffer buf;
- CLEAR (buf);
- return buf;
+ struct buffer buf;
+ CLEAR(buf);
+ return buf;
}
void
-free_buf (struct buffer *buf)
+free_buf(struct buffer *buf)
{
- if (buf->data)
- free (buf->data);
- CLEAR (*buf);
+ if (buf->data)
+ {
+ free(buf->data);
+ }
+ CLEAR(*buf);
}
/*
* Return a buffer for write that is a subset of another buffer
*/
struct buffer
-buf_sub (struct buffer *buf, int size, bool prepend)
+buf_sub(struct buffer *buf, int size, bool prepend)
{
- struct buffer ret;
- uint8_t *data;
+ struct buffer ret;
+ uint8_t *data;
- CLEAR (ret);
- data = prepend ? buf_prepend (buf, size) : buf_write_alloc (buf, size);
- if (data)
+ CLEAR(ret);
+ data = prepend ? buf_prepend(buf, size) : buf_write_alloc(buf, size);
+ if (data)
{
- ret.capacity = size;
- ret.data = data;
+ ret.capacity = size;
+ ret.data = data;
}
- return ret;
+ return ret;
}
/*
* printf append to a buffer with overflow check
*/
bool
-buf_printf (struct buffer *buf, const char *format, ...)
+buf_printf(struct buffer *buf, const char *format, ...)
{
- int ret = false;
- if (buf_defined (buf))
- {
- va_list arglist;
- uint8_t *ptr = BEND (buf);
- int cap = buf_forward_capacity (buf);
-
- if (cap > 0)
- {
- int stat;
- va_start (arglist, format);
- stat = vsnprintf ((char *)ptr, cap, format, arglist);
- va_end (arglist);
- *(buf->data + buf->capacity - 1) = 0; /* windows vsnprintf needs this */
- buf->len += (int) strlen ((char *)ptr);
- if (stat >= 0 && stat < cap)
- ret = true;
- }
- }
- return ret;
+ int ret = false;
+ if (buf_defined(buf))
+ {
+ va_list arglist;
+ uint8_t *ptr = BEND(buf);
+ int cap = buf_forward_capacity(buf);
+
+ if (cap > 0)
+ {
+ int stat;
+ va_start(arglist, format);
+ stat = vsnprintf((char *)ptr, cap, format, arglist);
+ va_end(arglist);
+ *(buf->data + buf->capacity - 1) = 0; /* windows vsnprintf needs this */
+ buf->len += (int) strlen((char *)ptr);
+ if (stat >= 0 && stat < cap)
+ {
+ ret = true;
+ }
+ }
+ }
+ return ret;
}
bool
buf_puts(struct buffer *buf, const char *str)
{
- int ret = false;
- uint8_t *ptr = BEND (buf);
- int cap = buf_forward_capacity (buf);
- if (cap > 0)
+ int ret = false;
+ uint8_t *ptr = BEND(buf);
+ int cap = buf_forward_capacity(buf);
+ if (cap > 0)
{
- strncpynt ((char *)ptr,str, cap);
- *(buf->data + buf->capacity - 1) = 0; /* windows vsnprintf needs this */
- buf->len += (int) strlen ((char *)ptr);
- ret = true;
+ strncpynt((char *)ptr,str, cap);
+ *(buf->data + buf->capacity - 1) = 0; /* windows vsnprintf needs this */
+ buf->len += (int) strlen((char *)ptr);
+ ret = true;
}
- return ret;
+ return ret;
}
-
+
/*
* This is necessary due to certain buggy implementations of snprintf,
@@ -260,18 +274,19 @@ buf_puts(struct buffer *buf, const char *str)
* Any modifications here should be done to the other place as well.
*/
-bool openvpn_snprintf(char *str, size_t size, const char *format, ...)
+bool
+openvpn_snprintf(char *str, size_t size, const char *format, ...)
{
- va_list arglist;
- int len = -1;
- if (size > 0)
+ va_list arglist;
+ int len = -1;
+ if (size > 0)
{
- va_start (arglist, format);
- len = vsnprintf (str, size, format, arglist);
- va_end (arglist);
- str[size - 1] = 0;
+ va_start(arglist, format);
+ len = vsnprintf(str, size, format, arglist);
+ va_end(arglist);
+ str[size - 1] = 0;
}
- return (len >= 0 && len < size);
+ return (len >= 0 && len < size);
}
/*
@@ -279,15 +294,15 @@ bool openvpn_snprintf(char *str, size_t size, const char *format, ...)
* truncated by buf_printf
*/
void
-buf_catrunc (struct buffer *buf, const char *str)
+buf_catrunc(struct buffer *buf, const char *str)
{
- if (buf_forward_capacity (buf) <= 1)
+ if (buf_forward_capacity(buf) <= 1)
{
- int len = (int) strlen (str) + 1;
- if (len < buf_forward_capacity_total (buf))
- {
- strncpynt ((char *)(buf->data + buf->capacity - len), str, len);
- }
+ int len = (int) strlen(str) + 1;
+ if (len < buf_forward_capacity_total(buf))
+ {
+ strncpynt((char *)(buf->data + buf->capacity - len), str, len);
+ }
}
}
@@ -295,26 +310,30 @@ buf_catrunc (struct buffer *buf, const char *str)
* convert a multi-line output to one line
*/
void
-convert_to_one_line (struct buffer *buf)
+convert_to_one_line(struct buffer *buf)
{
- uint8_t *cp = BPTR(buf);
- int len = BLEN(buf);
- while (len--)
+ uint8_t *cp = BPTR(buf);
+ int len = BLEN(buf);
+ while (len--)
{
- if (*cp == '\n')
- *cp = '|';
- ++cp;
+ if (*cp == '\n')
+ {
+ *cp = '|';
+ }
+ ++cp;
}
}
/* NOTE: requires that string be null terminated */
void
-buf_write_string_file (const struct buffer *buf, const char *filename, int fd)
+buf_write_string_file(const struct buffer *buf, const char *filename, int fd)
{
- const int len = strlen ((char *) BPTR (buf));
- const int size = write (fd, BPTR (buf), len);
- if (size != len)
- msg (M_ERR, "Write error on file '%s'", filename);
+ const int len = strlen((char *) BPTR(buf));
+ const int size = write(fd, BPTR(buf), len);
+ if (size != len)
+ {
+ msg(M_ERR, "Write error on file '%s'", filename);
+ }
}
/*
@@ -323,53 +342,53 @@ buf_write_string_file (const struct buffer *buf, const char *filename, int fd)
void *
#ifdef DMALLOC
-gc_malloc_debug (size_t size, bool clear, struct gc_arena *a, const char *file, int line)
+gc_malloc_debug(size_t size, bool clear, struct gc_arena *a, const char *file, int line)
#else
-gc_malloc (size_t size, bool clear, struct gc_arena *a)
+gc_malloc(size_t size, bool clear, struct gc_arena *a)
#endif
{
- void *ret;
- if (a)
+ void *ret;
+ if (a)
{
- struct gc_entry *e;
+ struct gc_entry *e;
#ifdef DMALLOC
- e = (struct gc_entry *) openvpn_dmalloc (file, line, size + sizeof (struct gc_entry));
+ e = (struct gc_entry *) openvpn_dmalloc(file, line, size + sizeof(struct gc_entry));
#else
- e = (struct gc_entry *) malloc (size + sizeof (struct gc_entry));
+ e = (struct gc_entry *) malloc(size + sizeof(struct gc_entry));
#endif
- check_malloc_return (e);
- ret = (char *) e + sizeof (struct gc_entry);
- e->next = a->list;
- a->list = e;
+ check_malloc_return(e);
+ ret = (char *) e + sizeof(struct gc_entry);
+ e->next = a->list;
+ a->list = e;
}
- else
+ else
{
#ifdef DMALLOC
- ret = openvpn_dmalloc (file, line, size);
+ ret = openvpn_dmalloc(file, line, size);
#else
- ret = malloc (size);
+ ret = malloc(size);
#endif
- check_malloc_return (ret);
+ check_malloc_return(ret);
}
#ifndef ZERO_BUFFER_ON_ALLOC
- if (clear)
+ if (clear)
#endif
- memset (ret, 0, size);
- return ret;
+ memset(ret, 0, size);
+ return ret;
}
void
-x_gc_free (struct gc_arena *a)
+x_gc_free(struct gc_arena *a)
{
- struct gc_entry *e;
- e = a->list;
- a->list = NULL;
-
- while (e != NULL)
+ struct gc_entry *e;
+ e = a->list;
+ a->list = NULL;
+
+ while (e != NULL)
{
- struct gc_entry *next = e->next;
- free (e);
- e = next;
+ struct gc_entry *next = e->next;
+ free(e);
+ e = next;
}
}
@@ -378,36 +397,37 @@ x_gc_free (struct gc_arena *a)
*/
void
-x_gc_freespecial (struct gc_arena *a)
+x_gc_freespecial(struct gc_arena *a)
{
- struct gc_entry_special *e;
- e = a->list_special;
- a->list_special = NULL;
+ struct gc_entry_special *e;
+ e = a->list_special;
+ a->list_special = NULL;
- while (e != NULL)
+ while (e != NULL)
{
- struct gc_entry_special *next = e->next;
- e->free_fnc (e->addr);
- free(e);
- e = next;
+ struct gc_entry_special *next = e->next;
+ e->free_fnc(e->addr);
+ free(e);
+ e = next;
}
}
-void gc_addspecial (void *addr, void (free_function)(void*), struct gc_arena *a)
+void
+gc_addspecial(void *addr, void(free_function)(void *), struct gc_arena *a)
{
- ASSERT(a);
- struct gc_entry_special *e;
+ ASSERT(a);
+ struct gc_entry_special *e;
#ifdef DMALLOC
- e = (struct gc_entry_special *) openvpn_dmalloc (file, line, sizeof (struct gc_entry_special));
+ e = (struct gc_entry_special *) openvpn_dmalloc(file, line, sizeof(struct gc_entry_special));
#else
- e = (struct gc_entry_special *) malloc (sizeof (struct gc_entry_special));
+ e = (struct gc_entry_special *) malloc(sizeof(struct gc_entry_special));
#endif
- check_malloc_return (e);
- e->free_fnc = free_function;
- e->addr = addr;
+ check_malloc_return(e);
+ e->free_fnc = free_function;
+ e->addr = addr;
- e->next = a->list_special;
- a->list_special = e;
+ e->next = a->list_special;
+ a->list_special = e;
}
@@ -415,19 +435,19 @@ void gc_addspecial (void *addr, void (free_function)(void*), struct gc_arena *a)
* Transfer src arena to dest, resetting src to an empty arena.
*/
void
-gc_transfer (struct gc_arena *dest, struct gc_arena *src)
+gc_transfer(struct gc_arena *dest, struct gc_arena *src)
{
- if (dest && src)
- {
- struct gc_entry *e = src->list;
- if (e)
- {
- while (e->next != NULL)
- e = e->next;
- e->next = dest->list;
- dest->list = src->list;
- src->list = NULL;
- }
+ if (dest && src)
+ {
+ struct gc_entry *e = src->list;
+ if (e)
+ {
+ while (e->next != NULL)
+ e = e->next;
+ e->next = dest->list;
+ dest->list = src->list;
+ src->list = NULL;
+ }
}
}
@@ -436,28 +456,34 @@ gc_transfer (struct gc_arena *dest, struct gc_arena *src)
*/
char *
-format_hex_ex (const uint8_t *data, int size, int maxoutput,
- unsigned int space_break_flags, const char* separator,
- struct gc_arena *gc)
+format_hex_ex(const uint8_t *data, int size, int maxoutput,
+ unsigned int space_break_flags, const char *separator,
+ struct gc_arena *gc)
{
- const size_t bytes_per_hexblock = space_break_flags & FHE_SPACE_BREAK_MASK;
- const size_t separator_len = separator ? strlen (separator) : 0;
- static_assert (INT_MAX <= SIZE_MAX, "Code assumes INT_MAX <= SIZE_MAX");
- const size_t out_len = maxoutput > 0 ? maxoutput :
- ((size * 2) + ((size / bytes_per_hexblock) * separator_len) + 2);
-
- struct buffer out = alloc_buf_gc (out_len, gc);
- for (int i = 0; i < size; ++i)
- {
- if (separator && i && !(i % bytes_per_hexblock))
- buf_printf (&out, "%s", separator);
- if (space_break_flags & FHE_CAPS)
- buf_printf (&out, "%02X", data[i]);
- else
- buf_printf (&out, "%02x", data[i]);
- }
- buf_catrunc (&out, "[more...]");
- return (char *)out.data;
+ const size_t bytes_per_hexblock = space_break_flags & FHE_SPACE_BREAK_MASK;
+ const size_t separator_len = separator ? strlen(separator) : 0;
+ static_assert(INT_MAX <= SIZE_MAX, "Code assumes INT_MAX <= SIZE_MAX");
+ const size_t out_len = maxoutput > 0 ? maxoutput :
+ ((size * 2) + ((size / bytes_per_hexblock) * separator_len) + 2);
+
+ struct buffer out = alloc_buf_gc(out_len, gc);
+ for (int i = 0; i < size; ++i)
+ {
+ if (separator && i && !(i % bytes_per_hexblock))
+ {
+ buf_printf(&out, "%s", separator);
+ }
+ if (space_break_flags & FHE_CAPS)
+ {
+ buf_printf(&out, "%02X", data[i]);
+ }
+ else
+ {
+ buf_printf(&out, "%02x", data[i]);
+ }
+ }
+ buf_catrunc(&out, "[more...]");
+ return (char *)out.data;
}
/*
@@ -465,13 +491,13 @@ format_hex_ex (const uint8_t *data, int size, int maxoutput,
*/
void
-buf_rmtail (struct buffer *buf, uint8_t remove)
+buf_rmtail(struct buffer *buf, uint8_t remove)
{
- uint8_t *cp = BLAST(buf);
- if (cp && *cp == remove)
+ uint8_t *cp = BLAST(buf);
+ if (cp && *cp == remove)
{
- *cp = '\0';
- --buf->len;
+ *cp = '\0';
+ --buf->len;
}
}
@@ -480,16 +506,20 @@ buf_rmtail (struct buffer *buf, uint8_t remove)
* truncation of the last char.
*/
void
-buf_null_terminate (struct buffer *buf)
+buf_null_terminate(struct buffer *buf)
{
- char *last = (char *) BLAST (buf);
- if (last && *last == '\0') /* already terminated? */
- return;
+ char *last = (char *) BLAST(buf);
+ if (last && *last == '\0') /* already terminated? */
+ {
+ return;
+ }
- if (!buf_safe (buf, 1)) /* make space for trailing null */
- buf_inc_len (buf, -1);
+ if (!buf_safe(buf, 1)) /* make space for trailing null */
+ {
+ buf_inc_len(buf, -1);
+ }
- buf_write_u8 (buf, 0);
+ buf_write_u8(buf, 0);
}
/*
@@ -497,79 +527,91 @@ buf_null_terminate (struct buffer *buf)
* null termination.
*/
void
-buf_chomp (struct buffer *buf)
+buf_chomp(struct buffer *buf)
{
- while (true)
- {
- char *last = (char *) BLAST (buf);
- if (!last)
- break;
- if (char_class (*last, CC_CRLF|CC_NULL))
- {
- if (!buf_inc_len (buf, -1))
- break;
- }
- else
- break;
- }
- buf_null_terminate (buf);
+ while (true)
+ {
+ char *last = (char *) BLAST(buf);
+ if (!last)
+ {
+ break;
+ }
+ if (char_class(*last, CC_CRLF|CC_NULL))
+ {
+ if (!buf_inc_len(buf, -1))
+ {
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ buf_null_terminate(buf);
}
const char *
-skip_leading_whitespace (const char *str)
+skip_leading_whitespace(const char *str)
{
- while (*str)
+ while (*str)
{
- const char c = *str;
- if (!(c == ' ' || c == '\t'))
- break;
- ++str;
+ const char c = *str;
+ if (!(c == ' ' || c == '\t'))
+ {
+ break;
+ }
+ ++str;
}
- return str;
+ return str;
}
/*
* like buf_null_terminate, but operate on strings
*/
void
-string_null_terminate (char *str, int len, int capacity)
+string_null_terminate(char *str, int len, int capacity)
{
- ASSERT (len >= 0 && len <= capacity && capacity > 0);
- if (len < capacity)
- *(str + len) = '\0';
- else if (len == capacity)
- *(str + len - 1) = '\0';
+ ASSERT(len >= 0 && len <= capacity && capacity > 0);
+ if (len < capacity)
+ {
+ *(str + len) = '\0';
+ }
+ else if (len == capacity)
+ {
+ *(str + len - 1) = '\0';
+ }
}
/*
* Remove trailing \r and \n chars.
*/
void
-chomp (char *str)
+chomp(char *str)
{
- rm_trailing_chars (str, "\r\n");
+ rm_trailing_chars(str, "\r\n");
}
/*
* Remove trailing chars
*/
void
-rm_trailing_chars (char *str, const char *what_to_delete)
+rm_trailing_chars(char *str, const char *what_to_delete)
{
- bool modified;
- do {
- const int len = strlen (str);
- modified = false;
- if (len > 0)
- {
- char *cp = str + (len - 1);
- if (strchr (what_to_delete, *cp) != NULL)
- {
- *cp = '\0';
- modified = true;
- }
- }
- } while (modified);
+ bool modified;
+ do {
+ const int len = strlen(str);
+ modified = false;
+ if (len > 0)
+ {
+ char *cp = str + (len - 1);
+ if (strchr(what_to_delete, *cp) != NULL)
+ {
+ *cp = '\0';
+ modified = true;
+ }
+ }
+ } while (modified);
}
/*
@@ -577,51 +619,56 @@ rm_trailing_chars (char *str, const char *what_to_delete)
*/
char *
#ifdef DMALLOC
-string_alloc_debug (const char *str, struct gc_arena *gc, const char *file, int line)
+string_alloc_debug(const char *str, struct gc_arena *gc, const char *file, int line)
#else
-string_alloc (const char *str, struct gc_arena *gc)
+string_alloc(const char *str, struct gc_arena *gc)
#endif
{
- if (str)
+ if (str)
{
- const int n = strlen (str) + 1;
- char *ret;
+ const int n = strlen(str) + 1;
+ char *ret;
- if (gc) {
+ if (gc)
+ {
#ifdef DMALLOC
- ret = (char *) gc_malloc_debug (n, false, gc, file, line);
+ ret = (char *) gc_malloc_debug(n, false, gc, file, line);
#else
- ret = (char *) gc_malloc (n, false, gc);
+ ret = (char *) gc_malloc(n, false, gc);
#endif
- } else {
- /* If there are no garbage collector available, it's expected
- * that the caller cleans up afterwards. This is coherent with the
- * earlier behaviour when gc_malloc() would be called with gc == NULL
- */
+ }
+ else
+ {
+ /* If there are no garbage collector available, it's expected
+ * that the caller cleans up afterwards. This is coherent with the
+ * earlier behaviour when gc_malloc() would be called with gc == NULL
+ */
#ifdef DMALLOC
- ret = openvpn_dmalloc (file, line, n);
- memset(ret, 0, n);
+ ret = openvpn_dmalloc(file, line, n);
+ memset(ret, 0, n);
#else
- ret = calloc(1, n);
+ ret = calloc(1, n);
#endif
- check_malloc_return(ret);
- }
- memcpy (ret, str, n);
- return ret;
+ check_malloc_return(ret);
+ }
+ memcpy(ret, str, n);
+ return ret;
+ }
+ else
+ {
+ return NULL;
}
- else
- return NULL;
}
/*
* Erase all characters in a string
*/
void
-string_clear (char *str)
+string_clear(char *str)
{
- if (str)
+ if (str)
{
- secure_memzero (str, strlen (str));
+ secure_memzero(str, strlen(str));
}
}
@@ -629,36 +676,44 @@ string_clear (char *str)
* Return the length of a string array
*/
int
-string_array_len (const char **array)
+string_array_len(const char **array)
{
- int i = 0;
- if (array)
+ int i = 0;
+ if (array)
{
- while (array[i])
- ++i;
+ while (array[i])
+ ++i;
}
- return i;
+ return i;
}
char *
-print_argv (const char **p, struct gc_arena *gc, const unsigned int flags)
+print_argv(const char **p, struct gc_arena *gc, const unsigned int flags)
{
- struct buffer out = alloc_buf_gc (256, gc);
- int i = 0;
- for (;;)
- {
- const char *cp = *p++;
- if (!cp)
- break;
- if (i)
- buf_printf (&out, " ");
- if (flags & PA_BRACKET)
- buf_printf (&out, "[%s]", cp);
- else
- buf_printf (&out, "%s", cp);
- ++i;
- }
- return BSTR (&out);
+ struct buffer out = alloc_buf_gc(256, gc);
+ int i = 0;
+ for (;; )
+ {
+ const char *cp = *p++;
+ if (!cp)
+ {
+ break;
+ }
+ if (i)
+ {
+ buf_printf(&out, " ");
+ }
+ if (flags & PA_BRACKET)
+ {
+ buf_printf(&out, "[%s]", cp);
+ }
+ else
+ {
+ buf_printf(&out, "%s", cp);
+ }
+ ++i;
+ }
+ return BSTR(&out);
}
/*
@@ -666,25 +721,27 @@ print_argv (const char **p, struct gc_arena *gc, const unsigned int flags)
*/
struct buffer
#ifdef DMALLOC
-string_alloc_buf_debug (const char *str, struct gc_arena *gc, const char *file, int line)
+string_alloc_buf_debug(const char *str, struct gc_arena *gc, const char *file, int line)
#else
-string_alloc_buf (const char *str, struct gc_arena *gc)
+string_alloc_buf(const char *str, struct gc_arena *gc)
#endif
{
- struct buffer buf;
+ struct buffer buf;
- ASSERT (str);
+ ASSERT(str);
#ifdef DMALLOC
- buf_set_read (&buf, (uint8_t*) string_alloc_debug (str, gc, file, line), strlen (str) + 1);
+ buf_set_read(&buf, (uint8_t *) string_alloc_debug(str, gc, file, line), strlen(str) + 1);
#else
- buf_set_read (&buf, (uint8_t*) string_alloc (str, gc), strlen (str) + 1);
+ buf_set_read(&buf, (uint8_t *) string_alloc(str, gc), strlen(str) + 1);
#endif
- if (buf.len > 0) /* Don't count trailing '\0' as part of length */
- --buf.len;
+ if (buf.len > 0) /* Don't count trailing '\0' as part of length */
+ {
+ --buf.len;
+ }
- return buf;
+ return buf;
}
/*
@@ -692,40 +749,46 @@ string_alloc_buf (const char *str, struct gc_arena *gc)
*/
bool
-buf_string_match_head_str (const struct buffer *src, const char *match)
+buf_string_match_head_str(const struct buffer *src, const char *match)
{
- const int size = strlen (match);
- if (size < 0 || size > src->len)
- return false;
- return memcmp (BPTR (src), match, size) == 0;
+ const int size = strlen(match);
+ if (size < 0 || size > src->len)
+ {
+ return false;
+ }
+ return memcmp(BPTR(src), match, size) == 0;
}
bool
-buf_string_compare_advance (struct buffer *src, const char *match)
+buf_string_compare_advance(struct buffer *src, const char *match)
{
- if (buf_string_match_head_str (src, match))
+ if (buf_string_match_head_str(src, match))
{
- buf_advance (src, strlen (match));
- return true;
+ buf_advance(src, strlen(match));
+ return true;
+ }
+ else
+ {
+ return false;
}
- else
- return false;
}
int
-buf_substring_len (const struct buffer *buf, int delim)
+buf_substring_len(const struct buffer *buf, int delim)
{
- int i = 0;
- struct buffer tmp = *buf;
- int c;
+ int i = 0;
+ struct buffer tmp = *buf;
+ int c;
- while ((c = buf_read_u8 (&tmp)) >= 0)
+ while ((c = buf_read_u8(&tmp)) >= 0)
{
- ++i;
- if (c == delim)
- return i;
+ ++i;
+ if (c == delim)
+ {
+ return i;
+ }
}
- return -1;
+ return -1;
}
/*
@@ -733,41 +796,51 @@ buf_substring_len (const struct buffer *buf, int delim)
*/
bool
-buf_parse (struct buffer *buf, const int delim, char *line, const int size)
+buf_parse(struct buffer *buf, const int delim, char *line, const int size)
{
- bool eol = false;
- int n = 0;
- int c;
+ bool eol = false;
+ int n = 0;
+ int c;
- ASSERT (size > 0);
+ ASSERT(size > 0);
- do
+ do
{
- c = buf_read_u8 (buf);
- if (c < 0)
- eol = true;
- if (c <= 0 || c == delim)
- c = 0;
- if (n >= size)
- break;
- line[n++] = c;
+ c = buf_read_u8(buf);
+ if (c < 0)
+ {
+ eol = true;
+ }
+ if (c <= 0 || c == delim)
+ {
+ c = 0;
+ }
+ if (n >= size)
+ {
+ break;
+ }
+ line[n++] = c;
}
- while (c);
+ while (c);
- line[size-1] = '\0';
- return !(eol && !strlen (line));
+ line[size-1] = '\0';
+ return !(eol && !strlen(line));
}
/*
* Print a string which might be NULL
*/
const char *
-np (const char *str)
+np(const char *str)
{
- if (str)
- return str;
- else
- return "[NULL]";
+ if (str)
+ {
+ return str;
+ }
+ else
+ {
+ return "[NULL]";
+ }
}
/*
@@ -775,97 +848,163 @@ np (const char *str)
*/
bool
-char_class (const unsigned char c, const unsigned int flags)
+char_class(const unsigned char c, const unsigned int flags)
{
- if (!flags)
- return false;
- if (flags & CC_ANY)
- return true;
+ if (!flags)
+ {
+ return false;
+ }
+ if (flags & CC_ANY)
+ {
+ return true;
+ }
- if ((flags & CC_NULL) && c == '\0')
- return true;
+ if ((flags & CC_NULL) && c == '\0')
+ {
+ return true;
+ }
- if ((flags & CC_ALNUM) && isalnum (c))
- return true;
- if ((flags & CC_ALPHA) && isalpha (c))
- return true;
- if ((flags & CC_ASCII) && isascii (c))
- return true;
- if ((flags & CC_CNTRL) && iscntrl (c))
- return true;
- if ((flags & CC_DIGIT) && isdigit (c))
- return true;
- if ((flags & CC_PRINT) && (c >= 32 && c != 127)) /* allow ascii non-control and UTF-8, consider DEL to be a control */
- return true;
- if ((flags & CC_PUNCT) && ispunct (c))
- return true;
- if ((flags & CC_SPACE) && isspace (c))
- return true;
- if ((flags & CC_XDIGIT) && isxdigit (c))
- return true;
+ if ((flags & CC_ALNUM) && isalnum(c))
+ {
+ return true;
+ }
+ if ((flags & CC_ALPHA) && isalpha(c))
+ {
+ return true;
+ }
+ if ((flags & CC_ASCII) && isascii(c))
+ {
+ return true;
+ }
+ if ((flags & CC_CNTRL) && iscntrl(c))
+ {
+ return true;
+ }
+ if ((flags & CC_DIGIT) && isdigit(c))
+ {
+ return true;
+ }
+ if ((flags & CC_PRINT) && (c >= 32 && c != 127)) /* allow ascii non-control and UTF-8, consider DEL to be a control */
+ {
+ return true;
+ }
+ if ((flags & CC_PUNCT) && ispunct(c))
+ {
+ return true;
+ }
+ if ((flags & CC_SPACE) && isspace(c))
+ {
+ return true;
+ }
+ if ((flags & CC_XDIGIT) && isxdigit(c))
+ {
+ return true;
+ }
- if ((flags & CC_BLANK) && (c == ' ' || c == '\t'))
- return true;
- if ((flags & CC_NEWLINE) && c == '\n')
- return true;
- if ((flags & CC_CR) && c == '\r')
- return true;
+ if ((flags & CC_BLANK) && (c == ' ' || c == '\t'))
+ {
+ return true;
+ }
+ if ((flags & CC_NEWLINE) && c == '\n')
+ {
+ return true;
+ }
+ if ((flags & CC_CR) && c == '\r')
+ {
+ return true;
+ }
- if ((flags & CC_BACKSLASH) && c == '\\')
- return true;
- if ((flags & CC_UNDERBAR) && c == '_')
- return true;
- if ((flags & CC_DASH) && c == '-')
- return true;
- if ((flags & CC_DOT) && c == '.')
- return true;
- if ((flags & CC_COMMA) && c == ',')
- return true;
- if ((flags & CC_COLON) && c == ':')
- return true;
- if ((flags & CC_SLASH) && c == '/')
- return true;
- if ((flags & CC_SINGLE_QUOTE) && c == '\'')
- return true;
- if ((flags & CC_DOUBLE_QUOTE) && c == '\"')
- return true;
- if ((flags & CC_REVERSE_QUOTE) && c == '`')
- return true;
- if ((flags & CC_AT) && c == '@')
- return true;
- if ((flags & CC_EQUAL) && c == '=')
- return true;
- if ((flags & CC_LESS_THAN) && c == '<')
- return true;
- if ((flags & CC_GREATER_THAN) && c == '>')
- return true;
- if ((flags & CC_PIPE) && c == '|')
- return true;
- if ((flags & CC_QUESTION_MARK) && c == '?')
- return true;
- if ((flags & CC_ASTERISK) && c == '*')
- return true;
+ if ((flags & CC_BACKSLASH) && c == '\\')
+ {
+ return true;
+ }
+ if ((flags & CC_UNDERBAR) && c == '_')
+ {
+ return true;
+ }
+ if ((flags & CC_DASH) && c == '-')
+ {
+ return true;
+ }
+ if ((flags & CC_DOT) && c == '.')
+ {
+ return true;
+ }
+ if ((flags & CC_COMMA) && c == ',')
+ {
+ return true;
+ }
+ if ((flags & CC_COLON) && c == ':')
+ {
+ return true;
+ }
+ if ((flags & CC_SLASH) && c == '/')
+ {
+ return true;
+ }
+ if ((flags & CC_SINGLE_QUOTE) && c == '\'')
+ {
+ return true;
+ }
+ if ((flags & CC_DOUBLE_QUOTE) && c == '\"')
+ {
+ return true;
+ }
+ if ((flags & CC_REVERSE_QUOTE) && c == '`')
+ {
+ return true;
+ }
+ if ((flags & CC_AT) && c == '@')
+ {
+ return true;
+ }
+ if ((flags & CC_EQUAL) && c == '=')
+ {
+ return true;
+ }
+ if ((flags & CC_LESS_THAN) && c == '<')
+ {
+ return true;
+ }
+ if ((flags & CC_GREATER_THAN) && c == '>')
+ {
+ return true;
+ }
+ if ((flags & CC_PIPE) && c == '|')
+ {
+ return true;
+ }
+ if ((flags & CC_QUESTION_MARK) && c == '?')
+ {
+ return true;
+ }
+ if ((flags & CC_ASTERISK) && c == '*')
+ {
+ return true;
+ }
- return false;
+ return false;
}
static inline bool
-char_inc_exc (const char c, const unsigned int inclusive, const unsigned int exclusive)
+char_inc_exc(const char c, const unsigned int inclusive, const unsigned int exclusive)
{
- return char_class (c, inclusive) && !char_class (c, exclusive);
+ return char_class(c, inclusive) && !char_class(c, exclusive);
}
bool
-string_class (const char *str, const unsigned int inclusive, const unsigned int exclusive)
+string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive)
{
- char c;
- ASSERT (str);
- while ((c = *str++))
+ char c;
+ ASSERT(str);
+ while ((c = *str++))
{
- if (!char_inc_exc (c, inclusive, exclusive))
- return false;
+ if (!char_inc_exc(c, inclusive, exclusive))
+ {
+ return false;
+ }
}
- return true;
+ return true;
}
/*
@@ -873,63 +1012,71 @@ string_class (const char *str, const unsigned int inclusive, const unsigned int
* Guaranteed to not increase string length.
*/
bool
-string_mod (char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
+string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
{
- const char *in = str;
- bool ret = true;
-
- ASSERT (str);
-
- while (true)
- {
- char c = *in++;
- if (c)
- {
- if (!char_inc_exc (c, inclusive, exclusive))
- {
- c = replace;
- ret = false;
- }
- if (c)
- *str++ = c;
- }
- else
- {
- *str = '\0';
- break;
- }
- }
- return ret;
+ const char *in = str;
+ bool ret = true;
+
+ ASSERT(str);
+
+ while (true)
+ {
+ char c = *in++;
+ if (c)
+ {
+ if (!char_inc_exc(c, inclusive, exclusive))
+ {
+ c = replace;
+ ret = false;
+ }
+ if (c)
+ {
+ *str++ = c;
+ }
+ }
+ else
+ {
+ *str = '\0';
+ break;
+ }
+ }
+ return ret;
}
const char *
-string_mod_const (const char *str,
- const unsigned int inclusive,
- const unsigned int exclusive,
- const char replace,
- struct gc_arena *gc)
+string_mod_const(const char *str,
+ const unsigned int inclusive,
+ const unsigned int exclusive,
+ const char replace,
+ struct gc_arena *gc)
{
- if (str)
+ if (str)
{
- char *buf = string_alloc (str, gc);
- string_mod (buf, inclusive, exclusive, replace);
- return buf;
+ char *buf = string_alloc(str, gc);
+ string_mod(buf, inclusive, exclusive, replace);
+ return buf;
+ }
+ else
+ {
+ return NULL;
}
- else
- return NULL;
}
void
-string_replace_leading (char *str, const char match, const char replace)
+string_replace_leading(char *str, const char match, const char replace)
{
- ASSERT (match != '\0');
- while (*str)
+ ASSERT(match != '\0');
+ while (*str)
{
- if (*str == match)
- *str = replace;
- else
- break;
- ++str;
+ if (*str == match)
+ {
+ *str = replace;
+ }
+ else
+ {
+ break;
+ }
+ ++str;
}
}
@@ -940,14 +1087,14 @@ string_replace_leading (char *str, const char match, const char replace)
#define CC_REPLACE ('.')
void
-character_class_debug (void)
+character_class_debug(void)
{
- char buf[256];
+ char buf[256];
- while (fgets (buf, sizeof (buf), stdin) != NULL)
+ while (fgets(buf, sizeof(buf), stdin) != NULL)
{
- string_mod (buf, CC_INCLUDE, CC_EXCLUDE, CC_REPLACE);
- printf ("%s", buf);
+ string_mod(buf, CC_INCLUDE, CC_EXCLUDE, CC_REPLACE);
+ printf("%s", buf);
}
}
@@ -955,214 +1102,228 @@ character_class_debug (void)
#ifdef VERIFY_ALIGNMENT
void
-valign4 (const struct buffer *buf, const char *file, const int line)
+valign4(const struct buffer *buf, const char *file, const int line)
{
- if (buf && buf->len)
+ if (buf && buf->len)
{
- int msglevel = D_ALIGN_DEBUG;
- const unsigned int u = (unsigned int) BPTR (buf);
-
- if (u & (PAYLOAD_ALIGN-1))
- msglevel = D_ALIGN_ERRORS;
-
- msg (msglevel, "%sAlignment at %s/%d ptr=" ptr_format " OLC=%d/%d/%d I=%s/%d",
- (msglevel == D_ALIGN_ERRORS) ? "ERROR: " : "",
- file,
- line,
- (ptr_type)buf->data,
- buf->offset,
- buf->len,
- buf->capacity,
- buf_debug_file (buf),
- buf_debug_line (buf));
+ int msglevel = D_ALIGN_DEBUG;
+ const unsigned int u = (unsigned int) BPTR(buf);
+
+ if (u & (PAYLOAD_ALIGN-1))
+ {
+ msglevel = D_ALIGN_ERRORS;
+ }
+
+ msg(msglevel, "%sAlignment at %s/%d ptr=" ptr_format " OLC=%d/%d/%d I=%s/%d",
+ (msglevel == D_ALIGN_ERRORS) ? "ERROR: " : "",
+ file,
+ line,
+ (ptr_type)buf->data,
+ buf->offset,
+ buf->len,
+ buf->capacity,
+ buf_debug_file(buf),
+ buf_debug_line(buf));
}
}
-#endif
+#endif /* ifdef VERIFY_ALIGNMENT */
/*
* struct buffer_list
*/
struct buffer_list *
-buffer_list_new (const int max_size)
+buffer_list_new(const int max_size)
{
- struct buffer_list *ret;
- ALLOC_OBJ_CLEAR (ret, struct buffer_list);
- ret->max_size = max_size;
- ret->size = 0;
- return ret;
+ struct buffer_list *ret;
+ ALLOC_OBJ_CLEAR(ret, struct buffer_list);
+ ret->max_size = max_size;
+ ret->size = 0;
+ return ret;
}
void
-buffer_list_free (struct buffer_list *ol)
+buffer_list_free(struct buffer_list *ol)
{
- if (ol)
+ if (ol)
{
- buffer_list_reset (ol);
- free (ol);
+ buffer_list_reset(ol);
+ free(ol);
}
}
bool
-buffer_list_defined (const struct buffer_list *ol)
+buffer_list_defined(const struct buffer_list *ol)
{
- return ol && ol->head != NULL;
+ return ol && ol->head != NULL;
}
void
-buffer_list_reset (struct buffer_list *ol)
+buffer_list_reset(struct buffer_list *ol)
{
- struct buffer_entry *e = ol->head;
- while (e)
+ struct buffer_entry *e = ol->head;
+ while (e)
{
- struct buffer_entry *next = e->next;
- free_buf (&e->buf);
- free (e);
- e = next;
+ struct buffer_entry *next = e->next;
+ free_buf(&e->buf);
+ free(e);
+ e = next;
}
- ol->head = ol->tail = NULL;
- ol->size = 0;
+ ol->head = ol->tail = NULL;
+ ol->size = 0;
}
void
-buffer_list_push (struct buffer_list *ol, const unsigned char *str)
+buffer_list_push(struct buffer_list *ol, const unsigned char *str)
{
- if (str)
+ if (str)
{
- const size_t len = strlen ((const char *)str);
- struct buffer_entry *e = buffer_list_push_data (ol, str, len+1);
- if (e)
- e->buf.len = len; /* Don't count trailing '\0' as part of length */
+ const size_t len = strlen((const char *)str);
+ struct buffer_entry *e = buffer_list_push_data(ol, str, len+1);
+ if (e)
+ {
+ e->buf.len = len; /* Don't count trailing '\0' as part of length */
+ }
}
}
struct buffer_entry *
-buffer_list_push_data (struct buffer_list *ol, const uint8_t *data, size_t size)
+buffer_list_push_data(struct buffer_list *ol, const uint8_t *data, size_t size)
{
- struct buffer_entry *e = NULL;
- if (data && (!ol->max_size || ol->size < ol->max_size))
- {
- ALLOC_OBJ_CLEAR (e, struct buffer_entry);
-
- ++ol->size;
- if (ol->tail)
- {
- ASSERT (ol->head);
- ol->tail->next = e;
- }
- else
- {
- ASSERT (!ol->head);
- ol->head = e;
- }
- e->buf = alloc_buf (size);
- memcpy (e->buf.data, data, size);
- e->buf.len = (int)size;
- ol->tail = e;
- }
- return e;
+ struct buffer_entry *e = NULL;
+ if (data && (!ol->max_size || ol->size < ol->max_size))
+ {
+ ALLOC_OBJ_CLEAR(e, struct buffer_entry);
+
+ ++ol->size;
+ if (ol->tail)
+ {
+ ASSERT(ol->head);
+ ol->tail->next = e;
+ }
+ else
+ {
+ ASSERT(!ol->head);
+ ol->head = e;
+ }
+ e->buf = alloc_buf(size);
+ memcpy(e->buf.data, data, size);
+ e->buf.len = (int)size;
+ ol->tail = e;
+ }
+ return e;
}
struct buffer *
-buffer_list_peek (struct buffer_list *ol)
+buffer_list_peek(struct buffer_list *ol)
{
- if (ol && ol->head)
- return &ol->head->buf;
- else
- return NULL;
+ if (ol && ol->head)
+ {
+ return &ol->head->buf;
+ }
+ else
+ {
+ return NULL;
+ }
}
void
-buffer_list_aggregate_separator (struct buffer_list *bl, const size_t max, const char *sep)
+buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max, const char *sep)
{
- int sep_len = strlen(sep);
-
- if (bl->head)
- {
- struct buffer_entry *more = bl->head;
- size_t size = 0;
- int count = 0;
- for (count = 0; more && size <= max; ++count)
- {
- size += BLEN(&more->buf) + sep_len;
- more = more->next;
- }
-
- if (count >= 2)
- {
- int i;
- struct buffer_entry *e = bl->head, *f;
-
- ALLOC_OBJ_CLEAR (f, struct buffer_entry);
- f->buf.data = malloc (size);
- check_malloc_return (f->buf.data);
- f->buf.capacity = size;
- for (i = 0; e && i < count; ++i)
- {
- struct buffer_entry *next = e->next;
- buf_copy (&f->buf, &e->buf);
- buf_write(&f->buf, sep, sep_len);
- free_buf (&e->buf);
- free (e);
- e = next;
- }
- bl->head = f;
- f->next = more;
- if (!more)
- bl->tail = f;
- }
+ int sep_len = strlen(sep);
+
+ if (bl->head)
+ {
+ struct buffer_entry *more = bl->head;
+ size_t size = 0;
+ int count = 0;
+ for (count = 0; more && size <= max; ++count)
+ {
+ size += BLEN(&more->buf) + sep_len;
+ more = more->next;
+ }
+
+ if (count >= 2)
+ {
+ int i;
+ struct buffer_entry *e = bl->head, *f;
+
+ ALLOC_OBJ_CLEAR(f, struct buffer_entry);
+ f->buf.data = malloc(size);
+ check_malloc_return(f->buf.data);
+ f->buf.capacity = size;
+ for (i = 0; e && i < count; ++i)
+ {
+ struct buffer_entry *next = e->next;
+ buf_copy(&f->buf, &e->buf);
+ buf_write(&f->buf, sep, sep_len);
+ free_buf(&e->buf);
+ free(e);
+ e = next;
+ }
+ bl->head = f;
+ f->next = more;
+ if (!more)
+ {
+ bl->tail = f;
+ }
+ }
}
}
void
-buffer_list_aggregate (struct buffer_list *bl, const size_t max)
+buffer_list_aggregate(struct buffer_list *bl, const size_t max)
{
- buffer_list_aggregate_separator(bl, max, "");
+ buffer_list_aggregate_separator(bl, max, "");
}
void
-buffer_list_pop (struct buffer_list *ol)
+buffer_list_pop(struct buffer_list *ol)
{
- if (ol && ol->head)
+ if (ol && ol->head)
{
- struct buffer_entry *e = ol->head->next;
- free_buf (&ol->head->buf);
- free (ol->head);
- ol->head = e;
- --ol->size;
- if (!e)
- ol->tail = NULL;
+ struct buffer_entry *e = ol->head->next;
+ free_buf(&ol->head->buf);
+ free(ol->head);
+ ol->head = e;
+ --ol->size;
+ if (!e)
+ {
+ ol->tail = NULL;
+ }
}
}
void
-buffer_list_advance (struct buffer_list *ol, int n)
+buffer_list_advance(struct buffer_list *ol, int n)
{
- if (ol->head)
+ if (ol->head)
{
- struct buffer *buf = &ol->head->buf;
- ASSERT (buf_advance (buf, n));
- if (!BLEN (buf))
- buffer_list_pop (ol);
+ struct buffer *buf = &ol->head->buf;
+ ASSERT(buf_advance(buf, n));
+ if (!BLEN(buf))
+ {
+ buffer_list_pop(ol);
+ }
}
}
struct buffer_list *
-buffer_list_file (const char *fn, int max_line_len)
+buffer_list_file(const char *fn, int max_line_len)
{
- FILE *fp = platform_fopen (fn, "r");
- struct buffer_list *bl = NULL;
-
- if (fp)
- {
- char *line = (char *) malloc (max_line_len);
- if (line)
- {
- bl = buffer_list_new (0);
- while (fgets (line, max_line_len, fp) != NULL)
- buffer_list_push (bl, (unsigned char *)line);
- free (line);
- }
- fclose (fp);
- }
- return bl;
+ FILE *fp = platform_fopen(fn, "r");
+ struct buffer_list *bl = NULL;
+
+ if (fp)
+ {
+ char *line = (char *) malloc(max_line_len);
+ if (line)
+ {
+ bl = buffer_list_new(0);
+ while (fgets(line, max_line_len, fp) != NULL)
+ buffer_list_push(bl, (unsigned char *)line);
+ free(line);
+ }
+ fclose(fp);
+ }
+ return bl;
}