From cbbe71752d7f9c6204ab0f16600fe7f10490f203 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sat, 24 Apr 2004 22:38:50 +0000 Subject: Completed implementation of ldap/ntlm/simple handlers --- common/buffer.c | 216 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 176 insertions(+), 40 deletions(-) (limited to 'common/buffer.c') diff --git a/common/buffer.c b/common/buffer.c index 28cab24..a5b18a7 100644 --- a/common/buffer.c +++ b/common/buffer.c @@ -47,6 +47,12 @@ void buffer_bump(ha_buffer_t* buf, int count) } } +void ha_bufinit(ha_buffer_t* buf) +{ + memset(buf, 0, sizeof(*buf)); + ha_bufreset(buf); +} + void ha_bufreset(ha_buffer_t* buf) { if(!buf->_dt || buf->_al == 0) @@ -67,12 +73,6 @@ void ha_bufreset(ha_buffer_t* buf) buf->_pp = buf->_dt; } -void ha_bufinit(ha_buffer_t* buf) -{ - memset(buf, 0, sizeof(*buf)); - ha_bufreset(buf); -} - void ha_buffree(ha_buffer_t* buf) { if(buf->_dt) @@ -82,7 +82,8 @@ void ha_buffree(ha_buffer_t* buf) buf->_rp = buf->_pp = NULL; } -int ha_readline(int fd, ha_buffer_t* buf) + +int ha_bufreadline(int fd, ha_buffer_t* buf) { int l; @@ -137,7 +138,7 @@ int ha_readline(int fd, ha_buffer_t* buf) return 1; } -char* ha_parseword(ha_buffer_t* buf, const char* delims) +char* ha_bufparseword(ha_buffer_t* buf, const char* delims) { char* word = NULL; @@ -185,7 +186,7 @@ char* ha_parseword(ha_buffer_t* buf, const char* delims) return word; } -char* ha_parseline(ha_buffer_t* buf, int trim) +char* ha_bufparseline(ha_buffer_t* buf, int trim) { char* t; char* line = NULL; @@ -231,55 +232,93 @@ char* ha_parseline(ha_buffer_t* buf, int trim) return line; } -void ha_bufnext(ha_buffer_t* buf) -{ - buffer_bump(buf, 1); - - if(!ha_buferr(buf)) - { - buf->_rp++; - buf->_pp = buf->_rp; - *(buf->_rp) = 0; - } -} - -void ha_bufcat(ha_buffer_t* buf, ...) +char* ha_bufmcat(ha_buffer_t* buf, ...) { const char* str; va_list ap; va_start(ap, buf); + if(ha_buferr(buf)) + return NULL; + + /* Move up the block pointer if we're not joining strings */ + if(ha_buflen(buf) > 0 && *(buf->_rp - 1) != 0) + buf->_pp = buf->_rp; + while((str = va_arg(ap, char*)) != NULL) { int len = strlen(str); - buffer_bump(buf, len); + /* Always add one for the terminating char */ + buffer_bump(buf, len + 1); if(ha_buferr(buf)) - return; + return NULL; - /* _rpoint points to teh null */ + /* _rp always points to the next write point */ strcpy(buf->_rp, str); buf->_rp += len; } + + buf->_rp++; + return buf->_pp; +} + +char* ha_bufcpy(ha_buffer_t* buf, const char* src) +{ + size_t len = strlen(src); + return ha_bufncpy(buf, src, len); +} + +char* ha_bufncpy(ha_buffer_t* buf, const char* src, size_t len) +{ + if(ha_buferr(buf)) + return NULL; + + /* Move up the block pointer if we're not joining strings */ + if(ha_buflen(buf) > 0 && *(buf->_rp - 1) != 0) + buf->_pp = buf->_rp; + + /* Always add one for the terminating char */ + buffer_bump(buf, len + 1); + + if(ha_buferr(buf)) + return NULL; + + memcpy(buf->_rp, src, len * sizeof(char)); + buf->_rp += (len + 1); + *(buf->_rp - 1) = 0; + return buf->_pp; } void* ha_bufmalloc(ha_buffer_t* buf, size_t sz) { void* ret; - ha_bufnext(buf); + if(ha_buferr(buf)) + return NULL; + + /* TODO: Align memory on an appropriate boundary here */ + + /* We're not working with strings so always bump the pointer up */ + buf->_pp = buf->_rp; + buffer_bump(buf, sz); - buf->_rp += sz; if(ha_buferr(buf)) return NULL; - ret = (void*)ha_bufdata(buf); - ha_bufnext(buf); + buf->_rp += sz; + return (void*)buf->_pp; +} - return ret; +void* ha_bufmemdup(ha_buffer_t* buf, const void* src, size_t bytes) +{ + void* mem = ha_bufmalloc(buf, bytes); + if(mem) + memcpy(mem, src, bytes); + return mem; } /* @@ -311,14 +350,15 @@ static const char BASE64C[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char PAD64C = '='; -void ha_bufenc64(ha_buffer_t* buf, const char* src, int len) +char* ha_bufenc64(ha_buffer_t* buf, const void* source, size_t len) { unsigned char input[3]; unsigned char output[4]; + unsigned char* src = (unsigned char*)source; size_t i; - if(len == -1) - len = strlen(src); + if(ha_buferr(buf)) + return NULL; while(2 < len) { @@ -332,10 +372,11 @@ void ha_bufenc64(ha_buffer_t* buf, const char* src, int len) output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); output[3] = input[2] & 0x3f; + /* This also accounts for the null terminator */ buffer_bump(buf, 5); if(ha_buferr(buf)) - return; + return NULL; *(buf->_rp++) = BASE64C[output[0]]; *(buf->_rp++) = BASE64C[output[1]]; @@ -355,10 +396,11 @@ void ha_bufenc64(ha_buffer_t* buf, const char* src, int len) output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + /* This also accounts for the null terminator */ buffer_bump(buf, 5); if(ha_buferr(buf)) - return; + return NULL; *(buf->_rp++) = BASE64C[output[0]]; *(buf->_rp++) = BASE64C[output[1]]; @@ -370,17 +412,23 @@ void ha_bufenc64(ha_buffer_t* buf, const char* src, int len) } *(buf->_rp++) = '\0'; + return buf->_pp; } -void ha_bufdec64(ha_buffer_t* buf, const char* src) +void* ha_bufdec64(ha_buffer_t* buf, const char* src, size_t bytes) { - int state; + int state = 0; int ch; char* pos; + size_t done = 0; - state = 0; + if(ha_buferr(buf)) + return NULL; - while((ch = *src++) != '\0') + if(bytes == 0) + bytes = ~0; + + while((ch = *src++) != '\0' && done < bytes) { if(isspace(ch)) /* Skip whitespace anywhere. */ continue; @@ -401,23 +449,27 @@ void ha_bufdec64(ha_buffer_t* buf, const char* src) { case 0: *(buf->_rp++) = (pos - BASE64C) << 2; + done++; state = 1; break; case 1: *(buf->_rp++) |= (pos - BASE64C) >> 4; + done++; *(buf->_rp) = ((pos - BASE64C) & 0x0f) << 4; state = 2; break; case 2: *(buf->_rp++) |= (pos - BASE64C) >> 2; + done++; *(buf->_rp) = ((pos - BASE64C) & 0x03) << 6; state = 3; break; case 3: *(buf->_rp++) |= (pos - BASE64C); + done++; state = 0; break; }; @@ -425,5 +477,89 @@ void ha_bufdec64(ha_buffer_t* buf, const char* src) /* TODO: Validate ending and return error if invalid somehow */ } - *(buf->_rp++) = '\0'; + /* If we were asked for a specific amount of bytes, then return null */ + if(bytes != ~0 && bytes != done) + return NULL; + + return buf->_pp; +} + +static const char HEXC[] = "0123456789ABCDEF"; + +char* ha_bufenchex(ha_buffer_t* buf, const void* source, size_t len) +{ + unsigned char* src = (unsigned char*)source; + unsigned char j; + + buffer_bump(buf, (len * 2) + 1); + + if(ha_buferr(buf)) + return NULL; + + while(len > 0) + { + j = *(src) >> 4 & 0xf; + if(j <= 9) + *(buf->_rp++) = (j + '0'); + else + *(buf->_rp++) = (j + 'a' - 10); + + j = *(src++) & 0xf; + len--; + + if(j <= 9) + *(buf->_rp++) = (j + '0'); + else + *(buf->_rp++) = (j + 'a' - 10); + } + + *(buf->_rp++) = 0; + return buf->_pp; +} + +void* ha_bufdechex(ha_buffer_t* buf, const char* src, size_t bytes) +{ + unsigned short a; + unsigned short b; + size_t done = 0; + char* pos; + + if(bytes != 0) + { + buffer_bump(buf, bytes + 1); + } + else + { + bytes = ~0; + buffer_bump(buf, (strlen(src) / 2) + 1); + } + + if(ha_buferr(buf)) + return NULL; + + while(src[0] && src[1] && done < bytes) + { + /* Find the position */ + pos = strchr(HEXC, src[0]); + if(pos == 0) + break; + + a = HEXC - pos; + + pos = strchr(HEXC, src[1]); + if(pos == 0); + break; + + b = HEXC - pos; + + *(buf->_rp++) = ((a & 0xf) << 4) | (b & 0xf); + src += 2; + done++; + } + + /* If we were asked for a specific amount of bytes, then return null */ + if(bytes != ~0 && bytes != done) + return NULL; + + return buf->_pp; } -- cgit v1.2.3