155682Smarkm/* 290926Snectar * Copyright (c) 1997 - 2002 Kungliga Tekniska H�gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 555682Smarkm * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 955682Smarkm * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1455682Smarkm * notice, this list of conditions and the following disclaimer in the 1555682Smarkm * documentation and/or other materials provided with the distribution. 1655682Smarkm * 1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors 1855682Smarkm * may be used to endorse or promote products derived from this software 1955682Smarkm * without specific prior written permission. 2055682Smarkm * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3155682Smarkm * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "krb5_locl.h" 35102644Snectar#include "store-int.h" 3655682Smarkm 37178825SdfrRCSID("$Id: store_emem.c 21745 2007-07-31 16:11:25Z lha $"); 3855682Smarkm 3955682Smarkmtypedef struct emem_storage{ 4055682Smarkm unsigned char *base; 4155682Smarkm size_t size; 4255682Smarkm size_t len; 4355682Smarkm unsigned char *ptr; 4455682Smarkm}emem_storage; 4555682Smarkm 4655682Smarkmstatic ssize_t 4755682Smarkmemem_fetch(krb5_storage *sp, void *data, size_t size) 4855682Smarkm{ 4955682Smarkm emem_storage *s = (emem_storage*)sp->data; 5055682Smarkm if(s->base + s->len - s->ptr < size) 5155682Smarkm size = s->base + s->len - s->ptr; 5255682Smarkm memmove(data, s->ptr, size); 5355682Smarkm sp->seek(sp, size, SEEK_CUR); 5455682Smarkm return size; 5555682Smarkm} 5655682Smarkm 5755682Smarkmstatic ssize_t 5872445Sassaremem_store(krb5_storage *sp, const void *data, size_t size) 5955682Smarkm{ 6055682Smarkm emem_storage *s = (emem_storage*)sp->data; 6155682Smarkm if(size > s->base + s->size - s->ptr){ 6255682Smarkm void *base; 6355682Smarkm size_t sz, off; 6455682Smarkm off = s->ptr - s->base; 65107207Snectar sz = off + size; 66107207Snectar if (sz < 4096) 67107207Snectar sz *= 2; 6855682Smarkm base = realloc(s->base, sz); 6955682Smarkm if(base == NULL) 7055682Smarkm return 0; 7155682Smarkm s->size = sz; 7255682Smarkm s->base = base; 7355682Smarkm s->ptr = (unsigned char*)base + off; 7455682Smarkm } 7555682Smarkm memmove(s->ptr, data, size); 7655682Smarkm sp->seek(sp, size, SEEK_CUR); 7755682Smarkm return size; 7855682Smarkm} 7955682Smarkm 8055682Smarkmstatic off_t 8155682Smarkmemem_seek(krb5_storage *sp, off_t offset, int whence) 8255682Smarkm{ 8355682Smarkm emem_storage *s = (emem_storage*)sp->data; 8455682Smarkm switch(whence){ 8555682Smarkm case SEEK_SET: 8655682Smarkm if(offset > s->size) 8755682Smarkm offset = s->size; 8855682Smarkm if(offset < 0) 8955682Smarkm offset = 0; 9055682Smarkm s->ptr = s->base + offset; 9155682Smarkm if(offset > s->len) 9255682Smarkm s->len = offset; 9355682Smarkm break; 9455682Smarkm case SEEK_CUR: 9555682Smarkm sp->seek(sp,s->ptr - s->base + offset, SEEK_SET); 9655682Smarkm break; 9755682Smarkm case SEEK_END: 9855682Smarkm sp->seek(sp, s->len + offset, SEEK_SET); 9955682Smarkm break; 10055682Smarkm default: 10155682Smarkm errno = EINVAL; 10255682Smarkm return -1; 10355682Smarkm } 10455682Smarkm return s->ptr - s->base; 10555682Smarkm} 10655682Smarkm 10755682Smarkmstatic void 10855682Smarkmemem_free(krb5_storage *sp) 10955682Smarkm{ 11090926Snectar emem_storage *s = sp->data; 11190926Snectar memset(s->base, 0, s->len); 11290926Snectar free(s->base); 11355682Smarkm} 11455682Smarkm 115178825Sdfrkrb5_storage * KRB5_LIB_FUNCTION 11655682Smarkmkrb5_storage_emem(void) 11755682Smarkm{ 11855682Smarkm krb5_storage *sp = malloc(sizeof(krb5_storage)); 119178825Sdfr if (sp == NULL) 120178825Sdfr return NULL; 12155682Smarkm emem_storage *s = malloc(sizeof(*s)); 122178825Sdfr if (s == NULL) { 123178825Sdfr free(sp); 124178825Sdfr return NULL; 125178825Sdfr } 12655682Smarkm sp->data = s; 12755682Smarkm sp->flags = 0; 128102644Snectar sp->eof_code = HEIM_ERR_EOF; 12955682Smarkm s->size = 1024; 13055682Smarkm s->base = malloc(s->size); 131178825Sdfr if (s->base == NULL) { 132178825Sdfr free(sp); 133178825Sdfr free(s); 134178825Sdfr return NULL; 135178825Sdfr } 13655682Smarkm s->len = 0; 13755682Smarkm s->ptr = s->base; 13855682Smarkm sp->fetch = emem_fetch; 13955682Smarkm sp->store = emem_store; 14055682Smarkm sp->seek = emem_seek; 14155682Smarkm sp->free = emem_free; 14255682Smarkm return sp; 14355682Smarkm} 144