xref: /onnv-gate/usr/src/common/openssl/crypto/objects/o_names.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate #include <stdio.h>
20Sstevel@tonic-gate #include <stdlib.h>
30Sstevel@tonic-gate #include <string.h>
40Sstevel@tonic-gate 
5*2139Sjp161948 #include <openssl/err.h>
60Sstevel@tonic-gate #include <openssl/lhash.h>
70Sstevel@tonic-gate #include <openssl/objects.h>
80Sstevel@tonic-gate #include <openssl/safestack.h>
90Sstevel@tonic-gate #include <openssl/e_os2.h>
100Sstevel@tonic-gate 
110Sstevel@tonic-gate /* Later versions of DEC C has started to add lnkage information to certain
120Sstevel@tonic-gate  * functions, which makes it tricky to use them as values to regular function
130Sstevel@tonic-gate  * pointers.  One way is to define a macro that takes care of casting them
140Sstevel@tonic-gate  * correctly.
150Sstevel@tonic-gate  */
160Sstevel@tonic-gate #ifdef OPENSSL_SYS_VMS_DECC
170Sstevel@tonic-gate # define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp
180Sstevel@tonic-gate #else
190Sstevel@tonic-gate # define OPENSSL_strcmp strcmp
200Sstevel@tonic-gate #endif
210Sstevel@tonic-gate 
220Sstevel@tonic-gate /* I use the ex_data stuff to manage the identifiers for the obj_name_types
230Sstevel@tonic-gate  * that applications may define.  I only really use the free function field.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate static LHASH *names_lh=NULL;
260Sstevel@tonic-gate static int names_type_num=OBJ_NAME_TYPE_NUM;
270Sstevel@tonic-gate 
280Sstevel@tonic-gate typedef struct name_funcs_st
290Sstevel@tonic-gate 	{
300Sstevel@tonic-gate 	unsigned long (*hash_func)(const char *name);
310Sstevel@tonic-gate 	int (*cmp_func)(const char *a,const char *b);
320Sstevel@tonic-gate 	void (*free_func)(const char *, int, const char *);
330Sstevel@tonic-gate 	} NAME_FUNCS;
340Sstevel@tonic-gate 
350Sstevel@tonic-gate DECLARE_STACK_OF(NAME_FUNCS)
360Sstevel@tonic-gate IMPLEMENT_STACK_OF(NAME_FUNCS)
370Sstevel@tonic-gate 
380Sstevel@tonic-gate static STACK_OF(NAME_FUNCS) *name_funcs_stack;
390Sstevel@tonic-gate 
400Sstevel@tonic-gate /* The LHASH callbacks now use the raw "void *" prototypes and do per-variable
410Sstevel@tonic-gate  * casting in the functions. This prevents function pointer casting without the
420Sstevel@tonic-gate  * need for macro-generated wrapper functions. */
430Sstevel@tonic-gate 
440Sstevel@tonic-gate /* static unsigned long obj_name_hash(OBJ_NAME *a); */
450Sstevel@tonic-gate static unsigned long obj_name_hash(const void *a_void);
460Sstevel@tonic-gate /* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */
470Sstevel@tonic-gate static int obj_name_cmp(const void *a_void,const void *b_void);
480Sstevel@tonic-gate 
OBJ_NAME_init(void)490Sstevel@tonic-gate int OBJ_NAME_init(void)
500Sstevel@tonic-gate 	{
510Sstevel@tonic-gate 	if (names_lh != NULL) return(1);
520Sstevel@tonic-gate 	MemCheck_off();
530Sstevel@tonic-gate 	names_lh=lh_new(obj_name_hash, obj_name_cmp);
540Sstevel@tonic-gate 	MemCheck_on();
550Sstevel@tonic-gate 	return(names_lh != NULL);
560Sstevel@tonic-gate 	}
570Sstevel@tonic-gate 
OBJ_NAME_new_index(unsigned long (* hash_func)(const char *),int (* cmp_func)(const char *,const char *),void (* free_func)(const char *,int,const char *))580Sstevel@tonic-gate int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
590Sstevel@tonic-gate 	int (*cmp_func)(const char *, const char *),
600Sstevel@tonic-gate 	void (*free_func)(const char *, int, const char *))
610Sstevel@tonic-gate 	{
620Sstevel@tonic-gate 	int ret;
630Sstevel@tonic-gate 	int i;
640Sstevel@tonic-gate 	NAME_FUNCS *name_funcs;
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 	if (name_funcs_stack == NULL)
670Sstevel@tonic-gate 		{
680Sstevel@tonic-gate 		MemCheck_off();
690Sstevel@tonic-gate 		name_funcs_stack=sk_NAME_FUNCS_new_null();
700Sstevel@tonic-gate 		MemCheck_on();
710Sstevel@tonic-gate 		}
720Sstevel@tonic-gate 	if ((name_funcs_stack == NULL))
730Sstevel@tonic-gate 		{
740Sstevel@tonic-gate 		/* ERROR */
750Sstevel@tonic-gate 		return(0);
760Sstevel@tonic-gate 		}
770Sstevel@tonic-gate 	ret=names_type_num;
780Sstevel@tonic-gate 	names_type_num++;
790Sstevel@tonic-gate 	for (i=sk_NAME_FUNCS_num(name_funcs_stack); i<names_type_num; i++)
800Sstevel@tonic-gate 		{
810Sstevel@tonic-gate 		MemCheck_off();
820Sstevel@tonic-gate 		name_funcs = OPENSSL_malloc(sizeof(NAME_FUNCS));
830Sstevel@tonic-gate 		MemCheck_on();
84*2139Sjp161948 		if (!name_funcs)
85*2139Sjp161948 			{
86*2139Sjp161948 			OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX,ERR_R_MALLOC_FAILURE);
87*2139Sjp161948 			return(0);
88*2139Sjp161948 			}
890Sstevel@tonic-gate 		name_funcs->hash_func = lh_strhash;
900Sstevel@tonic-gate 		name_funcs->cmp_func = OPENSSL_strcmp;
910Sstevel@tonic-gate 		name_funcs->free_func = 0; /* NULL is often declared to
920Sstevel@tonic-gate 						* ((void *)0), which according
930Sstevel@tonic-gate 						* to Compaq C is not really
940Sstevel@tonic-gate 						* compatible with a function
950Sstevel@tonic-gate 						* pointer.	-- Richard Levitte*/
960Sstevel@tonic-gate 		MemCheck_off();
970Sstevel@tonic-gate 		sk_NAME_FUNCS_push(name_funcs_stack,name_funcs);
980Sstevel@tonic-gate 		MemCheck_on();
990Sstevel@tonic-gate 		}
1000Sstevel@tonic-gate 	name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret);
1010Sstevel@tonic-gate 	if (hash_func != NULL)
1020Sstevel@tonic-gate 		name_funcs->hash_func = hash_func;
1030Sstevel@tonic-gate 	if (cmp_func != NULL)
1040Sstevel@tonic-gate 		name_funcs->cmp_func = cmp_func;
1050Sstevel@tonic-gate 	if (free_func != NULL)
1060Sstevel@tonic-gate 		name_funcs->free_func = free_func;
1070Sstevel@tonic-gate 	return(ret);
1080Sstevel@tonic-gate 	}
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate /* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */
obj_name_cmp(const void * a_void,const void * b_void)1110Sstevel@tonic-gate static int obj_name_cmp(const void *a_void, const void *b_void)
1120Sstevel@tonic-gate 	{
1130Sstevel@tonic-gate 	int ret;
114*2139Sjp161948 	const OBJ_NAME *a = (const OBJ_NAME *)a_void;
115*2139Sjp161948 	const OBJ_NAME *b = (const OBJ_NAME *)b_void;
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate 	ret=a->type-b->type;
1180Sstevel@tonic-gate 	if (ret == 0)
1190Sstevel@tonic-gate 		{
1200Sstevel@tonic-gate 		if ((name_funcs_stack != NULL)
1210Sstevel@tonic-gate 			&& (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
1220Sstevel@tonic-gate 			{
1230Sstevel@tonic-gate 			ret=sk_NAME_FUNCS_value(name_funcs_stack,
1240Sstevel@tonic-gate 				a->type)->cmp_func(a->name,b->name);
1250Sstevel@tonic-gate 			}
1260Sstevel@tonic-gate 		else
1270Sstevel@tonic-gate 			ret=strcmp(a->name,b->name);
1280Sstevel@tonic-gate 		}
1290Sstevel@tonic-gate 	return(ret);
1300Sstevel@tonic-gate 	}
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate /* static unsigned long obj_name_hash(OBJ_NAME *a) */
obj_name_hash(const void * a_void)1330Sstevel@tonic-gate static unsigned long obj_name_hash(const void *a_void)
1340Sstevel@tonic-gate 	{
1350Sstevel@tonic-gate 	unsigned long ret;
136*2139Sjp161948 	const OBJ_NAME *a = (const OBJ_NAME *)a_void;
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 	if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
1390Sstevel@tonic-gate 		{
1400Sstevel@tonic-gate 		ret=sk_NAME_FUNCS_value(name_funcs_stack,
1410Sstevel@tonic-gate 			a->type)->hash_func(a->name);
1420Sstevel@tonic-gate 		}
1430Sstevel@tonic-gate 	else
1440Sstevel@tonic-gate 		{
1450Sstevel@tonic-gate 		ret=lh_strhash(a->name);
1460Sstevel@tonic-gate 		}
1470Sstevel@tonic-gate 	ret^=a->type;
1480Sstevel@tonic-gate 	return(ret);
1490Sstevel@tonic-gate 	}
1500Sstevel@tonic-gate 
OBJ_NAME_get(const char * name,int type)1510Sstevel@tonic-gate const char *OBJ_NAME_get(const char *name, int type)
1520Sstevel@tonic-gate 	{
1530Sstevel@tonic-gate 	OBJ_NAME on,*ret;
1540Sstevel@tonic-gate 	int num=0,alias;
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 	if (name == NULL) return(NULL);
1570Sstevel@tonic-gate 	if ((names_lh == NULL) && !OBJ_NAME_init()) return(NULL);
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 	alias=type&OBJ_NAME_ALIAS;
1600Sstevel@tonic-gate 	type&= ~OBJ_NAME_ALIAS;
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate 	on.name=name;
1630Sstevel@tonic-gate 	on.type=type;
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	for (;;)
1660Sstevel@tonic-gate 	{
1670Sstevel@tonic-gate 		ret=(OBJ_NAME *)lh_retrieve(names_lh,&on);
1680Sstevel@tonic-gate 		if (ret == NULL) return(NULL);
1690Sstevel@tonic-gate 		if ((ret->alias) && !alias)
1700Sstevel@tonic-gate 			{
1710Sstevel@tonic-gate 			if (++num > 10) return(NULL);
1720Sstevel@tonic-gate 			on.name=ret->data;
1730Sstevel@tonic-gate 			}
1740Sstevel@tonic-gate 		else
1750Sstevel@tonic-gate 			{
1760Sstevel@tonic-gate 			return(ret->data);
1770Sstevel@tonic-gate 			}
1780Sstevel@tonic-gate 		}
1790Sstevel@tonic-gate 	}
1800Sstevel@tonic-gate 
OBJ_NAME_add(const char * name,int type,const char * data)1810Sstevel@tonic-gate int OBJ_NAME_add(const char *name, int type, const char *data)
1820Sstevel@tonic-gate 	{
1830Sstevel@tonic-gate 	OBJ_NAME *onp,*ret;
1840Sstevel@tonic-gate 	int alias;
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 	if ((names_lh == NULL) && !OBJ_NAME_init()) return(0);
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate 	alias=type&OBJ_NAME_ALIAS;
1890Sstevel@tonic-gate 	type&= ~OBJ_NAME_ALIAS;
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 	onp=(OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME));
1920Sstevel@tonic-gate 	if (onp == NULL)
1930Sstevel@tonic-gate 		{
1940Sstevel@tonic-gate 		/* ERROR */
1950Sstevel@tonic-gate 		return(0);
1960Sstevel@tonic-gate 		}
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 	onp->name=name;
1990Sstevel@tonic-gate 	onp->alias=alias;
2000Sstevel@tonic-gate 	onp->type=type;
2010Sstevel@tonic-gate 	onp->data=data;
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 	ret=(OBJ_NAME *)lh_insert(names_lh,onp);
2040Sstevel@tonic-gate 	if (ret != NULL)
2050Sstevel@tonic-gate 		{
2060Sstevel@tonic-gate 		/* free things */
2070Sstevel@tonic-gate 		if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
2080Sstevel@tonic-gate 			{
2090Sstevel@tonic-gate 			/* XXX: I'm not sure I understand why the free
2100Sstevel@tonic-gate 			 * function should get three arguments...
2110Sstevel@tonic-gate 			 * -- Richard Levitte
2120Sstevel@tonic-gate 			 */
2130Sstevel@tonic-gate 			sk_NAME_FUNCS_value(name_funcs_stack,
2140Sstevel@tonic-gate 				ret->type)->free_func(ret->name,ret->type,ret->data);
2150Sstevel@tonic-gate 			}
2160Sstevel@tonic-gate 		OPENSSL_free(ret);
2170Sstevel@tonic-gate 		}
2180Sstevel@tonic-gate 	else
2190Sstevel@tonic-gate 		{
2200Sstevel@tonic-gate 		if (lh_error(names_lh))
2210Sstevel@tonic-gate 			{
2220Sstevel@tonic-gate 			/* ERROR */
2230Sstevel@tonic-gate 			return(0);
2240Sstevel@tonic-gate 			}
2250Sstevel@tonic-gate 		}
2260Sstevel@tonic-gate 	return(1);
2270Sstevel@tonic-gate 	}
2280Sstevel@tonic-gate 
OBJ_NAME_remove(const char * name,int type)2290Sstevel@tonic-gate int OBJ_NAME_remove(const char *name, int type)
2300Sstevel@tonic-gate 	{
2310Sstevel@tonic-gate 	OBJ_NAME on,*ret;
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate 	if (names_lh == NULL) return(0);
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate 	type&= ~OBJ_NAME_ALIAS;
2360Sstevel@tonic-gate 	on.name=name;
2370Sstevel@tonic-gate 	on.type=type;
2380Sstevel@tonic-gate 	ret=(OBJ_NAME *)lh_delete(names_lh,&on);
2390Sstevel@tonic-gate 	if (ret != NULL)
2400Sstevel@tonic-gate 		{
2410Sstevel@tonic-gate 		/* free things */
2420Sstevel@tonic-gate 		if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
2430Sstevel@tonic-gate 			{
2440Sstevel@tonic-gate 			/* XXX: I'm not sure I understand why the free
2450Sstevel@tonic-gate 			 * function should get three arguments...
2460Sstevel@tonic-gate 			 * -- Richard Levitte
2470Sstevel@tonic-gate 			 */
2480Sstevel@tonic-gate 			sk_NAME_FUNCS_value(name_funcs_stack,
2490Sstevel@tonic-gate 				ret->type)->free_func(ret->name,ret->type,ret->data);
2500Sstevel@tonic-gate 			}
2510Sstevel@tonic-gate 		OPENSSL_free(ret);
2520Sstevel@tonic-gate 		return(1);
2530Sstevel@tonic-gate 		}
2540Sstevel@tonic-gate 	else
2550Sstevel@tonic-gate 		return(0);
2560Sstevel@tonic-gate 	}
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate struct doall
2590Sstevel@tonic-gate 	{
2600Sstevel@tonic-gate 	int type;
2610Sstevel@tonic-gate 	void (*fn)(const OBJ_NAME *,void *arg);
2620Sstevel@tonic-gate 	void *arg;
2630Sstevel@tonic-gate 	};
2640Sstevel@tonic-gate 
do_all_fn(const OBJ_NAME * name,struct doall * d)2650Sstevel@tonic-gate static void do_all_fn(const OBJ_NAME *name,struct doall *d)
2660Sstevel@tonic-gate 	{
2670Sstevel@tonic-gate 	if(name->type == d->type)
2680Sstevel@tonic-gate 		d->fn(name,d->arg);
2690Sstevel@tonic-gate 	}
2700Sstevel@tonic-gate 
IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn,const OBJ_NAME *,struct doall *)2710Sstevel@tonic-gate static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME *, struct doall *)
2720Sstevel@tonic-gate 
2730Sstevel@tonic-gate void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg)
2740Sstevel@tonic-gate 	{
2750Sstevel@tonic-gate 	struct doall d;
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate 	d.type=type;
2780Sstevel@tonic-gate 	d.fn=fn;
2790Sstevel@tonic-gate 	d.arg=arg;
2800Sstevel@tonic-gate 
2810Sstevel@tonic-gate 	lh_doall_arg(names_lh,LHASH_DOALL_ARG_FN(do_all_fn),&d);
2820Sstevel@tonic-gate 	}
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate struct doall_sorted
2850Sstevel@tonic-gate 	{
2860Sstevel@tonic-gate 	int type;
2870Sstevel@tonic-gate 	int n;
2880Sstevel@tonic-gate 	const OBJ_NAME **names;
2890Sstevel@tonic-gate 	};
2900Sstevel@tonic-gate 
do_all_sorted_fn(const OBJ_NAME * name,void * d_)2910Sstevel@tonic-gate static void do_all_sorted_fn(const OBJ_NAME *name,void *d_)
2920Sstevel@tonic-gate 	{
2930Sstevel@tonic-gate 	struct doall_sorted *d=d_;
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate 	if(name->type != d->type)
2960Sstevel@tonic-gate 		return;
2970Sstevel@tonic-gate 
2980Sstevel@tonic-gate 	d->names[d->n++]=name;
2990Sstevel@tonic-gate 	}
3000Sstevel@tonic-gate 
do_all_sorted_cmp(const void * n1_,const void * n2_)3010Sstevel@tonic-gate static int do_all_sorted_cmp(const void *n1_,const void *n2_)
3020Sstevel@tonic-gate 	{
3030Sstevel@tonic-gate 	const OBJ_NAME * const *n1=n1_;
3040Sstevel@tonic-gate 	const OBJ_NAME * const *n2=n2_;
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate 	return strcmp((*n1)->name,(*n2)->name);
3070Sstevel@tonic-gate 	}
3080Sstevel@tonic-gate 
OBJ_NAME_do_all_sorted(int type,void (* fn)(const OBJ_NAME *,void * arg),void * arg)3090Sstevel@tonic-gate void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
3100Sstevel@tonic-gate 				void *arg)
3110Sstevel@tonic-gate 	{
3120Sstevel@tonic-gate 	struct doall_sorted d;
3130Sstevel@tonic-gate 	int n;
3140Sstevel@tonic-gate 
3150Sstevel@tonic-gate 	d.type=type;
3160Sstevel@tonic-gate 	d.names=OPENSSL_malloc(lh_num_items(names_lh)*sizeof *d.names);
3170Sstevel@tonic-gate 	d.n=0;
3180Sstevel@tonic-gate 	OBJ_NAME_do_all(type,do_all_sorted_fn,&d);
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate 	qsort((void *)d.names,d.n,sizeof *d.names,do_all_sorted_cmp);
3210Sstevel@tonic-gate 
3220Sstevel@tonic-gate 	for(n=0 ; n < d.n ; ++n)
3230Sstevel@tonic-gate 		fn(d.names[n],arg);
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate 	OPENSSL_free((void *)d.names);
3260Sstevel@tonic-gate 	}
3270Sstevel@tonic-gate 
3280Sstevel@tonic-gate static int free_type;
3290Sstevel@tonic-gate 
names_lh_free(OBJ_NAME * onp)3300Sstevel@tonic-gate static void names_lh_free(OBJ_NAME *onp)
3310Sstevel@tonic-gate {
3320Sstevel@tonic-gate 	if(onp == NULL)
3330Sstevel@tonic-gate 		return;
3340Sstevel@tonic-gate 
3350Sstevel@tonic-gate 	if ((free_type < 0) || (free_type == onp->type))
3360Sstevel@tonic-gate 		{
3370Sstevel@tonic-gate 		OBJ_NAME_remove(onp->name,onp->type);
3380Sstevel@tonic-gate 		}
3390Sstevel@tonic-gate 	}
3400Sstevel@tonic-gate 
IMPLEMENT_LHASH_DOALL_FN(names_lh_free,OBJ_NAME *)3410Sstevel@tonic-gate static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME *)
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate static void name_funcs_free(NAME_FUNCS *ptr)
3440Sstevel@tonic-gate 	{
3450Sstevel@tonic-gate 	OPENSSL_free(ptr);
3460Sstevel@tonic-gate 	}
3470Sstevel@tonic-gate 
OBJ_NAME_cleanup(int type)3480Sstevel@tonic-gate void OBJ_NAME_cleanup(int type)
3490Sstevel@tonic-gate 	{
3500Sstevel@tonic-gate 	unsigned long down_load;
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate 	if (names_lh == NULL) return;
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate 	free_type=type;
3550Sstevel@tonic-gate 	down_load=names_lh->down_load;
3560Sstevel@tonic-gate 	names_lh->down_load=0;
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate 	lh_doall(names_lh,LHASH_DOALL_FN(names_lh_free));
3590Sstevel@tonic-gate 	if (type < 0)
3600Sstevel@tonic-gate 		{
3610Sstevel@tonic-gate 		lh_free(names_lh);
3620Sstevel@tonic-gate 		sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free);
3630Sstevel@tonic-gate 		names_lh=NULL;
3640Sstevel@tonic-gate 		name_funcs_stack = NULL;
3650Sstevel@tonic-gate 		}
3660Sstevel@tonic-gate 	else
3670Sstevel@tonic-gate 		names_lh->down_load=down_load;
3680Sstevel@tonic-gate 	}
3690Sstevel@tonic-gate 
370