1/*	$NetBSD: env.c,v 1.1.1.1 2011/04/13 18:15:10 elric Exp $	*/
2
3/*
4 * Copyright (c) 2007 - 2008 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the Institute nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include "hx_locl.h"
37
38/**
39 * @page page_env Hx509 enviroment functions
40 *
41 * See the library functions here: @ref hx509_env
42 */
43
44/**
45 * Add a new key/value pair to the hx509_env.
46 *
47 * @param context A hx509 context.
48 * @param env enviroment to add the enviroment variable too.
49 * @param key key to add
50 * @param value value to add
51 *
52 * @return An hx509 error code, see hx509_get_error_string().
53 *
54 * @ingroup hx509_env
55 */
56
57int
58hx509_env_add(hx509_context context, hx509_env *env,
59	      const char *key, const char *value)
60{
61    hx509_env n;
62
63    n = malloc(sizeof(*n));
64    if (n == NULL) {
65	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
66	return ENOMEM;
67    }
68
69    n->type = env_string;
70    n->next = NULL;
71    n->name = strdup(key);
72    if (n->name == NULL) {
73	free(n);
74	return ENOMEM;
75    }
76    n->u.string = strdup(value);
77    if (n->u.string == NULL) {
78	free(n->name);
79	free(n);
80	return ENOMEM;
81    }
82
83    /* add to tail */
84    if (*env) {
85	hx509_env e = *env;
86	while (e->next)
87	    e = e->next;
88	e->next = n;
89    } else
90	*env = n;
91
92    return 0;
93}
94
95/**
96 * Add a new key/binding pair to the hx509_env.
97 *
98 * @param context A hx509 context.
99 * @param env enviroment to add the enviroment variable too.
100 * @param key key to add
101 * @param list binding list to add
102 *
103 * @return An hx509 error code, see hx509_get_error_string().
104 *
105 * @ingroup hx509_env
106 */
107
108int
109hx509_env_add_binding(hx509_context context, hx509_env *env,
110		      const char *key, hx509_env list)
111{
112    hx509_env n;
113
114    n = malloc(sizeof(*n));
115    if (n == NULL) {
116	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
117	return ENOMEM;
118    }
119
120    n->type = env_list;
121    n->next = NULL;
122    n->name = strdup(key);
123    if (n->name == NULL) {
124	free(n);
125	return ENOMEM;
126    }
127    n->u.list = list;
128
129    /* add to tail */
130    if (*env) {
131	hx509_env e = *env;
132	while (e->next)
133	    e = e->next;
134	e->next = n;
135    } else
136	*env = n;
137
138    return 0;
139}
140
141
142/**
143 * Search the hx509_env for a length based key.
144 *
145 * @param context A hx509 context.
146 * @param env enviroment to add the enviroment variable too.
147 * @param key key to search for.
148 * @param len length of key.
149 *
150 * @return the value if the key is found, NULL otherwise.
151 *
152 * @ingroup hx509_env
153 */
154
155const char *
156hx509_env_lfind(hx509_context context, hx509_env env,
157		const char *key, size_t len)
158{
159    while(env) {
160	if (strncmp(key, env->name ,len) == 0
161	    && env->name[len] == '\0' && env->type == env_string)
162	    return env->u.string;
163	env = env->next;
164    }
165    return NULL;
166}
167
168/**
169 * Search the hx509_env for a key.
170 *
171 * @param context A hx509 context.
172 * @param env enviroment to add the enviroment variable too.
173 * @param key key to search for.
174 *
175 * @return the value if the key is found, NULL otherwise.
176 *
177 * @ingroup hx509_env
178 */
179
180const char *
181hx509_env_find(hx509_context context, hx509_env env, const char *key)
182{
183    while(env) {
184	if (strcmp(key, env->name) == 0 && env->type == env_string)
185	    return env->u.string;
186	env = env->next;
187    }
188    return NULL;
189}
190
191/**
192 * Search the hx509_env for a binding.
193 *
194 * @param context A hx509 context.
195 * @param env enviroment to add the enviroment variable too.
196 * @param key key to search for.
197 *
198 * @return the binding if the key is found, NULL if not found.
199 *
200 * @ingroup hx509_env
201 */
202
203hx509_env
204hx509_env_find_binding(hx509_context context,
205		       hx509_env env,
206		       const char *key)
207{
208    while(env) {
209	if (strcmp(key, env->name) == 0 && env->type == env_list)
210	    return env->u.list;
211	env = env->next;
212    }
213    return NULL;
214}
215
216static void
217env_free(hx509_env b)
218{
219    while(b) {
220	hx509_env next = b->next;
221
222	if (b->type == env_string)
223	    free(b->u.string);
224	else if (b->type == env_list)
225	    env_free(b->u.list);
226
227	free(b->name);
228	free(b);
229	b = next;
230    }
231}
232
233/**
234 * Free an hx509_env enviroment context.
235 *
236 * @param env the enviroment to free.
237 *
238 * @ingroup hx509_env
239 */
240
241void
242hx509_env_free(hx509_env *env)
243{
244    if (*env)
245	env_free(*env);
246    *env = NULL;
247}
248