diff options
Diffstat (limited to '')
-rw-r--r-- | libdnet-stripped/src/blob.c | 458 |
1 files changed, 458 insertions, 0 deletions
diff --git a/libdnet-stripped/src/blob.c b/libdnet-stripped/src/blob.c new file mode 100644 index 0000000..57ff0c3 --- /dev/null +++ b/libdnet-stripped/src/blob.c @@ -0,0 +1,458 @@ +/* + * blob.c + * + * Copyright (c) 2002 Dug Song <dugsong@monkey.org> + * + * $Id: blob.c 615 2006-01-08 16:06:49Z dugsong $ + */ + +#ifdef _WIN32 +#include "dnet_winconfig.h" +#else +#include "config.h" +#endif + +#include <ctype.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "dnet.h" + +static void *(*bl_malloc)(size_t) = malloc; +static void *(*bl_realloc)(void *, size_t) = realloc; +static void (*bl_free)(void *) = free; +static int bl_size = BUFSIZ; + +static int fmt_D(int, int, blob_t *, va_list *); +static int fmt_H(int, int, blob_t *, va_list *); +static int fmt_b(int, int, blob_t *, va_list *); +static int fmt_c(int, int, blob_t *, va_list *); +static int fmt_d(int, int, blob_t *, va_list *); +static int fmt_h(int, int, blob_t *, va_list *); +static int fmt_s(int, int, blob_t *, va_list *); + +static void print_hexl(blob_t *); + +static blob_fmt_cb blob_ascii_fmt[] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, fmt_D, NULL, NULL, NULL, + fmt_H, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, fmt_b, fmt_c, fmt_d, NULL, NULL, NULL, + fmt_h, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, fmt_s, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +struct blob_printer { + char *name; + void (*print)(blob_t *); +} blob_printers[] = { + { "hexl", print_hexl }, + { NULL, NULL }, +}; + +blob_t * +blob_new(void) +{ + blob_t *b; + + if ((b = bl_malloc(sizeof(*b))) != NULL) { + b->off = b->end = 0; + b->size = bl_size; + if ((b->base = bl_malloc(b->size)) == NULL) { + bl_free(b); + b = NULL; + } + } + return (b); +} + +static int +blob_reserve(blob_t *b, int len) +{ + void *p; + int nsize; + + if (b->size < b->end + len) { + if (b->size == 0) + return (-1); + + if ((nsize = b->end + len) > bl_size) + nsize = ((nsize / bl_size) + 1) * bl_size; + + if ((p = bl_realloc(b->base, nsize)) == NULL) + return (-1); + + b->base = p; + b->size = nsize; + } + b->end += len; + + return (0); +} + +int +blob_read(blob_t *b, void *buf, int len) +{ + if (b->end - b->off < len) + len = b->end - b->off; + + memcpy(buf, b->base + b->off, len); + b->off += len; + + return (len); +} + +int +blob_write(blob_t *b, const void *buf, int len) +{ + if (b->off + len <= b->end || + blob_reserve(b, b->off + len - b->end) == 0) { + memcpy(b->base + b->off, (u_char *)buf, len); + b->off += len; + return (len); + } + return (-1); +} + +int +blob_insert(blob_t *b, const void *buf, int len) +{ + if (blob_reserve(b, len) == 0 && b->size) { + if (b->end - b->off > 0) + memmove( b->base + b->off + len, b->base + b->off, b->end - b->off); + memcpy(b->base + b->off, buf, len); + b->off += len; + return (len); + } + return (-1); +} + +int +blob_delete(blob_t *b, void *buf, int len) +{ + if (b->off + len <= b->end && b->size) { + if (buf != NULL) + memcpy(buf, b->base + b->off, len); + memmove(b->base + b->off, b->base + b->off + len, b->end - (b->off + len)); + b->end -= len; + return (len); + } + return (-1); +} + +static int +blob_fmt(blob_t *b, int pack, const char *fmt, va_list *ap) +{ + blob_fmt_cb fmt_cb; + char *p; + int len; + + for (p = (char *)fmt; *p != '\0'; p++) { + if (*p == '%') { + p++; + if (isdigit((int) (unsigned char) *p)) { + len = strtol(p, &p, 10); + } else if (*p == '*') { + len = va_arg(*ap, int); + p++; + } else + len = 0; + + if ((fmt_cb = blob_ascii_fmt[(int)*p]) == NULL) + return (-1); + + if ((*fmt_cb)(pack, len, b, ap) < 0) + return (-1); + } else { + if (pack) { + if (b->off + 1 < b->end || + blob_reserve(b, b->off + 1 - b->end) == 0) + b->base[b->off++] = *p; + else + return (-1); + } else { + if (b->base[b->off++] != *p) + return (-1); + } + } + } + return (0); +} + +int +blob_pack(blob_t *b, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + return (blob_fmt(b, 1, fmt, &ap)); +} + +int +blob_unpack(blob_t *b, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + return (blob_fmt(b, 0, fmt, &ap)); +} + +int +blob_seek(blob_t *b, int off, int whence) +{ + if (whence == SEEK_CUR) + off += b->off; + else if (whence == SEEK_END) + off += b->end; + + if (off < 0 || off > b->end) + return (-1); + + return ((b->off = off)); +} + +int +blob_index(blob_t *b, const void *buf, int len) +{ + int i; + + for (i = b->off; i <= b->end - len; i++) { + if (memcmp(b->base + i, buf, len) == 0) + return (i); + } + return (-1); +} + +int +blob_rindex(blob_t *b, const void *buf, int len) +{ + int i; + + for (i = b->end - len; i >= 0; i--) { + if (memcmp(b->base + i, buf, len) == 0) + return (i); + } + return (-1); +} + +int +blob_print(blob_t *b, char *style, int len) +{ + struct blob_printer *bp; + + for (bp = blob_printers; bp->name != NULL; bp++) { + if (strcmp(bp->name, style) == 0) + bp->print(b); + } + return (0); +} + +int +blob_sprint(blob_t *b, char *style, int len, char *dst, int size) +{ + return (0); +} + +blob_t * +blob_free(blob_t *b) +{ + if (b->size) + bl_free(b->base); + bl_free(b); + return (NULL); +} + +int +blob_register_alloc(size_t size, void *(bmalloc)(size_t), + void (*bfree)(void *), void *(*brealloc)(void *, size_t)) +{ + bl_size = size; + if (bmalloc != NULL) + bl_malloc = bmalloc; + if (bfree != NULL) + bl_free = bfree; + if (brealloc != NULL) + bl_realloc = brealloc; + return (0); +} + +int +blob_register_pack(char c, blob_fmt_cb fmt_cb) +{ + if (blob_ascii_fmt[(int)c] == NULL) { + blob_ascii_fmt[(int)c] = fmt_cb; + return (0); + } + return (-1); +} + +static int +fmt_D(int pack, int len, blob_t *b, va_list *ap) +{ + if (len) return (-1); + + if (pack) { + uint32_t n = va_arg(*ap, uint32_t); + n = htonl(n); + if (blob_write(b, &n, sizeof(n)) < 0) + return (-1); + } else { + uint32_t *n = va_arg(*ap, uint32_t *); + if (blob_read(b, n, sizeof(*n)) != sizeof(*n)) + return (-1); + *n = ntohl(*n); + } + return (0); +} + +static int +fmt_H(int pack, int len, blob_t *b, va_list *ap) +{ + if (len) return (-1); + + if (pack) { + uint16_t n = va_arg(*ap, int); + n = htons(n); + if (blob_write(b, &n, sizeof(n)) < 0) + return (-1); + } else { + uint16_t *n = va_arg(*ap, uint16_t *); + if (blob_read(b, n, sizeof(*n)) != sizeof(*n)) + return (-1); + *n = ntohs(*n); + } + return (0); +} + +static int +fmt_b(int pack, int len, blob_t *b, va_list *ap) +{ + void *p = va_arg(*ap, void *); + + if (len <= 0) return (-1); + + if (pack) + return (blob_write(b, p, len)); + else + return (blob_read(b, p, len)); +} + +static int +fmt_c(int pack, int len, blob_t *b, va_list *ap) +{ + if (len) return (-1); + + if (pack) { + uint8_t n = va_arg(*ap, int); + return (blob_write(b, &n, sizeof(n))); + } else { + uint8_t *n = va_arg(*ap, uint8_t *); + return (blob_read(b, n, sizeof(*n))); + } +} + +static int +fmt_d(int pack, int len, blob_t *b, va_list *ap) +{ + if (len) return (-1); + + if (pack) { + uint32_t n = va_arg(*ap, uint32_t); + return (blob_write(b, &n, sizeof(n))); + } else { + uint32_t *n = va_arg(*ap, uint32_t *); + return (blob_read(b, n, sizeof(*n))); + } +} + +static int +fmt_h(int pack, int len, blob_t *b, va_list *ap) +{ + if (len) return (-1); + + if (pack) { + uint16_t n = va_arg(*ap, int); + return (blob_write(b, &n, sizeof(n))); + } else { + uint16_t *n = va_arg(*ap, uint16_t *); + return (blob_read(b, n, sizeof(*n))); + } +} + +static int +fmt_s(int pack, int len, blob_t *b, va_list *ap) +{ + char *p = va_arg(*ap, char *); + char c = '\0'; + int i, end; + + if (pack) { + if (len > 0) { + if ((c = p[len - 1]) != '\0') + p[len - 1] = '\0'; + } else + len = strlen(p) + 1; + + if (blob_write(b, p, len) > 0) { + if (c != '\0') + p[len - 1] = c; + return (len); + } + } else { + if (len <= 0) return (-1); + + if ((end = b->end - b->off) < len) + end = len; + + for (i = 0; i < end; i++) { + if ((p[i] = b->base[b->off + i]) == '\0') { + b->off += i + 1; + return (i); + } + } + } + return (-1); +} + +static void +print_hexl(blob_t *b) +{ + u_int i, j, jm, len; + u_char *p; + int c; + + p = b->base + b->off; + len = b->end - b->off; + + printf("\n"); + + for (i = 0; i < len; i += 0x10) { + printf(" %04x: ", (u_int)(i + b->off)); + jm = len - i; + jm = jm > 16 ? 16 : jm; + + for (j = 0; j < jm; j++) { + printf((j % 2) ? "%02x " : "%02x", (u_int)p[i + j]); + } + for (; j < 16; j++) { + printf((j % 2) ? " " : " "); + } + printf(" "); + + for (j = 0; j < jm; j++) { + c = p[i + j]; + printf("%c", isprint(c) ? c : '.'); + } + printf("\n"); + } +} |