o_names.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:8k
源码类别:

其他游戏

开发平台:

Visual C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <openssl/err.h>
  5. #include <openssl/lhash.h>
  6. #include <openssl/objects.h>
  7. #include <openssl/safestack.h>
  8. #include <openssl/e_os2.h>
  9. /* Later versions of DEC C has started to add lnkage information to certain
  10.  * functions, which makes it tricky to use them as values to regular function
  11.  * pointers.  One way is to define a macro that takes care of casting them
  12.  * correctly.
  13.  */
  14. #ifdef OPENSSL_SYS_VMS_DECC
  15. # define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp
  16. #else
  17. # define OPENSSL_strcmp strcmp
  18. #endif
  19. /* I use the ex_data stuff to manage the identifiers for the obj_name_types
  20.  * that applications may define.  I only really use the free function field.
  21.  */
  22. static LHASH *names_lh=NULL;
  23. static int names_type_num=OBJ_NAME_TYPE_NUM;
  24. typedef struct name_funcs_st
  25. {
  26. unsigned long (*hash_func)(const char *name);
  27. int (*cmp_func)(const char *a,const char *b);
  28. void (*free_func)(const char *, int, const char *);
  29. } NAME_FUNCS;
  30. DECLARE_STACK_OF(NAME_FUNCS)
  31. IMPLEMENT_STACK_OF(NAME_FUNCS)
  32. static STACK_OF(NAME_FUNCS) *name_funcs_stack;
  33. /* The LHASH callbacks now use the raw "void *" prototypes and do per-variable
  34.  * casting in the functions. This prevents function pointer casting without the
  35.  * need for macro-generated wrapper functions. */
  36. /* static unsigned long obj_name_hash(OBJ_NAME *a); */
  37. static unsigned long obj_name_hash(const void *a_void);
  38. /* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */
  39. static int obj_name_cmp(const void *a_void,const void *b_void);
  40. int OBJ_NAME_init(void)
  41. {
  42. if (names_lh != NULL) return(1);
  43. MemCheck_off();
  44. names_lh=lh_new(obj_name_hash, obj_name_cmp);
  45. MemCheck_on();
  46. return(names_lh != NULL);
  47. }
  48. int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
  49. int (*cmp_func)(const char *, const char *),
  50. void (*free_func)(const char *, int, const char *))
  51. {
  52. int ret;
  53. int i;
  54. NAME_FUNCS *name_funcs;
  55. if (name_funcs_stack == NULL)
  56. {
  57. MemCheck_off();
  58. name_funcs_stack=sk_NAME_FUNCS_new_null();
  59. MemCheck_on();
  60. }
  61. if ((name_funcs_stack == NULL))
  62. {
  63. /* ERROR */
  64. return(0);
  65. }
  66. ret=names_type_num;
  67. names_type_num++;
  68. for (i=sk_NAME_FUNCS_num(name_funcs_stack); i<names_type_num; i++)
  69. {
  70. MemCheck_off();
  71. name_funcs = OPENSSL_malloc(sizeof(NAME_FUNCS));
  72. MemCheck_on();
  73. if (!name_funcs)
  74. {
  75. OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX,ERR_R_MALLOC_FAILURE);
  76. return(0);
  77. }
  78. name_funcs->hash_func = lh_strhash;
  79. name_funcs->cmp_func = OPENSSL_strcmp;
  80. name_funcs->free_func = 0; /* NULL is often declared to
  81. * ((void *)0), which according
  82. * to Compaq C is not really
  83. * compatible with a function
  84. * pointer. -- Richard Levitte*/
  85. MemCheck_off();
  86. sk_NAME_FUNCS_push(name_funcs_stack,name_funcs);
  87. MemCheck_on();
  88. }
  89. name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret);
  90. if (hash_func != NULL)
  91. name_funcs->hash_func = hash_func;
  92. if (cmp_func != NULL)
  93. name_funcs->cmp_func = cmp_func;
  94. if (free_func != NULL)
  95. name_funcs->free_func = free_func;
  96. return(ret);
  97. }
  98. /* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */
  99. static int obj_name_cmp(const void *a_void, const void *b_void)
  100. {
  101. int ret;
  102. const OBJ_NAME *a = (const OBJ_NAME *)a_void;
  103. const OBJ_NAME *b = (const OBJ_NAME *)b_void;
  104. ret=a->type-b->type;
  105. if (ret == 0)
  106. {
  107. if ((name_funcs_stack != NULL)
  108. && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
  109. {
  110. ret=sk_NAME_FUNCS_value(name_funcs_stack,
  111. a->type)->cmp_func(a->name,b->name);
  112. }
  113. else
  114. ret=strcmp(a->name,b->name);
  115. }
  116. return(ret);
  117. }
  118. /* static unsigned long obj_name_hash(OBJ_NAME *a) */
  119. static unsigned long obj_name_hash(const void *a_void)
  120. {
  121. unsigned long ret;
  122. const OBJ_NAME *a = (const OBJ_NAME *)a_void;
  123. if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
  124. {
  125. ret=sk_NAME_FUNCS_value(name_funcs_stack,
  126. a->type)->hash_func(a->name);
  127. }
  128. else
  129. {
  130. ret=lh_strhash(a->name);
  131. }
  132. ret^=a->type;
  133. return(ret);
  134. }
  135. const char *OBJ_NAME_get(const char *name, int type)
  136. {
  137. OBJ_NAME on,*ret;
  138. int num=0,alias;
  139. if (name == NULL) return(NULL);
  140. if ((names_lh == NULL) && !OBJ_NAME_init()) return(NULL);
  141. alias=type&OBJ_NAME_ALIAS;
  142. type&= ~OBJ_NAME_ALIAS;
  143. on.name=name;
  144. on.type=type;
  145. for (;;)
  146. {
  147. ret=(OBJ_NAME *)lh_retrieve(names_lh,&on);
  148. if (ret == NULL) return(NULL);
  149. if ((ret->alias) && !alias)
  150. {
  151. if (++num > 10) return(NULL);
  152. on.name=ret->data;
  153. }
  154. else
  155. {
  156. return(ret->data);
  157. }
  158. }
  159. }
  160. int OBJ_NAME_add(const char *name, int type, const char *data)
  161. {
  162. OBJ_NAME *onp,*ret;
  163. int alias;
  164. if ((names_lh == NULL) && !OBJ_NAME_init()) return(0);
  165. alias=type&OBJ_NAME_ALIAS;
  166. type&= ~OBJ_NAME_ALIAS;
  167. onp=(OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME));
  168. if (onp == NULL)
  169. {
  170. /* ERROR */
  171. return(0);
  172. }
  173. onp->name=name;
  174. onp->alias=alias;
  175. onp->type=type;
  176. onp->data=data;
  177. ret=(OBJ_NAME *)lh_insert(names_lh,onp);
  178. if (ret != NULL)
  179. {
  180. /* free things */
  181. if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
  182. {
  183. /* XXX: I'm not sure I understand why the free
  184.  * function should get three arguments...
  185.  * -- Richard Levitte
  186.  */
  187. sk_NAME_FUNCS_value(name_funcs_stack,
  188. ret->type)->free_func(ret->name,ret->type,ret->data);
  189. }
  190. OPENSSL_free(ret);
  191. }
  192. else
  193. {
  194. if (lh_error(names_lh))
  195. {
  196. /* ERROR */
  197. return(0);
  198. }
  199. }
  200. return(1);
  201. }
  202. int OBJ_NAME_remove(const char *name, int type)
  203. {
  204. OBJ_NAME on,*ret;
  205. if (names_lh == NULL) return(0);
  206. type&= ~OBJ_NAME_ALIAS;
  207. on.name=name;
  208. on.type=type;
  209. ret=(OBJ_NAME *)lh_delete(names_lh,&on);
  210. if (ret != NULL)
  211. {
  212. /* free things */
  213. if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
  214. {
  215. /* XXX: I'm not sure I understand why the free
  216.  * function should get three arguments...
  217.  * -- Richard Levitte
  218.  */
  219. sk_NAME_FUNCS_value(name_funcs_stack,
  220. ret->type)->free_func(ret->name,ret->type,ret->data);
  221. }
  222. OPENSSL_free(ret);
  223. return(1);
  224. }
  225. else
  226. return(0);
  227. }
  228. struct doall
  229. {
  230. int type;
  231. void (*fn)(const OBJ_NAME *,void *arg);
  232. void *arg;
  233. };
  234. static void do_all_fn(const OBJ_NAME *name,struct doall *d)
  235. {
  236. if(name->type == d->type)
  237. d->fn(name,d->arg);
  238. }
  239. static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME *, struct doall *)
  240. void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg)
  241. {
  242. struct doall d;
  243. d.type=type;
  244. d.fn=fn;
  245. d.arg=arg;
  246. lh_doall_arg(names_lh,LHASH_DOALL_ARG_FN(do_all_fn),&d);
  247. }
  248. struct doall_sorted
  249. {
  250. int type;
  251. int n;
  252. const OBJ_NAME **names;
  253. };
  254. static void do_all_sorted_fn(const OBJ_NAME *name,void *d_)
  255. {
  256. struct doall_sorted *d=d_;
  257. if(name->type != d->type)
  258. return;
  259. d->names[d->n++]=name;
  260. }
  261. static int do_all_sorted_cmp(const void *n1_,const void *n2_)
  262. {
  263. const OBJ_NAME * const *n1=n1_;
  264. const OBJ_NAME * const *n2=n2_;
  265. return strcmp((*n1)->name,(*n2)->name);
  266. }
  267. void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
  268. void *arg)
  269. {
  270. struct doall_sorted d;
  271. int n;
  272. d.type=type;
  273. d.names=OPENSSL_malloc(lh_num_items(names_lh)*sizeof *d.names);
  274. d.n=0;
  275. OBJ_NAME_do_all(type,do_all_sorted_fn,&d);
  276. qsort((void *)d.names,d.n,sizeof *d.names,do_all_sorted_cmp);
  277. for(n=0 ; n < d.n ; ++n)
  278. fn(d.names[n],arg);
  279. OPENSSL_free((void *)d.names);
  280. }
  281. static int free_type;
  282. static void names_lh_free(OBJ_NAME *onp)
  283. {
  284. if(onp == NULL)
  285. return;
  286. if ((free_type < 0) || (free_type == onp->type))
  287. {
  288. OBJ_NAME_remove(onp->name,onp->type);
  289. }
  290. }
  291. static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME *)
  292. static void name_funcs_free(NAME_FUNCS *ptr)
  293. {
  294. OPENSSL_free(ptr);
  295. }
  296. void OBJ_NAME_cleanup(int type)
  297. {
  298. unsigned long down_load;
  299. if (names_lh == NULL) return;
  300. free_type=type;
  301. down_load=names_lh->down_load;
  302. names_lh->down_load=0;
  303. lh_doall(names_lh,LHASH_DOALL_FN(names_lh_free));
  304. if (type < 0)
  305. {
  306. lh_free(names_lh);
  307. sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free);
  308. names_lh=NULL;
  309. name_funcs_stack = NULL;
  310. }
  311. else
  312. names_lh->down_load=down_load;
  313. }