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

📄 ns_main.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
			dprintf(1, (ddt, "bye, bye, interface [%s]",				    inet_ntoa(dqp->dq_addr)));			syslog(LOG_CRIT, "interface [%s] missing; deleting",				    inet_ntoa(dqp->dq_addr));			if (pqp != NULL)				pqp->dq_next = dqp->dq_next;			else				datagramq = dqp->dq_next;			(void) free(dqp);		}	}	/*	 * Create separate qdatagram structure for socket	 * wildcard address.	 */	if (first) {		if ((dqp = (struct qdatagram *)calloc(1, sizeof(*dqp)))		    == NULL) {			dprintf(1, (ddt, "getnetconf: malloc error\n"));			syslog(LOG_ERR, "getnetconf: Out Of Memory");			exit(12);		}		dqp->dq_next = datagramq;		datagramq = dqp;		dqp->dq_addr.s_addr = INADDR_ANY;		opensocket(dqp);		ds = dqp->dq_dfd;	}	/*	 * Compute logical networks to which we're connected	 * based on attached subnets;	 * used for sorting based on network configuration.	 */	for (ntp = nettab; ntp != NULL; ntp = ntp->next) {		nm = net_mask(ntp->my_addr);		if (nm != ntp->mask) {			if (findnetinfo(ntp->my_addr))				continue;			ontp = (struct netinfo *)			       malloc(sizeof(struct netinfo));			if (ontp == NULL) {				dprintf(5, (ddt,					    "getnetconf: malloc error\n"));				syslog(LOG_ERR, "getnetconf: Out Of Memory");				exit(12);			}			ontp->my_addr = ntp->my_addr;			ontp->mask = nm;			ontp->net = ontp->my_addr.s_addr & nm;			ontp->next = *enettab;			*enettab = ontp;			enettab = &ontp->next;		}	}	first = 0;}/* * Find netinfo structure for logical network implied by address "addr", * if it's on list of local/favored networks. */struct netinfo *findnetinfo(addr)	struct in_addr addr;{	register struct netinfo *ntp;	u_int32_t net, mask;	mask = net_mask(addr);	net = addr.s_addr & mask;	for (ntp = nettab; ntp != NULL; ntp = ntp->next)		if (ntp->net == net && ntp->mask == mask)			return (ntp);	return ((struct netinfo *) NULL);}#ifdef DEBUGstatic voidprintnetinfo(ntp)	register struct netinfo *ntp;{	for ( ; ntp != NULL; ntp = ntp->next) {		fprintf(ddt,"net x%lx mask x%lx", ntp->net, ntp->mask);		fprintf(ddt," my_addr x%lx", ntp->my_addr.s_addr);		fprintf(ddt," %s\n", inet_ntoa(ntp->my_addr));	}}#endifstatic voidopensocket(dqp)	register struct qdatagram *dqp;{	int n, m;	int on = 1;	/*	 * Open datagram sockets bound to interface address.	 */	if ((dqp->dq_dfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {		syslog(LOG_ERR, "socket(SOCK_DGRAM): %m - exiting");		exit(1);	}	#ifdef DEBUG	if (debug)		fprintf(ddt,"dqp->dq_addr %s d_dfd %d\n",		    inet_ntoa(dqp->dq_addr), dqp->dq_dfd);#endif	if (setsockopt(dqp->dq_dfd, SOL_SOCKET, SO_REUSEADDR,	    (char *)&on, sizeof(on)) != 0)	{		syslog(LOG_ERR, "setsockopt(dqp->dq_dfd, reuseaddr): %m");		/* XXX press on regardless, this is not too serious. */	}#ifdef SO_RCVBUF	m = sizeof(n);	/* note: this depends on short-circuit evaluation, which is in the	 * C standards, but tricky nonetheless. (vix)	 */	if ((getsockopt(dqp->dq_dfd, SOL_SOCKET, SO_RCVBUF, &n, &m) >= 0)	    && (m == sizeof(n))	    && (n < rbufsize)) {		(void) setsockopt(dqp->dq_dfd, SOL_SOCKET, SO_RCVBUF,				  (char *)&rbufsize, sizeof(rbufsize));	}#endif /* SO_RCVBUF */	if ((n = fcntl(dqp->dq_dfd, F_GETFL, 0)) < 0) {		syslog(LOG_ERR, "fcntl(dfd, F_GETFL): %m");		/* XXX press on regardless, but this really is a problem. */	} else if (fcntl(dqp->dq_dfd, F_SETFL, n|PORT_NONBLOCK) != 0) {		syslog(LOG_ERR, "fcntl(dqp->dq_dfd, non-blocking): %m");		/* XXX press on regardless, but this really is a problem. */	}	/*	 *   NOTE: Some versions of SunOS have problems with the following	 *   call to bind.  Bind still seems to function on these systems	 *   if you comment out the exit inside the if.  This may cause	 *   Suns with multiple interfaces to reply strangely.	 */	nsaddr.sin_addr = dqp->dq_addr;	if (bind(dqp->dq_dfd, (struct sockaddr *)&nsaddr, sizeof(nsaddr))) {		syslog(LOG_ERR, "bind(dfd=%d, [%s].%d): %m - exiting",			dqp->dq_dfd, inet_ntoa(nsaddr.sin_addr),			ntohs(nsaddr.sin_port));#if !defined(sun)		exit(1);#endif	}}/*** Set flag saying to reload database upon receiving SIGHUP.** Must make sure that someone isn't walking through a data** structure at the time.*/static SIG_FNonhup(){#if defined(SYSV)	(void)signal(SIGHUP, onhup);#endif /* SYSV */	needreload = 1;}/*** Set flag saying to call ns_maint()** Must make sure that someone isn't walking through a data** structure at the time.*/static SIG_FNmaint_alarm(){#if defined(SYSV)	(void)signal(SIGALRM, maint_alarm);#endif /* SYSV */	needmaint = 1; }#ifdef ALLOW_UPDATES/* * Signal handler to schedule shutdown.  Just set flag, to ensure a consistent * state during dump. */static SIG_FNonintr(){        needToExit = 1;}#endif /* ALLOW_UPDATES *//* * Signal handler to schedule a data base dump.  Do this instead of dumping the * data base immediately, to avoid seeing it in a possibly inconsistent state * (due to updates), and to avoid long disk I/O delays at signal-handler * level */static SIG_FNsetdumpflg(){#if defined(SYSV)	(void)signal(SIGINT, setdumpflg);#endif /* SYSV */        needToDoadump = 1;}/*** Turn on or off debuging by open or closeing the debug file*/static voidsetdebug(code)	int code;{#if defined(lint) && !defined(DEBUG)	code = code;#endif#ifdef DEBUG	if (code) {		int n;		ddt = freopen(debugfile, "w+", stderr);		if ( ddt == NULL) {			syslog(LOG_WARNING, "can't open debug file %s: %m",			    debugfile);			debug = 0;		} else {#if defined(SYSV)			setvbuf(ddt, NULL, _IOLBF, BUFSIZ);#else			setlinebuf(ddt);#endif			if ((n = fcntl(fileno(ddt), F_GETFL, 0)) < 0) {				syslog(LOG_WARNING,				       "fcntl(ddt, F_GETFL): %m");			} else {				(void) fcntl(fileno(ddt), F_SETFL, n|O_APPEND);			}		}	} else		debug = 0;		/* delay closing ddt, we might interrupt someone */#endif}/*** Catch a special signal and set debug level.****  If debuging is off then turn on debuging else increment the level.**** Handy for looking in on long running name servers.*/static SIG_FNsetIncrDbgFlg(){#if defined(SYSV)	(void)signal(SIGUSR1, setIncrDbgFlg);#endif /* SYSV */#ifdef DEBUG	if (debug == 0) {		debug++;		setdebug(1);	}	else {		debug++;	}	fprintf(ddt,"Debug turned ON, Level %d\n",debug);#endif}/*** Catch a special signal to turn off debugging*/static SIG_FNsetNoDbgFlg(){#if defined(SYSV)	(void)signal(SIGUSR2, setNoDbgFlg);#endif /* SYSV */	setdebug(0);}#if defined(QRYLOG) && defined(SIGWINCH)/*** Set flag for query logging*/static SIG_FNsetQrylogFlg(){#if defined(SYSV)	(void)signal(SIGWINCH, setQrylogFlg);#endif /* SYSV */	qrylog = !qrylog;	syslog(LOG_NOTICE, "query log %s\n", qrylog ?"on" :"off");}#endif /*QRYLOG && SIGWINCH*//*** Set flag for statistics dump*/static SIG_FNsetstatsflg(){#if defined(SYSV)	(void)signal(SIGIOT, setstatsflg);#endif /* SYSV */	needStatsDump = 1;}static SIG_FNsetchkptflg(){#if defined(SYSV)	(void)signal(SIGQUIT, setchkptflg);#endif /* SYSV */	needToChkpt = 1;}/*** Catch a special signal SIGSYS****  this is setup to fork and exit to drop to /usr/tmp/gmon.out**   and keep the server running*/static SIG_FNsigprof(){#if defined(SYSV)	(void)signal(SIGSYS, sigprof);#endif /* SYSV */#ifdef DEBUG	if (debug)		fprintf(ddt,"sigprof()\n");#endif	if (fork() == 0)	{		(void) chdir(_PATH_TMPDIR);		exit(1);	}}/*** Routines for managing stream queue*/static struct qstream *sqadd(){	register struct qstream *sqp;	if (!(sqp = (struct qstream *)calloc(1, sizeof(struct qstream)))) {		dprintf(5, (ddt, "sqadd: calloc error\n"));		syslog(LOG_ERR, "sqadd: Out Of Memory");		return(QSTREAM_NULL);	}	dprintf(3, (ddt, "sqadd(x%x)\n", sqp));	sqp->s_next = streamq;	streamq = sqp;	return(sqp);}/* sqrm(qp) *	remove stream queue structure `qp'. *	no current queries may refer to this stream when it is removed. * side effects: *	memory is deallocated.  sockets are closed.  lists are relinked. */voidsqrm(qp)	register struct qstream *qp;{	register struct qstream *qsp;	dprintf(2, (ddt, "sqrm(%#x, %d ) rfcnt=%d\n",		    qp, qp->s_rfd, qp->s_refcnt));	if (qp->s_bufsize != 0)		free(qp->s_buf);	FD_CLR(qp->s_rfd, &mask);	(void) my_close(qp->s_rfd);	if (qp == streamq) {		streamq = qp->s_next;	} else {		for (qsp = streamq;		     qsp && (qsp->s_next != qp);		     qsp = qsp->s_next)			;		if (qsp) {			qsp->s_next = qp->s_next;		}	}	free((char *)qp);}/* sqflush() *	call sqrm() on all open streams * side effects: *	global list `streamq' becomes empty */voidsqflush(){	register struct qstream *sp, *spnext;	for (sp = streamq; sp != QSTREAM_NULL; sp = spnext) {		spnext = sp->s_next;		sqrm(sp);	}}/* int * sq_here(sp) *	determine whether stream 'sp' is still on the streamq * return: *	boolean: is it here? */static intsq_here(sp)	register struct qstream *sp;{	register struct qstream *t;	for (t = streamq;  t != QSTREAM_NULL;  t = t->s_next)		if (t == sp)			return 1;	return 0;}/* * Initiate query on stream; * mark as referenced and stop selecting for input. */static voidsq_query(sp)	register struct qstream *sp;{	sp->s_refcnt++;	FD_CLR(sp->s_rfd, &mask);}/* * Note that the current request on a stream has completed, * and that we should continue looking for requests on the stream. */voidsq_done(sp)	register struct qstream *sp;{	sp->s_refcnt = 0;	sp->s_time = tt.tv_sec;	FD_SET(sp->s_rfd, &mask);}voidsetproctitle(a, s)	char *a;	int s;{	int size;	register char *cp;	struct sockaddr_in sin;	char buf[80];	cp = Argv[0];	size = sizeof(sin);	if (getpeername(s, (struct sockaddr *)&sin, &size) == 0)		(void) sprintf(buf, "-%s [%s]", a, inet_ntoa(sin.sin_addr));	else {		syslog(LOG_DEBUG, "getpeername: %m");		(void) sprintf(buf, "-%s", a);	}	(void) strncpy(cp, buf, LastArg - cp);	cp += strlen(cp);	while (cp < LastArg)		*cp++ = ' ';}u_int32_tnet_mask(in)	struct in_addr in;{	register u_int32_t i = ntohl(in.s_addr);	if (IN_CLASSA(i))		return (htonl(IN_CLASSA_NET));	else if (IN_CLASSB(i))		return (htonl(IN_CLASSB_NET));	else		return (htonl(IN_CLASSC_NET));}#if defined(BSD43_BSD43_NFS)/* junk needed for old Sun NFS licensees */#undef dn_skipnameextern char *dn_skipname();char *(*hack_skipname)() = dn_skipname;#endif

⌨️ 快捷键说明

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