]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/objects/o_names.c
5 #include <openssl/err.h>
6 #include <openssl/lhash.h>
7 #include <openssl/objects.h>
8 #include <openssl/safestack.h>
9 #include <openssl/e_os2.h>
11 /* Later versions of DEC C has started to add lnkage information to certain
12 * functions, which makes it tricky to use them as values to regular function
13 * pointers. One way is to define a macro that takes care of casting them
16 #ifdef OPENSSL_SYS_VMS_DECC
17 # define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp
19 # define OPENSSL_strcmp strcmp
22 /* I use the ex_data stuff to manage the identifiers for the obj_name_types
23 * that applications may define. I only really use the free function field.
25 static LHASH
*names_lh
=NULL
;
26 static int names_type_num
=OBJ_NAME_TYPE_NUM
;
28 typedef struct name_funcs_st
30 unsigned long (*hash_func
)(const char *name
);
31 int (*cmp_func
)(const char *a
,const char *b
);
32 void (*free_func
)(const char *, int, const char *);
35 DECLARE_STACK_OF(NAME_FUNCS
)
36 IMPLEMENT_STACK_OF(NAME_FUNCS
)
38 static STACK_OF(NAME_FUNCS
) *name_funcs_stack
;
40 /* The LHASH callbacks now use the raw "void *" prototypes and do per-variable
41 * casting in the functions. This prevents function pointer casting without the
42 * need for macro-generated wrapper functions. */
44 /* static unsigned long obj_name_hash(OBJ_NAME *a); */
45 static unsigned long obj_name_hash(const void *a_void
);
46 /* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */
47 static int obj_name_cmp(const void *a_void
,const void *b_void
);
49 int OBJ_NAME_init(void)
51 if (names_lh
!= NULL
) return(1);
53 names_lh
=lh_new(obj_name_hash
, obj_name_cmp
);
55 return(names_lh
!= NULL
);
58 int OBJ_NAME_new_index(unsigned long (*hash_func
)(const char *),
59 int (*cmp_func
)(const char *, const char *),
60 void (*free_func
)(const char *, int, const char *))
64 NAME_FUNCS
*name_funcs
;
66 if (name_funcs_stack
== NULL
)
69 name_funcs_stack
=sk_NAME_FUNCS_new_null();
72 if ((name_funcs_stack
== NULL
))
79 for (i
=sk_NAME_FUNCS_num(name_funcs_stack
); i
<names_type_num
; i
++)
82 name_funcs
= OPENSSL_malloc(sizeof(NAME_FUNCS
));
86 OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX
,ERR_R_MALLOC_FAILURE
);
89 name_funcs
->hash_func
= lh_strhash
;
90 name_funcs
->cmp_func
= OPENSSL_strcmp
;
91 name_funcs
->free_func
= 0; /* NULL is often declared to
92 * ((void *)0), which according
93 * to Compaq C is not really
94 * compatible with a function
95 * pointer. -- Richard Levitte*/
97 sk_NAME_FUNCS_push(name_funcs_stack
,name_funcs
);
100 name_funcs
= sk_NAME_FUNCS_value(name_funcs_stack
, ret
);
101 if (hash_func
!= NULL
)
102 name_funcs
->hash_func
= hash_func
;
103 if (cmp_func
!= NULL
)
104 name_funcs
->cmp_func
= cmp_func
;
105 if (free_func
!= NULL
)
106 name_funcs
->free_func
= free_func
;
110 /* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */
111 static int obj_name_cmp(const void *a_void
, const void *b_void
)
114 OBJ_NAME
*a
= (OBJ_NAME
*)a_void
;
115 OBJ_NAME
*b
= (OBJ_NAME
*)b_void
;
120 if ((name_funcs_stack
!= NULL
)
121 && (sk_NAME_FUNCS_num(name_funcs_stack
) > a
->type
))
123 ret
=sk_NAME_FUNCS_value(name_funcs_stack
,
124 a
->type
)->cmp_func(a
->name
,b
->name
);
127 ret
=strcmp(a
->name
,b
->name
);
132 /* static unsigned long obj_name_hash(OBJ_NAME *a) */
133 static unsigned long obj_name_hash(const void *a_void
)
136 OBJ_NAME
*a
= (OBJ_NAME
*)a_void
;
138 if ((name_funcs_stack
!= NULL
) && (sk_NAME_FUNCS_num(name_funcs_stack
) > a
->type
))
140 ret
=sk_NAME_FUNCS_value(name_funcs_stack
,
141 a
->type
)->hash_func(a
->name
);
145 ret
=lh_strhash(a
->name
);
151 const char *OBJ_NAME_get(const char *name
, int type
)
156 if (name
== NULL
) return(NULL
);
157 if ((names_lh
== NULL
) && !OBJ_NAME_init()) return(NULL
);
159 alias
=type
&OBJ_NAME_ALIAS
;
160 type
&= ~OBJ_NAME_ALIAS
;
167 ret
=(OBJ_NAME
*)lh_retrieve(names_lh
,&on
);
168 if (ret
== NULL
) return(NULL
);
169 if ((ret
->alias
) && !alias
)
171 if (++num
> 10) return(NULL
);
181 int OBJ_NAME_add(const char *name
, int type
, const char *data
)
186 if ((names_lh
== NULL
) && !OBJ_NAME_init()) return(0);
188 alias
=type
&OBJ_NAME_ALIAS
;
189 type
&= ~OBJ_NAME_ALIAS
;
191 onp
=(OBJ_NAME
*)OPENSSL_malloc(sizeof(OBJ_NAME
));
203 ret
=(OBJ_NAME
*)lh_insert(names_lh
,onp
);
207 if ((name_funcs_stack
!= NULL
) && (sk_NAME_FUNCS_num(name_funcs_stack
) > ret
->type
))
209 /* XXX: I'm not sure I understand why the free
210 * function should get three arguments...
213 sk_NAME_FUNCS_value(name_funcs_stack
,
214 ret
->type
)->free_func(ret
->name
,ret
->type
,ret
->data
);
220 if (lh_error(names_lh
))
229 int OBJ_NAME_remove(const char *name
, int type
)
233 if (names_lh
== NULL
) return(0);
235 type
&= ~OBJ_NAME_ALIAS
;
238 ret
=(OBJ_NAME
*)lh_delete(names_lh
,&on
);
242 if ((name_funcs_stack
!= NULL
) && (sk_NAME_FUNCS_num(name_funcs_stack
) > ret
->type
))
244 /* XXX: I'm not sure I understand why the free
245 * function should get three arguments...
248 sk_NAME_FUNCS_value(name_funcs_stack
,
249 ret
->type
)->free_func(ret
->name
,ret
->type
,ret
->data
);
261 void (*fn
)(const OBJ_NAME
*,void *arg
);
265 static void do_all_fn(const OBJ_NAME
*name
,struct doall
*d
)
267 if(name
->type
== d
->type
)
271 static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn
, const OBJ_NAME
*, struct doall
*)
273 void OBJ_NAME_do_all(int type
,void (*fn
)(const OBJ_NAME
*,void *arg
),void *arg
)
281 lh_doall_arg(names_lh
,LHASH_DOALL_ARG_FN(do_all_fn
),&d
);
288 const OBJ_NAME
**names
;
291 static void do_all_sorted_fn(const OBJ_NAME
*name
,void *d_
)
293 struct doall_sorted
*d
=d_
;
295 if(name
->type
!= d
->type
)
298 d
->names
[d
->n
++]=name
;
301 static int do_all_sorted_cmp(const void *n1_
,const void *n2_
)
303 const OBJ_NAME
* const *n1
=n1_
;
304 const OBJ_NAME
* const *n2
=n2_
;
306 return strcmp((*n1
)->name
,(*n2
)->name
);
309 void OBJ_NAME_do_all_sorted(int type
,void (*fn
)(const OBJ_NAME
*,void *arg
),
312 struct doall_sorted d
;
316 d
.names
=OPENSSL_malloc(lh_num_items(names_lh
)*sizeof *d
.names
);
318 OBJ_NAME_do_all(type
,do_all_sorted_fn
,&d
);
320 qsort((void *)d
.names
,d
.n
,sizeof *d
.names
,do_all_sorted_cmp
);
322 for(n
=0 ; n
< d
.n
; ++n
)
325 OPENSSL_free((void *)d
.names
);
328 static int free_type
;
330 static void names_lh_free(OBJ_NAME
*onp
)
335 if ((free_type
< 0) || (free_type
== onp
->type
))
337 OBJ_NAME_remove(onp
->name
,onp
->type
);
341 static IMPLEMENT_LHASH_DOALL_FN(names_lh_free
, OBJ_NAME
*)
343 static void name_funcs_free(NAME_FUNCS
*ptr
)
348 void OBJ_NAME_cleanup(int type
)
350 unsigned long down_load
;
352 if (names_lh
== NULL
) return;
355 down_load
=names_lh
->down_load
;
356 names_lh
->down_load
=0;
358 lh_doall(names_lh
,LHASH_DOALL_FN(names_lh_free
));
362 sk_NAME_FUNCS_pop_free(name_funcs_stack
,name_funcs_free
);
364 name_funcs_stack
= NULL
;
367 names_lh
->down_load
=down_load
;