LCOV - code coverage report
Current view: top level - objects - o_names.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 80 151 53.0 %
Date: 2014-08-02 Functions: 11 19 57.9 %
Branches: 31 78 39.7 %

           Branch data     Line data    Source code
       1                 :            : #include <stdio.h>
       2                 :            : #include <stdlib.h>
       3                 :            : #include <string.h>
       4                 :            : 
       5                 :            : #include <openssl/err.h>
       6                 :            : #include <openssl/lhash.h>
       7                 :            : #include <openssl/objects.h>
       8                 :            : #include <openssl/safestack.h>
       9                 :            : #include <openssl/e_os2.h>
      10                 :            : 
      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
      13                 :            :  * pointers.  One way is to define a macro that takes care of casting them
      14                 :            :  * correctly.
      15                 :            :  */
      16                 :            : #ifdef OPENSSL_SYS_VMS_DECC
      17                 :            : # define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp
      18                 :            : #else
      19                 :            : # define OPENSSL_strcmp strcmp
      20                 :            : #endif
      21                 :            : 
      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.
      24                 :            :  */
      25                 :            : DECLARE_LHASH_OF(OBJ_NAME);
      26                 :            : static LHASH_OF(OBJ_NAME) *names_lh=NULL;
      27                 :            : static int names_type_num=OBJ_NAME_TYPE_NUM;
      28                 :            : 
      29                 :            : typedef struct name_funcs_st
      30                 :            :         {
      31                 :            :         unsigned long (*hash_func)(const char *name);
      32                 :            :         int (*cmp_func)(const char *a,const char *b);
      33                 :            :         void (*free_func)(const char *, int, const char *);
      34                 :            :         } NAME_FUNCS;
      35                 :            : 
      36                 :            : DECLARE_STACK_OF(NAME_FUNCS)
      37                 :            : IMPLEMENT_STACK_OF(NAME_FUNCS)
      38                 :            : 
      39                 :            : static STACK_OF(NAME_FUNCS) *name_funcs_stack;
      40                 :            : 
      41                 :            : /* The LHASH callbacks now use the raw "void *" prototypes and do per-variable
      42                 :            :  * casting in the functions. This prevents function pointer casting without the
      43                 :            :  * need for macro-generated wrapper functions. */
      44                 :            : 
      45                 :            : /* static unsigned long obj_name_hash(OBJ_NAME *a); */
      46                 :            : static unsigned long obj_name_hash(const void *a_void);
      47                 :            : /* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */
      48                 :            : static int obj_name_cmp(const void *a_void,const void *b_void);
      49                 :            : 
      50                 :    1198050 : static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME)
      51                 :     641858 : static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME)
      52                 :            : 
      53                 :       1621 : int OBJ_NAME_init(void)
      54                 :            :         {
      55         [ +  - ]:       1621 :         if (names_lh != NULL) return(1);
      56                 :       1621 :         MemCheck_off();
      57                 :       1621 :         names_lh=lh_OBJ_NAME_new();
      58                 :       1621 :         MemCheck_on();
      59                 :       1621 :         return(names_lh != NULL);
      60                 :            :         }
      61                 :            : 
      62                 :          0 : int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
      63                 :            :         int (*cmp_func)(const char *, const char *),
      64                 :            :         void (*free_func)(const char *, int, const char *))
      65                 :            :         {
      66                 :            :         int ret;
      67                 :            :         int i;
      68                 :            :         NAME_FUNCS *name_funcs;
      69                 :            : 
      70         [ #  # ]:          0 :         if (name_funcs_stack == NULL)
      71                 :            :                 {
      72                 :          0 :                 MemCheck_off();
      73                 :          0 :                 name_funcs_stack=sk_NAME_FUNCS_new_null();
      74                 :          0 :                 MemCheck_on();
      75                 :            :                 }
      76         [ #  # ]:          0 :         if (name_funcs_stack == NULL)
      77                 :            :                 {
      78                 :            :                 /* ERROR */
      79                 :            :                 return(0);
      80                 :            :                 }
      81                 :          0 :         ret=names_type_num;
      82                 :          0 :         names_type_num++;
      83         [ #  # ]:          0 :         for (i=sk_NAME_FUNCS_num(name_funcs_stack); i<names_type_num; i++)
      84                 :            :                 {
      85                 :          0 :                 MemCheck_off();
      86                 :          0 :                 name_funcs = OPENSSL_malloc(sizeof(NAME_FUNCS));
      87                 :          0 :                 MemCheck_on();
      88         [ #  # ]:          0 :                 if (!name_funcs)
      89                 :            :                         {
      90                 :          0 :                         OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX,ERR_R_MALLOC_FAILURE);
      91                 :          0 :                         return(0);
      92                 :            :                         }
      93                 :          0 :                 name_funcs->hash_func = lh_strhash;
      94                 :          0 :                 name_funcs->cmp_func = OPENSSL_strcmp;
      95                 :          0 :                 name_funcs->free_func = 0; /* NULL is often declared to
      96                 :            :                                                 * ((void *)0), which according
      97                 :            :                                                 * to Compaq C is not really
      98                 :            :                                                 * compatible with a function
      99                 :            :                                                 * pointer.      -- Richard Levitte*/
     100                 :          0 :                 MemCheck_off();
     101                 :          0 :                 sk_NAME_FUNCS_push(name_funcs_stack,name_funcs);
     102                 :          0 :                 MemCheck_on();
     103                 :            :                 }
     104                 :          0 :         name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret);
     105         [ #  # ]:          0 :         if (hash_func != NULL)
     106                 :          0 :                 name_funcs->hash_func = hash_func;
     107         [ #  # ]:          0 :         if (cmp_func != NULL)
     108                 :          0 :                 name_funcs->cmp_func = cmp_func;
     109         [ #  # ]:          0 :         if (free_func != NULL)
     110                 :          0 :                 name_funcs->free_func = free_func;
     111                 :          0 :         return(ret);
     112                 :            :         }
     113                 :            : 
     114                 :            : /* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */
     115                 :     320929 : static int obj_name_cmp(const void *a_void, const void *b_void)
     116                 :            :         {
     117                 :            :         int ret;
     118                 :     320929 :         const OBJ_NAME *a = (const OBJ_NAME *)a_void;
     119                 :     320929 :         const OBJ_NAME *b = (const OBJ_NAME *)b_void;
     120                 :            : 
     121                 :     320929 :         ret=a->type-b->type;
     122         [ +  - ]:     320929 :         if (ret == 0)
     123                 :            :                 {
     124         [ -  + ]:     320929 :                 if ((name_funcs_stack != NULL)
     125         [ #  # ]:          0 :                         && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
     126                 :            :                         {
     127                 :          0 :                         ret=sk_NAME_FUNCS_value(name_funcs_stack,
     128                 :          0 :                                 a->type)->cmp_func(a->name,b->name);
     129                 :            :                         }
     130                 :            :                 else
     131                 :     320929 :                         ret=strcmp(a->name,b->name);
     132                 :            :                 }
     133                 :     320929 :         return(ret);
     134                 :            :         }
     135                 :            : 
     136                 :            : /* static unsigned long obj_name_hash(OBJ_NAME *a) */
     137                 :     599025 : static unsigned long obj_name_hash(const void *a_void)
     138                 :            :         {
     139                 :            :         unsigned long ret;
     140                 :     599025 :         const OBJ_NAME *a = (const OBJ_NAME *)a_void;
     141                 :            : 
     142 [ -  + ][ #  # ]:     599025 :         if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
     143                 :            :                 {
     144                 :          0 :                 ret=sk_NAME_FUNCS_value(name_funcs_stack,
     145                 :          0 :                         a->type)->hash_func(a->name);
     146                 :            :                 }
     147                 :            :         else
     148                 :            :                 {
     149                 :     599025 :                 ret=lh_strhash(a->name);
     150                 :            :                 }
     151                 :     599025 :         ret^=a->type;
     152                 :     599025 :         return(ret);
     153                 :            :         }
     154                 :            : 
     155                 :      29231 : const char *OBJ_NAME_get(const char *name, int type)
     156                 :            :         {
     157                 :            :         OBJ_NAME on,*ret;
     158                 :      29231 :         int num=0,alias;
     159                 :            : 
     160         [ +  - ]:      29231 :         if (name == NULL) return(NULL);
     161 [ -  + ][ #  # ]:      29231 :         if ((names_lh == NULL) && !OBJ_NAME_init()) return(NULL);
     162                 :            : 
     163                 :      29231 :         alias=type&OBJ_NAME_ALIAS;
     164                 :      29231 :         type&= ~OBJ_NAME_ALIAS;
     165                 :            : 
     166                 :      29231 :         on.name=name;
     167                 :      29231 :         on.type=type;
     168                 :            : 
     169                 :            :         for (;;)
     170                 :            :         {
     171                 :      34693 :                 ret=lh_OBJ_NAME_retrieve(names_lh,&on);
     172         [ +  + ]:      34693 :                 if (ret == NULL) return(NULL);
     173 [ +  + ][ +  - ]:      31838 :                 if ((ret->alias) && !alias)
     174                 :            :                         {
     175         [ +  - ]:       5462 :                         if (++num > 10) return(NULL);
     176                 :       5462 :                         on.name=ret->data;
     177                 :            :                         }
     178                 :            :                 else
     179                 :            :                         {
     180                 :      26376 :                         return(ret->data);
     181                 :            :                         }
     182                 :       5462 :                 }
     183                 :            :         }
     184                 :            : 
     185                 :     289098 : int OBJ_NAME_add(const char *name, int type, const char *data)
     186                 :            :         {
     187                 :            :         OBJ_NAME *onp,*ret;
     188                 :            :         int alias;
     189                 :            : 
     190 [ +  + ][ +  - ]:     289098 :         if ((names_lh == NULL) && !OBJ_NAME_init()) return(0);
     191                 :            : 
     192                 :     289098 :         alias=type&OBJ_NAME_ALIAS;
     193                 :     289098 :         type&= ~OBJ_NAME_ALIAS;
     194                 :            : 
     195                 :     289098 :         onp=(OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME));
     196         [ +  - ]:     289098 :         if (onp == NULL)
     197                 :            :                 {
     198                 :            :                 /* ERROR */
     199                 :            :                 return(0);
     200                 :            :                 }
     201                 :            : 
     202                 :     289098 :         onp->name=name;
     203                 :     289098 :         onp->alias=alias;
     204                 :     289098 :         onp->type=type;
     205                 :     289098 :         onp->data=data;
     206                 :            : 
     207                 :     289098 :         ret=lh_OBJ_NAME_insert(names_lh,onp);
     208         [ +  + ]:     289098 :         if (ret != NULL)
     209                 :            :                 {
     210                 :            :                 /* free things */
     211 [ -  + ][ #  # ]:      13857 :                 if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
     212                 :            :                         {
     213                 :            :                         /* XXX: I'm not sure I understand why the free
     214                 :            :                          * function should get three arguments...
     215                 :            :                          * -- Richard Levitte
     216                 :            :                          */
     217                 :          0 :                         sk_NAME_FUNCS_value(name_funcs_stack,
     218                 :          0 :                                 ret->type)->free_func(ret->name,ret->type,ret->data);
     219                 :            :                         }
     220                 :      13857 :                 OPENSSL_free(ret);
     221                 :            :                 }
     222                 :            :         else
     223                 :            :                 {
     224         [ +  - ]:     275241 :                 if (lh_OBJ_NAME_error(names_lh))
     225                 :            :                         {
     226                 :            :                         /* ERROR */
     227                 :            :                         return(0);
     228                 :            :                         }
     229                 :            :                 }
     230                 :            :         return(1);
     231                 :            :         }
     232                 :            : 
     233                 :     275234 : int OBJ_NAME_remove(const char *name, int type)
     234                 :            :         {
     235                 :            :         OBJ_NAME on,*ret;
     236                 :            : 
     237         [ +  - ]:     275234 :         if (names_lh == NULL) return(0);
     238                 :            : 
     239                 :     275234 :         type&= ~OBJ_NAME_ALIAS;
     240                 :     275234 :         on.name=name;
     241                 :     275234 :         on.type=type;
     242                 :     275234 :         ret=lh_OBJ_NAME_delete(names_lh,&on);
     243         [ +  - ]:     275234 :         if (ret != NULL)
     244                 :            :                 {
     245                 :            :                 /* free things */
     246 [ -  + ][ #  # ]:     275234 :                 if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
     247                 :            :                         {
     248                 :            :                         /* XXX: I'm not sure I understand why the free
     249                 :            :                          * function should get three arguments...
     250                 :            :                          * -- Richard Levitte
     251                 :            :                          */
     252                 :          0 :                         sk_NAME_FUNCS_value(name_funcs_stack,
     253                 :          0 :                                 ret->type)->free_func(ret->name,ret->type,ret->data);
     254                 :            :                         }
     255                 :     275234 :                 OPENSSL_free(ret);
     256                 :     275234 :                 return(1);
     257                 :            :                 }
     258                 :            :         else
     259                 :            :                 return(0);
     260                 :            :         }
     261                 :            : 
     262                 :            : struct doall
     263                 :            :         {
     264                 :            :         int type;
     265                 :            :         void (*fn)(const OBJ_NAME *,void *arg);
     266                 :            :         void *arg;
     267                 :            :         };
     268                 :            : 
     269                 :          0 : static void do_all_fn_doall_arg(const OBJ_NAME *name,struct doall *d)
     270                 :            :         {
     271         [ #  # ]:          0 :         if(name->type == d->type)
     272                 :          0 :                 d->fn(name,d->arg);
     273                 :          0 :         }
     274                 :            : 
     275                 :          0 : static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall)
     276                 :            : 
     277                 :          0 : void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg)
     278                 :            :         {
     279                 :            :         struct doall d;
     280                 :            : 
     281                 :          0 :         d.type=type;
     282                 :          0 :         d.fn=fn;
     283                 :          0 :         d.arg=arg;
     284                 :            : 
     285                 :          0 :         lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn),
     286                 :            :                               struct doall, &d);
     287                 :          0 :         }
     288                 :            : 
     289                 :            : struct doall_sorted
     290                 :            :         {
     291                 :            :         int type;
     292                 :            :         int n;
     293                 :            :         const OBJ_NAME **names;
     294                 :            :         };
     295                 :            : 
     296                 :          0 : static void do_all_sorted_fn(const OBJ_NAME *name,void *d_)
     297                 :            :         {
     298                 :          0 :         struct doall_sorted *d=d_;
     299                 :            : 
     300         [ #  # ]:          0 :         if(name->type != d->type)
     301                 :          0 :                 return;
     302                 :            : 
     303                 :          0 :         d->names[d->n++]=name;
     304                 :            :         }
     305                 :            : 
     306                 :          0 : static int do_all_sorted_cmp(const void *n1_,const void *n2_)
     307                 :            :         {
     308                 :          0 :         const OBJ_NAME * const *n1=n1_;
     309                 :          0 :         const OBJ_NAME * const *n2=n2_;
     310                 :            : 
     311                 :          0 :         return strcmp((*n1)->name,(*n2)->name);
     312                 :            :         }
     313                 :            : 
     314                 :          0 : void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
     315                 :            :                                 void *arg)
     316                 :            :         {
     317                 :            :         struct doall_sorted d;
     318                 :            :         int n;
     319                 :            : 
     320                 :          0 :         d.type=type;
     321                 :          0 :         d.names=OPENSSL_malloc(lh_OBJ_NAME_num_items(names_lh)*sizeof *d.names);
     322                 :          0 :         d.n=0;
     323                 :          0 :         OBJ_NAME_do_all(type,do_all_sorted_fn,&d);
     324                 :            : 
     325                 :          0 :         qsort((void *)d.names,d.n,sizeof *d.names,do_all_sorted_cmp);
     326                 :            : 
     327         [ #  # ]:          0 :         for(n=0 ; n < d.n ; ++n)
     328                 :          0 :                 fn(d.names[n],arg);
     329                 :            : 
     330                 :          0 :         OPENSSL_free((void *)d.names);
     331                 :          0 :         }
     332                 :            : 
     333                 :            : static int free_type;
     334                 :            : 
     335                 :     351729 : static void names_lh_free_doall(OBJ_NAME *onp)
     336                 :            :         {
     337         [ +  - ]:     351729 :         if (onp == NULL)
     338                 :     351729 :                 return;
     339                 :            : 
     340 [ +  - ][ +  + ]:     351729 :         if (free_type < 0 || free_type == onp->type)
     341                 :     275234 :                 OBJ_NAME_remove(onp->name,onp->type);
     342                 :            :         }
     343                 :            : 
     344                 :     703458 : static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME)
     345                 :            : 
     346                 :          0 : static void name_funcs_free(NAME_FUNCS *ptr)
     347                 :            :         {
     348                 :          0 :         OPENSSL_free(ptr);
     349                 :          0 :         }
     350                 :            : 
     351                 :       4863 : void OBJ_NAME_cleanup(int type)
     352                 :            :         {
     353                 :            :         unsigned long down_load;
     354                 :            : 
     355         [ +  + ]:       4863 :         if (names_lh == NULL) return;
     356                 :            : 
     357                 :       4860 :         free_type=type;
     358                 :       4860 :         down_load=lh_OBJ_NAME_down_load(names_lh);
     359                 :       4860 :         lh_OBJ_NAME_down_load(names_lh)=0;
     360                 :            : 
     361                 :       4860 :         lh_OBJ_NAME_doall(names_lh,LHASH_DOALL_FN(names_lh_free));
     362         [ +  + ]:       4860 :         if (type < 0)
     363                 :            :                 {
     364                 :       1620 :                 lh_OBJ_NAME_free(names_lh);
     365                 :       1620 :                 sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free);
     366                 :       1620 :                 names_lh=NULL;
     367                 :       1620 :                 name_funcs_stack = NULL;
     368                 :            :                 }
     369                 :            :         else
     370                 :       3240 :                 lh_OBJ_NAME_down_load(names_lh)=down_load;
     371                 :            :         }
     372                 :            : 

Generated by: LCOV version 1.9