1329273Sasomers/*
2329273Sasomers * Copyright (c) 1997 - 2000, 2002 Kungliga Tekniska H�gskolan
3329273Sasomers * (Royal Institute of Technology, Stockholm, Sweden).
4329273Sasomers * All rights reserved.
5329273Sasomers *
6329273Sasomers * Redistribution and use in source and binary forms, with or without
7329273Sasomers * modification, are permitted provided that the following conditions
8329273Sasomers * are met:
9329273Sasomers *
10329273Sasomers * 1. Redistributions of source code must retain the above copyright
11329273Sasomers *    notice, this list of conditions and the following disclaimer.
12329273Sasomers *
13329273Sasomers * 2. Redistributions in binary form must reproduce the above copyright
14329273Sasomers *    notice, this list of conditions and the following disclaimer in the
15329273Sasomers *    documentation and/or other materials provided with the distribution.
16329273Sasomers *
17329273Sasomers * 3. Neither the name of the Institute nor the names of its contributors
18329273Sasomers *    may be used to endorse or promote products derived from this software
19329273Sasomers *    without specific prior written permission.
20329273Sasomers *
21329273Sasomers * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22329273Sasomers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23329273Sasomers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24329273Sasomers * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25329273Sasomers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26329273Sasomers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27345394Sasomers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28345394Sasomers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29329273Sasomers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30329273Sasomers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31329273Sasomers * SUCH DAMAGE.
32329273Sasomers */
33329273Sasomers
34329273Sasomers#include "krb5_locl.h"
35329273Sasomers#include "store-int.h"
36329273Sasomers
37329273SasomersRCSID("$Id: store_mem.c 20307 2007-04-11 11:16:28Z lha $");
38345394Sasomers
39345394Sasomerstypedef struct mem_storage{
40329273Sasomers    unsigned char *base;
41329273Sasomers    size_t size;
42329273Sasomers    unsigned char *ptr;
43329273Sasomers}mem_storage;
44329273Sasomers
45329273Sasomersstatic ssize_t
46329273Sasomersmem_fetch(krb5_storage *sp, void *data, size_t size)
47329273Sasomers{
48329273Sasomers    mem_storage *s = (mem_storage*)sp->data;
49329273Sasomers    if(size > s->base + s->size - s->ptr)
50329273Sasomers	size = s->base + s->size - s->ptr;
51329273Sasomers    memmove(data, s->ptr, size);
52329273Sasomers    sp->seek(sp, size, SEEK_CUR);
53329273Sasomers    return size;
54329273Sasomers}
55329273Sasomers
56329273Sasomersstatic ssize_t
57329273Sasomersmem_store(krb5_storage *sp, const void *data, size_t size)
58329273Sasomers{
59329273Sasomers    mem_storage *s = (mem_storage*)sp->data;
60329273Sasomers    if(size > s->base + s->size - s->ptr)
61329273Sasomers	size = s->base + s->size - s->ptr;
62329273Sasomers    memmove(s->ptr, data, size);
63329273Sasomers    sp->seek(sp, size, SEEK_CUR);
64345394Sasomers    return size;
65345394Sasomers}
66329273Sasomers
67329273Sasomersstatic ssize_t
68329273Sasomersmem_no_store(krb5_storage *sp, const void *data, size_t size)
69329273Sasomers{
70329273Sasomers    return -1;
71329273Sasomers}
72329273Sasomers
73329273Sasomersstatic off_t
74329273Sasomersmem_seek(krb5_storage *sp, off_t offset, int whence)
75329273Sasomers{
76329273Sasomers    mem_storage *s = (mem_storage*)sp->data;
77329273Sasomers    switch(whence){
78329273Sasomers    case SEEK_SET:
79329273Sasomers	if(offset > s->size)
80329273Sasomers	    offset = s->size;
81329273Sasomers	if(offset < 0)
82329273Sasomers	    offset = 0;
83329273Sasomers	s->ptr = s->base + offset;
84329273Sasomers	break;
85329273Sasomers    case SEEK_CUR:
86329273Sasomers	return sp->seek(sp, s->ptr - s->base + offset, SEEK_SET);
87329273Sasomers    case SEEK_END:
88329273Sasomers	return sp->seek(sp, s->size + offset, SEEK_SET);
89329273Sasomers    default:
90329273Sasomers	errno = EINVAL;
91329273Sasomers	return -1;
92329273Sasomers    }
93329273Sasomers    return s->ptr - s->base;
94329273Sasomers}
95329273Sasomers
96329273Sasomerskrb5_storage * KRB5_LIB_FUNCTION
97329273Sasomerskrb5_storage_from_mem(void *buf, size_t len)
98329273Sasomers{
99329273Sasomers    krb5_storage *sp = malloc(sizeof(krb5_storage));
100329273Sasomers    mem_storage *s;
101345394Sasomers    if(sp == NULL)
102345394Sasomers	return NULL;
103345394Sasomers    s = malloc(sizeof(*s));
104345394Sasomers    if(s == NULL) {
105329273Sasomers	free(sp);
106329273Sasomers	return NULL;
107329273Sasomers    }
108329273Sasomers    sp->data = s;
109329273Sasomers    sp->flags = 0;
110329273Sasomers    sp->eof_code = HEIM_ERR_EOF;
111329273Sasomers    s->base = buf;
112329273Sasomers    s->size = len;
113329273Sasomers    s->ptr = buf;
114329273Sasomers    sp->fetch = mem_fetch;
115329273Sasomers    sp->store = mem_store;
116329273Sasomers    sp->seek = mem_seek;
117329273Sasomers    sp->free = NULL;
118329273Sasomers    return sp;
119329273Sasomers}
120329273Sasomers
121329273Sasomerskrb5_storage * KRB5_LIB_FUNCTION
122329273Sasomerskrb5_storage_from_data(krb5_data *data)
123329273Sasomers{
124329273Sasomers    return krb5_storage_from_mem(data->data, data->length);
125329273Sasomers}
126329273Sasomers
127329273Sasomerskrb5_storage * KRB5_LIB_FUNCTION
128329273Sasomerskrb5_storage_from_readonly_mem(const void *buf, size_t len)
129329273Sasomers{
130329273Sasomers    krb5_storage *sp = malloc(sizeof(krb5_storage));
131329273Sasomers    mem_storage *s;
132329273Sasomers    if(sp == NULL)
133329273Sasomers	return NULL;
134329273Sasomers    s = malloc(sizeof(*s));
135329273Sasomers    if(s == NULL) {
136329273Sasomers	free(sp);
137329273Sasomers	return NULL;
138329273Sasomers    }
139329273Sasomers    sp->data = s;
140329273Sasomers    sp->flags = 0;
141329273Sasomers    sp->eof_code = HEIM_ERR_EOF;
142329273Sasomers    s->base = rk_UNCONST(buf);
143329273Sasomers    s->size = len;
144329273Sasomers    s->ptr = rk_UNCONST(buf);
145329273Sasomers    sp->fetch = mem_fetch;
146329273Sasomers    sp->store = mem_no_store;
147329273Sasomers    sp->seek = mem_seek;
148329273Sasomers    sp->free = NULL;
149329273Sasomers    return sp;
150329273Sasomers}
151329273Sasomers