1178825Sdfr/*
2233294Sstas * Copyright (c) 2007 - 2008 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
5178825Sdfr *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
9178825Sdfr *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
12178825Sdfr *
13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
14233294Sstas *    notice, this list of conditions and the following disclaimer in the
15233294Sstas *    documentation and/or other materials provided with the distribution.
16178825Sdfr *
17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors
18233294Sstas *    may be used to endorse or promote products derived from this software
19233294Sstas *    without specific prior written permission.
20178825Sdfr *
21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31233294Sstas * SUCH DAMAGE.
32178825Sdfr */
33178825Sdfr
34178825Sdfr#include "hx_locl.h"
35178825Sdfr
36178825Sdfr/**
37178825Sdfr * @page page_env Hx509 enviroment functions
38178825Sdfr *
39178825Sdfr * See the library functions here: @ref hx509_env
40178825Sdfr */
41178825Sdfr
42178825Sdfr/**
43233294Sstas * Add a new key/value pair to the hx509_env.
44178825Sdfr *
45178825Sdfr * @param context A hx509 context.
46233294Sstas * @param env enviroment to add the enviroment variable too.
47233294Sstas * @param key key to add
48233294Sstas * @param value value to add
49178825Sdfr *
50178825Sdfr * @return An hx509 error code, see hx509_get_error_string().
51178825Sdfr *
52178825Sdfr * @ingroup hx509_env
53178825Sdfr */
54178825Sdfr
55178825Sdfrint
56233294Sstashx509_env_add(hx509_context context, hx509_env *env,
57233294Sstas	      const char *key, const char *value)
58178825Sdfr{
59233294Sstas    hx509_env n;
60233294Sstas
61233294Sstas    n = malloc(sizeof(*n));
62233294Sstas    if (n == NULL) {
63178825Sdfr	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
64178825Sdfr	return ENOMEM;
65178825Sdfr    }
66233294Sstas
67233294Sstas    n->type = env_string;
68233294Sstas    n->next = NULL;
69233294Sstas    n->name = strdup(key);
70233294Sstas    if (n->name == NULL) {
71233294Sstas	free(n);
72233294Sstas	return ENOMEM;
73233294Sstas    }
74233294Sstas    n->u.string = strdup(value);
75233294Sstas    if (n->u.string == NULL) {
76233294Sstas	free(n->name);
77233294Sstas	free(n);
78233294Sstas	return ENOMEM;
79233294Sstas    }
80233294Sstas
81233294Sstas    /* add to tail */
82233294Sstas    if (*env) {
83233294Sstas	hx509_env e = *env;
84233294Sstas	while (e->next)
85233294Sstas	    e = e->next;
86233294Sstas	e->next = n;
87233294Sstas    } else
88233294Sstas	*env = n;
89233294Sstas
90178825Sdfr    return 0;
91178825Sdfr}
92178825Sdfr
93178825Sdfr/**
94233294Sstas * Add a new key/binding pair to the hx509_env.
95178825Sdfr *
96178825Sdfr * @param context A hx509 context.
97178825Sdfr * @param env enviroment to add the enviroment variable too.
98178825Sdfr * @param key key to add
99233294Sstas * @param list binding list to add
100178825Sdfr *
101178825Sdfr * @return An hx509 error code, see hx509_get_error_string().
102178825Sdfr *
103178825Sdfr * @ingroup hx509_env
104178825Sdfr */
105178825Sdfr
106178825Sdfrint
107233294Sstashx509_env_add_binding(hx509_context context, hx509_env *env,
108233294Sstas		      const char *key, hx509_env list)
109178825Sdfr{
110233294Sstas    hx509_env n;
111178825Sdfr
112233294Sstas    n = malloc(sizeof(*n));
113233294Sstas    if (n == NULL) {
114178825Sdfr	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
115178825Sdfr	return ENOMEM;
116178825Sdfr    }
117233294Sstas
118233294Sstas    n->type = env_list;
119233294Sstas    n->next = NULL;
120233294Sstas    n->name = strdup(key);
121233294Sstas    if (n->name == NULL) {
122233294Sstas	free(n);
123178825Sdfr	return ENOMEM;
124178825Sdfr    }
125233294Sstas    n->u.list = list;
126233294Sstas
127233294Sstas    /* add to tail */
128233294Sstas    if (*env) {
129233294Sstas	hx509_env e = *env;
130233294Sstas	while (e->next)
131233294Sstas	    e = e->next;
132233294Sstas	e->next = n;
133233294Sstas    } else
134233294Sstas	*env = n;
135233294Sstas
136178825Sdfr    return 0;
137178825Sdfr}
138178825Sdfr
139233294Sstas
140178825Sdfr/**
141233294Sstas * Search the hx509_env for a length based key.
142178825Sdfr *
143178825Sdfr * @param context A hx509 context.
144178825Sdfr * @param env enviroment to add the enviroment variable too.
145178825Sdfr * @param key key to search for.
146178825Sdfr * @param len length of key.
147178825Sdfr *
148178825Sdfr * @return the value if the key is found, NULL otherwise.
149178825Sdfr *
150178825Sdfr * @ingroup hx509_env
151178825Sdfr */
152178825Sdfr
153178825Sdfrconst char *
154178825Sdfrhx509_env_lfind(hx509_context context, hx509_env env,
155178825Sdfr		const char *key, size_t len)
156178825Sdfr{
157233294Sstas    while(env) {
158233294Sstas	if (strncmp(key, env->name ,len) == 0
159233294Sstas	    && env->name[len] == '\0' && env->type == env_string)
160233294Sstas	    return env->u.string;
161233294Sstas	env = env->next;
162233294Sstas    }
163233294Sstas    return NULL;
164233294Sstas}
165178825Sdfr
166233294Sstas/**
167233294Sstas * Search the hx509_env for a key.
168233294Sstas *
169233294Sstas * @param context A hx509 context.
170233294Sstas * @param env enviroment to add the enviroment variable too.
171233294Sstas * @param key key to search for.
172233294Sstas *
173233294Sstas * @return the value if the key is found, NULL otherwise.
174233294Sstas *
175233294Sstas * @ingroup hx509_env
176233294Sstas */
177233294Sstas
178233294Sstasconst char *
179233294Sstashx509_env_find(hx509_context context, hx509_env env, const char *key)
180233294Sstas{
181233294Sstas    while(env) {
182233294Sstas	if (strcmp(key, env->name) == 0 && env->type == env_string)
183233294Sstas	    return env->u.string;
184233294Sstas	env = env->next;
185178825Sdfr    }
186178825Sdfr    return NULL;
187178825Sdfr}
188178825Sdfr
189178825Sdfr/**
190233294Sstas * Search the hx509_env for a binding.
191233294Sstas *
192233294Sstas * @param context A hx509 context.
193233294Sstas * @param env enviroment to add the enviroment variable too.
194233294Sstas * @param key key to search for.
195233294Sstas *
196233294Sstas * @return the binding if the key is found, NULL if not found.
197233294Sstas *
198233294Sstas * @ingroup hx509_env
199233294Sstas */
200233294Sstas
201233294Sstashx509_env
202233294Sstashx509_env_find_binding(hx509_context context,
203233294Sstas		       hx509_env env,
204233294Sstas		       const char *key)
205233294Sstas{
206233294Sstas    while(env) {
207233294Sstas	if (strcmp(key, env->name) == 0 && env->type == env_list)
208233294Sstas	    return env->u.list;
209233294Sstas	env = env->next;
210233294Sstas    }
211233294Sstas    return NULL;
212233294Sstas}
213233294Sstas
214233294Sstasstatic void
215233294Sstasenv_free(hx509_env b)
216233294Sstas{
217233294Sstas    while(b) {
218233294Sstas	hx509_env next = b->next;
219233294Sstas
220233294Sstas	if (b->type == env_string)
221233294Sstas	    free(b->u.string);
222233294Sstas	else if (b->type == env_list)
223233294Sstas	    env_free(b->u.list);
224233294Sstas
225233294Sstas	free(b->name);
226233294Sstas	free(b);
227233294Sstas	b = next;
228233294Sstas    }
229233294Sstas}
230233294Sstas
231233294Sstas/**
232178825Sdfr * Free an hx509_env enviroment context.
233178825Sdfr *
234178825Sdfr * @param env the enviroment to free.
235178825Sdfr *
236178825Sdfr * @ingroup hx509_env
237178825Sdfr */
238178825Sdfr
239178825Sdfrvoid
240178825Sdfrhx509_env_free(hx509_env *env)
241178825Sdfr{
242233294Sstas    if (*env)
243233294Sstas	env_free(*env);
244178825Sdfr    *env = NULL;
245178825Sdfr}
246