ns_maint.c

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

C
1,201
字号
#ifndef lintstatic	char	*sccsid = "@(#)ns_maint.c	4.2	(ULTRIX)	11/15/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1984-1988 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* * Copyright (c) 1986 Regents of the University of California *	All Rights Reserved * static char sccsid[] = "@(#)ns_maint.c	4.23 (Berkeley) 2/28/88"; *//* * Modification History: * * 18-Jan-88	logcher *	Added BIND 4.7.2. * * 26-Jan-88	logcher *	Added BIND 4.7.3. * * 17-May-89	logcher *	Added BIND 4.8. */#include <sys/param.h>#include <sys/socket.h>#include <sys/time.h>#ifdef ULTRIXFUNC#include <sys/stat.h>#endif ULTRIXFUNC#if defined(SYSV)#include <unistd.h>#endif SYSV#include <netinet/in.h>#include <stdio.h>#include <syslog.h>#include <signal.h>#include <errno.h>#include <arpa/nameser.h>#ifdef ULTRIXFUNC#include <netdb.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/ip_icmp.h>#include <resolv.h>#endif ULTRIXFUNC#include <sys/types.h>#include <sys/wait.h>#include <sys/resource.h>#include "ns.h"#include "db.h"extern int errno;extern int maint_interval;#ifdef AUTHENextern char *res_dotname_head();extern int netsafe;extern int defauthentype;extern int defauthenver;#endif AUTHEN#ifdef ULTRIXFUNCextern struct protoent *getprotobyname_local();#define MAXPACKET       4096			/* max packet size */#endif ULTRIXFUNCextern int needzoneload;#ifdef ULTRIXFUNCextern int continuemaint;extern int ns_port;extern map_t m_credval[];extern map_t m_credtype[];extern file_ref_st *load_prep();extern char *m_val_str();#endif ULTRIXFUNCint xfers_running;	       /* number of xfers running */int xfers_deferred;	       /* number of needed xfers not run yet */static int alarm_pending;#ifdef ULTRIXFUNC/* * Invoked at regular intervals by signal interrupt; refresh all secondary * zones from primary name server and remove old cache entries.  Also, * ifdef'd ALLOW_UPDATES, dump database if it has changed since last * dump/bootup. */ns_continuemaint(){	register struct zoneinfo *zp;	int zonenum;	time_t next_refresh = 0;	struct itimerval ival;	int needsched;	int status;#ifdef DEBUG	if (debug)		fprintf(ddt,"ns_continuemaint()\n");#endif	needsched = 0;							continuemaint = 0;	gettime(&tt);	for (zp = zones, zonenum = 0; zp < &zones[nzones]; zp++, zonenum++) {#ifdef DEBUG		if (debug >= 2)			printzoneinfo(zonenum);#endif		/* if the zone is being slowly loaded, continue to load. */		if (zp->z_state & Z_SLOW_RELOAD) {			switch(zp->z_type) {#ifdef NEW_SIG			case Z_PRIMARY:				if ((status = db_load(zp->z_load_info,						NUM_ITER_LOAD)) != -2 ) {					/* the load is done or it failed */					if(status >= 0 &&					    !zp->z_load_info->format_errs) {						/* load is done */						replace_data(hashtab,zonenum);						set_zp(zp->z_load_info->zp,							zp);						free_files(zp->z_files);						zp->z_files =						  zp->z_load_info->files;						zp->z_auth = 1;					} else {						delete_zone(1, hashtab, zonenum);						free_files(zp->z_load_info->files);#ifdef PRIMARY_MAINT						zp->z_time = tt.tv_sec + zp->z_retry;#endif PRIMARY_MAINT					}					needsched = 1;					free(zp->z_load_info->zp);					free(zp->z_load_info);					zp->z_load_info = NULL;					zp->z_state &= ~Z_SLOW_RELOAD;				} else {					/* The load is not finished */					continuemaint = 1;				}				break;#endif NEW_SIG			case Z_SECONDARY:				if ((status = db_load(zp->z_load_info,						NUM_ITER_LOAD)) != -2 ) {					/* the load is done or it failed */					if(status >= 0 &&					    !zp->z_load_info->format_errs) {						/* load is done */						replace_data(hashtab, zonenum);						set_zp(zp->z_load_info->zp,							zp);						free_files(zp->z_files);						zp->z_files =						  zp->z_load_info->files;						zp->z_auth = 1;					} else {						delete_zone(1, hashtab, zonenum);						free_files(zp->z_load_info->files);						zp->z_time = tt.tv_sec + zp->z_retry;					}					needsched = 1;					free(zp->z_load_info->zp);					free(zp->z_load_info);					zp->z_load_info = NULL;					zp->z_state &= ~Z_SLOW_RELOAD;				} else {					/* The load is not finished */					continuemaint = 1;				}				break;			case Z_CACHE:				break;			default:				break;			}			gettime(&tt);		}	}	if(needsched)		sched_maint();#ifdef DEBUG	if (debug)		fprintf(ddt,"exit ns_continuemaint()\n");#endif}#endif ULTRIXFUNC/* * Invoked at regular intervals by signal interrupt; refresh all secondary * zones from primary name server and remove old cache entries.  Also, * ifdef'd ALLOW_UPDATES, dump database if it has changed since last * dump/bootup. */ns_maint(){	register struct zoneinfo *zp;	struct itimerval ival;	time_t next_refresh = 0;	int zonenum;#ifdef DEBUG	if (debug)		fprintf(ddt,"\nns_maint()\n");#endif	gettime(&tt);	xfers_deferred = 0;	alarm_pending = 0;	for (zp = zones, zonenum = 0; zp < &zones[nzones]; zp++, zonenum++) {#ifdef DEBUG		if (debug >= 2)			printzoneinfo(zonenum);#endif		if ((tt.tv_sec >= zp->z_time) && zp->z_refresh > 0) {			/*			 * Set default time for next action first,			 * so that it can be changed later if necessary.			 */			zp->z_time = tt.tv_sec + zp->z_refresh;			switch (zp->z_type) {			case Z_CACHE:				doachkpt();				break;			case Z_SECONDARY:#ifndef ULTRIXFUNC				if ((zp->z_state & Z_NEED_RELOAD) == 0)#endif ULTRIXFUNC				    if (zp->z_state & Z_XFER_RUNNING)					abortxfer(zp);#ifdef ULTRIXFUNC				    else if (zp->z_state & Z_NEED_RELOAD) {					zp->z_state &= ~Z_NEED_RELOAD;					zp->z_time = tt.tv_sec + zp->z_retry;				    } else if (zp->z_state & Z_SLOW_RELOAD)					abortslowreload(zp, zonenum);#endif ULTRIXFUNC				    else if (xfers_running < MAX_XFERS_RUNNING)					startxfer(zp);				    else {					zp->z_state |= Z_NEED_XFER;					++xfers_deferred;#ifdef DEBUG					if (debug > 1)					    fprintf(ddt,						"xfer deferred for %s\n",						zp->z_origin);#endif				    }				break;#ifdef PRIMARY_MAINT			case Z_PRIMARY:				if (zp->z_state & Z_SLOW_RELOAD)				    abortslowreload(zp, zonenum);				else {				    if(need_primaryload(zp)) {					zp->z_time = zp->z_refresh+ tt.tv_sec;					break;				    }				    if((zp->z_load_info = load_prep(zp,						filename, origin,						zp - zones)) == NULL) {					zp->z_time = zp->z_retry+ tt.tv_sec;					break;				    }				    if ((status = db_load(zp->z_load_info,						NUM_ITER_LOAD)) != -2 ) {					/* the load is done or it failed */					if(status >= 0 &&					    !zp->z_load_info->format_errs) {					    /* load is done */					    replace_data(hashtab, zonenum);					    set_zp(zp->z_load_info->zp, zp);					    free_files(zp->z_files);					    zp->z_files = load_info->files;											} else {					    delete_zone(1, hashtab, zonenum);					    free_files(zp->z_load_info->files);					    zp->z_time = tt.tv_sec + zp->z_retry;					}					free(zp->z_load_info->zp);					free(zp->z_load_info);					zp->z_load_info = NULL;					zp->z_state &= ~Z_SLOW_RELOAD;				    } else {					/* The load is not finished */					zp->z_time = zp->z_refresh+ tt.tv_sec;					zp->z_state |= Z_SLOW_RELOAD;					continuemaint = 1;				    }				}				break;#else PRIMARY_MAINT#ifdef ALLOW_UPDATES			case Z_PRIMARY:				/*				 * Checkpoint the zone if it has changed				 * since we last checkpointed				 */				if (zp->hasChanged)					zonedump(zp);				break;#endif ALLOW_UPDATES#endif PRIMARY_MAINT			}			gettime(&tt);		}	}	sched_maint();#ifdef DEBUG	if (debug)		fprintf(ddt,"exit ns_maint()\n");#endif}#ifdef NEW_SIG/* * Invoked at regular intervals by signal interrupt; refresh all secondary * zones from primary name server and remove old cache entries.  Also, * ifdef'd ALLOW_UPDATES, dump database if it has changed since last * dump/bootup. */ns_rereadzones(){	register struct zoneinfo *zp;	struct itimerval ival;	time_t next_refresh = 0;	int zonenum;	int status;#ifdef DEBUG	if (debug)		fprintf(ddt,"\nns_rereadzones()\n");#endif	gettime(&tt);	xfers_deferred = 0;	for (zp = zones, zonenum = 0; zp < &zones[nzones]; zp++, zonenum++) {#ifdef DEBUG		if (debug >= 2)			printzoneinfo(zonenum);#endif		/*		 * Set default time for next action first,		 * so that it can be changed later if necessary.		 */		switch (zp->z_type) {		case Z_CACHE:			break;		case Z_SECONDARY:		    if (zp->z_state & Z_XFER_RUNNING)			break;		    else if (zp->z_state & Z_NEED_RELOAD)			zp->z_state &= ~Z_NEED_RELOAD;		    else if (zp->z_state & Z_SLOW_RELOAD)			abortslowreload(zp, zonenum);		    if (xfers_running < MAX_XFERS_RUNNING)			startxfer(zp);		    else {			zp->z_time = tt.tv_sec + zp->z_refresh;			zp->z_state |= Z_NEED_XFER;			++xfers_deferred;#ifdef DEBUG			if (debug > 1)			    fprintf(ddt,				"xfer deferred for %s\n",				zp->z_origin);#endif		    }		    break;		case Z_PRIMARY:		    if (zp->z_state & Z_SLOW_RELOAD)			abortslowreload(zp, zonenum);		    else {			if(!need_primaryload(zp)) {#ifdef PRIMARY_MAINT			    zp->z_time = zp->z_refresh+ tt.tv_sec;#endif PRIMARY_MAINT			    break;			}			if((zp->z_load_info = load_prep(zp,				zp->z_source, zp->z_origin,				zp - zones)) == NULL) {#ifdef PRIMARY_MAINT			    zp->z_time = zp->z_retry+ tt.tv_sec;#endif PRIMARY_MAINT			    break;			}			if ((status = db_load(zp->z_load_info,				NUM_ITER_LOAD)) != -2 ) {			    /* the load is done or it failed */			    if(status >= 0 &&					!zp->z_load_info->format_errs) {				/* load is done */				replace_data(hashtab, zonenum);				set_zp(zp->z_load_info->zp, zp);				free_files(zp->z_files);				zp->z_files = zp->z_load_info->files;#ifdef PRIMARY_MAINT				zp->z_time = tt.tv_sec + zp->z_refresh;#endif PRIMARY_MAINT			    } else {				delete_zone(1, hashtab, zonenum);				free_files(zp->z_load_info->files);#ifdef PRIMARY_MAINT				zp->z_time = tt.tv_sec + zp->z_retry;#endif PRIMARY_MAINT			    }			    free(zp->z_load_info->zp);			    free(zp->z_load_info);			    zp->z_load_info = NULL;			    zp->z_state &= ~Z_SLOW_RELOAD;			} else {			    /* The load is not finished */#ifdef PRIMARY_MAINT			    zp->z_time = zp->z_refresh+ tt.tv_sec;#endif PRIMARY_MAINT			    zp->z_state |= Z_SLOW_RELOAD;			    continuemaint = 1;			}		    }		    break;		}		gettime(&tt);	}	sched_maint();#ifdef DEBUG	if (debug)		fprintf(ddt,"exit ns_maint()\n");#endif}#endif NEW_SIGabort_loads(){	register struct zoneinfo *zp;	int zonenum;	xfers_deferred = 0;	for (zp = zones, zonenum = 0; zp < &zones[nzones]; zp++, zonenum++) {		if(zp->z_state & Z_NEED_RELOAD) {			zp->z_state &= ~Z_NEED_RELOAD;			zp->z_time = tt.tv_sec + zp->z_retry;		}		else if(zp->z_state & Z_XFER_RUNNING)			abortxfer(zp);		else if(zp->z_state & Z_NEED_XFER) {			zp->z_state &= ~Z_NEED_XFER;		}		else if(zp->z_state & Z_SLOW_RELOAD)			abortslowreload(zp, zonenum);	}}abortslowreload(zp, zonenum)	register struct zoneinfo *zp;	int zonenum;{	int status;	if ((status = db_load(zp->z_load_info, STOP_LOAD)) >= -2 ) {		syslog(LOG_ERR, "abortslowreload failed\n");#ifdef DEBUG		if (debug)			fprintf(ddt, "abortslowreload failed\n");#endif	} else {		free_files(zp->z_load_info->files);		delete_zone(1, hashtab, zonenum);		zp->z_time = tt.tv_sec + zp->z_retry;		free(zp->z_load_info->zp);		free(zp->z_load_info);		zp->z_load_info = NULL;		zp->z_state &= ~Z_SLOW_RELOAD;	}}/* * Find when the next refresh needs to be and set * interrupt time accordingly. */sched_maint(){	register struct zoneinfo *zp;	struct itimerval ival;	time_t next_refresh = 0;	static time_t next_alarm;	for (zp = zones; zp < &zones[nzones]; zp++)		if (zp->z_time != 0 &&		    (next_refresh == 0 || next_refresh > zp->z_time))			next_refresh = zp->z_time;        /*	 *  Schedule the next call to ns_maint.	 *  Don't visit any sooner than maint_interval.	 */	bzero((char *)&ival, sizeof (ival));	if (next_refresh != 0) {		if (next_refresh == next_alarm && alarm_pending) {#ifdef DEBUG			if (debug)			    fprintf(ddt,"sched_maint: no schedule change\n");#endif			return;		}		ival.it_value.tv_sec = next_refresh - tt.tv_sec;		if (ival.it_value.tv_sec < maint_interval)			ival.it_value.tv_sec = maint_interval;		next_alarm = next_refresh;		alarm_pending = 1;	}	(void) setitimer(ITIMER_REAL, &ival, (struct itimerval *)NULL);#ifdef DEBUG	if (debug)		fprintf(ddt,"sched_maint: Next interrupt in %d sec\n",			ival.it_value.tv_sec);#endif}/* * Start an asynchronous zone transfer for a zone. * Depends on current time being in tt.

⌨️ 快捷键说明

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