xfer.c

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

C
1,802
字号
#ifndef lintstatic	char	*sccsid = "@(#)xfer.c	4.1	(ULTRIX)	7/2/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1990 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.	* *									* ************************************************************************//* * Modification History: * * 30-Mar-90	sue *	Added the Hesiod class to case A record per Mark Rosenstein's *	MIT bug report. * * 28-Feb-90	sue *	Added two missing if (debug) lines to DEBUG spots in getzone(). * * 07-Feb-90	sue *	Added proper TXT handling according to rfc1035. * * 07-Feb-90	bbrown *	Added 4.8.2 and Kerberos *//* * Copyright (c) 1988 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that this notice is preserved and that due credit is given * to the University of California at Berkeley. The name of the University * may not be used to endorse or promote products derived from this * software without specific prior written permission. This software * is provided ``as is'' without express or implied warranty. * * The original version of xfer is by Kevin Dunlap. * Completed and integrated with named by David Waitzman (dwaitzman@bbn.com) * 3/14/88. * Modified by M. Karels and O. Kure 10-88. * static char sccsid[] = "@(#)xfer.c	4.8 (Berkeley) 10/4/89"; */#include <sys/param.h>#include <sys/file.h>#include <sys/time.h>#include <sys/stat.h>#include <sys/wait.h>#include <sys/resource.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/uio.h>#include <netinet/in.h>#include <net/if.h>#include <stdio.h>#include <syslog.h>#include <errno.h>#include <signal.h>#include <netdb.h>#include <arpa/inet.h>#include <arpa/nameser.h>#include <resolv.h>#ifdef AUTHEN#include <krb.h>#endif AUTHEN#define XFER			/* modifies the ns.h include file */#include "ns.h"char	*savestr();/* max length of data in RR data field */#define MAXDATA		1024	/* from db.h */ int	debug = 0; int	quiet = 0;int	read_interrupted = 0;struct	zoneinfo zones;		/* zone information */struct	timeval	tt;static	char *ddtfile = _PATH_TMPXFER;static	char *tmpname;FILE	*fp = 0, *ddt, *dbfp;char	*domain;			/* domain being xfered */int	domain_len;			/* strlen(domain) */extern char *malloc();extern int errno;#ifdef AUTHENint	defauthentype = AUTH_KRB;int	defauthenver = ONE;int	netsafe = 0;extern map_t m_credval[];extern map_t m_credtype[];extern struct hostent *gethostbyaddr_local();extern struct hostent *gethostbyname_local();extern char *res_dotname_head();char *mktemp();#endif AUTHENmain(argc, argv)	int argc;	char *argv[];{	register struct zoneinfo *zp;	register struct hostent *hp; 	char *dbfile = NULL, *tracefile = NULL, *tm = NULL;	int dbfd, ddtd, result, c;	u_long serial_no = 0;	extern char *optarg;	extern int optind, getopt();	u_short port = htons(NAMESERVER_PORT);#ifdef AUTHEN	char *p_char;	char *optarg2;	char localhost[MAXDNAME];	struct hostent *temp_ent;	char tkt_filename[50];#endif AUTHEN	(void) umask(022);#ifdef LOG_DAEMON	openlog("named-xfer", LOG_PID|LOG_CONS, LOG_DAEMON);#else	openlog("named-xfer", LOG_PID);#endif#ifdef AUTHEN	while ((c = getopt(argc, argv, "a:d:l:s:t:z:f:p:P:qn")) != EOF)#else AUTHEN	while ((c = getopt(argc, argv, "d:l:s:t:z:f:p:P:q")) != EOF)#endif AUTHEN	    switch (c) {#ifdef AUTHEN		case 'a':			for( p_char = optarg; *p_char != '.' && *p_char != '\0';			    p_char++);			if(*p_char != '.')				usage();			else {				optarg2 = p_char + 1;				*p_char = '\0';			}			if((defauthentype = m_str_val(m_credtype, NUMMAPCREDTYPE,			     optarg))== RET_BAD)				usage();			_res.defauthtype = defauthentype;			if((defauthenver=m_str_val(m_credval, NUMMAPCREDVAL,			     optarg2)) == RET_BAD)				usage();			_res.defauthversion= defauthenver;			break;		case 'n':			netsafe = 1;			break;#endif AUTHEN		case 'd':			debug = atoi(optarg);			break;		case 'l':			ddtfile = malloc(strlen(optarg) +			    sizeof(".XXXXXX") + 1);			(void) strcpy(ddtfile, optarg);			(void) strcat(ddtfile, ".XXXXXX");			break;		case 's':			serial_no = (u_long) atol(optarg);			break;		case 't':			tracefile = optarg;			break;		case 'z':		/* zone == domain */			domain = optarg;			domain_len = strlen(domain);			break;		case 'f':			dbfile = optarg;			tmpname = malloc((unsigned)strlen(optarg) +			    sizeof(".XXXXXX") + 1);			(void) strcpy(tmpname, optarg);			break;		case 'p':			port = htons((u_short)atoi(optarg));			break;		case 'P':			port = (u_short)atoi(optarg);			break;		case 'q':			quiet++;			break;		case '?':		default:			usage();			/* NOTREACHED */	    }	if (!domain || !dbfile || optind >= argc) {		usage();		/* NOTREACHED */	}	    #ifdef AUTHEN	if(netsafe) {		if(gethostname(localhost, MAXDNAME)) {			if (!quiet)			    syslog(LOG_ERR, "bad gethostname call\n");			exit(XFER_FAIL);		}		if((temp_ent = gethostbyname_local(localhost)) < 0)		{			if (!quiet)			    syslog(LOG_ERR, "bad gethostbyname call %s\n",				localhost);			exit(XFER_FAIL);		}		if((p_char = index(localhost, '.')) != (char *)0)			*p_char = '\0';		strcpy(tkt_filename, "/var/dss/kerberos/tkt/tkt.xfer.XXXXXX");		if (mktemp(tkt_filename) == (char *)NULL) {			perror(tkt_filename);			if (!quiet)				syslog(LOG_ERR,"can't make tkt tmpfile\n");			exit(XFER_FAIL);		}		if((result = krb_svc_init("named", localhost, NULL, 0, NULL,				tkt_filename)) != RET_OK) {			if (!quiet)			    syslog(LOG_ERR, "bad krb_svc_int call %d\n", result);			exit(XFER_FAIL);		}				}#endif AUTHEN	if (tracefile && (fp = fopen(tracefile, "w")) == NULL)		perror(tracefile);	(void) strcat(tmpname, ".XXXXXX");	/* tmpname is now something like "/etc/named/named.bu.db.XXXXXX" */	if ((dbfd = mkstemp(tmpname)) == -1) {		perror(tmpname);		if (!quiet)			syslog(LOG_ERR, "can't make tmpfile (%s): %m\n",			    tmpname);		exit(XFER_FAIL);	}	if (fchmod(dbfd, 0644) == -1) {		perror(tmpname);		if (!quiet)			syslog(LOG_ERR, "can't fchmod tmpfile (%s): %m\n",			    tmpname);		exit(XFER_FAIL);	}	if ((dbfp = fdopen(dbfd, "r+")) == NULL) {		perror(tmpname);		if (!quiet)			syslog(LOG_ERR, "can't fdopen tmpfile (%s)", tmpname);		exit(XFER_FAIL);	}#ifdef DEBUG	if (debug) {		/* ddtfile is now something like "/usr/tmp/xfer.ddt.XXXXXX" */		if ((ddtd = mkstemp(ddtfile)) == -1) {			perror(ddtfile);			debug = 0;		} else if (fchmod(ddtd, 0644) == -1) {			perror(ddtfile);			debug = 0;		} else if ((ddt = fdopen(ddtd, "w")) == NULL) {			perror(ddtfile);			debug = 0;		} else {			setlinebuf(ddt);		}	}#endif	/*	 * Ignore many types of signals that named (assumed to be our parent)	 * considers important- if not, the user controlling named with	 * signals usually kills us.	 */	(void) signal(SIGHUP, SIG_IGN);	(void) signal(SIGSYS, SIG_IGN);	if (debug == 0) {		(void) signal(SIGINT, SIG_IGN);		(void) signal(SIGQUIT, SIG_IGN);	}	(void) signal(SIGIOT, SIG_IGN);#if defined(SIGUSR1) && defined(SIGUSR2)	(void) signal(SIGUSR1, SIG_IGN);	(void) signal(SIGUSR2, SIG_IGN);#else	SIGUSR1&&SIGUSR2	(void) signal(SIGEMT, SIG_IGN);	(void) signal(SIGFPE, SIG_IGN);#endif SIGUSR1&&SIGUSR2#ifdef ULTRIXFUNC	(void) signal(SIGTRAP, SIG_IGN);	(void) signal(SIGXFSZ, SIG_IGN);#endif ULTRIXFUNC#ifdef DEBUG	if (debug) (void)fprintf(ddt, "domain `%s' file `%s' ser no %lu \n", 	      domain, dbfile,serial_no);#endif	buildservicelist();	buildprotolist();	/* init zone data */ 	zp = &zones;	zp->z_type = Z_SECONDARY;	zp->z_origin = domain;	zp->z_source = dbfile;	zp->z_addrcnt = 0;	zp->z_class = C_ANY;#ifdef DEBUG	if (debug) {		(void)fprintf(ddt,"zone found (%d): ", zp->z_type);		if (zp->z_origin[0] == '\0')			(void)fprintf(ddt,"'.'");		else			(void)fprintf(ddt,"'%s'", zp->z_origin);		(void)fprintf(ddt,", source = %s\n", zp->z_source);	}#endif	for (; optind != argc; optind++,zp->z_addrcnt++) {		tm = argv[optind];		zp->z_addr[zp->z_addrcnt].s_addr = inet_addr(tm); 		if (zp->z_addr[zp->z_addrcnt].s_addr == (unsigned)-1) {			hp = gethostbyname_local(tm);			if (hp == NULL) {				syslog(LOG_ERR,"uninterpretable server name %s\n",					tm);				continue;			}			bcopy(hp->h_addr,			    (char *)&zp->z_addr[zp->z_addrcnt].s_addr,			    sizeof(zp->z_addr[zp->z_addrcnt].s_addr));#ifdef DEBUG			if (debug)				(void)fprintf(ddt,", %s",tm);#endif					}#ifdef AUTHEN		else {			if((hp = gethostbyaddr_local(			    &(zp->z_addr[zp->z_addrcnt].s_addr),			    sizeof(struct in_addr), AF_INET)) ==			    (struct hostent *)NULL) {				syslog(LOG_ERR,"uninterpretable server addr %s\n",					tm);				continue;			}		}		strcpy(zp->z_dname[zp->z_addrcnt], hp->h_name);#endif AUTHEN		if (zp->z_addrcnt >= NSMAX) {			zp->z_addrcnt = NSMAX;#ifdef DEBUG			if (debug)			    (void)fprintf(ddt, "\nns.h NSMAX reached\n");#endif			break;		}	}#ifdef DEBUG	if (debug) (void)fprintf(ddt," (addrcnt) = %d\n", zp->z_addrcnt);#endif	_res.options &= ~(RES_DEFNAMES | RES_DNSRCH | RES_RECURSE);	result = getzone(zp, serial_no, port);	(void) fclose(dbfp);	if(netsafe)		unlink(tkt_filename);	switch (result) {	case XFER_SUCCESS:			/* ok exit */		if (rename(tmpname, dbfile) == -1) {			perror("rename");			if (!quiet)			    syslog(LOG_ERR, "rename %s to %s: %m",				tmpname, dbfile);			exit(XFER_FAIL);		}		exit(XFER_SUCCESS);	case XFER_UPTODATE:		/* the zone was already uptodate */		(void) unlink(tmpname);		exit(XFER_UPTODATE);	case XFER_TIMEOUT:#ifdef DEBUG		if (!debug)#endif		    (void) unlink(tmpname);		exit(XFER_TIMEOUT);		/* servers not reachable exit */	case XFER_FAIL:	default:#ifdef DEBUG		if (!debug)#endif		    (void) unlink(tmpname);		exit(XFER_FAIL);		/* yuck exit */	}} usage(){	(void)fprintf(stderr,"Usage: xfer\n\\t-z zone_to_transfer\n\\t-f db_file\n\\t-s serial_no\n\\t[-d debug_level]\n\\t[-l debug_log_file (default %s)]\n\\t[-t trace_file]\n\\t[-p port]\n\\t[-n]\n\\t[-a auth_type.auth_ver]\n\\tservers...\n", ddtfile);	exit(XFER_FAIL);}int	minimum_ttl = 0, got_soa = 0;char	prev_origin[MAXDNAME];char	prev_dname[MAXDNAME];getzone(zp, serial_no, port)	struct zoneinfo *zp;	u_long serial_no;	u_short port;{	HEADER *hp;	u_short len;	u_long serial;	int s, n, l, cnt, soacnt, error = 0; 	u_char *cp, *nmp, *eom, *tmp ;	u_char *buf = NULL;	int bufsize;	u_char name[MAXDNAME], name2[MAXDNAME];	struct sockaddr_in sin;	struct zoneinfo zp_start, zp_finish;	struct itimerval ival, zeroival;	extern void read_alarm();	struct sigvec sv, osv;	int ancount, aucount;#ifdef AUTHEN       	u_char	*authen_tmp;	int 	authen_len;	int	authen;	CREDENTIALS cred;	u_char *namptr;	int authen_answtype;	int authen_answclass;	char *krbnameptr;#endif AUTHEN#ifdef DEBUG	if (debug)		(void)fprintf(ddt,"getzone() %s\n", zp->z_origin);#endif	bzero((char *)&zeroival, sizeof(zeroival));	ival = zeroival;	ival.it_value.tv_sec = 120;	sv.sv_handler = read_alarm;	sv.sv_onstack = 0;	sv.sv_mask = ~0;	(void) sigvec(SIGALRM, &sv, &osv);	strcpy(prev_origin, zp->z_origin);	for (cnt = 0; cnt < zp->z_addrcnt; cnt++) {		error = 0;		if (buf == NULL) {			if ((buf = (u_char *)malloc(2 * PACKETSZ)) == NULL) {				syslog(LOG_ERR, "malloc(%u) failed",				    2 * PACKETSZ);				error++;				break;			}			bufsize = 2 * PACKETSZ;		}		bzero((char *)&sin, sizeof(sin));		sin.sin_family = AF_INET;		sin.sin_port = port;		sin.sin_addr = zp->z_addr[cnt];		if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {			syslog(LOG_ERR, "socket: %m");			error++;			break;		}	#ifdef DEBUG		if (debug >= 2) {			(void)fprintf(ddt,"connecting to server #%d %s, %d\n",			   cnt+1, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));		}#endif#ifdef ULTRIXFUNC		if (icmp_ping(&sin.sin_addr)) {			(void) close(s);			error++;				#ifdef DEBUG			if (debug)				(void)fprintf(ddt,"icmp_ping failed\n");#endif			continue;		}#endif ULTRIXFUNC		if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {			(void) close(s);			error++;#ifdef DEBUG			if (debug)				(void)fprintf(ddt, "connect failed, errno %d\n",				errno);#endif			continue;		}	#ifdef AUTHEN		if(netsafe && defauthentype == AUTH_KRB && defauthenver==ONE) {			if ((n = res_mkquery(AQUERY, zp->z_origin, zp->z_class,			    T_SOA, (char *)NULL, 0, NULL, buf, bufsize)) < 0) {				if (!quiet)				    syslog(LOG_ERR,					"zone %s: res_mkquery T_SOA failed",					zp->z_origin);				(void) close(s);				(void) sigvec(SIGALRM, &osv, (struct sigvec *)0);				return XFER_FAIL;			}			krbnameptr = res_dotname_head(zp->z_dname[cnt]);			if((authen_len = res_mkl_krbcred(ONE,							 "named",							 krbnameptr,							 &cred, buf, buf + n,							 bufsize - n,							 zp->z_origin, T_SOA,							 zp->z_class))			   < RET_OK) {				if (!quiet)				    syslog(LOG_ERR,				       "zoneref: res_mkl_krbcred T_SOA failed");				free(krbnameptr);				(void) close(s);				(void) sigvec(SIGALRM, &osv, (struct sigvec *)0);				return XFER_FAIL;			}			free(krbnameptr);			n += authen_len;					} else if (netsafe){			if (!quiet)				syslog(LOG_ERR, "%s:",				    "bad default auth type in zoneref T_SOA");				(void) close(s);				(void) sigvec(SIGALRM, &osv, (struct sigvec *)0);			return XFER_FAIL;		} else {			if ((n = res_mkquery(QUERY, zp->z_origin, zp->z_class,			    T_SOA, (char *)NULL, 0, NULL, buf, bufsize)) < 0) {				if (!quiet)				    syslog(LOG_ERR,					"zone %s: res_mkquery T_SOA failed",					zp->z_origin);				(void) close(s);				(void) sigvec(SIGALRM, &osv, (struct sigvec *)0);

⌨️ 快捷键说明

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