]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/objects/o_names.c
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
)(const char *name
);
18 int (*cmp_func
)(const char *a
,const char *b
);
19 void (*free_func
)(const char *, int, const char *);
22 DECLARE_STACK_OF(NAME_FUNCS
)
23 IMPLEMENT_STACK_OF(NAME_FUNCS
)
25 static STACK_OF(NAME_FUNCS
) *name_funcs_stack
;
27 /* The LHASH callbacks now use the raw "void *" prototypes and do per-variable
28 * casting in the functions. This prevents function pointer casting without the
29 * need for macro-generated wrapper functions. */
31 /* static unsigned long obj_name_hash(OBJ_NAME *a); */
32 static unsigned long obj_name_hash(const void *a_void
);
33 /* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */
34 static int obj_name_cmp(const void *a_void
,const void *b_void
);
36 int OBJ_NAME_init(void)
38 if (names_lh
!= NULL
) return(1);
40 names_lh
=lh_new(obj_name_hash
, obj_name_cmp
);
42 return(names_lh
!= NULL
);
45 int OBJ_NAME_new_index(unsigned long (*hash_func
)(const char *),
46 int (*cmp_func
)(const char *, const char *),
47 void (*free_func
)(const char *, int, const char *))
51 NAME_FUNCS
*name_funcs
;
53 if (name_funcs_stack
== NULL
)
56 name_funcs_stack
=sk_NAME_FUNCS_new_null();
59 if ((name_funcs_stack
== NULL
))
66 for (i
=sk_NAME_FUNCS_num(name_funcs_stack
); i
<names_type_num
; i
++)
69 name_funcs
= OPENSSL_malloc(sizeof(NAME_FUNCS
));
70 name_funcs
->hash_func
= (LHASH_HASH_FN_TYPE
)lh_strhash
;
71 name_funcs
->cmp_func
= (LHASH_COMP_FN_TYPE
)strcmp
;
72 name_funcs
->free_func
= 0; /* NULL is often declared to
73 * ((void *)0), which according
74 * to Compaq C is not really
75 * compatible with a function
76 * pointer. -- Richard Levitte*/
77 sk_NAME_FUNCS_push(name_funcs_stack
,name_funcs
);
80 name_funcs
= sk_NAME_FUNCS_value(name_funcs_stack
, ret
);
81 if (hash_func
!= NULL
)
82 name_funcs
->hash_func
= hash_func
;
84 name_funcs
->cmp_func
= cmp_func
;
85 if (free_func
!= NULL
)
86 name_funcs
->free_func
= free_func
;
90 /* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */
91 static int obj_name_cmp(const void *a_void
, const void *b_void
)
94 OBJ_NAME
*a
= (OBJ_NAME
*)a_void
;
95 OBJ_NAME
*b
= (OBJ_NAME
*)b_void
;
100 if ((name_funcs_stack
!= NULL
)
101 && (sk_NAME_FUNCS_num(name_funcs_stack
) > a
->type
))
103 ret
=sk_NAME_FUNCS_value(name_funcs_stack
,a
->type
)
104 ->cmp_func(a
->name
,b
->name
);
107 ret
=strcmp(a
->name
,b
->name
);
112 /* static unsigned long obj_name_hash(OBJ_NAME *a) */
113 static unsigned long obj_name_hash(const void *a_void
)
116 OBJ_NAME
*a
= (OBJ_NAME
*)a_void
;
118 if ((name_funcs_stack
!= NULL
) && (sk_NAME_FUNCS_num(name_funcs_stack
) > a
->type
))
120 ret
=sk_NAME_FUNCS_value(name_funcs_stack
,a
->type
)
121 ->hash_func(a
->name
);
125 ret
=lh_strhash(a
->name
);
131 const char *OBJ_NAME_get(const char *name
, int type
)
136 if (name
== NULL
) return(NULL
);
137 if ((names_lh
== NULL
) && !OBJ_NAME_init()) return(NULL
);
139 alias
=type
&OBJ_NAME_ALIAS
;
140 type
&= ~OBJ_NAME_ALIAS
;
147 ret
=(OBJ_NAME
*)lh_retrieve(names_lh
,&on
);
148 if (ret
== NULL
) return(NULL
);
149 if ((ret
->alias
) && !alias
)
151 if (++num
> 10) return(NULL
);
161 int OBJ_NAME_add(const char *name
, int type
, const char *data
)
166 if ((names_lh
== NULL
) && !OBJ_NAME_init()) return(0);
168 alias
=type
&OBJ_NAME_ALIAS
;
169 type
&= ~OBJ_NAME_ALIAS
;
171 onp
=(OBJ_NAME
*)OPENSSL_malloc(sizeof(OBJ_NAME
));
183 ret
=(OBJ_NAME
*)lh_insert(names_lh
,onp
);
187 if ((name_funcs_stack
!= NULL
) && (sk_NAME_FUNCS_num(name_funcs_stack
) > ret
->type
))
189 /* XXX: I'm not sure I understand why the free
190 * function should get three arguments...
193 sk_NAME_FUNCS_value(name_funcs_stack
,ret
->type
)
194 ->free_func(ret
->name
,ret
->type
,ret
->data
);
200 if (lh_error(names_lh
))
209 int OBJ_NAME_remove(const char *name
, int type
)
213 if (names_lh
== NULL
) return(0);
215 type
&= ~OBJ_NAME_ALIAS
;
218 ret
=(OBJ_NAME
*)lh_delete(names_lh
,&on
);
222 if ((name_funcs_stack
!= NULL
) && (sk_NAME_FUNCS_num(name_funcs_stack
) > ret
->type
))
224 /* XXX: I'm not sure I understand why the free
225 * function should get three arguments...
228 sk_NAME_FUNCS_value(name_funcs_stack
,ret
->type
)
229 ->free_func(ret
->name
,ret
->type
,ret
->data
);
241 void (*fn
)(const OBJ_NAME
*,void *arg
);
245 static void do_all_fn(const OBJ_NAME
*name
,struct doall
*d
)
247 if(name
->type
== d
->type
)
251 static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn
, const OBJ_NAME
*, struct doall
*)
253 void OBJ_NAME_do_all(int type
,void (*fn
)(const OBJ_NAME
*,void *arg
),void *arg
)
261 lh_doall_arg(names_lh
,LHASH_DOALL_ARG_FN(do_all_fn
),&d
);
268 const OBJ_NAME
**names
;
271 static void do_all_sorted_fn(const OBJ_NAME
*name
,void *d_
)
273 struct doall_sorted
*d
=d_
;
275 if(name
->type
!= d
->type
)
278 d
->names
[d
->n
++]=name
;
281 static int do_all_sorted_cmp(const void *n1_
,const void *n2_
)
283 const OBJ_NAME
* const *n1
=n1_
;
284 const OBJ_NAME
* const *n2
=n2_
;
286 return strcmp((*n1
)->name
,(*n2
)->name
);
289 void OBJ_NAME_do_all_sorted(int type
,void (*fn
)(const OBJ_NAME
*,void *arg
),
292 struct doall_sorted d
;
296 d
.names
=OPENSSL_malloc(lh_num_items(names_lh
)*sizeof *d
.names
);
298 OBJ_NAME_do_all(type
,do_all_sorted_fn
,&d
);
300 qsort((void *)d
.names
,d
.n
,sizeof *d
.names
,do_all_sorted_cmp
);
302 for(n
=0 ; n
< d
.n
; ++n
)
305 OPENSSL_free((void *)d
.names
);
308 static int free_type
;
310 static void names_lh_free(OBJ_NAME
*onp
)
315 if ((free_type
< 0) || (free_type
== onp
->type
))
317 OBJ_NAME_remove(onp
->name
,onp
->type
);
321 static IMPLEMENT_LHASH_DOALL_FN(names_lh_free
, OBJ_NAME
*)
323 static void name_funcs_free(NAME_FUNCS
*ptr
)
328 void OBJ_NAME_cleanup(int type
)
330 unsigned long down_load
;
332 if (names_lh
== NULL
) return;
335 down_load
=names_lh
->down_load
;
336 names_lh
->down_load
=0;
338 lh_doall(names_lh
,LHASH_DOALL_FN(names_lh_free
));
342 sk_NAME_FUNCS_pop_free(name_funcs_stack
,name_funcs_free
);
344 name_funcs_stack
= NULL
;
347 names_lh
->down_load
=down_load
;