⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yp_enum.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic char *sccsid = "@(#)yp_enum.c	4.1	ULTRIX	7/3/90";#endif lint/**************************************************************** *								* *  Licensed to Digital Equipment Corporation, Maynard, MA	* *		Copyright 1985 Sun Microsystems, Inc.		* *			All rights reserved.			* *								* ****************************************************************//* * Modification history: * *	Fred L. Templin (templin@decvax) Sept. 15, 1987 *   Removed change of Sept. 5, 1986 which caused unacceptable performance *   degradation. Side effect of this change leaves an open socket descriptor *   in the calling process's descriptor table. This can break binaries which *   make assumptions about the ordering of their descriptors. * *	Fred L. Templin (temlin@decvax) Sept. 5, 1986 *   Added a call to "yp_unbind" in the functions "yp_first" and "yp_next *   to release the domain binding created by "_yp_dobind". This may hamper *   performace of a yp_next loop which enumerates a big map, but it should *   never be left to the caller to close the domain binding! * *	Fred L. Templin (templin@decvax) Sept. 17, 1986 *   Added parameter checking in yp_next to ensure that "inkey" and "inkeylen" *   are non-null. */#define NULL 0#include <sys/time.h>#include <rpc/rpc.h>#include <rpcsvc/yp_prot.h>#include <rpcsvc/ypv1_prot.h>#include <rpcsvc/ypclnt.h>static char ypsymbol_prefix[] = "YP_";static int ypsymbol_prefix_length = 3;static int v2dofirst(), v1dofirst(), v2donext(), v1donext();extern struct timeval _ypserv_timeout;extern unsigned int _ypsleeptime;extern int _yp_dobind();extern char *malloc();/* * This requests the yp server associated with a given domain to return the * first key/value pair from the map data base.  The returned key should be * used as an input to the call to ypclnt_next.  This part does the parameter * checking, and the do-until-success loop. */intyp_first (domain, map, key, keylen, val, vallen)	char *domain;	char *map;	char **key;		/* return: key array */	int  *keylen;		/* return: bytes in key */	char **val;		/* return: value array */	int  *vallen;		/* return: bytes in val */{	int domlen;	int maplen;	struct dom_binding *pdomb;	int reason;	int (*dofun)();	if ( (map == NULL) || (domain == NULL) ) {		return (YPERR_BADARGS);	}		domlen = strlen(domain);	maplen = strlen(map);		if ( (domlen == 0) || (domlen > YPMAXDOMAIN) ||	    (maplen == 0) || (maplen > YPMAXMAP) ) {		return (YPERR_BADARGS);	}	for (;;) {				if (reason = _yp_dobind(domain, &pdomb) ) {			return (reason);		}		dofun = (pdomb->dom_vers == YPVERS) ? v2dofirst : v1dofirst;		reason = (*dofun)(domain, map, pdomb, _ypserv_timeout,		    key, keylen, val, vallen);		if (reason == YPERR_RPC) {			yp_unbind(domain);			(void) sleep(_ypsleeptime);		} else {			break;		}	}	return (reason);}/* * This part of the "get first" interface talks to ypserv. */static intv2dofirst (domain, map, pdomb, timeout, key, keylen, val, vallen)	char *domain;	char *map;	struct dom_binding *pdomb;	struct timeval timeout;	char **key;	int  *keylen;	char **val;	int  *vallen;{	struct ypreq_nokey req;	struct ypresp_key_val resp;	unsigned int retval = 0;	req.domain = domain;	req.map = map;	resp.keydat.dptr = resp.valdat.dptr = NULL;	resp.keydat.dsize = resp.valdat.dsize = 0;	/*	 * Do the get first request.  If the rpc call failed, return with status	 * from this point.	 */		if(clnt_call(pdomb->dom_client, YPPROC_FIRST, xdr_ypreq_nokey,	    &req, xdr_ypresp_key_val, &resp, timeout) != RPC_SUCCESS) {		return (YPERR_RPC);	}	/* See if the request succeeded */		if (resp.status != YP_TRUE) {		retval = ypprot_err((unsigned) resp.status);	}	/* Get some memory which the user can get rid of as he likes */	if (!retval) {		if ((*key =		    (char *) malloc((unsigned)		        resp.keydat.dsize + 2)) != NULL) {			if ((*val = (char *) malloc(			    (unsigned) resp.valdat.dsize + 2) ) == NULL) {				free((char *) *key);				retval = YPERR_RESRC;			}				} else {			retval = YPERR_RESRC;		}	}	/* Copy the returned key and value byte strings into the new memory */	if (!retval) {		*keylen = resp.keydat.dsize;		bcopy(resp.keydat.dptr, *key, resp.keydat.dsize);		(*key)[resp.keydat.dsize] = '\n';		(*key)[resp.keydat.dsize + 1] = '\0';				*vallen = resp.valdat.dsize;		bcopy(resp.valdat.dptr, *val, resp.valdat.dsize);		(*val)[resp.valdat.dsize] = '\n';		(*val)[resp.valdat.dsize + 1] = '\0';	}		CLNT_FREERES(pdomb->dom_client, xdr_ypresp_key_val, &resp); 	return (retval);}static intv1dofirst (domain, map, pdomb, timeout, key, keylen, val, vallen)	char *domain;	char *map;	struct dom_binding *pdomb;	struct timeval timeout;	char **key;	int  *keylen;	char **val;	int  *vallen;{	int result;		result = v1prot_dofirst (domain, map, pdomb, timeout,	    key, keylen, val, vallen);	if (result) {		return(result);	} else {		return(v1filter (domain, map, pdomb, timeout,		    key, keylen, val, vallen));	}}intv1prot_dofirst (domain, map, pdomb, timeout, key, keylen, val, vallen)	char *domain;	char *map;	struct dom_binding *pdomb;	struct timeval timeout;	char **key;	int  *keylen;	char **val;	int  *vallen;{	struct yprequest req;	struct ypresponse resp;	unsigned int retval = 0;	req.yp_reqtype = YPFIRST_REQTYPE;	req.ypfirst_req_domain = domain;	req.ypfirst_req_map = map;		resp.ypfirst_resp_keyptr = NULL;	resp.ypfirst_resp_keysize = 0;	resp.ypfirst_resp_valptr = NULL;	resp.ypfirst_resp_valsize = 0;	/*	 * Do the get first request.  If the rpc call failed, return with status	 * from this point.	 */		if(clnt_call(pdomb->dom_client, YPOLDPROC_FIRST, _xdr_yprequest,	    &req, _xdr_ypresponse, &resp, timeout) != RPC_SUCCESS) {		return (YPERR_RPC);	}	/* See if the request succeeded */		if (resp.ypfirst_resp_status != YP_TRUE) {		retval = ypprot_err((unsigned) resp.ypfirst_resp_status);	}	/* Get some memory which the user can get rid of as he likes */	if (!retval) {		if ((*key =		    (char *) malloc((unsigned)		        resp.ypfirst_resp_keysize + 2)) != NULL) {			if ((*val = (char *) malloc((unsigned)			    resp.ypfirst_resp_valsize + 2) ) == NULL) {				free((char *) *key);				retval = YPERR_RESRC;			}				} else {			retval = YPERR_RESRC;		}	}	/* Copy the returned key and value byte strings into the new memory */	if (!retval) {		*keylen = resp.ypfirst_resp_keysize;		bcopy(resp.ypfirst_resp_keyptr,		    *key, resp.ypfirst_resp_keysize);		(*key)[resp.ypfirst_resp_keysize] = '\n';		(*key)[resp.ypfirst_resp_keysize + 1] = '\0';				*vallen = resp.ypfirst_resp_valsize;		bcopy(resp.ypfirst_resp_valptr, *val,		    resp.ypfirst_resp_valsize);		(*val)[resp.ypfirst_resp_valsize] = '\n';		(*val)[resp.ypfirst_resp_valsize + 1] = '\0';	}		CLNT_FREERES(pdomb->dom_client, _xdr_ypresponse, &resp); 	return (retval);}/* * This requests the yp server associated with a given domain to return the * "next" key/value pair from the map data base.  The input key should be * one returned by ypclnt_first or a previous call to ypclnt_next.  The * returned key should be used as an input to the next call to ypclnt_next. * This part does the parameter checking, and the do-until-success loop. */intyp_next (domain, map, inkey, inkeylen, outkey, outkeylen, val, vallen)	char *domain;	char *map;	char *inkey;	int  inkeylen;	char **outkey;		/* return: key array associated with val */	int  *outkeylen;	/* return: bytes in key */	char **val;		/* return: value array associated with outkey */	int  *vallen;		/* return: bytes in val */{	int domlen;	int maplen;	struct dom_binding *pdomb;	int reason;	int (*dofun)();	if ( (map == NULL) || (domain == NULL) ) {		return(YPERR_BADARGS);	}		domlen = strlen(domain);	maplen = strlen(map);		if ( (domlen == 0) || (domlen > YPMAXDOMAIN) ||	    (maplen == 0) || (maplen > YPMAXMAP) ||	    (inkey == NULL) || (inkeylen == 0) ) {		return(YPERR_BADARGS);	}	for (;;) {		if (reason = _yp_dobind(domain, &pdomb) ) {			return(reason);		}		dofun = (pdomb->dom_vers == YPVERS) ? v2donext : v1donext;		reason = (*dofun)(domain, map, inkey, inkeylen, pdomb,		    _ypserv_timeout, outkey, outkeylen, val, vallen);		if (reason == YPERR_RPC) {			yp_unbind(domain);			(void) sleep(_ypsleeptime);		} else {			break;		}	}	return(reason);}/* * This part of the "get next" interface talks to ypserv. */static intv2donext (domain, map, inkey, inkeylen, pdomb, timeout, outkey, outkeylen,    val, vallen)	char *domain;	char *map;	char *inkey;	int  inkeylen;	struct dom_binding *pdomb;	struct timeval timeout;	char **outkey;		/* return: key array associated with val */	int  *outkeylen;	/* return: bytes in key */	char **val;		/* return: value array associated with outkey */	int  *vallen;		/* return: bytes in val */{	struct ypreq_key req;	struct ypresp_key_val resp;	unsigned int retval = 0;	req.domain = domain;	req.map = map;	req.keydat.dptr = inkey;	req.keydat.dsize = inkeylen;		resp.keydat.dptr = resp.valdat.dptr = NULL;	resp.keydat.dsize = resp.valdat.dsize = 0;	/*	 * Do the get next request.  If the rpc call failed, return with status	 * from this point.	 */		if(clnt_call(pdomb->dom_client,	    YPPROC_NEXT, xdr_ypreq_key, &req, xdr_ypresp_key_val, &resp,	    timeout) != RPC_SUCCESS) {		return(YPERR_RPC);	}	/* See if the request succeeded */		if (resp.status != YP_TRUE) {		retval = ypprot_err((unsigned) resp.status);	}	/* Get some memory which the user can get rid of as he likes */	if (!retval) {		if ( (*outkey = (char *) malloc((unsigned)		    resp.keydat.dsize + 2) ) != NULL) {			if ( (*val = (char *) malloc((unsigned)			    resp.valdat.dsize + 2) ) == NULL) {				free((char *) *outkey);				retval = YPERR_RESRC;			}				} else {			retval = YPERR_RESRC;		}	}	/* Copy the returned key and value byte strings into the new memory */	if (!retval) {		*outkeylen = resp.keydat.dsize;		bcopy(resp.keydat.dptr, *outkey,		    resp.keydat.dsize);		(*outkey)[resp.keydat.dsize] = '\n';		(*outkey)[resp.keydat.dsize + 1] = '\0';				*vallen = resp.valdat.dsize;		bcopy(resp.valdat.dptr, *val, resp.valdat.dsize);		(*val)[resp.valdat.dsize] = '\n';		(*val)[resp.valdat.dsize + 1] = '\0';	}		CLNT_FREERES(pdomb->dom_client, xdr_ypresp_key_val, &resp);	return(retval);}static intv1donext (domain, map, inkey, inkeylen, pdomb, timeout,    outkey, outkeylen, val, vallen)	char *domain;	char *map;	char *inkey;	int  inkeylen;	struct dom_binding *pdomb;	struct timeval timeout;	char **outkey;		/* return: key array associated with val */	int  *outkeylen;	/* return: bytes in key */	char **val;		/* return: value array associated with outkey */	int  *vallen;		/* return: bytes in val */{	int result;		result = v1prot_donext (domain, map, inkey, inkeylen, pdomb, timeout,	    outkey, outkeylen, val, vallen);	if (result) {		return(result);	} else {		return(v1filter (domain, map, pdomb, timeout,		    outkey, outkeylen, val, vallen));	}}intv1prot_donext (domain, map, inkey, inkeylen, pdomb, timeout,    outkey, outkeylen, val, vallen)	char *domain;	char *map;	char *inkey;	int  inkeylen;	struct dom_binding *pdomb;	struct timeval timeout;	char **outkey;		/* return: key array associated with val */	int  *outkeylen;	/* return: bytes in key */	char **val;		/* return: value array associated with outkey */	int  *vallen;		/* return: bytes in val */{	struct yprequest req;	struct ypresponse resp;	unsigned int retval = 0;	req.yp_reqtype = YPNEXT_REQTYPE;	req.ypnext_req_domain = domain;	req.ypnext_req_map = map;	req.ypnext_req_keyptr = inkey;	req.ypnext_req_keysize = inkeylen;		resp.ypnext_resp_keyptr = NULL;	resp.ypnext_resp_keysize = 0;	resp.ypnext_resp_valptr = NULL;	resp.ypnext_resp_valsize = 0;		/*	 * Do the get next request.  If the rpc call failed, return with status	 * from this point.	 */		if(clnt_call(pdomb->dom_client, YPOLDPROC_NEXT, _xdr_yprequest,	    &req, _xdr_ypresponse, &resp, timeout) != RPC_SUCCESS) {		return(YPERR_RPC);	}	if (resp.ypnext_resp_status != YP_TRUE) {		retval = ypprot_err((unsigned) resp.ypnext_resp_status);	}	/* Get some memory which the user can get rid of as he likes */	if (!retval) {		if ( (*outkey = (char *) malloc((unsigned)		    resp.ypnext_resp_keysize + 2) ) != NULL) {			if ( (*val = (char *) malloc((unsigned)			    resp.ypnext_resp_valsize + 2) ) == NULL) {				free((char *) *outkey);				retval = YPERR_RESRC;			}				} else {			retval = YPERR_RESRC;		}	}	/* Copy the returned key and value byte strings into the new memory */	if (!retval) {		*outkeylen = resp.ypnext_resp_keysize;		bcopy(resp.ypnext_resp_keyptr, *outkey,		    resp.ypnext_resp_keysize);		(*outkey)[resp.ypnext_resp_keysize] = '\n';		(*outkey)[resp.ypnext_resp_keysize + 1] = '\0';				*vallen = resp.ypnext_resp_valsize;		bcopy(resp.ypnext_resp_valptr, *val, resp.ypnext_resp_valsize);		(*val)[resp.ypnext_resp_valsize] = '\n';		(*val)[resp.ypnext_resp_valsize + 1] = '\0';	}		CLNT_FREERES(pdomb->dom_client, _xdr_ypresponse, &resp);	return(retval);}/* * This supplies client side yp-private key filtration.  It is needed in * speaking with v.1 protocol-speaking servers. * * This continues to get "next" key-value pairs from the map while the * key-value pairs which come back have keys which are yp private symbols. */static intv1filter (domain, map, pdomb, timeout, key, keylen, val, vallen)	char *domain;	char *map;	struct dom_binding *pdomb;	struct timeval timeout;	char **key;		/* return: key array */	int  *keylen;		/* return: bytes in key */	char **val;		/* return: value array */	int  *vallen;		/* return: bytes in val */{	char *inkey;	int inkeylen;	int result = 0;	/*	 * Keep trying to get the next key-value pair as long as we	 * (1) continue to succeed, and	 * (2) the key we get back is a yp reserved symbol.	 */ 	inkey = NULL;	inkeylen = 0; 	while ( (!result) &&	    (!bcmp(*key, ypsymbol_prefix, ypsymbol_prefix_length) ) ) {		inkey = *key;		inkeylen = *keylen;		*key = NULL;		*keylen = 0;		free(*val);		*val = NULL;		*vallen = 0;		result = v1prot_donext (domain, map, inkey, inkeylen,		    pdomb, timeout, key, keylen, val, vallen);		free(inkey);		inkeylen = 0;	}	return(result);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -