| OLD | NEW |
| 1 /* crypto/stack/stack.c */ | 1 /* crypto/stack/stack.c */ |
| 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 * All rights reserved. | 3 * All rights reserved. |
| 4 * | 4 * |
| 5 * This package is an SSL implementation written | 5 * This package is an SSL implementation written |
| 6 * by Eric Young (eay@cryptsoft.com). | 6 * by Eric Young (eay@cryptsoft.com). |
| 7 * The implementation was written so as to conform with Netscapes SSL. | 7 * The implementation was written so as to conform with Netscapes SSL. |
| 8 * | 8 * |
| 9 * This library is free for commercial and non-commercial use as long as | 9 * This library is free for commercial and non-commercial use as long as |
| 10 * the following conditions are aheared to. The following conditions | 10 * the following conditions are aheared to. The following conditions |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 #include <openssl/stack.h> | 70 #include <openssl/stack.h> |
| 71 #include <openssl/objects.h> | 71 #include <openssl/objects.h> |
| 72 | 72 |
| 73 #undef MIN_NODES | 73 #undef MIN_NODES |
| 74 #define MIN_NODES 4 | 74 #define MIN_NODES 4 |
| 75 | 75 |
| 76 const char STACK_version[]="Stack" OPENSSL_VERSION_PTEXT; | 76 const char STACK_version[]="Stack" OPENSSL_VERSION_PTEXT; |
| 77 | 77 |
| 78 #include <errno.h> | 78 #include <errno.h> |
| 79 | 79 |
| 80 int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,const char * cons
t *))) | 80 int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *))) |
| 81 » » (const char * const *, const char * const *) | 81 » » (const void *, const void *) |
| 82 { | 82 { |
| 83 » int (*old)(const char * const *,const char * const *)=sk->comp; | 83 » int (*old)(const void *,const void *)=sk->comp; |
| 84 | 84 |
| 85 if (sk->comp != c) | 85 if (sk->comp != c) |
| 86 sk->sorted=0; | 86 sk->sorted=0; |
| 87 sk->comp=c; | 87 sk->comp=c; |
| 88 | 88 |
| 89 return old; | 89 return old; |
| 90 } | 90 } |
| 91 | 91 |
| 92 STACK *sk_dup(STACK *sk) | 92 _STACK *sk_dup(_STACK *sk) |
| 93 { | 93 { |
| 94 » STACK *ret; | 94 » _STACK *ret; |
| 95 char **s; | 95 char **s; |
| 96 | 96 |
| 97 if ((ret=sk_new(sk->comp)) == NULL) goto err; | 97 if ((ret=sk_new(sk->comp)) == NULL) goto err; |
| 98 s=(char **)OPENSSL_realloc((char *)ret->data, | 98 s=(char **)OPENSSL_realloc((char *)ret->data, |
| 99 (unsigned int)sizeof(char *)*sk->num_alloc); | 99 (unsigned int)sizeof(char *)*sk->num_alloc); |
| 100 if (s == NULL) goto err; | 100 if (s == NULL) goto err; |
| 101 ret->data=s; | 101 ret->data=s; |
| 102 | 102 |
| 103 ret->num=sk->num; | 103 ret->num=sk->num; |
| 104 memcpy(ret->data,sk->data,sizeof(char *)*sk->num); | 104 memcpy(ret->data,sk->data,sizeof(char *)*sk->num); |
| 105 ret->sorted=sk->sorted; | 105 ret->sorted=sk->sorted; |
| 106 ret->num_alloc=sk->num_alloc; | 106 ret->num_alloc=sk->num_alloc; |
| 107 ret->comp=sk->comp; | 107 ret->comp=sk->comp; |
| 108 return(ret); | 108 return(ret); |
| 109 err: | 109 err: |
| 110 if(ret) | 110 if(ret) |
| 111 sk_free(ret); | 111 sk_free(ret); |
| 112 return(NULL); | 112 return(NULL); |
| 113 } | 113 } |
| 114 | 114 |
| 115 STACK *sk_new_null(void) | 115 _STACK *sk_new_null(void) |
| 116 { | 116 { |
| 117 » return sk_new((int (*)(const char * const *, const char * const *))0); | 117 » return sk_new((int (*)(const void *, const void *))0); |
| 118 } | 118 } |
| 119 | 119 |
| 120 STACK *sk_new(int (*c)(const char * const *, const char * const *)) | 120 _STACK *sk_new(int (*c)(const void *, const void *)) |
| 121 { | 121 { |
| 122 » STACK *ret; | 122 » _STACK *ret; |
| 123 int i; | 123 int i; |
| 124 | 124 |
| 125 » if ((ret=(STACK *)OPENSSL_malloc(sizeof(STACK))) == NULL) | 125 » if ((ret=OPENSSL_malloc(sizeof(_STACK))) == NULL) |
| 126 goto err; | 126 goto err; |
| 127 » if ((ret->data=(char **)OPENSSL_malloc(sizeof(char *)*MIN_NODES)) == NUL
L) | 127 » if ((ret->data=OPENSSL_malloc(sizeof(char *)*MIN_NODES)) == NULL) |
| 128 goto err; | 128 goto err; |
| 129 for (i=0; i<MIN_NODES; i++) | 129 for (i=0; i<MIN_NODES; i++) |
| 130 ret->data[i]=NULL; | 130 ret->data[i]=NULL; |
| 131 ret->comp=c; | 131 ret->comp=c; |
| 132 ret->num_alloc=MIN_NODES; | 132 ret->num_alloc=MIN_NODES; |
| 133 ret->num=0; | 133 ret->num=0; |
| 134 ret->sorted=0; | 134 ret->sorted=0; |
| 135 return(ret); | 135 return(ret); |
| 136 err: | 136 err: |
| 137 if(ret) | 137 if(ret) |
| 138 OPENSSL_free(ret); | 138 OPENSSL_free(ret); |
| 139 return(NULL); | 139 return(NULL); |
| 140 } | 140 } |
| 141 | 141 |
| 142 int sk_insert(STACK *st, char *data, int loc) | 142 int sk_insert(_STACK *st, void *data, int loc) |
| 143 { | 143 { |
| 144 char **s; | 144 char **s; |
| 145 | 145 |
| 146 if(st == NULL) return 0; | 146 if(st == NULL) return 0; |
| 147 if (st->num_alloc <= st->num+1) | 147 if (st->num_alloc <= st->num+1) |
| 148 { | 148 { |
| 149 » » s=(char **)OPENSSL_realloc((char *)st->data, | 149 » » s=OPENSSL_realloc((char *)st->data, |
| 150 (unsigned int)sizeof(char *)*st->num_alloc*2); | 150 (unsigned int)sizeof(char *)*st->num_alloc*2); |
| 151 if (s == NULL) | 151 if (s == NULL) |
| 152 return(0); | 152 return(0); |
| 153 st->data=s; | 153 st->data=s; |
| 154 st->num_alloc*=2; | 154 st->num_alloc*=2; |
| 155 } | 155 } |
| 156 if ((loc >= (int)st->num) || (loc < 0)) | 156 if ((loc >= (int)st->num) || (loc < 0)) |
| 157 st->data[st->num]=data; | 157 st->data[st->num]=data; |
| 158 else | 158 else |
| 159 { | 159 { |
| 160 int i; | 160 int i; |
| 161 char **f,**t; | 161 char **f,**t; |
| 162 | 162 |
| 163 » » f=(char **)st->data; | 163 » » f=st->data; |
| 164 » » t=(char **)&(st->data[1]); | 164 » » t=&(st->data[1]); |
| 165 for (i=st->num; i>=loc; i--) | 165 for (i=st->num; i>=loc; i--) |
| 166 t[i]=f[i]; | 166 t[i]=f[i]; |
| 167 | 167 |
| 168 #ifdef undef /* no memmove on sunos :-( */ | 168 #ifdef undef /* no memmove on sunos :-( */ |
| 169 » » memmove( (char *)&(st->data[loc+1]), | 169 » » memmove(&(st->data[loc+1]), |
| 170 » » » (char *)&(st->data[loc]), | 170 » » » &(st->data[loc]), |
| 171 sizeof(char *)*(st->num-loc)); | 171 sizeof(char *)*(st->num-loc)); |
| 172 #endif | 172 #endif |
| 173 st->data[loc]=data; | 173 st->data[loc]=data; |
| 174 } | 174 } |
| 175 st->num++; | 175 st->num++; |
| 176 st->sorted=0; | 176 st->sorted=0; |
| 177 return(st->num); | 177 return(st->num); |
| 178 } | 178 } |
| 179 | 179 |
| 180 char *sk_delete_ptr(STACK *st, char *p) | 180 void *sk_delete_ptr(_STACK *st, void *p) |
| 181 { | 181 { |
| 182 int i; | 182 int i; |
| 183 | 183 |
| 184 for (i=0; i<st->num; i++) | 184 for (i=0; i<st->num; i++) |
| 185 if (st->data[i] == p) | 185 if (st->data[i] == p) |
| 186 return(sk_delete(st,i)); | 186 return(sk_delete(st,i)); |
| 187 return(NULL); | 187 return(NULL); |
| 188 } | 188 } |
| 189 | 189 |
| 190 char *sk_delete(STACK *st, int loc) | 190 void *sk_delete(_STACK *st, int loc) |
| 191 { | 191 { |
| 192 char *ret; | 192 char *ret; |
| 193 int i,j; | 193 int i,j; |
| 194 | 194 |
| 195 if(!st || (loc < 0) || (loc >= st->num)) return NULL; | 195 if(!st || (loc < 0) || (loc >= st->num)) return NULL; |
| 196 | 196 |
| 197 ret=st->data[loc]; | 197 ret=st->data[loc]; |
| 198 if (loc != st->num-1) | 198 if (loc != st->num-1) |
| 199 { | 199 { |
| 200 j=st->num-1; | 200 j=st->num-1; |
| 201 for (i=loc; i<j; i++) | 201 for (i=loc; i<j; i++) |
| 202 st->data[i]=st->data[i+1]; | 202 st->data[i]=st->data[i+1]; |
| 203 /* In theory memcpy is not safe for this | 203 /* In theory memcpy is not safe for this |
| 204 * memcpy( &(st->data[loc]), | 204 * memcpy( &(st->data[loc]), |
| 205 * &(st->data[loc+1]), | 205 * &(st->data[loc+1]), |
| 206 * sizeof(char *)*(st->num-loc-1)); | 206 * sizeof(char *)*(st->num-loc-1)); |
| 207 */ | 207 */ |
| 208 } | 208 } |
| 209 st->num--; | 209 st->num--; |
| 210 return(ret); | 210 return(ret); |
| 211 } | 211 } |
| 212 | 212 |
| 213 static int internal_find(STACK *st, char *data, int ret_val_options) | 213 static int internal_find(_STACK *st, void *data, int ret_val_options) |
| 214 { | 214 { |
| 215 » char **r; | 215 » const void * const *r; |
| 216 int i; | 216 int i; |
| 217 » int (*comp_func)(const void *,const void *); | 217 |
| 218 if(st == NULL) return -1; | 218 if(st == NULL) return -1; |
| 219 | 219 |
| 220 if (st->comp == NULL) | 220 if (st->comp == NULL) |
| 221 { | 221 { |
| 222 for (i=0; i<st->num; i++) | 222 for (i=0; i<st->num; i++) |
| 223 if (st->data[i] == data) | 223 if (st->data[i] == data) |
| 224 return(i); | 224 return(i); |
| 225 return(-1); | 225 return(-1); |
| 226 } | 226 } |
| 227 sk_sort(st); | 227 sk_sort(st); |
| 228 if (data == NULL) return(-1); | 228 if (data == NULL) return(-1); |
| 229 » /* This (and the "qsort" below) are the two places in OpenSSL | 229 » r=OBJ_bsearch_ex_(&data,st->data,st->num,sizeof(void *),st->comp, |
| 230 » * where we need to convert from our standard (type **,type **) | 230 » » » ret_val_options); |
| 231 » * compare callback type to the (void *,void *) type required by | |
| 232 » * bsearch. However, the "data" it is being called(back) with are | |
| 233 » * not (type *) pointers, but the *pointers* to (type *) pointers, | |
| 234 » * so we get our extra level of pointer dereferencing that way. */ | |
| 235 » comp_func=(int (*)(const void *,const void *))(st->comp); | |
| 236 » r=(char **)OBJ_bsearch_ex((char *)&data,(char *)st->data, | |
| 237 » » st->num,sizeof(char *),comp_func,ret_val_options); | |
| 238 if (r == NULL) return(-1); | 231 if (r == NULL) return(-1); |
| 239 » return((int)(r-st->data)); | 232 » return (int)((char **)r-st->data); |
| 240 } | 233 } |
| 241 | 234 |
| 242 int sk_find(STACK *st, char *data) | 235 int sk_find(_STACK *st, void *data) |
| 243 { | 236 { |
| 244 return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); | 237 return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); |
| 245 } | 238 } |
| 246 int sk_find_ex(STACK *st, char *data) | 239 int sk_find_ex(_STACK *st, void *data) |
| 247 { | 240 { |
| 248 return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); | 241 return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); |
| 249 } | 242 } |
| 250 | 243 |
| 251 int sk_push(STACK *st, char *data) | 244 int sk_push(_STACK *st, void *data) |
| 252 { | 245 { |
| 253 return(sk_insert(st,data,st->num)); | 246 return(sk_insert(st,data,st->num)); |
| 254 } | 247 } |
| 255 | 248 |
| 256 int sk_unshift(STACK *st, char *data) | 249 int sk_unshift(_STACK *st, void *data) |
| 257 { | 250 { |
| 258 return(sk_insert(st,data,0)); | 251 return(sk_insert(st,data,0)); |
| 259 } | 252 } |
| 260 | 253 |
| 261 char *sk_shift(STACK *st) | 254 void *sk_shift(_STACK *st) |
| 262 { | 255 { |
| 263 if (st == NULL) return(NULL); | 256 if (st == NULL) return(NULL); |
| 264 if (st->num <= 0) return(NULL); | 257 if (st->num <= 0) return(NULL); |
| 265 return(sk_delete(st,0)); | 258 return(sk_delete(st,0)); |
| 266 } | 259 } |
| 267 | 260 |
| 268 char *sk_pop(STACK *st) | 261 void *sk_pop(_STACK *st) |
| 269 { | 262 { |
| 270 if (st == NULL) return(NULL); | 263 if (st == NULL) return(NULL); |
| 271 if (st->num <= 0) return(NULL); | 264 if (st->num <= 0) return(NULL); |
| 272 return(sk_delete(st,st->num-1)); | 265 return(sk_delete(st,st->num-1)); |
| 273 } | 266 } |
| 274 | 267 |
| 275 void sk_zero(STACK *st) | 268 void sk_zero(_STACK *st) |
| 276 { | 269 { |
| 277 if (st == NULL) return; | 270 if (st == NULL) return; |
| 278 if (st->num <= 0) return; | 271 if (st->num <= 0) return; |
| 279 memset((char *)st->data,0,sizeof(st->data)*st->num); | 272 memset((char *)st->data,0,sizeof(st->data)*st->num); |
| 280 st->num=0; | 273 st->num=0; |
| 281 } | 274 } |
| 282 | 275 |
| 283 void sk_pop_free(STACK *st, void (*func)(void *)) | 276 void sk_pop_free(_STACK *st, void (*func)(void *)) |
| 284 { | 277 { |
| 285 int i; | 278 int i; |
| 286 | 279 |
| 287 if (st == NULL) return; | 280 if (st == NULL) return; |
| 288 for (i=0; i<st->num; i++) | 281 for (i=0; i<st->num; i++) |
| 289 if (st->data[i] != NULL) | 282 if (st->data[i] != NULL) |
| 290 func(st->data[i]); | 283 func(st->data[i]); |
| 291 sk_free(st); | 284 sk_free(st); |
| 292 } | 285 } |
| 293 | 286 |
| 294 void sk_free(STACK *st) | 287 void sk_free(_STACK *st) |
| 295 { | 288 { |
| 296 if (st == NULL) return; | 289 if (st == NULL) return; |
| 297 if (st->data != NULL) OPENSSL_free(st->data); | 290 if (st->data != NULL) OPENSSL_free(st->data); |
| 298 OPENSSL_free(st); | 291 OPENSSL_free(st); |
| 299 } | 292 } |
| 300 | 293 |
| 301 int sk_num(const STACK *st) | 294 int sk_num(const _STACK *st) |
| 302 { | 295 { |
| 303 if(st == NULL) return -1; | 296 if(st == NULL) return -1; |
| 304 return st->num; | 297 return st->num; |
| 305 } | 298 } |
| 306 | 299 |
| 307 char *sk_value(const STACK *st, int i) | 300 void *sk_value(const _STACK *st, int i) |
| 308 { | 301 { |
| 309 if(!st || (i < 0) || (i >= st->num)) return NULL; | 302 if(!st || (i < 0) || (i >= st->num)) return NULL; |
| 310 return st->data[i]; | 303 return st->data[i]; |
| 311 } | 304 } |
| 312 | 305 |
| 313 char *sk_set(STACK *st, int i, char *value) | 306 void *sk_set(_STACK *st, int i, void *value) |
| 314 { | 307 { |
| 315 if(!st || (i < 0) || (i >= st->num)) return NULL; | 308 if(!st || (i < 0) || (i >= st->num)) return NULL; |
| 316 return (st->data[i] = value); | 309 return (st->data[i] = value); |
| 317 } | 310 } |
| 318 | 311 |
| 319 void sk_sort(STACK *st) | 312 void sk_sort(_STACK *st) |
| 320 { | 313 { |
| 321 if (st && !st->sorted) | 314 if (st && !st->sorted) |
| 322 { | 315 { |
| 323 int (*comp_func)(const void *,const void *); | 316 int (*comp_func)(const void *,const void *); |
| 324 | 317 |
| 325 /* same comment as in sk_find ... previously st->comp was declar
ed | 318 /* same comment as in sk_find ... previously st->comp was declar
ed |
| 326 * as a (void*,void*) callback type, but this made the populatio
n | 319 * as a (void*,void*) callback type, but this made the populatio
n |
| 327 * of the callback pointer illogical - our callbacks compare | 320 * of the callback pointer illogical - our callbacks compare |
| 328 * type** with type**, so we leave the casting until absolutely | 321 * type** with type**, so we leave the casting until absolutely |
| 329 * necessary (ie. "now"). */ | 322 * necessary (ie. "now"). */ |
| 330 comp_func=(int (*)(const void *,const void *))(st->comp); | 323 comp_func=(int (*)(const void *,const void *))(st->comp); |
| 331 qsort(st->data,st->num,sizeof(char *), comp_func); | 324 qsort(st->data,st->num,sizeof(char *), comp_func); |
| 332 st->sorted=1; | 325 st->sorted=1; |
| 333 } | 326 } |
| 334 } | 327 } |
| 335 | 328 |
| 336 int sk_is_sorted(const STACK *st) | 329 int sk_is_sorted(const _STACK *st) |
| 337 { | 330 { |
| 338 if (!st) | 331 if (!st) |
| 339 return 1; | 332 return 1; |
| 340 return st->sorted; | 333 return st->sorted; |
| 341 } | 334 } |
| OLD | NEW |