ypserv_proc.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 970 行 · 第 1/2 页

C
970
字号
#ifndef lintstatic char *sccsid = "@(#)ypserv_proc.c	4.1	ULTRIX	7/2/90";#endif lint/**************************************************************** *								* *  Licensed to Digital Equipment Corporation, Maynard, MA	* *		Copyright 1985 Sun Microsystems, Inc.		* *			All rights reserved.			* *								* ****************************************************************//* * This contains yellow pages server code which supplies the set of * functions requested using rpc.   The top level functions in this * module are those which have symbols of the form YPPROC_xxxx defined * in yp_prot.h, and symbols of the form YPOLDPROC_xxxx  as  * defined in  ypsym.h. * The latter exist to provide compatibility to the old version of the * yp protocol/server, and may emulate the behaviour of the previous * software by invoking some other program. *  * This module also contains functions which are used by (and only by) * the top-level functions here. *   */#include "ypsym.h"extern char *environ;static char ypxfr_proc[] = YPXFR_PROC;static char yppush_proc[] = YPPUSH_PROC;struct yppriv_sym {	char *sym;	unsigned len;};static struct yppriv_sym filter_set[] = {	{ORDER_KEY, ORDER_KEY_LENGTH},	{MASTER_KEY, MASTER_KEY_LENGTH},	{INPUT_FILE, INPUT_FILE_LENGTH},	{NULL, 0}};static char err_fork[] = "ypserv:  %s fork failure.\n";#define FORK_ERR logprintf( err_fork, fun)static char err_execl[] = "ypserv:  %s execl failure.\n";#define EXEC_ERR logprintf( err_execl, fun)static char err_respond[] = "ypserv: %s can't respond to rpc request.\n";#define RESPOND_ERR logprintf( err_respond, fun)static char err_free[] = "ypserv: %s can't free args.\n";#define FREE_ERR logprintf( err_free, fun)void ypfilter();bool isypsym();bool xdrypserv_ypall();extern char *inet_ntoa();/* * This determines whether or not a passed domain is served by this server, * and returns a boolean.  Used by both old and new protocol versions. */voidypdomain(rqstp, transp, always_respond)	struct svc_req *rqstp;	SVCXPRT *transp;	bool always_respond;{	char domain_name[YPMAXDOMAIN + 1];	char *pdomain_name = domain_name;	bool isserved;	char *fun = "ypdomain";	if (!svc_getargs(transp, xdr_ypdomain_wrap_string, &pdomain_name) ) {		svcerr_decode(transp);		return;	}	isserved = (bool) ypcheck_domain(domain_name);	if (isserved || always_respond) {				if (!svc_sendreply(transp, xdr_bool, &isserved) ) {			RESPOND_ERR;		}		if (!isserved)			logprintf("Domain %s not supported\n",				domain_name);	} else {		/*		 * This case is the one in which the domain is not		 * supported, and in which we are not to respond in the		 * unsupported case.  We are going to make an error happen		 * to allow the portmapper to end his wait without the		 * normal udp timeout period.  The assumption here is that		 * the only process in the world which is using the function		 * in its no-answer-if-nack form is the portmapper, which is		 * doing the krock for pseudo-broadcast.  If some poor fool		 * calls this function as a single-cast message, the nack		 * case will look like an incomprehensible error.  Sigh...		 * (The traditional Unix disclaimer)		 */			svcerr_decode(transp);		logprintf("Domain %s not supported (broadcast)\n",				domain_name);	}	if (!svc_freeargs(transp, xdr_ypdomain_wrap_string, &pdomain_name) ) {		FREE_ERR ;	}}/* * The following procedures are used only in the new protocol. *//* * This implements the yp "match" function. */voidypmatch(rqstp, transp) 	struct svc_req *rqstp;	SVCXPRT *transp;{	struct ypreq_key req;	struct ypresp_val resp;	char *fun = "ypmatch";		req.domain = req.map = NULL;	req.keydat.dptr = NULL;	resp.valdat.dptr = NULL;	resp.valdat.dsize = 0;	if (!svc_getargs(transp, xdr_ypreq_key, &req) ) {		svcerr_decode(transp);		return;	}	if (ypset_current_map(req.map, req.domain, &resp.status) ) {		if (isypsym(&req.keydat) ) {			resp.status = YP_NOKEY;		} else {			resp.valdat = fetch(req.keydat);			if (resp.valdat.dptr != NULL) {				resp.status = YP_TRUE;			} else {				resp.status = YP_NOKEY;			}		}	}	if (!svc_sendreply(transp, xdr_ypresp_val, &resp) ) {		RESPOND_ERR;	}	if (!svc_freeargs(transp, xdr_ypreq_key, &req) ) {		FREE_ERR;	}}/* * This implements the yp "get first" function. */voidypfirst(rqstp, transp)	struct svc_req *rqstp;	SVCXPRT *transp;{	struct ypreq_nokey req;	struct ypresp_key_val resp;	char *fun = "ypfirst";		req.domain = req.map = NULL;	resp.keydat.dptr = resp.valdat.dptr = NULL;	resp.keydat.dsize = resp.valdat.dsize = 0;	if (!svc_getargs(transp, xdr_ypreq_nokey, &req) ) {		svcerr_decode(transp);		return;	}	if (ypset_current_map(req.map, req.domain, &resp.status) ) {		ypfilter(NULL, &resp.keydat, &resp.valdat, &resp.status);	}	if (!svc_sendreply(transp, xdr_ypresp_key_val, &resp) ) {		RESPOND_ERR;	}	if (!svc_freeargs(transp, xdr_ypreq_nokey, &req) ) {		FREE_ERR;	}}/* * This implements the yp "get next" function. */voidypnext(rqstp, transp)	struct svc_req *rqstp;	SVCXPRT *transp;{	struct ypreq_key req;	struct ypresp_key_val resp;	char *fun = "ypnext";		req.domain = req.map = req.keydat.dptr = NULL;	req.keydat.dsize = 0;	resp.keydat.dptr = resp.valdat.dptr = NULL;	resp.keydat.dsize = resp.valdat.dsize = 0;	if (!svc_getargs(transp, xdr_ypreq_key, &req) ) {		svcerr_decode(transp);		return;	}	if (ypset_current_map(req.map, req.domain, &resp.status) ) {		ypfilter(&req.keydat, &resp.keydat, &resp.valdat, &resp.status);	}		if (!svc_sendreply(transp, xdr_ypresp_key_val, &resp) ) {		RESPOND_ERR;	}	if (!svc_freeargs(transp, xdr_ypreq_key, &req) ) {		FREE_ERR;	}}/* * This implements the  "transfer map" function.  It takes the domain and * map names and the callback information provided by the requester (yppush * on some node), and execs a ypxfr process to do the actual transfer.   */voidypxfr(rqstp, transp)	struct svc_req *rqstp;	SVCXPRT *transp;{	struct ypreq_xfr req;	char transid[10];	char proto[15];	char port[10];	struct sockaddr_in *caller;	char *ipaddr;	int pid;	char *fun = "ypxfr";	req.ypxfr_domain = req.ypxfr_map = req.ypxfr_owner = NULL;	req.ypxfr_ordernum = 0;			if (!svc_getargs(transp, xdr_ypreq_xfr, &req) ) {		svcerr_decode(transp);		return;	}	(void) sprintf(transid, "%d", req.transid);	(void) sprintf(proto, "%d", req.proto);	(void) sprintf(port, "%d", req.port);	caller = svc_getcaller(transp);	ipaddr = inet_ntoa(caller->sin_addr);	pid = vfork();			if (pid == -1) {		FORK_ERR;	} else if (pid == 0) {		if (execl(ypxfr_proc, "ypxfr", "-d", req.ypxfr_domain, 		    "-C", transid, proto, ipaddr, port, req.ypxfr_map, NULL)) {			EXEC_ERR;		}		_exit(1);	}	if (!svc_sendreply(transp, xdr_void, 0) ) {		RESPOND_ERR;	}		if (!svc_freeargs(transp, xdr_ypreq_xfr, &req) ) {		FREE_ERR;	}}/* * This implements the "get all" function. */voidypall(rqstp, transp)	struct svc_req *rqstp;	SVCXPRT *transp;{	struct ypreq_nokey req;	int pid;	char *fun = "ypall";	req.domain = req.map = NULL;	if (!svc_getargs(transp, xdr_ypreq_nokey, &req) ) {		svcerr_decode(transp);		return;	}	pid = fork();		if (pid) {				if (pid == -1) {			FORK_ERR;		}		if (!svc_freeargs(transp, xdr_ypreq_nokey, &req) ) {			FREE_ERR;		}		return;	}		/*	 * This is the child process.  The work gets done by xdrypserv_ypall	 * we must clear the "current map" first so that we do not	 * share a seek pointer with the parent server.	 */		ypclr_current_map();	if (!svc_sendreply(transp, xdrypserv_ypall, &req) ) {		RESPOND_ERR;	}	if (!svc_freeargs(transp, xdr_ypreq_nokey, &req) ) {		FREE_ERR;	}		exit(0);}/* * This implements the "get master name" function. */voidypmaster(rqstp, transp)	struct svc_req *rqstp;	SVCXPRT *transp;{	struct ypreq_nokey req;	struct ypresp_master resp;	char *nullstring = "";	char *fun = "ypmaster";		req.domain = req.map = NULL;	resp.master = nullstring;	resp.status  = YP_TRUE;	if (!svc_getargs(transp, xdr_ypreq_nokey, &req) ) {		svcerr_decode(transp);		return;	}	if (ypset_current_map(req.map, req.domain, &resp.status)) {				if (!ypget_map_master(req.map, req.domain, &resp.master) ) {			resp.status = YP_BADDB;		}	}		if (!svc_sendreply(transp, xdr_ypresp_master, &resp) ) {		RESPOND_ERR;	}	if (!svc_freeargs(transp, xdr_ypreq_nokey, &req) ) {		FREE_ERR;	}}/* * This implements the "get order number" function. */voidyporder(rqstp, transp)	struct svc_req *rqstp;	SVCXPRT *transp;{	struct ypreq_nokey req;	struct ypresp_order resp;	char *fun = "yporder";		req.domain = req.map = NULL;	resp.status  = YP_TRUE;	resp.ordernum  = 0;	if (!svc_getargs(transp, xdr_ypreq_nokey, &req) ) {		svcerr_decode(transp);		return;	}	resp.ordernum = 0;	if (ypset_current_map(req.map, req.domain, &resp.status)) {		if (!ypget_map_order(req.map, req.domain, &resp.ordernum) ) {			resp.status = YP_BADDB;		}	}	if (!svc_sendreply(transp, xdr_ypresp_order, &resp) ) {		RESPOND_ERR;	}	if (!svc_freeargs(transp, xdr_ypreq_nokey, &req) ) {		FREE_ERR;	}}voidypmaplist(rqstp, transp)	struct svc_req *rqstp;	SVCXPRT *transp;{	char domain_name[YPMAXDOMAIN + 1];	char *pdomain_name = domain_name;	char *fun = "ypmaplist";	struct ypresp_maplist maplist;	struct ypmaplist *tmp;	maplist.list = (struct ypmaplist *) NULL;	if (!svc_getargs(transp, xdr_ypdomain_wrap_string, &pdomain_name) ) {		svcerr_decode(transp);		return;	}	maplist.status = yplist_maps(domain_name, &maplist.list);		if (!svc_sendreply(transp, xdr_ypresp_maplist, &maplist) ) {		RESPOND_ERR;	}	while (maplist.list) {		tmp = maplist.list->ypml_next;		(void) free(maplist.list);		maplist.list = tmp;	}}/* * The following procedures are used only to support the old protocol. *//* * This implements the yp "match" function. */voidypoldmatch(rqstp, transp) 	struct svc_req *rqstp;	SVCXPRT *transp;{	char mapname[YPDBPATH_LENGTH + YPMAXDOMAIN + YPMAXMAP + 3];	bool dbmop_ok = TRUE;	struct yprequest req;	struct ypresponse resp;	char *fun = "ypoldmatch";		req.ypmatch_req_domain = req.ypmatch_req_map = NULL;	req.ypmatch_req_keyptr = NULL;	resp.ypmatch_resp_valptr = NULL;	resp.ypmatch_resp_valsize = 0;	if (!svc_getargs(transp, _xdr_yprequest, &req) ) {		svcerr_decode(transp);		return;	}	if (req.yp_reqtype != YPMATCH_REQTYPE) {		resp.ypmatch_resp_status = YP_BADARGS;		dbmop_ok = FALSE;	};	if (dbmop_ok && ypset_current_map(req.ypmatch_req_map,	    req.ypmatch_req_domain, &resp.ypmatch_resp_status) ) {

⌨️ 快捷键说明

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