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

📄 nserve.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		/*		 * if response was authoritative, break and return it.		 */		if (hp->h_flags & AUTHORITY) {			ret = hp->h_rcode;			nsrclose(npd);			break;		}		/*		 * Otherwise check for indirection.		 */		if (hp->h_rcode == R_NOERR && hp->h_nscnt != 0 && hp->h_arcnt != 0)			chg += mkalist(addrlist,nreq,NULL);		freerp(nreq);		free(nblock);		hp = NULL;		nsrclose(npd);	}	/*	 * Done. if hp is NULL, no response was found, otherwise	 *       return nblock to sender.	 */	if (hp == NULL) {		LOG2(L_ALL,"(%5d) remsend: return R_NSFAIL\n",Logstamp);		/* if chg was set, we got an indirection, but no answer */		/* if oreq is set, we are going to the primary only, so */		/* no indirection is expected.				*/		if (sndback(pd,(chg || oreq)?R_SEND:R_RCV) == RFS_FAILURE)			nsrclose(pd);		ret = R_NSFAIL;	/* this sets up backout if necessary	*/	}	else {		if (nswrite(pd,nblock,nsize) == -1) {			LOG2(L_ALL,"(%5d) remsend: nswrite of resp failed\n",			   Logstamp);			nsrclose(pd);		}		if (oreq && oreq->rq_head && 			oreq->rq_head->h_opcode == NS_INIT) {			exit(setmaster(nreq)); /* NS_INIT does not signal parent */		}	}	kill(getppid(),SIGUSR2);	/* notify parent	*/	exit(ret);}/* * This function is a sanity timer for the child process. * if the child takes longer than CHILDTIME to complete, it will be * interrupted, and the operation will fail.  CHILDTIME should * be set to several minutes to guarantee that it only goes * off when things are clearly hung (i.e., > 200).  In particular, * it should be at least double R_TIMEOUT, which is the recovery * timeout. */static intsane_cld(){	LOG3(L_OVER,"(%5d) sane_cld: Child %d timed out\n",Logstamp,getpid());	kill(getppid(),SIGUSR2);	exit(R_NSFAIL);}intsndback(pd,rcode)int	pd;int	rcode;{	struct	request	rq;	struct	header	hd;	char	*block=NULL;	int	size;	LOG4(L_TRANS,"(%5d) sndback: pd=%d, rcode=%d\n",Logstamp,pd,rcode);	rq.rq_head = &hd;	hd.h_version = NSVERSION;	hd.h_flags = RESPONSE | NOT_AUTHORITY;	hd.h_opcode = NS_SNDBACK;	hd.h_rcode = rcode;	hd.h_dname = Dname;	hd.h_qdcnt = hd.h_ancnt = hd.h_nscnt = hd.h_arcnt = 0;	if ((block = reqtob(&rq,block,&size)) == NULL) {		LOG1(L_TRANS,"(%5d) sndback: block is NULL\n");		return(RFS_FAILURE);	}	if (nswrite(pd,block,size) == -1) {		LOG2(L_TRANS,"(%5d) sndback: nswrite failed\n",Logstamp);		free(block);		return(RFS_FAILURE);	}	free(block);	return(RFS_SUCCESS);}/* * This function makes a temporary netmaster file * from an address, and reads it in using readfile. */static intputprime(addr)struct address	*addr;{	char	*tmpnam();	char	*tmpfile = tmpnam(NULL);	char	*p_name = PRIMENAME;	char	addbuf[BUFSIZ];	FILE	*fopen();	FILE	*fd;	int	ret;	LOG3(L_TRANS,"(%5d) putprime: addr=%x\n",Logstamp,addr);	if (!addr || aatos(addbuf,addr,HEX) == NULL) {		LOG2(L_TRANS,"(%5d) putprime: Can't translate address\n",Logstamp);		return(RFS_FAILURE);	}	LOG3(L_TRANS | L_OVER,"(%5d) putprime: set primary address to %s\n",		Logstamp,addbuf);	if (eqaddr(addr,getmyaddr()))		p_name = Dname;	if ((fd = fopen(tmpfile,"w")) == NULL) {		perror("RFS name server: putprime temporary file");		return(RFS_FAILURE);	}	fprintf(fd,"%s p %s\n%s a %s\n",		dompart(Dname),p_name,p_name,addbuf);	fclose(fd);	ret = readdb(tmpfile);	unlink(tmpfile);	if (ret <= 0)		PLOG1("RFS name server: RFS_FAILURE reading primary address\n");	return((ret <= 0)?RFS_FAILURE:RFS_SUCCESS);}intfreerp(req)struct request	*req;{	long	i;	struct header	*hp;	hp = req->rq_head;	/* remove resource records	*/	for (i=0; i < hp->h_ancnt; i++)		freerec(req->rq_an[i]);	for (i=0; i < hp->h_nscnt; i++)		freerec(req->rq_ns[i]);	for (i=0; i < hp->h_arcnt; i++)		freerec(req->rq_ar[i]);	if (hp->h_ancnt) free(req->rq_an);	if (hp->h_nscnt) free(req->rq_ns);	if (hp->h_arcnt) free(req->rq_ar);	/* now do the query section	*/	for (i=0; i < hp->h_qdcnt; i++) {		free(req->rq_qd[i]->q_name);		free(req->rq_qd[i]);	}	if (hp->h_qdcnt) free(req->rq_qd);	if (hp->h_dname)		free(hp->h_dname);	free(hp);	free(req);	return;}static intsigterm(){	LOG2(L_ALL,"(%5d): sigterm called\n",Logstamp);	clrnslock();	Done = TRUE;}/* wait for child	*/static intwaitcld(){	register int	i;	int	stat_loc;	int	child;	struct request	*req;	int	alrm_tim;	static int	alrm_fn();	sigset(SIGUSR2, SIG_IGN);	alrm_tim = alarm(0);	sigset(SIGALRM,alrm_fn);	alarm(CHILDWAIT);	LOG2(L_COMM,"(%5d) waitcld: entering\n", Logstamp);	while ((child = wait(&stat_loc)) != -1) {	    alarm(0);	    LOG4(L_COMM,"(%5d) waitcld: child %d exits with code 0x%x\n",		Logstamp,child,stat_loc);	    /* see if child is in table	*/	    for (i=0; i < MAXCHILDREN; i++)		if (Children[i].c_pid == child) {			Children[i].c_pid = 0;			req = Children[i].c_req;			Children[i].c_req = NULL;			if ((stat_loc & 0xFF) == 0 && stat_loc)				ns_undo(req);			else {				if (req->rq_head->h_opcode == NS_INIT) {					if (re_read() == RFS_FAILURE) 					    Done = TRUE;					else if (!Primary && r_init() == RFS_FAILURE) {					    PLOG1("RFS Name Server: r_init after merge FATAL\n");					    Done = TRUE;					}				}				freerp(req);			}			break;		}		sigset(SIGALRM,alrm_fn);		alarm(CHILDWAIT);	}	alarm(0);	sigset(SIGALRM,Alarmsig);	if (Alarmsig != SIG_IGN)		alarm((alrm_tim)?alrm_tim:Polltime);	sigset(SIGUSR2,waitcld);	return;}static intalrm_fn(){	sigset(SIGALRM,alrm_fn);	LOG2(L_OVER,"(%5d) waitcld: wait sanity alarm\n",Logstamp);}static intre_read(){	int	errflg;	if ((errflg = readfile(Netmaster,TRUE,FALSE)) <= 0) {		if (errflg == 0)			PLOG2("RFS name server: %s is empty after INIT\n",Netmaster);		else			PLOG3("RFS name server: can't open %s, error %s after INIT\n",			    Netmaster,			    (errno > sys_nerr)?"unknown error":sys_errlist[errno]);		return(RFS_FAILURE);	}	merge(DOMMASTER,FALSE);	return(RFS_SUCCESS);}static intsavecld(child,req)int	child;struct request	*req;{	int	i;	for (i=0; i < MAXCHILDREN; i++)		if (Children[i].c_pid == NULL) {			Children[i].c_pid = child;			Children[i].c_req = req;			return(RFS_SUCCESS);		}	/* ran out of room, warn but continue	*/	PLOG1("RFS name server: WARNING exceeded maximum outstanding children\n");	freerp(req);	return(RFS_FAILURE);}static intmkalist(addrlist,req,addr)struct address	**addrlist;struct request	*req;struct address	**addr;{	int	i,j;	int	istart;		/* initial length of addrlist	*/	struct header	*hp;	struct address	*ap;	LOG5(L_TRANS,"(%5d) mkalist(addrlist=%x,req=%x,addr[0]=%s\n",		Logstamp,addrlist,req,(addr && addr[0])?			aatos(Logbuf,addr[0],KEEP | HEX):"NULL");	/* find end of addrlist	*/	for (i=0; addrlist[i] != NULL && i < MAX_RETRY; i++)		;	if (i == MAX_RETRY)		return(0);	istart = i;	if (addr)	    for (j=0; j < MAXNS; j++)		if (addr[j] && notinlist(addrlist,addr[j])) {			addrlist[i++] = addr[j];			if (i < MAX_RETRY) {				LOG3(L_TRANS,"(%5d) mkalist: add Paddress %s\n",				    Logstamp,aatos(Logbuf,addr[j],KEEP|HEX));				addrlist[i] = NULL;			}		}	if (req) {		hp = req->rq_head;		for (j=0; j < hp->h_arcnt && i < MAX_RETRY; j++) {			if (ap = astoa(req->rq_ar[j]->rr_a,NULL)) {			    if (notinlist(addrlist,ap)) {				addrlist[i++] = ap;				if (i < MAX_RETRY) {					LOG3(L_TRANS,					   "(%5d) mkalist: add address %s\n",				           Logstamp,aatos(Logbuf,ap,KEEP|HEX));					addrlist[i] = NULL;				}			    }			    else				free(ap);			}		}	}	return(i - istart);}static intnotinlist(addrlist,ap)register struct	address	**addrlist;register struct	address	*ap;{	register int	i;	for (i=0; i < MAX_RETRY && *addrlist != NULL; i++, addrlist++)		if (eqaddr(*addrlist,ap))			return(FALSE);	return(TRUE);}static inteqaddr(a,b)register struct address *a;register struct address *b;{	if (!a || !b)		return(FALSE);	if (a->addbuf.len != b->addbuf.len)		return(FALSE);	if (a->protocol && b->protocol && strcmp(a->protocol,b->protocol) != NULL)		return(FALSE);	if (memcmp(a->addbuf.buf,b->addbuf.buf,a->addbuf.len))		return(FALSE);	return(TRUE);}static intns_undo(req)struct request	*req;{	struct header	*hp;	struct request	*nreq;	LOG2(L_COMM,"ns_undo: req=0X%x\n",req);	hp = req->rq_head;	/* for now, only undo advertisements	*/	if (hp->h_opcode == NS_ADV) {	    hp->h_opcode = NS_UNADV;	    if ((nreq = nsfunc(req,-1)) == NULL)		LOG1(L_ALL,"ns_undo: can't backout request\n");	    else		freerp(nreq);	}	freerp(req);	return;}/* * setnslock sets a lock file to make sure that two name servers * are not allowed to run at once.  It also writes this name server's * pid into the lock file so that rfstop can use it. */static int	Lockfd = -1;	/* current lock fd	*/static intsetnslock(){	char	buf[BUFSIZ];	if ((Lockfd = open(NSPID, O_RDWR|O_CREAT, 0600)) == -1) {		perror(NSPID);		return(-1);	}	if (lockf(Lockfd,F_TLOCK,0L) == -1) {		perror(NSPID);		return(-1);	}	sprintf(buf,"%-7d",getpid());	write(Lockfd,buf,strlen(buf)+1);	return(0);}static intclrnslock(){	if (Lockfd == -1)		return(-1);	close(Lockfd);	unlink(NSPID);	Lockfd = -1;	return(0);}/* 4.1 BSD signalling functions used by the name server emulated * with 4.2 BSD calls.  */intsighold(sig)	int sig;{	if (sig == SIGKILL) {		errno = EINVAL;		return (-1);	/* sigblock quietly disallows SIGKILL */	}	(void) sigblock(sigmask(sig));	return (0);		/* SVID specifies 0 return on success */}intsigrelse(sig)	int sig;{	if (sig == SIGKILL) {		errno = EINVAL;		return (-1);	/* sigsetmask quietly disallows SIGKILL */	}	(void) sigsetmask(sigblock(0) & ~sigmask(sig));	return (0);		/* SVID specifies 0 return on success */}intsigignore(sig)	int sig;{	struct sigvec vec;	if (sig == SIGKILL) {		errno = EINVAL;		return (-1);	/* sigsetmask quietly disallows SIGKILL */	}	if (sigvec(sig, (struct sigvec *)0, &vec) < 0)		return (-1);	vec.sv_handler = SIG_IGN;	if (sigvec(sig, &vec, (struct sigvec *)0) < 0)		return (-1);	(void) sigsetmask(sigblock(0) & ~sigmask(sig));	return (0);		/* SVID specifies 0 return on success */}void (*sigset(sig, func))()	int sig;	void (*func)();{	struct sigvec newvec;	int newmask;	struct sigvec oldvec;	int oldmask;	if (sigvec(sig, (struct sigvec *)0, &oldvec) < 0)		return (SIG_ERR);	oldmask = sigblock(0);	newvec = oldvec;	newvec.sv_flags |= SV_INTERRUPT;	newvec.sv_flags &= ~SV_RESETHAND;	newvec.sv_mask = 0;	newmask = oldmask;	if (func == SIG_HOLD) {		/*		 * Signal will be held.  Set the bit for that		 * signal in the signal mask.  Leave the action		 * alone.		 */		newmask |= sigmask(sig);	} else {		/*		 * Signal will not be held.  Clear the bit		 * for it in the signal mask.  Set the action		 * for it.		 */		newmask &= ~sigmask(sig);		newvec.sv_handler = func;	}	if (sigvec(sig, &newvec, (struct sigvec *)0) < 0)		return (SIG_ERR);	if (sigsetmask(newmask) < 0)		return (SIG_ERR);	if (oldmask & sigmask(sig))		return (SIG_HOLD);      /* signal was held */	else		return (oldvec.sv_handler);}

⌨️ 快捷键说明

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