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

📄 yp_bind.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
							} else {				rebind = TRUE;			}			if (rebind) {				cu_sock = (int *)pdomb->dom_client->cl_private;				*cu_sock = -1;				pdomb->dom_socket = -1;				yp_unbind(domain);  				pdomb = (struct dom_binding *) NULL;				break;			} else {				*binding = pdomb;				return (TRUE);			}		}	}	return (FALSE);}/* * This check whether the portmapper is up.  If the connect succeeds, the * portmapper is dead.  As a side effect, the pmapper sockaddr_in is * initialized. */static boolcheck_pmap_up(pmapper, err)	struct sockaddr_in *pmapper;	int *err;{	int sokt;	int status;	pmapper->sin_addr = my_addr;	pmapper->sin_family = AF_INET;	pmapper->sin_port = htons(PMAPPORT);	bzero(pmapper->sin_zero, 8);	sokt =  socket(AF_INET, SOCK_STREAM, 0); 		if (sokt == -1) {		*err = YPERR_RESRC;		return (FALSE);	}	if ((status = connect(sokt, (struct sockaddr *) pmapper,	    sizeof(struct sockaddr_in))) < 0) {		(void) close(sokt);		*err = YPERR_PMAP;		return (FALSE);	}		(void) close(sokt);	return (TRUE);}/* * This check whether ypbind is up.  If the bind fails, ypbind is dead. * There are two side effects.  The ypbind sockaddr_in is initialized. If * the function returns FALSE, the global binder_port will be set to 0.   */static boolcheck_binder_up(ypbinder, err)	struct sockaddr_in *ypbinder;	int *err;{	int sokt;	int status;	if (binder_port == 0) {		return (FALSE);	}		ypbinder->sin_addr = my_addr;	ypbinder->sin_family = AF_INET;	ypbinder->sin_port = htons(binder_port);	bzero(ypbinder->sin_zero, 8);	sokt =  socket(AF_INET, SOCK_DGRAM, 0); /* Throw-away socket */		if (sokt == -1) {		binder_port = 0;		*err = YPERR_RESRC;		return (FALSE);	}	errno = 0;	status = bind(sokt, (struct sockaddr *) ypbinder,	    sizeof(struct sockaddr_in));	(void) close(sokt);	            if (status == -1) {                if (errno == EADDRINUSE) {                        /*                         * since we cannot grab the port, ypbind must be                         * up and healthy.                         */                        return (TRUE);                }                if ((errno == EACCES) &&                    (binder_port < IPPORT_RESERVED) &&                    (geteuid() != 0)) {                        /*                         * The port is priviledged.  This must be "secure"                         * unix where have to use the yelow pages.                         */                        return (TRUE);                }        }	binder_port = 0;	*err = YPERR_YPBIND;	return (FALSE);}/* * This asks the portmapper for addressing info for ypbind speaking a passed * program version number.  If it gets that info, the port number is stashed * in binder_port, but binder_port will be set to 0 when talk2_pmap returns * anything except BS_OK.  If the RPC call to the portmapper failed, the * current process will be put to sleep for _ypsleeptime seconds before * this function returns. */static enum bind_statustalk2_pmap(pmapper, vers, err)	struct sockaddr_in *pmapper;	int vers;	int *err;{	int sokt;	CLIENT *client;	struct pmap portmap;	enum clnt_stat clnt_stat;	binder_port = 0;	portmap.pm_prog = YPBINDPROG;	portmap.pm_vers = vers;	portmap.pm_prot = IPPROTO_UDP;	portmap.pm_port = 0;		/* Don't care */	sokt = RPC_ANYSOCK;	if ((client = clntudp_bufcreate(pmapper, PMAPPROG, PMAPVERS,	    bind_intertry, &sokt, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE))  == NULL) {		*err = YPERR_RPC;		return (BS_BAGIT);	}	clnt_stat = (enum clnt_stat) clnt_call(client, PMAPPROC_GETPORT,	    xdr_pmap, &portmap, xdr_u_long, &binder_port, bind_timeout);	clnt_destroy(client);	(void) close(sokt);		if (clnt_stat  == RPC_SUCCESS) {		if (binder_port != 0) {			return (BS_OK);		} else {			*err = YPERR_YPBIND;			return (BS_BAGIT);		}	} else {		(void) sleep(_ypsleeptime);		*err = YPERR_RPC;		return (BS_RETRY);	}}/* * This talks to the local ypbind process, and asks for a binding for the * passed domain.  As a side effect, if a version mismatch is detected, the * ypbind program version number may be changed to the old version.  In the * success case, the ypbind response will be returned as it was loaded by * ypbind - that is, containing a valid binding.  If the RPC call to ypbind * failed, the current process will be put to sleep for _ypsleeptime seconds * before this function returns.   */static enum bind_statustalk2_binder(ypbinder, vers, tries, ppdomain, ypbind_resp, err)	struct sockaddr_in *ypbinder;	int *vers;	int tries;	char **ppdomain;	struct ypbind_resp *ypbind_resp;	int *err;{	int sokt;	CLIENT *client;	enum clnt_stat clnt_stat;	sokt = RPC_ANYSOCK;	if ((*vers == YPBINDVERS) && (tries > MAX_TRIES_FOR_NEW_YP) )		*vers = YPBINDOLDVERS;			if ((client = clntudp_bufcreate(ypbinder, YPBINDPROG, *vers,	    bind_intertry, &sokt, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE))  == NULL) {		*err = YPERR_RPC;		return (BS_BAGIT);	}	clnt_stat = (enum clnt_stat)clnt_call(client, YPBINDPROC_DOMAIN,	    xdr_ypdomain_wrap_string, ppdomain, xdr_ypbind_resp,	    ypbind_resp, bind_timeout);	clnt_destroy(client);	(void) close(sokt);	    	if (clnt_stat == RPC_SUCCESS) {					if (ypbind_resp->ypbind_status == YPBIND_SUCC_VAL) {			/* Binding successfully returned from ypbind */			return (BS_OK);		} else {			if ( ((*vers == YPBINDVERS) &&			    (tries < MAX_TRIES_FOR_NEW_YP)) ||			    (*vers == YPBINDOLDVERS) ) {				(void) sleep(_ypsleeptime);			}							*err = YPERR_DOMAIN;			return (BS_RETRY);		}				} else {		if (clnt_stat == RPC_PROGVERSMISMATCH) {			if (*vers == YPBINDOLDVERS) {				*err = YPERR_YPBIND;				return (BS_BAGIT);			} else {				*vers = YPBINDOLDVERS;			}		} else {			(void) sleep(_ypsleeptime);			binder_port = 0;		}				*err = YPERR_RPC;		return (BS_RETRY);	}}/* * This handles all the conversation with the portmapper to find the port * ypbind is listening on.  If binder_port is already non-zero, this returns * BS_OK immediately without changing anything. */static enum bind_statusget_binder_port(vers, err)	int vers;			/* !ypbind! program version number */	int *err;{	struct sockaddr_in pmapper;	if (binder_port) {		return (BS_OK);	}	if (!check_pmap_up(&pmapper, err) ) {		return (BS_BAGIT);	}		return (talk2_pmap(&pmapper, vers, err) );}/* * This allocates some memory for a domain binding, initialize it, and * returns a pointer to it.  Based on the program version we ended up * talking to ypbind with, fill out an opvector of appropriate protocol * modules.   */static struct dom_binding *load_dom_binding(ypbind_resp, vers, domain, err)	struct ypbind_resp *ypbind_resp;	int vers;	char *domain;	int *err;{	struct dom_binding *pdomb;	struct sockaddr_in dummy;	/* To get a port bound to socket */	struct sockaddr_in local_name;	int local_name_len = sizeof(struct sockaddr_in);	pdomb = (struct dom_binding *) NULL;	 	if ((pdomb = (struct dom_binding *) malloc(sizeof(struct dom_binding)))		== NULL) {		(void) fprintf(stderr, "load_dom_binding:  malloc failure.\n");		*err = YPERR_RESRC;		return (struct dom_binding *) (NULL);	}	pdomb->dom_server_addr.sin_addr =	    ypbind_resp->ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr;	pdomb->dom_server_addr.sin_family = AF_INET;	pdomb->dom_server_addr.sin_port =	    ypbind_resp->ypbind_respbody.ypbind_bindinfo.ypbind_binding_port;	bzero(pdomb->dom_server_addr.sin_zero, 8);	pdomb->dom_server_port =	    ypbind_resp->ypbind_respbody.ypbind_bindinfo.ypbind_binding_port;	pdomb->dom_socket = RPC_ANYSOCK;	pdomb->dom_vers = (vers == YPBINDOLDVERS) ? YPOLDVERS : YPVERS;		/*	 * Open up a udp path to the server, which will remain active globally.	 */	if ((pdomb->dom_client = clntudp_bufcreate(&(pdomb->dom_server_addr),	    YPPROG, ((vers == YPBINDVERS) ? YPVERS : YPOLDVERS) ,	    ypserv_intertry, &(pdomb->dom_socket), RPCSMALLMSGSIZE, YPMSGSZ))	    == NULL) {		free((char *) pdomb);		*err = YPERR_RPC;		return (struct dom_binding *) (NULL);	}	/*	 * Bind the socket to a bogus address so a port gets allocated for	 * the socket, but so that sendto will still work.	 *	 */        (void) fcntl(pdomb->dom_socket, F_SETFD, 1);        bzero((char *)&dummy, sizeof (dummy));        dummy.sin_family = AF_INET;		if (bind (pdomb->dom_socket, (struct sockaddr *) &dummy,	    sizeof(dummy) ) != 0) {		/*(void) close (pdomb->dom_socket);		free((char *) pdomb);		fprintf(stderr,"bind errno=%x\n",errno);		*err = YPERR_YPERR;		return (struct dom_binding *) (NULL); */	}	/*	 * Remember the bound port number	 */	if (getsockname(pdomb->dom_socket, (struct sockaddr *) &local_name,	    &local_name_len) == 0) {		pdomb->dom_local_port = local_name.sin_port;	} else {		(void) close (pdomb->dom_socket);		free((char *) pdomb);		*err = YPERR_YPERR;		return (struct dom_binding *) (NULL);	}	(void) strcpy(pdomb->dom_domain, domain);/* Remember the domain name */	pdomb->dom_pnext = bound_domains;	/* Link this to the list as */	bound_domains = pdomb;			/* ... the head entry */	return (pdomb);}/* * This checks to see if a ypserv which we know speaks v1 YP program number * also speaks v2 version.  This makes the assumption that the yp service at * the node is supplied by a single process, and that RPC will deliver a * message for a different program version number than that which the server * regestered.   */static voidtalk2_server(pdomb)	struct dom_binding *pdomb;{	int sokt;	CLIENT *client;	enum clnt_stat clnt_stat;	sokt = RPC_ANYSOCK;		if ((client = clntudp_bufcreate(&(pdomb->dom_server_addr),	    YPPROG, YPVERS, ypserv_intertry, &sokt, RPCSMALLMSGSIZE, YPMSGSZ))	    == NULL) {		return;	}	clnt_stat = (enum clnt_stat) clnt_call(client, YPBINDPROC_NULL,	    xdr_void, 0, xdr_void, 0, _ypserv_timeout);	    	if (clnt_stat == RPC_SUCCESS) {		clnt_destroy(pdomb->dom_client);		(void) close(pdomb->dom_socket);		pdomb->dom_client = client;		pdomb->dom_socket = sokt;		pdomb->dom_vers = YPVERS;	} else {		clnt_destroy(client);		(void) close(sokt);	}}

⌨️ 快捷键说明

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