ypserv.c

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

C
444
字号
#ifndef lintstatic  char    *sccsid = "@(#)ypserv.c	4.3  (ULTRIX)        3/1/91";#endif lint/**************************************************************** *								* *  Licensed to Digital Equipment Corporation, Maynard, MA	* *		Copyright 1985 Sun Microsystems, Inc.		* *			All rights reserved.			* *								* ****************************************************************//* * This contains the mainline code for the yellowpages server.  Data * structures which are process-global are also in this module.   *//* 	terry	02/27/91	support new file descriptor handling */#include "ypsym.h"#include <sys/ioctl.h>#include <sys/file.h>static char create_failed[] = "ypserv:  Unable to create server for ";static char register_failed[] = "ypserv:  Unable to register service for ";char ypdbpath[] = __YP_PATH_PREFIX;char order_key[] = ORDER_KEY;char master_key[] = MASTER_KEY;struct timeval ypintertry = {		/* udp secs betw tries in peer comm */	YPINTERTRY_TIME,		/* Seconds */	0				/* uSecs */};struct timeval yptimeout = {		/* udp total timeout for peer comm */	YPTOTAL_TIME,			/* Seconds */	0				/* uSecs */};char myhostname[MAX_MASTER_NAME + 1];SVCXPRT *udphandle;SVCXPRT *tcphandle;bool silent = TRUE;char logfile[] = "/etc/yp/ypserv.log";void ypexit();void ypinit();void ypdispatch();void ypolddispatch();void ypget_command_line_args();void dezombie();void logprintf();/* * External refs to functions named only by the dispatchers. */extern void ypdomain();extern void ypmatch();extern void ypfirst();extern void ypnext();extern void ypxfr();extern void ypall();extern void ypmaster();extern void yporder();extern void ypoldmatch();extern void ypoldfirst();extern void ypoldnext();extern void ypoldpoll();extern void yppush();extern void yppull();extern void ypget();extern void ypmaplist();/* * This is the main line code for the yp server. */main(argc, argv)	int argc;	char **argv;{	int readfds;	struct timer_action *palarm_action;	/*	 * must be superuser to run 	 */	if (geteuid() != 0){		(void) fprintf(stderr, "ypserv:  must be super user\n");		(void) fflush(stderr);		exit(1);	} 	ypinit(argc, argv); 			/* Set up shop */	for (;;) {		readfds = svc_fds;		errno = 0;		switch ( (int) select(32, &readfds, (int *) NULL,		    (int *) NULL, (struct timeval *) NULL) ) {		case -1:  {					if (errno != EINTR) {			    logprintf(			   "ypserv:  bad fds bits in main loop select mask.\n");			}			break;		}		case 0:  {			logprintf(			    "ypserv:  invalid timeout in main loop select.\n");			break;		}		default:  {			svc_getreq(readfds);			break;		}				}	}}/* * Does startup processing for the yp server. */voidypinit(argc, argv)	int argc;	char **argv;{	int pid;	int t;	pmap_unset(YPPROG, YPVERS);	pmap_unset(YPPROG, YPOLDVERS);	ypget_command_line_args(argc, argv);	if (silent) {				pid = fork();				if (pid == -1) {			logprintf(			     "ypserv:  ypinit fork failure.\n");			ypexit();		}			if (pid != 0) {			exit(0);		}			if (access(logfile, W_OK)) {			(void) freopen("/dev/null", "w", stderr);		} else {			(void) freopen(logfile, "a", stderr);			(void) freopen(logfile, "a", stdout);		}		logprintf("ypserv: started \n");		for (t = 3; t < 20; t++) {			(void) close(t);		} 		t = open("/dev/tty", 2);	 		if (t >= 0) { 			(void) ioctl(t, (int) TIOCNOTTY, (char *) 0); 			(void) close(t); 		}	}	(void) gethostname(myhostname, 256);	if ((int) signal(SIGCHLD, dezombie) == -1) {		logprintf( "Can't catch process exit signal.\n");		ypexit();	}	if ((udphandle = svcudp_bufcreate(RPC_ANYSOCK, YPMSGSZ, YPMSGSZ))	    == (SVCXPRT *) NULL) {		logprintf( "%s%s.\n", create_failed, "udp");		ypexit();	}	if ((tcphandle = svctcp_create(RPC_ANYSOCK, YPMSGSZ, YPMSGSZ))	    == (SVCXPRT *) NULL) {		logprintf( "%s%s.\n", create_failed, "tcp");		ypexit();	}	if (!svc_register(udphandle, YPPROG, YPVERS, ypdispatch,	    IPPROTO_UDP) ) {		logprintf( "%s%s.\n", register_failed, "udp");		ypexit();	}	if (!svc_register(tcphandle, YPPROG, YPVERS, ypdispatch,	    IPPROTO_TCP) ) {		logprintf( "%s%s.\n", register_failed, "tcp");		ypexit();	}		if (!svc_register(udphandle, YPPROG, YPOLDVERS, ypolddispatch,	    IPPROTO_UDP) ) {		logprintf( "%s%s.\n", register_failed, "udp");		ypexit();	}	if (!svc_register(tcphandle, YPPROG, YPOLDVERS, ypolddispatch,	    IPPROTO_TCP) ) {		logprintf( "%s%s.\n", register_failed, "tcp");		ypexit();	}	logprintf("ypserv: initialized/registered \n");}/* * This picks up any command line args passed from the process invocation. */voidypget_command_line_args(argc, argv)	int argc;	char **argv;{	argv++;	while (--argc) {				if ((*argv)[0] == '-') {			switch ((*argv)[1]) {				case 'v': {					silent = FALSE;				}				default: {					;				}			}						}	}}/* * This dispatches to server action routines based on the input procedure * number.  ypdispatch is called from the RPC function svc_getreq. */voidypdispatch(rqstp, transp)	struct svc_req *rqstp;	SVCXPRT *transp;{	switch (rqstp->rq_proc) {	case YPPROC_NULL:		if (!svc_sendreply(transp, xdr_void, 0) ) {			logprintf(			    "ypserv:  Can't reply to rpc call.\n");		}		break;	case YPPROC_DOMAIN:		ypdomain(rqstp, transp, TRUE);		break;	case YPPROC_DOMAIN_NONACK:		ypdomain(rqstp, transp, FALSE);		break;	case YPPROC_MATCH:		ypmatch(rqstp, transp);		break;	case YPPROC_FIRST:		ypfirst(rqstp, transp);		break;	case YPPROC_NEXT:		ypnext(rqstp, transp);		break;	case YPPROC_XFR:		ypxfr(rqstp, transp);		break;	case YPPROC_CLEAR:		ypclr_current_map();				if (!svc_sendreply(transp, xdr_void, 0) ) {			logprintf(			    "ypserv:  Can't reply to rpc call.\n");		}		break;	case YPPROC_ALL:		ypall(rqstp, transp);		break;	case YPPROC_MASTER:		ypmaster(rqstp, transp);		break;	case YPPROC_ORDER:		yporder(rqstp, transp);		break;	case YPPROC_MAPLIST:		ypmaplist(rqstp, transp);		break;	default:		svcerr_noproc(transp);		break;	}	return;}/* * This is the dispatcher for the old yp protocol.  The case symbols are * defined in ypv1_prot.h, and are copied (with an added "OLD") from version * 1 of yp_prot.h. */voidypolddispatch(rqstp, transp)	struct svc_req *rqstp;	SVCXPRT *transp;{	switch (rqstp->rq_proc) {	case YPOLDPROC_NULL:		if (!svc_sendreply(transp, xdr_void, 0) ) {			logprintf(			    "ypserv:  Can't reply to rpc call.\n");		}		break;	case YPOLDPROC_DOMAIN:		ypdomain(rqstp, transp, TRUE);		break;	case YPOLDPROC_DOMAIN_NONACK:		ypdomain(rqstp, transp, FALSE);		break;	case YPOLDPROC_MATCH:		ypoldmatch(rqstp, transp);		break;	case YPOLDPROC_FIRST:		ypoldfirst(rqstp, transp);		break;	case YPOLDPROC_NEXT:		ypoldnext(rqstp, transp);		break;	case YPOLDPROC_POLL:		ypoldpoll(rqstp, transp);		break;	case YPOLDPROC_PUSH:		yppush(rqstp, transp);		break;	case YPOLDPROC_PULL:		yppull(rqstp, transp);		break;	case YPOLDPROC_GET:		ypget(rqstp, transp);		break;	default:		svcerr_noproc(transp);		break;	}	return;}/* * This flushes output to stderr, then aborts the server process to leave a * core dump. */static voidypexit(){	(void) fflush(stderr);	(void) abort();}/* * This reaps all exit statuses without looking at them to make sure zombies * don't accumulate.   */voiddezombie(){	int pid;	union wait wait_status;		while (TRUE) {		pid = wait3 (&wait_status, WNOHANG, NULL);		if (pid == 0) {			break;		} else if (pid == -1) {			break;		}	}}/* * This constructs a logging record. */voidlogprintf(arg1,arg2,arg3,arg4,arg5,arg6,arg7){	struct timeval t;	if (silent) {		(void) gettimeofday(&t, NULL);		fseek(stderr,0,2);		(void) fprintf(stderr, "%19.19s: ", ctime(&t.tv_sec));	}	(void) fprintf(stderr,arg1,arg2,arg3,arg4,arg5,arg6,arg7);	fflush(stderr);}

⌨️ 快捷键说明

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