/*1* Copyright (c) 2007 - 2008 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#include "hx_locl.h"3435/**36* @page page_env Hx509 enviroment functions37*38* See the library functions here: @ref hx509_env39*/4041/**42* Add a new key/value pair to the hx509_env.43*44* @param context A hx509 context.45* @param env enviroment to add the enviroment variable too.46* @param key key to add47* @param value value to add48*49* @return An hx509 error code, see hx509_get_error_string().50*51* @ingroup hx509_env52*/5354int55hx509_env_add(hx509_context context, hx509_env *env,56const char *key, const char *value)57{58hx509_env n;5960n = malloc(sizeof(*n));61if (n == NULL) {62hx509_set_error_string(context, 0, ENOMEM, "out of memory");63return ENOMEM;64}6566n->type = env_string;67n->next = NULL;68n->name = strdup(key);69if (n->name == NULL) {70free(n);71return ENOMEM;72}73n->u.string = strdup(value);74if (n->u.string == NULL) {75free(n->name);76free(n);77return ENOMEM;78}7980/* add to tail */81if (*env) {82hx509_env e = *env;83while (e->next)84e = e->next;85e->next = n;86} else87*env = n;8889return 0;90}9192/**93* Add a new key/binding pair to the hx509_env.94*95* @param context A hx509 context.96* @param env enviroment to add the enviroment variable too.97* @param key key to add98* @param list binding list to add99*100* @return An hx509 error code, see hx509_get_error_string().101*102* @ingroup hx509_env103*/104105int106hx509_env_add_binding(hx509_context context, hx509_env *env,107const char *key, hx509_env list)108{109hx509_env n;110111n = malloc(sizeof(*n));112if (n == NULL) {113hx509_set_error_string(context, 0, ENOMEM, "out of memory");114return ENOMEM;115}116117n->type = env_list;118n->next = NULL;119n->name = strdup(key);120if (n->name == NULL) {121free(n);122return ENOMEM;123}124n->u.list = list;125126/* add to tail */127if (*env) {128hx509_env e = *env;129while (e->next)130e = e->next;131e->next = n;132} else133*env = n;134135return 0;136}137138139/**140* Search the hx509_env for a length based key.141*142* @param context A hx509 context.143* @param env enviroment to add the enviroment variable too.144* @param key key to search for.145* @param len length of key.146*147* @return the value if the key is found, NULL otherwise.148*149* @ingroup hx509_env150*/151152const char *153hx509_env_lfind(hx509_context context, hx509_env env,154const char *key, size_t len)155{156while(env) {157if (strncmp(key, env->name ,len) == 0158&& env->name[len] == '\0' && env->type == env_string)159return env->u.string;160env = env->next;161}162return NULL;163}164165/**166* Search the hx509_env for a key.167*168* @param context A hx509 context.169* @param env enviroment to add the enviroment variable too.170* @param key key to search for.171*172* @return the value if the key is found, NULL otherwise.173*174* @ingroup hx509_env175*/176177const char *178hx509_env_find(hx509_context context, hx509_env env, const char *key)179{180while(env) {181if (strcmp(key, env->name) == 0 && env->type == env_string)182return env->u.string;183env = env->next;184}185return NULL;186}187188/**189* Search the hx509_env for a binding.190*191* @param context A hx509 context.192* @param env enviroment to add the enviroment variable too.193* @param key key to search for.194*195* @return the binding if the key is found, NULL if not found.196*197* @ingroup hx509_env198*/199200hx509_env201hx509_env_find_binding(hx509_context context,202hx509_env env,203const char *key)204{205while(env) {206if (strcmp(key, env->name) == 0 && env->type == env_list)207return env->u.list;208env = env->next;209}210return NULL;211}212213static void214env_free(hx509_env b)215{216while(b) {217hx509_env next = b->next;218219if (b->type == env_string)220free(b->u.string);221else if (b->type == env_list)222env_free(b->u.list);223224free(b->name);225free(b);226b = next;227}228}229230/**231* Free an hx509_env enviroment context.232*233* @param env the enviroment to free.234*235* @ingroup hx509_env236*/237238void239hx509_env_free(hx509_env *env)240{241if (*env)242env_free(*env);243*env = NULL;244}245246247