]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/objects/o_names.c
d861b6d083177ae3697fb85adf666aa9efac5675
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>
12 * Later versions of DEC C has started to add lnkage information to certain
13 * functions, which makes it tricky to use them as values to regular function
14 * pointers. One way is to define a macro that takes care of casting them
17 #ifdef OPENSSL_SYS_VMS_DECC
18 # define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp
20 # define OPENSSL_strcmp strcmp
24 * I use the ex_data stuff to manage the identifiers for the obj_name_types
25 * that applications may define. I only really use the free function field.
27 DECLARE_LHASH_OF(OBJ_NAME
);
28 static LHASH_OF(OBJ_NAME
) *names_lh
= NULL
;
29 static int names_type_num
= OBJ_NAME_TYPE_NUM
;
31 typedef struct name_funcs_st
{
32 unsigned long (*hash_func
) (const char *name
);
33 int (*cmp_func
) (const char *a
, const char *b
);
34 void (*free_func
) (const char *, int, const char *);
37 DECLARE_STACK_OF(NAME_FUNCS
)
39 static STACK_OF(NAME_FUNCS
) *name_funcs_stack
;
42 * The LHASH callbacks now use the raw "void *" prototypes and do
43 * per-variable casting in the functions. This prevents function pointer
44 * casting without the need for macro-generated wrapper functions.
47 /* static unsigned long obj_name_hash(OBJ_NAME *a); */
48 static unsigned long obj_name_hash(const void *a_void
);
49 /* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */
50 static int obj_name_cmp(const void *a_void
, const void *b_void
);
52 static IMPLEMENT_LHASH_HASH_FN(obj_name
, OBJ_NAME
)
53 static IMPLEMENT_LHASH_COMP_FN(obj_name
, OBJ_NAME
)
55 int OBJ_NAME_init(void)
60 names_lh
= lh_OBJ_NAME_new();
62 return (names_lh
!= NULL
);
65 int OBJ_NAME_new_index(unsigned long (*hash_func
) (const char *),
66 int (*cmp_func
) (const char *, const char *),
67 void (*free_func
) (const char *, int, const char *))
71 NAME_FUNCS
*name_funcs
;
73 if (name_funcs_stack
== NULL
) {
75 name_funcs_stack
= sk_NAME_FUNCS_new_null();
78 if (name_funcs_stack
== NULL
) {
84 for (i
= sk_NAME_FUNCS_num(name_funcs_stack
); i
< names_type_num
; i
++) {
86 name_funcs
= OPENSSL_malloc(sizeof(*name_funcs
));
89 OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX
, ERR_R_MALLOC_FAILURE
);
92 name_funcs
->hash_func
= lh_strhash
;
93 name_funcs
->cmp_func
= OPENSSL_strcmp
;
94 name_funcs
->free_func
= 0; /* NULL is often declared to * ((void
95 * *)0), which according * to Compaq C is
96 * not really * compatible with a function
97 * * pointer. -- Richard Levitte */
99 sk_NAME_FUNCS_push(name_funcs_stack
, name_funcs
);
102 name_funcs
= sk_NAME_FUNCS_value(name_funcs_stack
, ret
);
103 if (hash_func
!= NULL
)
104 name_funcs
->hash_func
= hash_func
;
105 if (cmp_func
!= NULL
)
106 name_funcs
->cmp_func
= cmp_func
;
107 if (free_func
!= NULL
)
108 name_funcs
->free_func
= free_func
;
112 /* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */
113 static int obj_name_cmp(const void *a_void
, const void *b_void
)
116 const OBJ_NAME
*a
= (const OBJ_NAME
*)a_void
;
117 const OBJ_NAME
*b
= (const OBJ_NAME
*)b_void
;
119 ret
= a
->type
- b
->type
;
121 if ((name_funcs_stack
!= NULL
)
122 && (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
);
126 ret
= strcmp(a
->name
, b
->name
);
131 /* static unsigned long obj_name_hash(OBJ_NAME *a) */
132 static unsigned long obj_name_hash(const void *a_void
)
135 const OBJ_NAME
*a
= (const OBJ_NAME
*)a_void
;
137 if ((name_funcs_stack
!= NULL
)
138 && (sk_NAME_FUNCS_num(name_funcs_stack
) > a
->type
)) {
140 sk_NAME_FUNCS_value(name_funcs_stack
,
141 a
->type
)->hash_func(a
->name
);
143 ret
= lh_strhash(a
->name
);
149 const char *OBJ_NAME_get(const char *name
, int type
)
156 if ((names_lh
== NULL
) && !OBJ_NAME_init())
159 alias
= type
& OBJ_NAME_ALIAS
;
160 type
&= ~OBJ_NAME_ALIAS
;
166 ret
= lh_OBJ_NAME_retrieve(names_lh
, &on
);
169 if ((ret
->alias
) && !alias
) {
179 int OBJ_NAME_add(const char *name
, int type
, const char *data
)
184 if ((names_lh
== NULL
) && !OBJ_NAME_init())
187 alias
= type
& OBJ_NAME_ALIAS
;
188 type
&= ~OBJ_NAME_ALIAS
;
190 onp
= OPENSSL_malloc(sizeof(*onp
));
201 ret
= lh_OBJ_NAME_insert(names_lh
, onp
);
204 if ((name_funcs_stack
!= NULL
)
205 && (sk_NAME_FUNCS_num(name_funcs_stack
) > ret
->type
)) {
207 * XXX: I'm not sure I understand why the free function should
208 * get three arguments... -- Richard Levitte
210 sk_NAME_FUNCS_value(name_funcs_stack
,
211 ret
->type
)->free_func(ret
->name
, ret
->type
,
216 if (lh_OBJ_NAME_error(names_lh
)) {
224 int OBJ_NAME_remove(const char *name
, int type
)
228 if (names_lh
== NULL
)
231 type
&= ~OBJ_NAME_ALIAS
;
234 ret
= lh_OBJ_NAME_delete(names_lh
, &on
);
237 if ((name_funcs_stack
!= NULL
)
238 && (sk_NAME_FUNCS_num(name_funcs_stack
) > ret
->type
)) {
240 * XXX: I'm not sure I understand why the free function should
241 * get three arguments... -- Richard Levitte
243 sk_NAME_FUNCS_value(name_funcs_stack
,
244 ret
->type
)->free_func(ret
->name
, ret
->type
,
255 void (*fn
) (const OBJ_NAME
*, void *arg
);
259 static void do_all_fn_doall_arg(const OBJ_NAME
*name
, struct doall
*d
)
261 if (name
->type
== d
->type
)
265 static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn
, const OBJ_NAME
, struct doall
)
267 void OBJ_NAME_do_all(int type
, void (*fn
) (const OBJ_NAME
*, void *arg
),
276 lh_OBJ_NAME_doall_arg(names_lh
, LHASH_DOALL_ARG_FN(do_all_fn
),
280 struct doall_sorted
{
283 const OBJ_NAME
**names
;
286 static void do_all_sorted_fn(const OBJ_NAME
*name
, void *d_
)
288 struct doall_sorted
*d
= d_
;
290 if (name
->type
!= d
->type
)
293 d
->names
[d
->n
++] = name
;
296 static int do_all_sorted_cmp(const void *n1_
, const void *n2_
)
298 const OBJ_NAME
*const *n1
= n1_
;
299 const OBJ_NAME
*const *n2
= n2_
;
301 return strcmp((*n1
)->name
, (*n2
)->name
);
304 void OBJ_NAME_do_all_sorted(int type
,
305 void (*fn
) (const OBJ_NAME
*, void *arg
),
308 struct doall_sorted d
;
313 OPENSSL_malloc(sizeof(*d
.names
) * lh_OBJ_NAME_num_items(names_lh
));
314 /* Really should return an error if !d.names...but its a void function! */
317 OBJ_NAME_do_all(type
, do_all_sorted_fn
, &d
);
319 qsort((void *)d
.names
, d
.n
, sizeof(*d
.names
), do_all_sorted_cmp
);
321 for (n
= 0; n
< d
.n
; ++n
)
324 OPENSSL_free((void *)d
.names
);
328 static int free_type
;
330 static void names_lh_free_doall(OBJ_NAME
*onp
)
335 if (free_type
< 0 || free_type
== onp
->type
)
336 OBJ_NAME_remove(onp
->name
, onp
->type
);
339 static IMPLEMENT_LHASH_DOALL_FN(names_lh_free
, OBJ_NAME
)
341 static void name_funcs_free(NAME_FUNCS
*ptr
)
346 void OBJ_NAME_cleanup(int type
)
348 unsigned long down_load
;
350 if (names_lh
== NULL
)
354 down_load
= lh_OBJ_NAME_down_load(names_lh
);
355 lh_OBJ_NAME_down_load(names_lh
) = 0;
357 lh_OBJ_NAME_doall(names_lh
, LHASH_DOALL_FN(names_lh_free
));
359 lh_OBJ_NAME_free(names_lh
);
360 sk_NAME_FUNCS_pop_free(name_funcs_stack
, name_funcs_free
);
362 name_funcs_stack
= NULL
;
364 lh_OBJ_NAME_down_load(names_lh
) = down_load
;