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 244