5 #include <openssl/lhash.h>
6 #include <openssl/objects.h>
7 #include <openssl/safestack.h>
9 /* I use the ex_data stuff to manage the identifiers for the obj_name_types
10 * that applications may define. I only really use the free function field.
12 static LHASH *names_lh=NULL;
13 static int names_type_num=OBJ_NAME_TYPE_NUM;
15 typedef struct name_funcs_st
17 unsigned long (*hash_func)();
22 DECLARE_STACK_OF(NAME_FUNCS)
23 /* This block of defines is updated by a perl script, please do not touch! */
24 #ifndef DEBUG_SAFESTACK
25 #define sk_NAME_FUNCS_new(a) sk_new((int (*) \
26 (const char * const *, const char * const *))(a))
27 #define sk_NAME_FUNCS_new_null() sk_new_null()
28 #define sk_NAME_FUNCS_free(a) sk_free(a)
29 #define sk_NAME_FUNCS_num(a) sk_num(a)
30 #define sk_NAME_FUNCS_value(a,b) ((NAME_FUNCS *) \
32 #define sk_NAME_FUNCS_set(a,b,c) ((NAME_FUNCS *) \
33 sk_set((a),(b),(char *)(c)))
34 #define sk_NAME_FUNCS_zero(a) sk_zero(a)
35 #define sk_NAME_FUNCS_push(a,b) sk_push((a),(char *)(b))
36 #define sk_NAME_FUNCS_unshift(a,b) sk_unshift((a),(b))
37 #define sk_NAME_FUNCS_find(a,b) sk_find((a), (char *)(b))
38 #define sk_NAME_FUNCS_delete(a,b) ((NAME_FUNCS *) \
40 #define sk_NAME_FUNCS_delete_ptr(a,b) ((NAME_FUNCS *) \
41 sk_delete_ptr((a),(char *)(b)))
42 #define sk_NAME_FUNCS_insert(a,b,c) sk_insert((a),(char *)(b),(c))
43 #define sk_NAME_FUNCS_set_cmp_func(a,b) ((int (*) \
44 (const NAME_FUNCS * const *,const NAME_FUNCS * const *)) \
45 sk_set_cmp_func((a),(int (*) \
46 (const char * const *, const char * const *))(b)))
47 #define sk_NAME_FUNCS_dup(a) sk_dup(a)
48 #define sk_NAME_FUNCS_pop_free(a,b) sk_pop_free((a),(void (*)(void *))(b))
49 #define sk_NAME_FUNCS_shift(a) ((NAME_FUNCS *)sk_shift(a))
50 #define sk_NAME_FUNCS_pop(a) ((NAME_FUNCS *)sk_pop(a))
51 #define sk_NAME_FUNCS_sort(a) sk_sort(a)
52 #endif /* !DEBUG_SAFESTACK */
53 /* End of perl script block, you may now edit :-) */
54 IMPLEMENT_STACK_OF(NAME_FUNCS)
56 static STACK_OF(NAME_FUNCS) *name_funcs_stack;
58 static unsigned long obj_name_hash(OBJ_NAME *a);
59 static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b);
61 int OBJ_NAME_init(void)
63 if (names_lh != NULL) return(1);
65 names_lh=lh_new(obj_name_hash,obj_name_cmp);
67 return(names_lh != NULL);
70 int OBJ_NAME_new_index(unsigned long (*hash_func)(), int (*cmp_func)(),
75 NAME_FUNCS *name_funcs;
77 if (name_funcs_stack == NULL)
80 name_funcs_stack=sk_NAME_FUNCS_new_null();
83 if ((name_funcs_stack == NULL))
90 for (i=sk_NAME_FUNCS_num(name_funcs_stack); i<names_type_num; i++)
93 name_funcs = OPENSSL_malloc(sizeof(NAME_FUNCS));
94 name_funcs->hash_func = lh_strhash;
95 name_funcs->cmp_func = (int (*)())strcmp;
96 name_funcs->free_func = 0; /* NULL is often declared to
97 * ((void *)0), which according
98 * to Compaq C is not really
99 * compatible with a function
100 * pointer. -- Richard Levitte*/
101 sk_NAME_FUNCS_push(name_funcs_stack,name_funcs);
104 name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret);
105 if (hash_func != NULL)
106 name_funcs->hash_func = hash_func;
107 if (cmp_func != NULL)
108 name_funcs->cmp_func = cmp_func;
109 if (free_func != NULL)
110 name_funcs->free_func = free_func;
114 static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b)
121 if ((name_funcs_stack != NULL)
122 && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
124 ret=sk_NAME_FUNCS_value(name_funcs_stack,a->type)
125 ->cmp_func(a->name,b->name);
128 ret=strcmp(a->name,b->name);
133 static unsigned long obj_name_hash(OBJ_NAME *a)
137 if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
139 ret=sk_NAME_FUNCS_value(name_funcs_stack,a->type)
140 ->hash_func(a->name);
144 ret=lh_strhash(a->name);
150 const char *OBJ_NAME_get(const char *name, int type)
155 if (name == NULL) return(NULL);
156 if ((names_lh == NULL) && !OBJ_NAME_init()) return(NULL);
158 alias=type&OBJ_NAME_ALIAS;
159 type&= ~OBJ_NAME_ALIAS;
166 ret=(OBJ_NAME *)lh_retrieve(names_lh,&on);
167 if (ret == NULL) return(NULL);
168 if ((ret->alias) && !alias)
170 if (++num > 10) return(NULL);
180 int OBJ_NAME_add(const char *name, int type, const char *data)
185 if ((names_lh == NULL) && !OBJ_NAME_init()) return(0);
187 alias=type&OBJ_NAME_ALIAS;
188 type&= ~OBJ_NAME_ALIAS;
190 onp=(OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME));
202 ret=(OBJ_NAME *)lh_insert(names_lh,onp);
206 if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
208 /* XXX: I'm not sure I understand why the free
209 * function should get three arguments...
212 sk_NAME_FUNCS_value(name_funcs_stack,ret->type)
213 ->free_func(ret->name,ret->type,ret->data);
219 if (lh_error(names_lh))
228 int OBJ_NAME_remove(const char *name, int type)
232 if (names_lh == NULL) return(0);
234 type&= ~OBJ_NAME_ALIAS;
237 ret=(OBJ_NAME *)lh_delete(names_lh,&on);
241 if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
243 /* XXX: I'm not sure I understand why the free
244 * function should get three arguments...
247 sk_NAME_FUNCS_value(name_funcs_stack,ret->type)
248 ->free_func(ret->name,ret->type,ret->data);
257 static int free_type;
259 static void names_lh_free(OBJ_NAME *onp, int type)
264 if ((free_type < 0) || (free_type == onp->type))
266 OBJ_NAME_remove(onp->name,onp->type);
270 static void name_funcs_free(NAME_FUNCS *ptr)
275 void OBJ_NAME_cleanup(int type)
277 unsigned long down_load;
279 if (names_lh == NULL) return;
282 down_load=names_lh->down_load;
283 names_lh->down_load=0;
285 lh_doall(names_lh,names_lh_free);
289 sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free);
291 name_funcs_stack = NULL;
294 names_lh->down_load=down_load;