diff options
Diffstat (limited to 'src/lib/libcrypto/objects/o_names.c')
-rw-r--r-- | src/lib/libcrypto/objects/o_names.c | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/src/lib/libcrypto/objects/o_names.c b/src/lib/libcrypto/objects/o_names.c new file mode 100644 index 0000000000..4da5e45b9c --- /dev/null +++ b/src/lib/libcrypto/objects/o_names.c | |||
@@ -0,0 +1,243 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | |||
5 | #include <openssl/lhash.h> | ||
6 | #include <openssl/objects.h> | ||
7 | |||
8 | /* I use the ex_data stuff to manage the identifiers for the obj_name_types | ||
9 | * that applications may define. I only really use the free function field. | ||
10 | */ | ||
11 | static LHASH *names_lh=NULL; | ||
12 | static int names_type_num=OBJ_NAME_TYPE_NUM; | ||
13 | static STACK *names_cmp=NULL; | ||
14 | static STACK *names_hash=NULL; | ||
15 | static STACK *names_free=NULL; | ||
16 | |||
17 | static unsigned long obj_name_hash(OBJ_NAME *a); | ||
18 | static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); | ||
19 | |||
20 | int OBJ_NAME_init(void) | ||
21 | { | ||
22 | if (names_lh != NULL) return(1); | ||
23 | MemCheck_off(); | ||
24 | names_lh=lh_new(obj_name_hash,obj_name_cmp); | ||
25 | MemCheck_on(); | ||
26 | return(names_lh != NULL); | ||
27 | } | ||
28 | |||
29 | int OBJ_NAME_new_index(unsigned long (*hash_func)(), int (*cmp_func)(), | ||
30 | void (*free_func)()) | ||
31 | { | ||
32 | int ret; | ||
33 | int i; | ||
34 | |||
35 | if (names_free == NULL) | ||
36 | { | ||
37 | MemCheck_off(); | ||
38 | names_hash=sk_new_null(); | ||
39 | names_cmp=sk_new_null(); | ||
40 | names_free=sk_new_null(); | ||
41 | MemCheck_on(); | ||
42 | } | ||
43 | if ((names_free == NULL) || (names_hash == NULL) || (names_cmp == NULL)) | ||
44 | { | ||
45 | /* ERROR */ | ||
46 | return(0); | ||
47 | } | ||
48 | ret=names_type_num; | ||
49 | names_type_num++; | ||
50 | for (i=sk_num(names_free); i<names_type_num; i++) | ||
51 | { | ||
52 | MemCheck_off(); | ||
53 | sk_push(names_hash,(char *)strcmp); | ||
54 | sk_push(names_cmp,(char *)lh_strhash); | ||
55 | sk_push(names_free,NULL); | ||
56 | MemCheck_on(); | ||
57 | } | ||
58 | if (hash_func != NULL) | ||
59 | sk_set(names_hash,ret,(char *)hash_func); | ||
60 | if (cmp_func != NULL) | ||
61 | sk_set(names_cmp,ret,(char *)cmp_func); | ||
62 | if (free_func != NULL) | ||
63 | sk_set(names_free,ret,(char *)free_func); | ||
64 | return(ret); | ||
65 | } | ||
66 | |||
67 | static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) | ||
68 | { | ||
69 | int ret; | ||
70 | int (*cmp)(); | ||
71 | |||
72 | ret=a->type-b->type; | ||
73 | if (ret == 0) | ||
74 | { | ||
75 | if ((names_cmp != NULL) && (sk_num(names_cmp) > a->type)) | ||
76 | { | ||
77 | cmp=(int (*)())sk_value(names_cmp,a->type); | ||
78 | ret=cmp(a->name,b->name); | ||
79 | } | ||
80 | else | ||
81 | ret=strcmp(a->name,b->name); | ||
82 | } | ||
83 | return(ret); | ||
84 | } | ||
85 | |||
86 | static unsigned long obj_name_hash(OBJ_NAME *a) | ||
87 | { | ||
88 | unsigned long ret; | ||
89 | unsigned long (*hash)(); | ||
90 | |||
91 | if ((names_hash != NULL) && (sk_num(names_hash) > a->type)) | ||
92 | { | ||
93 | hash=(unsigned long (*)())sk_value(names_hash,a->type); | ||
94 | ret=hash(a->name); | ||
95 | } | ||
96 | else | ||
97 | { | ||
98 | ret=lh_strhash(a->name); | ||
99 | } | ||
100 | ret^=a->type; | ||
101 | return(ret); | ||
102 | } | ||
103 | |||
104 | const char *OBJ_NAME_get(const char *name, int type) | ||
105 | { | ||
106 | OBJ_NAME on,*ret; | ||
107 | int num=0,alias; | ||
108 | |||
109 | if (name == NULL) return(NULL); | ||
110 | if ((names_lh == NULL) && !OBJ_NAME_init()) return(NULL); | ||
111 | |||
112 | alias=type&OBJ_NAME_ALIAS; | ||
113 | type&= ~OBJ_NAME_ALIAS; | ||
114 | |||
115 | on.name=name; | ||
116 | on.type=type; | ||
117 | |||
118 | for (;;) | ||
119 | { | ||
120 | ret=(OBJ_NAME *)lh_retrieve(names_lh,(char *)&on); | ||
121 | if (ret == NULL) return(NULL); | ||
122 | if ((ret->alias) && !alias) | ||
123 | { | ||
124 | if (++num > 10) return(NULL); | ||
125 | on.name=ret->data; | ||
126 | } | ||
127 | else | ||
128 | { | ||
129 | return(ret->data); | ||
130 | } | ||
131 | } | ||
132 | } | ||
133 | |||
134 | int OBJ_NAME_add(const char *name, int type, const char *data) | ||
135 | { | ||
136 | void (*f)(); | ||
137 | OBJ_NAME *onp,*ret; | ||
138 | int alias; | ||
139 | |||
140 | if ((names_lh == NULL) && !OBJ_NAME_init()) return(0); | ||
141 | |||
142 | alias=type&OBJ_NAME_ALIAS; | ||
143 | type&= ~OBJ_NAME_ALIAS; | ||
144 | |||
145 | onp=(OBJ_NAME *)Malloc(sizeof(OBJ_NAME)); | ||
146 | if (onp == NULL) | ||
147 | { | ||
148 | /* ERROR */ | ||
149 | return(0); | ||
150 | } | ||
151 | |||
152 | onp->name=name; | ||
153 | onp->alias=alias; | ||
154 | onp->type=type; | ||
155 | onp->data=data; | ||
156 | |||
157 | ret=(OBJ_NAME *)lh_insert(names_lh,(char *)onp); | ||
158 | if (ret != NULL) | ||
159 | { | ||
160 | /* free things */ | ||
161 | if ((names_free != NULL) && (sk_num(names_free) > ret->type)) | ||
162 | { | ||
163 | f=(void (*)())sk_value(names_free,ret->type); | ||
164 | f(ret->name,ret->type,ret->data); | ||
165 | } | ||
166 | Free((char *)ret); | ||
167 | } | ||
168 | else | ||
169 | { | ||
170 | if (lh_error(names_lh)) | ||
171 | { | ||
172 | /* ERROR */ | ||
173 | return(0); | ||
174 | } | ||
175 | } | ||
176 | return(1); | ||
177 | } | ||
178 | |||
179 | int OBJ_NAME_remove(const char *name, int type) | ||
180 | { | ||
181 | OBJ_NAME on,*ret; | ||
182 | void (*f)(); | ||
183 | |||
184 | if (names_lh == NULL) return(0); | ||
185 | |||
186 | type&= ~OBJ_NAME_ALIAS; | ||
187 | on.name=name; | ||
188 | on.type=type; | ||
189 | ret=(OBJ_NAME *)lh_delete(names_lh,(char *)&on); | ||
190 | if (ret != NULL) | ||
191 | { | ||
192 | /* free things */ | ||
193 | if ((names_free != NULL) && (sk_num(names_free) > type)) | ||
194 | { | ||
195 | f=(void (*)())sk_value(names_free,type); | ||
196 | f(ret->name,ret->type,ret->data); | ||
197 | } | ||
198 | Free((char *)ret); | ||
199 | return(1); | ||
200 | } | ||
201 | else | ||
202 | return(0); | ||
203 | } | ||
204 | |||
205 | static int free_type; | ||
206 | |||
207 | static void names_lh_free(OBJ_NAME *onp, int type) | ||
208 | { | ||
209 | if(onp == NULL) | ||
210 | return; | ||
211 | |||
212 | if ((free_type < 0) || (free_type == onp->type)) | ||
213 | { | ||
214 | OBJ_NAME_remove(onp->name,onp->type); | ||
215 | } | ||
216 | } | ||
217 | |||
218 | void OBJ_NAME_cleanup(int type) | ||
219 | { | ||
220 | unsigned long down_load; | ||
221 | |||
222 | if (names_lh == NULL) return; | ||
223 | |||
224 | free_type=type; | ||
225 | down_load=names_lh->down_load; | ||
226 | names_lh->down_load=0; | ||
227 | |||
228 | lh_doall(names_lh,names_lh_free); | ||
229 | if (type < 0) | ||
230 | { | ||
231 | lh_free(names_lh); | ||
232 | sk_free(names_hash); | ||
233 | sk_free(names_cmp); | ||
234 | sk_free(names_free); | ||
235 | names_lh=NULL; | ||
236 | names_hash=NULL; | ||
237 | names_cmp=NULL; | ||
238 | names_free=NULL; | ||
239 | } | ||
240 | else | ||
241 | names_lh->down_load=down_load; | ||
242 | } | ||
243 | |||