heimdal: update to lorikeet-heimdal rev 801
[samba.git] / source4 / heimdal / lib / hx509 / env.c
index f868c22488cb4d333909d45b0a302bb90af7c1db..a124e6ea1c35d4753b82c987c7676ea8d33e674e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 2007 - 2008 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: env.c 22349 2007-12-26 19:32:49Z lha $");
+RCSID("$Id: env.c 22677 2008-03-13 17:35:49Z lha $");
 
 /**
  * @page page_env Hx509 enviroment functions
@@ -40,19 +40,13 @@ RCSID("$Id: env.c 22349 2007-12-26 19:32:49Z lha $");
  * See the library functions here: @ref hx509_env
  */
 
-struct hx509_env {
-    struct {
-       char *key;
-       char *value;
-    } *val;
-    size_t len;
-};
-
 /**
- * Allocate a new hx509_env container object.
+ * Add a new key/value pair to the hx509_env.
  *
  * @param context A hx509 context.
- * @param env return a hx509_env structure, free with hx509_env_free().
+ * @param env enviroment to add the enviroment variable too.
+ * @param key key to add
+ * @param value value to add
  *
  * @return An hx509 error code, see hx509_get_error_string().
  *
@@ -60,23 +54,50 @@ struct hx509_env {
  */
 
 int
-hx509_env_init(hx509_context context, hx509_env *env)
+hx509_env_add(hx509_context context, hx509_env *env, 
+             const char *key, const char *value)
 {
-    *env = calloc(1, sizeof(**env));
-    if (*env == NULL) {
+    hx509_env n;
+
+    n = malloc(sizeof(*n));
+    if (n == NULL) {
        hx509_set_error_string(context, 0, ENOMEM, "out of memory");
        return ENOMEM;
     }
+
+    n->type = env_string;
+    n->next = NULL;
+    n->name = strdup(key);
+    if (n->name == NULL) {
+       free(n);
+       return ENOMEM;
+    }
+    n->u.string = strdup(value);
+    if (n->u.string == NULL) {
+       free(n->name);
+       free(n);
+       return ENOMEM;
+    }
+
+    /* add to tail */
+    if (*env) {
+       hx509_env e = *env;
+       while (e->next)
+           e = e->next;
+       e->next = n;
+    } else
+       *env = n;
+
     return 0;
 }
 
 /**
- * Add a new key/value pair to the hx509_env.
+ * Add a new key/binding pair to the hx509_env.
  *
  * @param context A hx509 context.
  * @param env enviroment to add the enviroment variable too.
  * @param key key to add
- * @param value value to add
+ * @param list binding list to add
  *
  * @return An hx509 error code, see hx509_get_error_string().
  *
@@ -84,34 +105,41 @@ hx509_env_init(hx509_context context, hx509_env *env)
  */
 
 int
-hx509_env_add(hx509_context context, hx509_env env, 
-             const char *key, const char *value)
+hx509_env_add_binding(hx509_context context, hx509_env *env, 
+                     const char *key, hx509_env list)
 {
-    void *ptr;
+    hx509_env n;
 
-    ptr = realloc(env->val, sizeof(env->val[0]) * (env->len + 1));
-    if (ptr == NULL) {
+    n = malloc(sizeof(*n));
+    if (n == NULL) {
        hx509_set_error_string(context, 0, ENOMEM, "out of memory");
        return ENOMEM;
     }
-    env->val = ptr;
-    env->val[env->len].key = strdup(key);
-    if (env->val[env->len].key == NULL) {
-       hx509_set_error_string(context, 0, ENOMEM, "out of memory");
-       return ENOMEM;
-    }
-    env->val[env->len].value = strdup(value);
-    if (env->val[env->len].value == NULL) {
-       free(env->val[env->len].key);
-       hx509_set_error_string(context, 0, ENOMEM, "out of memory");
+
+    n->type = env_list;
+    n->next = NULL;
+    n->name = strdup(key);
+    if (n->name == NULL) {
+       free(n);
        return ENOMEM;
     }
-    env->len++;
+    n->u.list = list;
+
+    /* add to tail */
+    if (*env) {
+       hx509_env e = *env;
+       while (e->next)
+           e = e->next;
+       e->next = n;
+    } else
+       *env = n;
+
     return 0;
 }
 
+
 /**
- * Search the hx509_env for a key.
+ * Search the hx509_env for a length based key.
  *
  * @param context A hx509 context.
  * @param env enviroment to add the enviroment variable too.
@@ -127,16 +155,80 @@ const char *
 hx509_env_lfind(hx509_context context, hx509_env env,
                const char *key, size_t len)
 {
-    size_t i;
+    while(env) {
+       if (strncmp(key, env->name ,len) == 0
+           && env->name[len] == '\0' && env->type == env_string) 
+           return env->u.string;
+       env = env->next;
+    }
+    return NULL;
+}
 
-    for (i = 0; i < env->len; i++) {
-       char *s = env->val[i].key;
-       if (strncmp(key, s, len) == 0 && s[len] == '\0')
-           return env->val[i].value;
+/**
+ * Search the hx509_env for a key.
+ *
+ * @param context A hx509 context.
+ * @param env enviroment to add the enviroment variable too.
+ * @param key key to search for.
+ *
+ * @return the value if the key is found, NULL otherwise.
+ *
+ * @ingroup hx509_env
+ */
+
+const char *
+hx509_env_find(hx509_context context, hx509_env env, const char *key)
+{
+    while(env) {
+       if (strcmp(key, env->name) == 0 && env->type == env_string) 
+           return env->u.string;
+       env = env->next;
     }
     return NULL;
 }
 
+/**
+ * Search the hx509_env for a binding.
+ *
+ * @param context A hx509 context.
+ * @param env enviroment to add the enviroment variable too.
+ * @param key key to search for.
+ *
+ * @return the binding if the key is found, NULL if not found.
+ *
+ * @ingroup hx509_env
+ */
+
+hx509_env
+hx509_env_find_binding(hx509_context context,
+                      hx509_env env,
+                      const char *key)
+{
+    while(env) {
+       if (strcmp(key, env->name) == 0 && env->type == env_list)
+           return env->u.list;
+       env = env->next;
+    }
+    return NULL;
+}
+
+static void
+env_free(hx509_env b)
+{
+    while(b) {
+       hx509_env next = b->next;
+
+       if (b->type == env_string)
+           free(b->u.string);
+       else if (b->type == env_list)
+           env_free(b->u.list);
+
+       free(b->name);
+       free(b);
+       b = next;
+    }
+}
+
 /**
  * Free an hx509_env enviroment context.
  *
@@ -148,14 +240,7 @@ hx509_env_lfind(hx509_context context, hx509_env env,
 void
 hx509_env_free(hx509_env *env)
 {
-    size_t i;
-
-    for (i = 0; i < (*env)->len; i++) {
-       free((*env)->val[i].key);
-       free((*env)->val[i].value);
-    }
-    free((*env)->val);
-    free(*env);
+    if (*env)
+       env_free(*env);
     *env = NULL;
 }
-