Beispiel #1
0
main()
{
    LHASH *conf;
    char buf[256];
    int i;

    conf = lh_new(lh_strhash, strcmp);
    for (;;) {
        char *p;

        buf[0] = '\0';
        fgets(buf, 256, stdin);
        if (buf[0] == '\0')
            break;
        i = strlen(buf);
        p = OPENSSL_malloc(i + 1);
        memcpy(p, buf, i + 1);
        lh_insert(conf, p);
    }

    lh_node_stats(conf, stdout);
    lh_stats(conf, stdout);
    lh_node_usage_stats(conf, stdout);
    exit(0);
}
main()
	{
	LHASH *conf;
	char buf[256];
	int i;

	conf=lh_new(lh_strhash,TINYCLR_SSL_STRCMP);
	for (;;)
		{
		char *p;

		buf[0]='\0';
		TINYCLR_SSL_FGETS(buf,256,OPENSSL_TYPE__FILE_STDIN);
		if (buf[0] == '\0') break;
		i=TINYCLR_SSL_STRLEN(buf);
		p=OPENSSL_malloc(i+1);
		TINYCLR_SSL_MEMCPY(p,buf,i+1);
		lh_insert(conf,p);
		}

	lh_node_stats(conf,OPENSSL_TYPE__FILE_STDOUT);
	lh_stats(conf,OPENSSL_TYPE__FILE_STDOUT);
	lh_node_usage_stats(conf,OPENSSL_TYPE__FILE_STDOUT);
	TINYCLR_SSL_EXIT(0);
	}
anon_octs_t*
anon_octs_new()
{
    anon_octs_t *a;

    a = (anon_octs_t *) malloc(sizeof(anon_octs_t));
    if (! a) {
        return NULL;
    }
    memset(a, 0, sizeof(anon_octs_t));

    a->hash_table = lh_new(LHASH_HASH_FN(anon_octs_hash),
                           LHASH_COMP_FN(anon_octs_cmp));
    a->state = INIT; /* we're initializing, so we don't want to do
		      * checks on previous state values
		      */

    /* initialize randomness - this might not be the best way to do it */
    while (! RAND_status()) {
        fprintf(stderr, "initializing randomness...");
        char buf;
        buf = rand();
        RAND_seed(&buf, 1);
        fprintf(stderr, "done\n");
    }

    return a;
}
Beispiel #4
0
void ERR_load_strings(int lib, ERR_STRING_DATA *str)
	{
	if (error_hash == NULL)
		{
		CRYPTO_w_lock(CRYPTO_LOCK_ERR_HASH);
		error_hash=lh_new(err_hash,err_cmp);
		if (error_hash == NULL)
			{
			CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);
			return;
			}
		CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);

		ERR_load_ERR_strings();
		}

	CRYPTO_w_lock(CRYPTO_LOCK_ERR_HASH);
	while (str->error)
		{
		str->error|=ERR_PACK(lib,0,0);
		lh_insert(error_hash,str);
		str++;
		}
	CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);
	}
Beispiel #5
0
EXPORT_C int OBJ_NAME_init(void)
	{
	if (names_lh != NULL) return(1);
	MemCheck_off();
	names_lh=lh_new(obj_name_hash, obj_name_cmp);
	MemCheck_on();
	return(names_lh != NULL);
	}
int OBJ_NAME_init(void)
	{
	if (names_lh != NULL) return(1);
	MemCheck_off();
	names_lh=lh_new((func_hash_t)obj_name_hash, (func_comp_t)obj_name_cmp);
	MemCheck_on();
	return(names_lh != NULL);
	}
Beispiel #7
0
static int int_table_check(ENGINE_TABLE **t, int create)
	{
	LHASH *lh;
	if(*t) return 1;
	if(!create) return 0;
	if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash),
			LHASH_COMP_FN(engine_pile_cmp))) == NULL)
		return 0;
	*t = (ENGINE_TABLE *)lh;
	return 1;
	}
Beispiel #8
0
ERR_STATE *ERR_get_state(void)
	{
	ERR_STATE *ret=NULL,tmp,*tmpp;
	int i;
	unsigned long pid;

	pid=(unsigned long)CRYPTO_thread_id();

	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
	if (thread_hash == NULL)
		{
		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
		CRYPTO_w_lock(CRYPTO_LOCK_ERR);
		if (thread_hash == NULL)
			{
			MemCheck_off();
			thread_hash=lh_new(pid_hash,pid_cmp);
			MemCheck_on();
			CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
			if (thread_hash == NULL) return(getFallback());
			}
		else
			CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
		}
	else
		{
		tmp.pid=pid;
		ret=(ERR_STATE *)lh_retrieve(thread_hash,&tmp);
		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
		}

	/* ret == the error state, if NULL, make a new one */
	if (ret == NULL)
		{
		ret=(ERR_STATE *)Malloc(sizeof(ERR_STATE));
		if (ret == NULL) return(getFallback());
		ret->pid=pid;
		ret->top=0;
		ret->bottom=0;
		for (i=0; i<ERR_NUM_ERRORS; i++)
			{
			ret->err_data[i]=NULL;
			ret->err_data_flags[i]=0;
			}
		CRYPTO_w_lock(CRYPTO_LOCK_ERR);
		tmpp=(ERR_STATE *)lh_insert(thread_hash,ret);
		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
		if (tmpp != NULL) /* old entry - should not happen */
			{
			ERR_STATE_free(tmpp);
			}
		}
	return(ret);
	}
Beispiel #9
0
int CRYPTO_push_info_(const char *info, const char *file, int line)
	{
	APP_INFO *ami, *amim;
	int ret=0;

	if (is_MemCheck_on())
		{
		MemCheck_off(); /* obtain MALLOC2 lock */

		if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
			{
			ret=0;
			goto err;
			}
		if (amih == NULL)
			{
			if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL)
				{
				OPENSSL_free(ami);
				ret=0;
				goto err;
				}
			}

		ami->thread=CRYPTO_thread_id();
		ami->file=file;
		ami->line=line;
		ami->info=info;
		ami->references=1;
		ami->next=NULL;

		if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL)
			{
#ifdef LEVITTE_DEBUG_MEM
			if (ami->thread != amim->thread)
				{
				fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
					amim->thread, ami->thread);
				abort();
				}
#endif
			ami->next=amim;
			}
 err:
		MemCheck_on(); /* release MALLOC2 lock */
		}

	return(ret);
	}
Beispiel #10
0
void test_localization(void) {
    const char* filePath = NULL;
    const char* language = NULL;
    const char* testLanguage = NULL;
    const char* const* languages;
    size_t i = 0;
    LocalizationHandler* lh = NULL;

    filePath = "localization.txt";
    language = "en";
    testLanguage = "it";

    g_print("\n\rInitialize localization with '%s' file and '%s' language...\n\r", filePath, language);
    lh = lh_new(filePath, language);

    g_print("File path is '%s' ", lh_get_file_path(lh));
    g_print(", language is '%s'\n\r", lh_get_language(lh));

    languages = lh_get_supported_languages(lh);
    g_return_if_fail(languages != NULL);

    g_print("Supported languages: ");
    for (i = 0; languages[i]; i++) {
        g_print("%s ", languages[i]);
    }
    g_print("\n\r");

    g_print("Check file strings...\n\r");
    g_print("Check localized file strings...\n\r");

    test_print_localization_strings(lh, NULL);
    
    if (lh_language_is_supported(lh, testLanguage) == FALSE) {
        g_print("'%s' language is not supported...\n\r", testLanguage);
    }

    if (lh_language_is_supported(lh, language) == TRUE) {
        test_print_localization_strings(lh, language);
    }

    if (lh_language_is_supported(lh, testLanguage) == TRUE) {
        test_print_localization_strings(lh, language);
    }

    g_print("Release localization resources...\n\r");
    lh_free(lh);
}
Beispiel #11
0
static LHASH *prog_init(void)
{
    LHASH *ret;
    FUNCTION *f;
    size_t i;

    /* Purely so it looks nice when the user hits ? */
    for (i = 0, f = functions; f->name != NULL; ++f, ++i) ;
    qsort(functions, i, sizeof *functions, SortFnByName);

    if ((ret = lh_new(hash, cmp)) == NULL)
        return (NULL);

    for (f = functions; f->name != NULL; f++)
        lh_insert(ret, f);
    return (ret);
}
static LHASH *int_err_get(int create)
	{
	LHASH *ret = NULL;

	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
	if (!int_error_hash && create)
		{
		CRYPTO_push_info("int_err_get (err.c)");
		int_error_hash = lh_new(err_hash, err_cmp);
		CRYPTO_pop_info();
		}
	if (int_error_hash)
		ret = int_error_hash;
	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);

	return ret;
	}
static LHASH *int_thread_get(int create)
	{
	LHASH *ret = NULL;

	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
	if (!int_thread_hash && create)
		{
		CRYPTO_push_info("int_thread_get (err.c)");
		int_thread_hash = lh_new(pid_hash, pid_cmp);
		CRYPTO_pop_info();
		}
	if (int_thread_hash)
		{
		int_thread_hash_references++;
		ret = int_thread_hash;
		}
	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
	return ret;
	}
Beispiel #14
0
int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(char **),
		LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
	{
	LHASH *idx;
	char **r;
	int i,n;

	if (field >= db->num_fields)
		{
		db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
		return(0);
		}
	if ((idx=lh_new(hash,cmp)) == NULL)
		{
		db->error=DB_ERROR_MALLOC;
		return(0);
		}
	n=sk_num(db->data);
	for (i=0; i<n; i++)
		{
		r=(char **)sk_value(db->data,i);
		if ((qual != NULL) && (qual(r) == 0)) continue;
		if ((r=lh_insert(idx,r)) != NULL)
			{
			db->error=DB_ERROR_INDEX_CLASH;
			db->arg1=sk_find(db->data,(char *)r);
			db->arg2=i;
			lh_free(idx);
			return(0);
			}
		}
	if (db->index[field] != NULL) lh_free(db->index[field]);
	db->index[field]=idx;
	db->qual[field]=qual;
	return(1);
	}
    char *key_1 = "bacon";
    char *key_2 = "chicken";
    char *key_3 = "pork";

    /* some data */
    int data_1 = 1;
    int data_2 = 2;
    int data_3 = 3;

    /* temporary data pointer used for testing get */
    int *data = 0;

    puts("\ntesting delete functionality ");

    puts("creating a table");
    table = lh_new();
    assert(table);
    assert( 32 == table->size );
    assert( 0 == lh_nelems(table) );


    puts("inserting some data");
    assert( lh_insert(table, key_1, &data_1) );
    assert( 1 == lh_nelems(table) );
    assert( 0 == lh_get(table, key_2) );
    assert( 0 == lh_get(table, key_3) );

    data = lh_get(table, key_1);
    assert(data);
    assert( data_1 == *data );
Beispiel #16
0
void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
	int before_p)
	{
	MEM *m,*mm;
	APP_INFO tmp,*amim;

	switch(before_p & 127)
		{
	case 0:
		break;
	case 1:
		if (addr == NULL)
			break;

		if (is_MemCheck_on())
			{
			MemCheck_off(); /* make sure we hold MALLOC2 lock */
			if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
				{
				OPENSSL_free(addr);
				MemCheck_on(); /* release MALLOC2 lock
				                * if num_disabled drops to 0 */
				return;
				}
			if (mh == NULL)
				{
				if ((mh=lh_new(mem_hash, mem_cmp)) == NULL)
					{
					OPENSSL_free(addr);
					OPENSSL_free(m);
					addr=NULL;
					goto err;
					}
				}

			m->addr=addr;
			m->file=file;
			m->line=line;
			m->num=num;
			if (options & V_CRYPTO_MDEBUG_THREAD)
				m->thread=CRYPTO_thread_id();
			else
				m->thread=0;

			if (order == break_order_num)
				{
				/* BREAK HERE */
				m->order=order;
				}
			m->order=order++;
#ifdef LEVITTE_DEBUG_MEM
			fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n",
				m->order,
				(before_p & 128) ? '*' : '+',
				m->addr, m->num);
#endif
			if (options & V_CRYPTO_MDEBUG_TIME)
				m->time=time(NULL);
			else
				m->time=0;

			tmp.thread=CRYPTO_thread_id();
			m->app_info=NULL;
			if (amih != NULL
				&& (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL)
				{
				m->app_info = amim;
				amim->references++;
				}

			if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
				{
				/* Not good, but don't sweat it */
				if (mm->app_info != NULL)
					{
					mm->app_info->references--;
					}
				OPENSSL_free(mm);
				}
		err:
			MemCheck_on(); /* release MALLOC2 lock
			                * if num_disabled drops to 0 */
			}
		break;
		}
	return;
	}
void set(void){
    /* our simple hash table */
    struct lh_table *table = 0;

    /* some keys */
    char *key_1 = "rhubarb";
    char *key_2 = "carrot";
    char *key_3 = "potato";

    /* some data */
    int data_1 = 1;
    int data_2 = 2;
    int data_3 = 3;

    /* some data we override with */
    int new_data_1 = 14;
    int new_data_2 = 15;
    int new_data_3 = 16;


    /* temporary data pointer used for testing get */
    int *data = 0;

    puts("\ntesting set functionality");

    puts("creating table");
    table = lh_new();
    assert(table);
    assert( 32 == table->size );
    assert( 0 == lh_nelems(table) );


    puts("inserting some data");
    assert( lh_insert(table, key_1, &data_1) );
    assert( 1 == lh_nelems(table) );
    assert( 0 == lh_get(table, key_2) );
    assert( 0 == lh_get(table, key_3) );

    data = lh_get(table, key_1);
    assert(data);
    assert( data_1 == *data );


    assert( lh_insert(table, key_2, &data_2) );
    assert( 2 == lh_nelems(table) );
    assert( 0 == lh_get(table, key_3) );

    data = lh_get(table, key_2);
    assert(data);
    assert( data_2 == *data );


    assert( lh_insert(table, key_3, &data_3) );
    assert( 3 == lh_nelems(table) );

    data = lh_get(table, key_3);
    assert(data);
    assert( data_3 == *data );


    puts("testing set");
    puts("testing set failure for non-existing key");
    data = lh_set(table, "foobarr", &data_1);
    assert( 0 == data );

    puts("two set");
    data = lh_set(table, key_2, &new_data_2);
    assert(data);
    assert( *data == data_2 );
    assert( 3 == lh_nelems(table) );

    data = lh_get(table, key_2);
    assert(data);
    assert( *data == new_data_2 );

    puts("three set");
    data = lh_set(table, key_3, &new_data_3);
    assert(data);
    assert( *data == data_3 );
    assert( 3 == lh_nelems(table) );

    data = lh_get(table, key_3);
    assert(data);
    assert( *data == new_data_3 );

    puts("one set");
    data = lh_set(table, key_1, &new_data_1);
    assert(data);
    assert( *data == data_1 );
    assert( 3 == lh_nelems(table) );

    data = lh_get(table, key_1);
    assert(data);
    assert( *data == new_data_1 );


    assert( lh_destroy(table, 1, 0) );
    puts("success!");
}
Beispiel #18
0
static int init_added(void)
  {
  if (added != NULL) return(1);
  added=lh_new(add_hash,add_cmp);
  return(added != NULL);
  }
Beispiel #19
0
int main(int argc, char **argv) {
  _LHASH *lh;
  struct dummy_lhash dummy_lh = {NULL};
  unsigned i;

  CRYPTO_library_init();

  lh = lh_new(NULL, NULL);
  if (lh == NULL) {
    return 1;
  }

  for (i = 0; i < 100000; i++) {
    unsigned action;
    char *s, *s1, *s2;

    if (dummy_lh_num_items(&dummy_lh) != lh_num_items(lh)) {
      fprintf(stderr, "Length mismatch\n");
      return 1;
    }

    action = rand() % 3;
    switch (action) {
      case 0:
        s = rand_string();
        s1 = (char *)lh_retrieve(lh, s);
        s2 = dummy_lh_retrieve(&dummy_lh, s);
        if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) {
          fprintf(stderr, "lh_retrieve failure\n");
          abort();
        }
        free(s);
        break;

      case 1:
        s = rand_string();
        lh_insert(lh, (void **)&s1, s);
        dummy_lh_insert(&dummy_lh, &s2, strdup(s));

        if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) {
          fprintf(stderr, "lh_insert failure\n");
          abort();
        }

        if (s1) {
          free(s1);
        }
        if (s2) {
          free(s2);
        }
        break;

      case 2:
        s = rand_string();
        s1 = lh_delete(lh, s);
        s2 = dummy_lh_delete(&dummy_lh, s);

        if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) {
          fprintf(stderr, "lh_insert failure\n");
          abort();
        }

        if (s1) {
          free(s1);
        }
        if (s2) {
          free(s2);
        }
        free(s);
        break;

      default:
        abort();
    }
  }

  lh_doall(lh, free);
  lh_free(lh);
  dummy_lh_free(&dummy_lh);
  printf("PASS\n");
  return 0;
}
void new_insert_get_destroy(void){
    /* our simple hash table */
    struct lh_table *table = 0;

    /* some keys */
    char *key_1 = "bbbbb";
    char *key_2 = "aaaaa";
    char *key_3 = "ccccc";

    /* some data */
    int data_1 = 1;
    int data_2 = 2;
    int data_3 = 3;

    /* temporary data pointer used for testing get */
    int *data = 0;


    puts("\ntesting basic functionality");

    puts("testing new");
    table = lh_new();
    assert(table);
    assert( 32 == table->size );
    assert( 0 == lh_nelems(table) );
    assert( 0 == lh_load(table) );


    puts("testing insert and get");
    puts("one insert");
    assert( lh_insert(table, key_1, &data_1) );
    assert( 1 == lh_nelems(table));
    assert( 0 == lh_get(table, key_2) );
    assert( 0 == lh_get(table, key_3) );

    puts("one get");
    data = lh_get(table, key_1);
    assert(data);
    assert( data_1 == *data );


    puts("two insert");
    assert( lh_insert(table, key_2, &data_2) );
    assert( 2 == lh_nelems(table) );
    assert( 0 == lh_get(table, key_3) );

    puts("two get");
    data = lh_get(table, key_2);
    assert(data);
    assert( data_2 == *data );


    puts("three insert");
    assert( lh_insert(table, key_3, &data_3) );
    assert( 3 == lh_nelems(table) );

    puts("three get");
    data = lh_get(table, key_3);
    assert(data);
    assert( data_3 == *data );


    assert( lh_destroy(table, 1, 0) );
    puts("success!");
}
Beispiel #21
0
/*
 * Store a pathname in the pathname store.
 */
char*
Pathstore_path(Pathstore *store, char *pathname, int discardDuplicateFiles)
{
	char chksum1[CHKSUMFILE_SIZE];
	struct unixfilesystem *fs = (struct unixfilesystem *) (store->fshandle);

	numstores++;
	
	PathstoreElement *entry;
	
	/* For 1 file case
	 * No hash table or checksum 
	 */
	if(numfilesseen == 0){
		numfilesseen++;
		entry = malloc(sizeof(PathstoreElement));;
	    entry->pathname = strdup(pathname);
		if (entry->pathname == NULL) {
		  	free(entry);
			printf("memory problem 2\n");
		  	return NULL;
		}
		store->elementList = entry;
		return entry->pathname;
	}
	
	/* For >1 file
	 * Use hash table and checksums
	 */
	_LHASH *hashtable;
	
	// if we are going from 1 file case to 2 files
	if(numfilesseen == 1){
		numfilesseen++;
		//store first entry somewhere
		PathstoreElement *temp = store->elementList;
		//calc checksum for file 1 path
		int err = chksumfile_bypathname(fs, temp->pathname, chksum1);
		if (err < 0) {
	    	fprintf(stderr,"Can't checksum path %s\n", pathname);
		    return 0;
	 	}
		memcpy(temp->chksum, chksum1, CHKSUMFILE_SIZE);
		//initialize hash table
		store->elementList = lh_new(HashCallback, CompareCallback);
		hashtable = (_LHASH*) (store->elementList);
		//seed hash table with first entry
		lh_insert(hashtable,(char *) temp);
	    if (lh_error(hashtable)) {
	    	free(temp);
			printf("hash problem\n");
	    	return NULL;
	    }
	}else{
		hashtable = (_LHASH*) (store->elementList);
	}
	// calc checksum of pathname
	int err = chksumfile_bypathname(fs, pathname, chksum1);
	if (err < 0) {
    	fprintf(stderr,"Can't checksum path %s\n", pathname);
	    return 0;
 	}	

	PathstoreElement key;
	memcpy(key.chksum, chksum1, CHKSUMFILE_SIZE);	
	
	// if discardDups, see if its in table, if it is, return
	if (discardDuplicateFiles) {
		entry = lh_retrieve(hashtable, (char *) &key);
		if(entry != NULL){
			numdups++;
			return NULL;
		}
	}
	
	// otherwise add
	entry = malloc(sizeof(PathstoreElement));
    if (entry == NULL) {
		printf("memory problem\n");
      	return NULL;
    }
	memcpy(entry->chksum, chksum1, CHKSUMFILE_SIZE);
    entry->pathname = strdup(pathname);
	if (entry->pathname == NULL) {
	  	free(entry);
		printf("memory problem 2\n");
	  	return NULL;
	}

    lh_insert(hashtable,(char *) entry);

    if (lh_error(hashtable)) {
    	free(entry);
		printf("hash problem\n");
    	return NULL;
    }
  
	return entry->pathname;
}
Beispiel #22
0
HashTable create_hash_table()
{
  return lh_new(LHASH_HASH_FN(RelocEntry_hash),
                LHASH_COMP_FN(RelocEntry_cmp));
}
Beispiel #23
0
ERR_STATE *ERR_get_state(void)
	{
	static ERR_STATE fallback;
	ERR_STATE *ret=NULL,tmp,*tmpp=NULL;
	int thread_state_exists;
	int i;
	unsigned long pid;

	pid=(unsigned long)CRYPTO_thread_id();

	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
	if (thread_hash != NULL)
		{
		tmp.pid=pid;
		ret=(ERR_STATE *)lh_retrieve(thread_hash,&tmp);
		}
	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);

	/* ret == the error state, if NULL, make a new one */
	if (ret == NULL)
		{
		ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
		if (ret == NULL) return(&fallback);
		ret->pid=pid;
		ret->top=0;
		ret->bottom=0;
		for (i=0; i<ERR_NUM_ERRORS; i++)
			{
			ret->err_data[i]=NULL;
			ret->err_data_flags[i]=0;
			}

		CRYPTO_w_lock(CRYPTO_LOCK_ERR);

		/* no entry yet in thread_hash for current thread -
		 * thus, it may have changed since we last looked at it */
		if (thread_hash == NULL)
			thread_hash = lh_new(pid_hash, pid_cmp);
		if (thread_hash == NULL)
			thread_state_exists = 0; /* allocation error */
		else
			{
			tmpp=(ERR_STATE *)lh_insert(thread_hash,ret);
			thread_state_exists = 1;
			}

		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);

		if (!thread_state_exists)
			{
			ERR_STATE_free(ret); /* could not insert it */
			return(&fallback);
			}
		
		if (tmpp != NULL) /* old entry - should not happen */
			{
			ERR_STATE_free(tmpp);
			}
		}
	return(ret);
	}