]>
Commit | Line | Data |
---|---|---|
dfeab068 RE |
1 | #include <stdio.h> |
2 | #include <stdlib.h> | |
3 | #include <string.h> | |
4 | ||
ec577822 BM |
5 | #include <openssl/lhash.h> |
6 | #include <openssl/objects.h> | |
1e264ff3 | 7 | #include <openssl/safestack.h> |
a9188d4e | 8 | |
dfeab068 RE |
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. | |
11 | */ | |
12 | static LHASH *names_lh=NULL; | |
13 | static int names_type_num=OBJ_NAME_TYPE_NUM; | |
1e264ff3 RL |
14 | |
15 | typedef struct name_funcs_st | |
16 | { | |
17 | unsigned long (*hash_func)(); | |
18 | int (*cmp_func)(); | |
19 | void (*free_func)(); | |
20 | } NAME_FUNCS; | |
21 | ||
22 | DECLARE_STACK_OF(NAME_FUNCS) | |
23 | IMPLEMENT_STACK_OF(NAME_FUNCS) | |
24 | ||
25 | STACK_OF(NAME_FUNCS) *name_funcs_stack; | |
dfeab068 RE |
26 | |
27 | static unsigned long obj_name_hash(OBJ_NAME *a); | |
28 | static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); | |
29 | ||
6b691a5c | 30 | int OBJ_NAME_init(void) |
dfeab068 RE |
31 | { |
32 | if (names_lh != NULL) return(1); | |
33 | MemCheck_off(); | |
34 | names_lh=lh_new(obj_name_hash,obj_name_cmp); | |
35 | MemCheck_on(); | |
36 | return(names_lh != NULL); | |
37 | } | |
38 | ||
6b691a5c UM |
39 | int OBJ_NAME_new_index(unsigned long (*hash_func)(), int (*cmp_func)(), |
40 | void (*free_func)()) | |
dfeab068 RE |
41 | { |
42 | int ret; | |
43 | int i; | |
1e264ff3 RL |
44 | NAME_FUNCS *name_funcs; |
45 | ||
46 | if (name_funcs_stack == NULL) | |
dfeab068 RE |
47 | { |
48 | MemCheck_off(); | |
1e264ff3 | 49 | name_funcs_stack=sk_NAME_FUNCS_new_null(); |
dfeab068 RE |
50 | MemCheck_on(); |
51 | } | |
1e264ff3 | 52 | if ((name_funcs_stack == NULL)) |
dfeab068 RE |
53 | { |
54 | /* ERROR */ | |
55 | return(0); | |
56 | } | |
57 | ret=names_type_num; | |
58 | names_type_num++; | |
1e264ff3 | 59 | for (i=sk_NAME_FUNCS_num(name_funcs_stack); i<names_type_num; i++) |
dfeab068 RE |
60 | { |
61 | MemCheck_off(); | |
1e264ff3 RL |
62 | name_funcs = Malloc(sizeof(NAME_FUNCS)); |
63 | name_funcs->hash_func = lh_strhash; | |
64 | name_funcs->cmp_func = strcmp; | |
65 | name_funcs->free_func = 0; /* NULL is often declared to | |
66 | * ((void *)0), which according | |
67 | * to Compaq C is not really | |
68 | * compatible with a function | |
69 | * pointer. -- Richard Levitte*/ | |
70 | sk_NAME_FUNCS_push(name_funcs_stack,name_funcs); | |
dfeab068 RE |
71 | MemCheck_on(); |
72 | } | |
1e264ff3 | 73 | name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret); |
dfeab068 | 74 | if (hash_func != NULL) |
1e264ff3 | 75 | name_funcs->hash_func = hash_func; |
dfeab068 | 76 | if (cmp_func != NULL) |
1e264ff3 | 77 | name_funcs->cmp_func = cmp_func; |
dfeab068 | 78 | if (free_func != NULL) |
1e264ff3 | 79 | name_funcs->free_func = free_func; |
dfeab068 RE |
80 | return(ret); |
81 | } | |
82 | ||
6b691a5c | 83 | static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) |
dfeab068 RE |
84 | { |
85 | int ret; | |
dfeab068 RE |
86 | |
87 | ret=a->type-b->type; | |
88 | if (ret == 0) | |
89 | { | |
1e264ff3 RL |
90 | if ((name_funcs_stack != NULL) |
91 | && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) | |
dfeab068 | 92 | { |
1e264ff3 RL |
93 | ret=sk_NAME_FUNCS_value(name_funcs_stack,a->type) |
94 | ->cmp_func(a->name,b->name); | |
dfeab068 RE |
95 | } |
96 | else | |
97 | ret=strcmp(a->name,b->name); | |
98 | } | |
99 | return(ret); | |
100 | } | |
101 | ||
6b691a5c | 102 | static unsigned long obj_name_hash(OBJ_NAME *a) |
dfeab068 RE |
103 | { |
104 | unsigned long ret; | |
dfeab068 | 105 | |
1e264ff3 | 106 | if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) |
dfeab068 | 107 | { |
1e264ff3 RL |
108 | ret=sk_NAME_FUNCS_value(name_funcs_stack,a->type) |
109 | ->hash_func(a->name); | |
dfeab068 RE |
110 | } |
111 | else | |
112 | { | |
113 | ret=lh_strhash(a->name); | |
114 | } | |
115 | ret^=a->type; | |
116 | return(ret); | |
117 | } | |
118 | ||
6b691a5c | 119 | const char *OBJ_NAME_get(const char *name, int type) |
dfeab068 RE |
120 | { |
121 | OBJ_NAME on,*ret; | |
122 | int num=0,alias; | |
123 | ||
124 | if (name == NULL) return(NULL); | |
125 | if ((names_lh == NULL) && !OBJ_NAME_init()) return(NULL); | |
126 | ||
127 | alias=type&OBJ_NAME_ALIAS; | |
128 | type&= ~OBJ_NAME_ALIAS; | |
129 | ||
130 | on.name=name; | |
131 | on.type=type; | |
132 | ||
133 | for (;;) | |
134 | { | |
9d1a01be | 135 | ret=(OBJ_NAME *)lh_retrieve(names_lh,&on); |
dfeab068 RE |
136 | if (ret == NULL) return(NULL); |
137 | if ((ret->alias) && !alias) | |
138 | { | |
139 | if (++num > 10) return(NULL); | |
140 | on.name=ret->data; | |
141 | } | |
142 | else | |
143 | { | |
144 | return(ret->data); | |
145 | } | |
146 | } | |
147 | } | |
148 | ||
6b691a5c | 149 | int OBJ_NAME_add(const char *name, int type, const char *data) |
dfeab068 | 150 | { |
dfeab068 RE |
151 | OBJ_NAME *onp,*ret; |
152 | int alias; | |
153 | ||
154 | if ((names_lh == NULL) && !OBJ_NAME_init()) return(0); | |
155 | ||
156 | alias=type&OBJ_NAME_ALIAS; | |
157 | type&= ~OBJ_NAME_ALIAS; | |
158 | ||
159 | onp=(OBJ_NAME *)Malloc(sizeof(OBJ_NAME)); | |
160 | if (onp == NULL) | |
161 | { | |
162 | /* ERROR */ | |
163 | return(0); | |
164 | } | |
165 | ||
166 | onp->name=name; | |
167 | onp->alias=alias; | |
168 | onp->type=type; | |
169 | onp->data=data; | |
170 | ||
9d1a01be | 171 | ret=(OBJ_NAME *)lh_insert(names_lh,onp); |
dfeab068 RE |
172 | if (ret != NULL) |
173 | { | |
174 | /* free things */ | |
1e264ff3 | 175 | if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) |
dfeab068 | 176 | { |
1e264ff3 RL |
177 | /* XXX: I'm not sure I understand why the free |
178 | * function should get three arguments... | |
179 | * -- Richard Levitte | |
180 | */ | |
181 | sk_NAME_FUNCS_value(name_funcs_stack,ret->type) | |
182 | ->free_func(ret->name,ret->type,ret->data); | |
dfeab068 RE |
183 | } |
184 | Free((char *)ret); | |
185 | } | |
186 | else | |
187 | { | |
188 | if (lh_error(names_lh)) | |
189 | { | |
190 | /* ERROR */ | |
191 | return(0); | |
192 | } | |
193 | } | |
194 | return(1); | |
195 | } | |
196 | ||
6b691a5c | 197 | int OBJ_NAME_remove(const char *name, int type) |
dfeab068 RE |
198 | { |
199 | OBJ_NAME on,*ret; | |
dfeab068 RE |
200 | |
201 | if (names_lh == NULL) return(0); | |
202 | ||
203 | type&= ~OBJ_NAME_ALIAS; | |
204 | on.name=name; | |
205 | on.type=type; | |
9d1a01be | 206 | ret=(OBJ_NAME *)lh_delete(names_lh,&on); |
dfeab068 RE |
207 | if (ret != NULL) |
208 | { | |
209 | /* free things */ | |
1e264ff3 | 210 | if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) |
dfeab068 | 211 | { |
1e264ff3 RL |
212 | /* XXX: I'm not sure I understand why the free |
213 | * function should get three arguments... | |
214 | * -- Richard Levitte | |
215 | */ | |
216 | sk_NAME_FUNCS_value(name_funcs_stack,ret->type) | |
217 | ->free_func(ret->name,ret->type,ret->data); | |
dfeab068 RE |
218 | } |
219 | Free((char *)ret); | |
220 | return(1); | |
221 | } | |
222 | else | |
223 | return(0); | |
224 | } | |
225 | ||
226 | static int free_type; | |
227 | ||
6b691a5c UM |
228 | static void names_lh_free(OBJ_NAME *onp, int type) |
229 | { | |
f9e6fac3 BL |
230 | if(onp == NULL) |
231 | return; | |
232 | ||
dfeab068 RE |
233 | if ((free_type < 0) || (free_type == onp->type)) |
234 | { | |
235 | OBJ_NAME_remove(onp->name,onp->type); | |
236 | } | |
237 | } | |
238 | ||
1e264ff3 RL |
239 | static void name_funcs_free(NAME_FUNCS *ptr) |
240 | { | |
241 | Free(ptr); | |
242 | } | |
243 | ||
6b691a5c | 244 | void OBJ_NAME_cleanup(int type) |
dfeab068 RE |
245 | { |
246 | unsigned long down_load; | |
247 | ||
248 | if (names_lh == NULL) return; | |
249 | ||
250 | free_type=type; | |
251 | down_load=names_lh->down_load; | |
252 | names_lh->down_load=0; | |
253 | ||
254 | lh_doall(names_lh,names_lh_free); | |
255 | if (type < 0) | |
256 | { | |
257 | lh_free(names_lh); | |
1e264ff3 | 258 | sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free); |
dfeab068 | 259 | names_lh=NULL; |
1e264ff3 | 260 | name_funcs_stack = NULL; |
dfeab068 RE |
261 | } |
262 | else | |
263 | names_lh->down_load=down_load; | |
264 | } | |
265 |