| OLD | NEW |
| 1 #include <stdio.h> | 1 #include <stdio.h> |
| 2 #include <stdlib.h> | 2 #include <stdlib.h> |
| 3 #include <string.h> | 3 #include <string.h> |
| 4 | 4 |
| 5 #include <openssl/err.h> | 5 #include <openssl/err.h> |
| 6 #include <openssl/lhash.h> | 6 #include <openssl/lhash.h> |
| 7 #include <openssl/objects.h> | 7 #include <openssl/objects.h> |
| 8 #include <openssl/safestack.h> | 8 #include <openssl/safestack.h> |
| 9 #include <openssl/e_os2.h> | 9 #include <openssl/e_os2.h> |
| 10 | 10 |
| 11 /* Later versions of DEC C has started to add lnkage information to certain | 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 | 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 | 13 * pointers. One way is to define a macro that takes care of casting them |
| 14 * correctly. | 14 * correctly. |
| 15 */ | 15 */ |
| 16 #ifdef OPENSSL_SYS_VMS_DECC | 16 #ifdef OPENSSL_SYS_VMS_DECC |
| 17 # define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp | 17 # define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp |
| 18 #else | 18 #else |
| 19 # define OPENSSL_strcmp strcmp | 19 # define OPENSSL_strcmp strcmp |
| 20 #endif | 20 #endif |
| 21 | 21 |
| 22 /* I use the ex_data stuff to manage the identifiers for the obj_name_types | 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. | 23 * that applications may define. I only really use the free function field. |
| 24 */ | 24 */ |
| 25 static LHASH *names_lh=NULL; | 25 DECLARE_LHASH_OF(OBJ_NAME); |
| 26 static LHASH_OF(OBJ_NAME) *names_lh=NULL; |
| 26 static int names_type_num=OBJ_NAME_TYPE_NUM; | 27 static int names_type_num=OBJ_NAME_TYPE_NUM; |
| 27 | 28 |
| 28 typedef struct name_funcs_st | 29 typedef struct name_funcs_st |
| 29 { | 30 { |
| 30 unsigned long (*hash_func)(const char *name); | 31 unsigned long (*hash_func)(const char *name); |
| 31 int (*cmp_func)(const char *a,const char *b); | 32 int (*cmp_func)(const char *a,const char *b); |
| 32 void (*free_func)(const char *, int, const char *); | 33 void (*free_func)(const char *, int, const char *); |
| 33 } NAME_FUNCS; | 34 } NAME_FUNCS; |
| 34 | 35 |
| 35 DECLARE_STACK_OF(NAME_FUNCS) | 36 DECLARE_STACK_OF(NAME_FUNCS) |
| 36 IMPLEMENT_STACK_OF(NAME_FUNCS) | 37 IMPLEMENT_STACK_OF(NAME_FUNCS) |
| 37 | 38 |
| 38 static STACK_OF(NAME_FUNCS) *name_funcs_stack; | 39 static STACK_OF(NAME_FUNCS) *name_funcs_stack; |
| 39 | 40 |
| 40 /* The LHASH callbacks now use the raw "void *" prototypes and do per-variable | 41 /* 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 * casting in the functions. This prevents function pointer casting without the |
| 42 * need for macro-generated wrapper functions. */ | 43 * need for macro-generated wrapper functions. */ |
| 43 | 44 |
| 44 /* static unsigned long obj_name_hash(OBJ_NAME *a); */ | 45 /* static unsigned long obj_name_hash(OBJ_NAME *a); */ |
| 45 static unsigned long obj_name_hash(const void *a_void); | 46 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(OBJ_NAME *a,OBJ_NAME *b); */ |
| 47 static int obj_name_cmp(const void *a_void,const void *b_void); | 48 static int obj_name_cmp(const void *a_void,const void *b_void); |
| 48 | 49 |
| 50 static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME) |
| 51 static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME) |
| 52 |
| 49 int OBJ_NAME_init(void) | 53 int OBJ_NAME_init(void) |
| 50 { | 54 { |
| 51 if (names_lh != NULL) return(1); | 55 if (names_lh != NULL) return(1); |
| 52 MemCheck_off(); | 56 MemCheck_off(); |
| 53 » names_lh=lh_new(obj_name_hash, obj_name_cmp); | 57 » names_lh=lh_OBJ_NAME_new(); |
| 54 MemCheck_on(); | 58 MemCheck_on(); |
| 55 return(names_lh != NULL); | 59 return(names_lh != NULL); |
| 56 } | 60 } |
| 57 | 61 |
| 58 int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *), | 62 int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *), |
| 59 int (*cmp_func)(const char *, const char *), | 63 int (*cmp_func)(const char *, const char *), |
| 60 void (*free_func)(const char *, int, const char *)) | 64 void (*free_func)(const char *, int, const char *)) |
| 61 { | 65 { |
| 62 int ret; | 66 int ret; |
| 63 int i; | 67 int i; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 if ((names_lh == NULL) && !OBJ_NAME_init()) return(NULL); | 161 if ((names_lh == NULL) && !OBJ_NAME_init()) return(NULL); |
| 158 | 162 |
| 159 alias=type&OBJ_NAME_ALIAS; | 163 alias=type&OBJ_NAME_ALIAS; |
| 160 type&= ~OBJ_NAME_ALIAS; | 164 type&= ~OBJ_NAME_ALIAS; |
| 161 | 165 |
| 162 on.name=name; | 166 on.name=name; |
| 163 on.type=type; | 167 on.type=type; |
| 164 | 168 |
| 165 for (;;) | 169 for (;;) |
| 166 { | 170 { |
| 167 » » ret=(OBJ_NAME *)lh_retrieve(names_lh,&on); | 171 » » ret=lh_OBJ_NAME_retrieve(names_lh,&on); |
| 168 if (ret == NULL) return(NULL); | 172 if (ret == NULL) return(NULL); |
| 169 if ((ret->alias) && !alias) | 173 if ((ret->alias) && !alias) |
| 170 { | 174 { |
| 171 if (++num > 10) return(NULL); | 175 if (++num > 10) return(NULL); |
| 172 on.name=ret->data; | 176 on.name=ret->data; |
| 173 } | 177 } |
| 174 else | 178 else |
| 175 { | 179 { |
| 176 return(ret->data); | 180 return(ret->data); |
| 177 } | 181 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 193 { | 197 { |
| 194 /* ERROR */ | 198 /* ERROR */ |
| 195 return(0); | 199 return(0); |
| 196 } | 200 } |
| 197 | 201 |
| 198 onp->name=name; | 202 onp->name=name; |
| 199 onp->alias=alias; | 203 onp->alias=alias; |
| 200 onp->type=type; | 204 onp->type=type; |
| 201 onp->data=data; | 205 onp->data=data; |
| 202 | 206 |
| 203 » ret=(OBJ_NAME *)lh_insert(names_lh,onp); | 207 » ret=lh_OBJ_NAME_insert(names_lh,onp); |
| 204 if (ret != NULL) | 208 if (ret != NULL) |
| 205 { | 209 { |
| 206 /* free things */ | 210 /* free things */ |
| 207 if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_
stack) > ret->type)) | 211 if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_
stack) > ret->type)) |
| 208 { | 212 { |
| 209 /* XXX: I'm not sure I understand why the free | 213 /* XXX: I'm not sure I understand why the free |
| 210 * function should get three arguments... | 214 * function should get three arguments... |
| 211 * -- Richard Levitte | 215 * -- Richard Levitte |
| 212 */ | 216 */ |
| 213 sk_NAME_FUNCS_value(name_funcs_stack, | 217 sk_NAME_FUNCS_value(name_funcs_stack, |
| 214 ret->type)->free_func(ret->name,ret->type,ret->d
ata); | 218 ret->type)->free_func(ret->name,ret->type,ret->d
ata); |
| 215 } | 219 } |
| 216 OPENSSL_free(ret); | 220 OPENSSL_free(ret); |
| 217 } | 221 } |
| 218 else | 222 else |
| 219 { | 223 { |
| 220 » » if (lh_error(names_lh)) | 224 » » if (lh_OBJ_NAME_error(names_lh)) |
| 221 { | 225 { |
| 222 /* ERROR */ | 226 /* ERROR */ |
| 223 return(0); | 227 return(0); |
| 224 } | 228 } |
| 225 } | 229 } |
| 226 return(1); | 230 return(1); |
| 227 } | 231 } |
| 228 | 232 |
| 229 int OBJ_NAME_remove(const char *name, int type) | 233 int OBJ_NAME_remove(const char *name, int type) |
| 230 { | 234 { |
| 231 OBJ_NAME on,*ret; | 235 OBJ_NAME on,*ret; |
| 232 | 236 |
| 233 if (names_lh == NULL) return(0); | 237 if (names_lh == NULL) return(0); |
| 234 | 238 |
| 235 type&= ~OBJ_NAME_ALIAS; | 239 type&= ~OBJ_NAME_ALIAS; |
| 236 on.name=name; | 240 on.name=name; |
| 237 on.type=type; | 241 on.type=type; |
| 238 » ret=(OBJ_NAME *)lh_delete(names_lh,&on); | 242 » ret=lh_OBJ_NAME_delete(names_lh,&on); |
| 239 if (ret != NULL) | 243 if (ret != NULL) |
| 240 { | 244 { |
| 241 /* free things */ | 245 /* free things */ |
| 242 if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_
stack) > ret->type)) | 246 if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_
stack) > ret->type)) |
| 243 { | 247 { |
| 244 /* XXX: I'm not sure I understand why the free | 248 /* XXX: I'm not sure I understand why the free |
| 245 * function should get three arguments... | 249 * function should get three arguments... |
| 246 * -- Richard Levitte | 250 * -- Richard Levitte |
| 247 */ | 251 */ |
| 248 sk_NAME_FUNCS_value(name_funcs_stack, | 252 sk_NAME_FUNCS_value(name_funcs_stack, |
| 249 ret->type)->free_func(ret->name,ret->type,ret->d
ata); | 253 ret->type)->free_func(ret->name,ret->type,ret->d
ata); |
| 250 } | 254 } |
| 251 OPENSSL_free(ret); | 255 OPENSSL_free(ret); |
| 252 return(1); | 256 return(1); |
| 253 } | 257 } |
| 254 else | 258 else |
| 255 return(0); | 259 return(0); |
| 256 } | 260 } |
| 257 | 261 |
| 258 struct doall | 262 struct doall |
| 259 { | 263 { |
| 260 int type; | 264 int type; |
| 261 void (*fn)(const OBJ_NAME *,void *arg); | 265 void (*fn)(const OBJ_NAME *,void *arg); |
| 262 void *arg; | 266 void *arg; |
| 263 }; | 267 }; |
| 264 | 268 |
| 265 static void do_all_fn(const OBJ_NAME *name,struct doall *d) | 269 static void do_all_fn_doall_arg(const OBJ_NAME *name,struct doall *d) |
| 266 { | 270 { |
| 267 if(name->type == d->type) | 271 if(name->type == d->type) |
| 268 d->fn(name,d->arg); | 272 d->fn(name,d->arg); |
| 269 } | 273 } |
| 270 | 274 |
| 271 static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME *, struct doall *) | 275 static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall) |
| 272 | 276 |
| 273 void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg) | 277 void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg) |
| 274 { | 278 { |
| 275 struct doall d; | 279 struct doall d; |
| 276 | 280 |
| 277 d.type=type; | 281 d.type=type; |
| 278 d.fn=fn; | 282 d.fn=fn; |
| 279 d.arg=arg; | 283 d.arg=arg; |
| 280 | 284 |
| 281 » lh_doall_arg(names_lh,LHASH_DOALL_ARG_FN(do_all_fn),&d); | 285 » lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn), |
| 286 » » » struct doall, &d); |
| 282 } | 287 } |
| 283 | 288 |
| 284 struct doall_sorted | 289 struct doall_sorted |
| 285 { | 290 { |
| 286 int type; | 291 int type; |
| 287 int n; | 292 int n; |
| 288 const OBJ_NAME **names; | 293 const OBJ_NAME **names; |
| 289 }; | 294 }; |
| 290 | 295 |
| 291 static void do_all_sorted_fn(const OBJ_NAME *name,void *d_) | 296 static void do_all_sorted_fn(const OBJ_NAME *name,void *d_) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 306 return strcmp((*n1)->name,(*n2)->name); | 311 return strcmp((*n1)->name,(*n2)->name); |
| 307 } | 312 } |
| 308 | 313 |
| 309 void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg), | 314 void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg), |
| 310 void *arg) | 315 void *arg) |
| 311 { | 316 { |
| 312 struct doall_sorted d; | 317 struct doall_sorted d; |
| 313 int n; | 318 int n; |
| 314 | 319 |
| 315 d.type=type; | 320 d.type=type; |
| 316 » d.names=OPENSSL_malloc(lh_num_items(names_lh)*sizeof *d.names); | 321 » d.names=OPENSSL_malloc(lh_OBJ_NAME_num_items(names_lh)*sizeof *d.names); |
| 317 d.n=0; | 322 d.n=0; |
| 318 OBJ_NAME_do_all(type,do_all_sorted_fn,&d); | 323 OBJ_NAME_do_all(type,do_all_sorted_fn,&d); |
| 319 | 324 |
| 320 qsort((void *)d.names,d.n,sizeof *d.names,do_all_sorted_cmp); | 325 qsort((void *)d.names,d.n,sizeof *d.names,do_all_sorted_cmp); |
| 321 | 326 |
| 322 for(n=0 ; n < d.n ; ++n) | 327 for(n=0 ; n < d.n ; ++n) |
| 323 fn(d.names[n],arg); | 328 fn(d.names[n],arg); |
| 324 | 329 |
| 325 OPENSSL_free((void *)d.names); | 330 OPENSSL_free((void *)d.names); |
| 326 } | 331 } |
| 327 | 332 |
| 328 static int free_type; | 333 static int free_type; |
| 329 | 334 |
| 330 static void names_lh_free(OBJ_NAME *onp) | 335 static void names_lh_free_doall(OBJ_NAME *onp) |
| 331 { | 336 » { |
| 332 » if(onp == NULL) | 337 » if (onp == NULL) |
| 333 return; | 338 return; |
| 334 | 339 |
| 335 » if ((free_type < 0) || (free_type == onp->type)) | 340 » if (free_type < 0 || free_type == onp->type) |
| 336 » » { | |
| 337 OBJ_NAME_remove(onp->name,onp->type); | 341 OBJ_NAME_remove(onp->name,onp->type); |
| 338 } | |
| 339 } | 342 } |
| 340 | 343 |
| 341 static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME *) | 344 static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME) |
| 342 | 345 |
| 343 static void name_funcs_free(NAME_FUNCS *ptr) | 346 static void name_funcs_free(NAME_FUNCS *ptr) |
| 344 { | 347 { |
| 345 OPENSSL_free(ptr); | 348 OPENSSL_free(ptr); |
| 346 } | 349 } |
| 347 | 350 |
| 348 void OBJ_NAME_cleanup(int type) | 351 void OBJ_NAME_cleanup(int type) |
| 349 { | 352 { |
| 350 unsigned long down_load; | 353 unsigned long down_load; |
| 351 | 354 |
| 352 if (names_lh == NULL) return; | 355 if (names_lh == NULL) return; |
| 353 | 356 |
| 354 free_type=type; | 357 free_type=type; |
| 355 » down_load=names_lh->down_load; | 358 » down_load=lh_OBJ_NAME_down_load(names_lh); |
| 356 » names_lh->down_load=0; | 359 » lh_OBJ_NAME_down_load(names_lh)=0; |
| 357 | 360 |
| 358 » lh_doall(names_lh,LHASH_DOALL_FN(names_lh_free)); | 361 » lh_OBJ_NAME_doall(names_lh,LHASH_DOALL_FN(names_lh_free)); |
| 359 if (type < 0) | 362 if (type < 0) |
| 360 { | 363 { |
| 361 » » lh_free(names_lh); | 364 » » lh_OBJ_NAME_free(names_lh); |
| 362 sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free); | 365 sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free); |
| 363 names_lh=NULL; | 366 names_lh=NULL; |
| 364 name_funcs_stack = NULL; | 367 name_funcs_stack = NULL; |
| 365 } | 368 } |
| 366 else | 369 else |
| 367 » » names_lh->down_load=down_load; | 370 » » lh_OBJ_NAME_down_load(names_lh)=down_load; |
| 368 } | 371 } |
| 369 | 372 |
| OLD | NEW |