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

📄 yp_match.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#if	!defined(lint) && defined(SCCSIDS)static  char sccsid[] = "@(#)yp_match.c 1.1 92/07/30 Copyr 1990 Sun Micro";#endif#define	NULL 0#include <sys/time.h>#include <rpc/rpc.h>#include "yp_prot.h"#include "ypv1_prot.h"#include "ypclnt.h"extern struct timeval _ypserv_timeout;extern int _yp_dobind();extern unsigned int _ypsleeptime;extern malloc_t malloc();static int v2domatch(), v1domatch();struct	cache {	struct cache *next;	unsigned int birth;	char *domain;	char *map;	char *key;	int  keylen;	char *val;	int  vallen;};static struct cache *head;#define	CACHESZ 16#define	CACHETO 60*5	/*5 minutes*/static voiddetachnode(prev, n)	register struct cache *prev, *n;{	if (prev == 0) {		/* assertion: n is head */		head = n->next;	} else {		prev->next = n->next;	}	n->next = 0;}static voidfreenode(n)	register struct cache *n;{	if (n->val != 0)	    free(n->val);	if (n->key != 0)	    free(n->key);	if (n->map != 0)	    free(n->map);	if (n->domain != 0)	    free(n->domain);	bzero((char *) n, sizeof(*n));	free((char *) n);}static struct cache *makenode(domain, map, keylen, vallen)	char *domain, *map;	int keylen, vallen;{	register struct cache *n =	    (struct cache *) malloc(sizeof(struct cache));	if (n == 0)	    return (0);	bzero((char *) n, sizeof(*n));	for (;;) {		if ((n->domain = malloc(1 + strlen(domain))) == 0)		    break;		if ((n->map = malloc(1 + strlen(map))) == 0)		    break;		if ((n->key = malloc(keylen)) == 0)		    break;		if ((n->val = malloc(vallen)) == 0)		    break;		return (n);	}	freenode(n);	return (0);}/* * Requests the NIS server associated with a given domain to attempt to match * the passed key datum in the named map, and to return the associated value * datum. This part does parameter checking, and implements the "infinite" * (until success) sleep loop. */intyp_match (domain, map, key, keylen, val, vallen)	char *domain;	char *map;	char *key;	register int  keylen;	char **val;		/* returns value array */	int  *vallen;		/* returns bytes in val */{	int domlen;	int maplen;	int reason;	struct dom_binding *pdomb;	register struct cache *c, *prev;	int cnt, savesize;	struct timeval now;	struct timezone tz;	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) ||	    (key == NULL) || (keylen == 0) ) {		return (YPERR_BADARGS);	}	/* is it in our cache ? */	prev = 0;	for (prev=0, cnt=0, c=head; c != 0; prev=c, c=c->next, cnt++) {		if ((c->keylen == keylen) &&		    (bcmp(key, c->key, keylen) == 0) &&		    (strcmp(map, c->map) == 0) &&		    (strcmp(domain, c->domain) == 0)) {			/* cache hit */			(void) gettimeofday(&now, &tz);			if ((now.tv_sec - c->birth) > CACHETO) {				/* rats.  it it too old to use */				detachnode(prev, c);				freenode(c);				break;			} else {				/* NB: Copy two extra bytes; see below */				savesize = c->vallen + 2;				*val = malloc(savesize);				if (*val == 0) {					return (YPERR_RESRC);				}				bcopy(c->val, *val, savesize);				*vallen = c->vallen;/*reorganize the list to make this element the head if it is already not the head.  This check fixes bug 1023528*/				if (prev != 0){					prev->next = c->next;					c->next = head;					head = c;					}				return (0);			}		}		if (cnt >= CACHESZ) {			detachnode(prev, c);			freenode(c);			break;		}	}	for (;;) {		if (reason = _yp_dobind(domain, &pdomb) ) {			return (reason);		}		dofun = (pdomb->dom_vers == YPVERS) ? v2domatch : v1domatch;		reason = (*dofun)(domain, map, key, keylen, pdomb,		    _ypserv_timeout, val, vallen);		if (reason == YPERR_RPC) {			yp_unbind(domain);			(void) sleep(_ypsleeptime);		} else {			break;		}	}	/* add to our cache */	if (reason == 0) {		/*		 * NB: allocate and copy extract two bytes of the value;		 * these two bytes are mandatory CR and NULL bytes.		 */		savesize = *vallen + 2;		c = makenode(domain, map, keylen, savesize);		if (c != 0) {			(void) gettimeofday(&now, &tz);			c->next = head;			head = c;			c->birth = now.tv_sec;			(void) strcpy(c->domain, domain);			(void) strcpy(c->map, map);			bcopy(key, c->key, c->keylen = keylen);			bcopy(*val, c->val, savesize);			c->vallen = *vallen;		}	}	return (reason);}/* * This talks v2 protocol to ypserv */static intv2domatch (domain, map, key, keylen, pdomb, timeout, val, vallen)	char *domain;	char *map;	char *key;	int  keylen;	struct dom_binding *pdomb;	struct timeval timeout;	char **val;		/* return: value array */	int  *vallen;		/* return: bytes in val */{	struct ypreq_key req;	struct ypresp_val resp;	unsigned int retval = 0;	req.domain = domain;	req.map = map;	req.keydat.dptr = key;	req.keydat.dsize = keylen;	resp.valdat.dptr = NULL;	resp.valdat.dsize = 0;	/*	 * Do the match request.  If the rpc call failed, return with status	 * from this point.	 */	if(clnt_call(pdomb->dom_client,	    YPPROC_MATCH, xdr_ypreq_key, &req, xdr_ypresp_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 && ((*val = malloc((unsigned)	    resp.valdat.dsize + 2)) == NULL)) {		retval = YPERR_RESRC;	}	/* Copy the returned value byte string into the new memory */	if (!retval) {		*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_val, &resp);	return (retval);}/* * This talks v1 protocol to ypserv */static intv1domatch (domain, map, key, keylen, pdomb, timeout, val, vallen)	char *domain;	char *map;	char *key;	int  keylen;	struct dom_binding *pdomb;	struct timeval timeout;	char **val;		/* return: value array */	int  *vallen;		/* return: bytes in val */{	struct yprequest req;	struct ypresponse resp;	unsigned int retval = 0;	req.yp_reqtype = YPMATCH_REQTYPE;	req.ypmatch_req_domain = domain;	req.ypmatch_req_map = map;	req.ypmatch_req_keyptr = key;	req.ypmatch_req_keysize = keylen;	resp.ypmatch_resp_valptr = NULL;	resp.ypmatch_resp_valsize = 0;	/*	 * Do the match request.  If the rpc call failed, return with status	 * from this point.	 */	if(clnt_call(pdomb->dom_client,	    YPOLDPROC_MATCH, _xdr_yprequest, &req, _xdr_ypresponse, &resp,	    timeout) != RPC_SUCCESS) {		return (YPERR_RPC);	}	/* See if the request succeeded */	if (resp.ypmatch_resp_status != YP_TRUE) {		retval = ypprot_err((unsigned) resp.ypmatch_resp_status);	}	/* Get some memory which the user can get rid of as he likes */	if (!retval && ((*val = malloc((unsigned)	    resp.ypmatch_resp_valsize + 2)) == NULL)) {		retval = YPERR_RESRC;	}	/* Copy the returned value byte string into the new memory */	if (!retval) {		*vallen = resp.ypmatch_resp_valsize;		bcopy(resp.ypmatch_resp_valptr, *val,		    resp.ypmatch_resp_valsize);		(*val)[resp.ypmatch_resp_valsize] = '\n';		(*val)[resp.ypmatch_resp_valsize + 1] = '\0';	}	CLNT_FREERES(pdomb->dom_client, _xdr_ypresponse, &resp);	return (retval);}

⌨️ 快捷键说明

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