ns_maint.c

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

C
1,201
字号
 * The caller must call sched_maint after startxfer. */startxfer(zp)	struct zoneinfo *zp;{	static char *argv[NSMAX + 20], argv_ns[NSMAX][MAXDNAME];	int cnt, argc = 0, argc_ns = 0, pid, omask;	char debug_str[10];	char serial_str[10];	char port_str[10];#ifdef AUTHEN	char authen_str[(MAXDNAME * 2) + 1];#endif AUTHEN#ifdef ULTRIXFUNC	char *tmp_cptr;#endif ULTRIXFUNC#ifdef DEBUG	if (debug)		fprintf(ddt,"startxfer() %s\n", zp->z_origin);#endif	argv[argc++] = "named-xfer";	argv[argc++] = "-z";	argv[argc++] = zp->z_origin;	argv[argc++] = "-f";	argv[argc++] = zp->z_source;	argv[argc++] = "-s";	sprintf(serial_str, "%d", zp->z_serial);	argv[argc++] = serial_str;#ifndef ULTRIXFUNC	if (zp->z_state & Z_SYSLOGGED)		argv[argc++] = "-q";#endif ULTRIXFUNC	argv[argc++] = "-P";	sprintf(port_str, "%d", ns_port);	argv[argc++] = port_str;#ifdef AUTHEN	if(netsafe) {		argv[argc++] = "-n";		argv[argc++] = "-a";		if((tmp_cptr = m_val_str(m_credtype, NUMMAPCREDTYPE,		    defauthentype)) == NULL) {				}		strcpy(authen_str, tmp_cptr);		strcat(authen_str, ".");		if((tmp_cptr = m_val_str(m_credval, NUMMAPCREDVAL,		    defauthenver)) == NULL) {				}		strcat(authen_str, tmp_cptr);		argv[argc++] = authen_str;	}#endif AUTHEN#ifdef DEBUG	if (debug) {		argv[argc++] = "-d";		sprintf(debug_str, "%d", debug);		argv[argc++] = debug_str;		argv[argc++] = "-l";		argv[argc++] = "/usr/tmp/xfer.ddt";		if (debug > 5) {			argv[argc++] = "-t";			argv[argc++] = "/usr/tmp/xfer.trace";		}	}#endif		/*	 * Copy the server ip addresses into argv, after converting	 * to ascii and saving the static inet_ntoa result	 */	for (cnt = 0; cnt < zp->z_addrcnt; cnt++)		argv[argc++] = strcpy(argv_ns[argc_ns++],		    inet_ntoa(zp->z_addr[cnt]));	argv[argc] = 0;#ifdef DEBUG#ifdef ECHOARGS	if (debug) {		int i;		for (i = 0; i < argc; i++) 			fprintf(ddt, "Arg %d=%s\n", i, argv[i]);        }#endif /* ECHOARGS */#endif /* DEBUG */#ifdef SYSV#define vfork fork#else	gettime(&tt);	omask = sigblock(sigmask(SIGCHLD));#endif	if ((pid = vfork()) == -1) {#ifdef DEBUG		if (debug)			fprintf(ddt, "xfer [v]fork: %d\n", errno);#endif		syslog(LOG_ERR, "xfer [v]fork: %m");#ifndef SYSV		(void) sigsetmask(omask);#endif		zp->z_time = tt.tv_sec + XFER_TIME_FUDGE;		return;	}	if (pid) {#ifdef DEBUG		if (debug)			fprintf(ddt, "started xfer child %d\n", pid);#endif		zp->z_state &= ~Z_NEED_XFER;		zp->z_state |= Z_XFER_RUNNING;		zp->z_xferpid = pid;		xfers_running++;		zp->z_time = tt.tv_sec + MAX_XFER_TIME;#ifndef SYSV		(void) sigsetmask(omask);#endif	} else {		execve(_PATH_XFER, argv, NULL);		syslog(LOG_ERR, "can't exec %s: %m", _PATH_XFER);		_exit(XFER_FAIL);	/* avoid duplicate buffer flushes */	}}#ifdef DEBUGprintzoneinfo(zonenum)int zonenum;{	struct timeval  tt;	struct zoneinfo *zp = &zones[zonenum];	char *ZoneType;	if (!debug)		return; /* Else fprintf to ddt will bomb */	fprintf(ddt, "printzoneinfo(%d):\n", zonenum);	gettime(&tt);	switch (zp->z_type) {		case Z_PRIMARY: ZoneType = "Primary"; break;		case Z_SECONDARY: ZoneType = "Secondary"; break;		case Z_CACHE: ZoneType = "Cache"; break;		default: ZoneType = "Unknown";	}#ifdef ULTRIXFUNC	if (zp->z_origin == (char *)NULL || zp->z_origin[0] == '\0')#else ULTRIXFUNC	if (zp->z_origin[0] == '\0')#endif ULTRIXFUNC		fprintf(ddt,"origin ='.'");	else		fprintf(ddt,"origin ='%s'", zp->z_origin);	fprintf(ddt,", type = %s", ZoneType);	fprintf(ddt,", source = %s\n", zp->z_source);	fprintf(ddt,"z_refresh = %ld", zp->z_refresh);	fprintf(ddt,", retry = %ld", zp->z_retry);	fprintf(ddt,", expire = %ld", zp->z_expire);	fprintf(ddt,", minimum = %ld", zp->z_minimum);	fprintf(ddt,", serial = %ld\n", zp->z_serial);	fprintf(ddt,"z_time = %d", zp->z_time);	if (zp->z_time) {		fprintf(ddt,", now time : %d sec", tt.tv_sec);		fprintf(ddt,", time left: %d sec", zp->z_time - tt.tv_sec);	}}#endif DEBUG#ifdef ULTRIXFUNC/* * replace_data (htp, zone) -- *     Delete all RR's in the zone "zone" on n_data lists.  Replace this *     data with records of zone "zone" on the n_loaddb lists. */replace_data (htp, zone)    register struct hashbuf *htp;    register int zone;{	delete_zone(0, htp, zone);	move_loaddb(htp, zone);}/* * move_loaddb (htp, zone) -- *     Place data with records of zone "zone" in the n_loaddb lists on *     the n_data lists. */move_loaddb(htp, zone)    register struct hashbuf *htp;    register int zone;{    register struct databuf *dp;    register struct databuf *pdp;    register struct databuf *temp;    register struct namebuf *np;    struct namebuf **npp, **nppend;    nppend = htp->h_tab + htp->h_size;    for (npp = htp->h_tab; npp < nppend; npp++) {    	for (np = *npp; np != NULL; np = np->n_next) {    	    for (pdp = NULL, dp = np->n_loaddb; dp != NULL; ) {		if (dp->d_zone == zone || zone == ALL_DATA) {			if(pdp == NULL)				np->n_loaddb = dp->d_next;			else				pdp->d_next = dp->d_next;			temp = dp->d_next;			dp->d_next = np->n_data;			np->n_data = dp;			dp = temp;		} else {			pdp = dp;			dp = dp->d_next;		}			    }	    /* Call recursively to clean up subdomains. */	    if (np->n_hash != NULL)		move_loaddb (np->n_hash, zone);	}    }}/* * delete_zone (htp, zone) -- *     Delete all RR's in the zone "zone" on either the n_loaddb lists or *     the n_data lists. Flag determines from which list to delete. */delete_zone (flag, htp, zone)    int flag;    register struct hashbuf *htp;    register int zone;{    register struct databuf *dp;    register struct databuf *pdp;    register struct namebuf *np;    struct namebuf **npp, **nppend;    nppend = htp->h_tab + htp->h_size;    for (npp = htp->h_tab; npp < nppend; npp++) {    	for (np = *npp; np != NULL; np = np->n_next) {    	    for (pdp = NULL, dp = ((flag) ? np->n_loaddb: np->n_data);			dp != NULL; ) {					if (dp->d_zone == zone || zone == ALL_DATA) {			dp =  rm_datum(flag, dp, np, pdp);		} else {			pdp = dp;			dp = dp->d_next;		}    	    }	    /* Call recursively to clean up subdomains. */	    if (np->n_hash != NULL)		delete_zone (flag, np->n_hash, zone);	}    }}#endif ULTRIXFUNC   /* * Abort an xfer that has taken too long. */abortxfer(zp)	register struct zoneinfo *zp;{	kill(zp->z_xferpid, SIGKILL); /* don't trust it at all */#ifdef DEBUG	if (debug)	  fprintf(ddt, "Killed child %d (zone %s) due to timeout\n",	     zp->z_xferpid, zp->z_origin);#endif /* DEBUG */#ifdef ULTRIXFUNC	zp->z_state &= ~Z_XFER_RUNNING;#endif ULTRIXFUNC	zp->z_time = tt.tv_sec + zp->z_retry;}#ifdef SYSVunion wait {	unsigned short	w_termsig:7;	/* termination signal */	unsigned short	w_coredump:1;	/* core dump indicator */	unsigned short	w_retcode:8;	/* exit code if w_termsig==0 */};#endif/* * SIGCHLD signal handler: process exit of xfer's. * (Note: also called when outgoing transfer completes.) */voidendxfer(){    	register struct zoneinfo *zp;   	int pid, xfers = 0;	union wait status;	static int first_time = 1;#ifdef ULTRIXFUNC	int start;	int num_zones;#endif ULTRIXFUNC	gettime(&tt);	if(first_time)		srandom((int)(tt.tv_usec & 0xffff));#if defined(SYSV)	{ int stat;	pid = wait(&stat);	status.w_termsig = stat & 0x7f;	status.w_retcode = stat >> 8;	}#else /* SYSV */	while ((pid = wait3(&status, WNOHANG, (struct rusage *)NULL)) > 0) {#endif /* SYSV */		for (zp = zones; zp < &zones[nzones]; zp++)		    if (zp->z_xferpid == pid) {			xfers++;			xfers_running--;			zp->z_xferpid = 0;			zp->z_state &= ~Z_XFER_RUNNING;#ifdef DEBUG			if (debug) 			    fprintf(ddt,		"\nendxfer: child %d zone %s returned status=%d termsig=%d\n", 				pid, zp->z_origin, status.w_retcode,				status.w_termsig);#endif			if (status.w_termsig != 0) {				if (status.w_termsig != SIGKILL) {					syslog(LOG_ERR,					   "named-xfer exited with signal %d\n",					   status.w_termsig);#ifdef DEBUG					if (debug)					    fprintf(ddt,					 "\tchild termination with signal %d\n",						status.w_termsig);#endif				}				zp->z_time = tt.tv_sec + zp->z_retry;			} else switch (status.w_retcode) {				case XFER_UPTODATE:#ifndef ULTRIXFUNC					zp->z_state &= ~Z_SYSLOGGED;#endif ULTRIXFUNC					zp->z_lastupdate = tt.tv_sec;					zp->z_time = tt.tv_sec + zp->z_refresh;#ifndef ULTRIXFUNC					/*					 * Restore z_auth in case expired,					 * but only if there were no errors					 * in the zone file.					 */					if ((zp->z_state & Z_DB_BAD) == 0)						zp->z_auth = 1;#endif ULTRIXFUNC					if (zp->z_source) {#if defined(SYSV)						struct utimbuf t;						t.actime = tt.tv_sec;						t.modtime = tt.tv_sec;						(void) utime(zp->z_source, &t);#else						struct timeval t[2];						t[0] = tt;						t[1] = tt;						(void) utimes(zp->z_source, t);#endif /* SYSV */					}					break;				case XFER_SUCCESS:					zp->z_state |= Z_NEED_RELOAD;#ifndef ULTRIXFUNC					zp->z_state &= ~Z_SYSLOGGED;#endif ULTRIXFUNC					needzoneload++;					break;				case XFER_TIMEOUT:#ifdef DEBUG					if (debug) fprintf(ddt,		    "zoneref: Masters for secondary zone %s unreachable\n",					    zp->z_origin);#endif#ifndef ULTRIXFUNC					if ((zp->z_state & Z_SYSLOGGED) == 0) {						zp->z_state |= Z_SYSLOGGED;#endif ULTRIXFUNC						syslog(LOG_WARNING,		      "zoneref: Masters for secondary zone %s unreachable",						    zp->z_origin);#ifndef ULTRIXFUNC					}#endif ULTRIXFUNC					zp->z_time = tt.tv_sec + zp->z_retry;					break;				default:#ifndef ULTRIXFUNC					if ((zp->z_state & Z_SYSLOGGED) == 0) {						zp->z_state |= Z_SYSLOGGED;#endif ULTRIXFUNC						syslog(LOG_ERR,						    "named-xfer exit code %d",						    status.w_retcode);#ifndef ULTRIXFUNC					}#endif ULTRIXFUNC					/* FALLTHROUGH */				case XFER_FAIL:#ifndef ULTRIXFUNC					zp->z_state |= Z_SYSLOGGED;#endif ULTRIXFUNC					zp->z_time = tt.tv_sec + zp->z_retry;					break;			}			break;		}#ifndef SYSV	}#endif /* SYSV */#ifdef ULTRIXFUNC	if (xfers) {		start = random() % nzones;		for (zp = &zones[start], num_zones = 0;			xfers_deferred != 0 &&			xfers_running < MAX_XFERS_RUNNING &&			num_zones != nzones;			num_zones++, zp++) {		    if(zp > &zones[nzones])			zp = zones;		    if (zp->z_state & Z_NEED_XFER) {			xfers_deferred--;			startxfer(zp);		    }		}		sched_maint();	}#else ULTRIXFUNC	if (xfers) {		for (zp = zones;		    xfers_deferred != 0 && xfers_running < MAX_XFERS_RUNNING &&		    zp < &zones[nzones]; zp++)			if (zp->z_state & Z_NEED_XFER) {				xfers_deferred--;				startxfer(zp);			}		sched_maint();	}#endif ULTRIXFUNC#if defined(SYSV)	(void)signal(SIGCLD, endxfer);#endif}/* * Reload zones whose transfers have completed. */loadxfer(){    	register struct zoneinfo *zp;   	int status, zonenum;	gettime(&tt);	for (zp = zones, zonenum = 0; zp < &zones[nzones]; zp++, zonenum++)	    if (zp->z_state & Z_NEED_RELOAD) {#ifdef DEBUG		if (debug)			fprintf(ddt, "loadxfer() '%s'\n",			zp->z_origin[0] ? zp->z_origin : ".");#endif		zp->z_state &= ~Z_NEED_RELOAD;#ifdef ULTRIXFUNC	 	if((zp->z_load_info = load_prep(zp, zp->z_source,		    zp->z_origin, zonenum)) == 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 = zp->z_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_state |= Z_SLOW_RELOAD;			continuemaint = 1;		}#else ULTRIXFUNC		zp->z_auth = 0;		remove_zone(hashtab, zp - zones);		if (db_load(zp->z_source, zp->z_origin, zp, 0) == 0)			zp->z_auth = 1;#endif ULTRIXFUNC	    }	sched_maint();}free_files(files)	files_st *files;{	for(;files != (files_st *)NULL; files = files->next) {		free(files);	}}	need_primaryload(zp)	struct zoneinfo *zp;{	struct stat	f_stats;	files_st	*files;	if(zp->z_files == (files_st *)NULL)		return(1);	for(files = zp->z_files; files != (files_st *)NULL;			files = files->next) {		if (stat(files->f_name, &f_stats) < 0) {			return(1);		} else {			if (f_stats.st_mtime > files->f_stats.st_mtime)				return(1);		}	}	return(0);}/*file_copy(in, fp)	FILE	*in;	FILE	*out;{	}*/set_zp(zp_in, zp_out)     struct zoneinfo *zp_in;     struct zoneinfo *zp_out;{	zp_out->z_type = zp_in->z_type;	zp_out->z_auth = zp_in->z_auth;	zp_out->z_origin = zp_in->z_origin;	zp_out->z_time = zp_in->z_time;	zp_out->z_lastupdate = zp_in->z_lastupdate;	zp_out->z_refresh = zp_in->z_refresh;	zp_out->z_retry = zp_in->z_retry;	zp_out->z_expire = zp_in->z_expire;	zp_out->z_minimum = zp_in->z_minimum;	zp_out->z_serial = zp_in->z_serial;	zp_out->z_source = zp_in->z_source;	zp_out->z_ftime = zp_in->z_ftime;	zp_out->z_addrcnt = zp_in->z_addrcnt;	zp_out->z_sysloged = zp_in->z_sysloged;	zp_out->z_state = zp_in->z_state;	zp_out->z_xferpid = zp_in->z_xferpid;	zp_out->z_class = zp_in->z_class;	zp_out->z_files = zp_in->z_files;	zp_out->z_load_info = zp_in->z_load_info;}

⌨️ 快捷键说明

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