xfer.c

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

C
1,802
字号
					continue;				}				if (dn_expand(buf, buf + 512, nmp, name2, 				    sizeof(name2)) == -1)					goto badsoa;				if (strcasecmp((char *)name, (char *)name2) != 0) {#ifdef DEBUG					if (debug > 1)					    (void)fprintf(ddt,					      "extraneous SOA for %s\n",					      name2);#endif DEBUG					continue;				}				tmp -= sizeof(u_short);				if (soa_zinfo(&zp_finish, tmp, eom) == -1)					goto badsoa;#ifdef DEBUG				if (debug > 1)				    (void)fprintf(ddt,				      "SOA, serial %d\n", zp_finish.z_serial);#endif DEBUG				if (serial != zp_finish.z_serial) {					soacnt = 0;					got_soa = 0;					minimum_ttl = 0;					strcpy(prev_origin, zp->z_origin);					prev_dname[0] = 0;#ifdef DEBUG					if (debug)					    (void)fprintf(ddt,						"serial changed, restart\n");#endif DEBUG					/*					 * Flush buffer, truncate file					 * and seek to beginning to restart.					 */					fflush(dbfp);					if (ftruncate(fileno(dbfp), 0) != 0) {						if (!quiet)						    syslog(LOG_ERR,							"ftruncate %s: %m\n",							tmpname);						return(XFER_FAIL);					}					fseek(dbfp, 0L, 0);				} else					break;			}		}		(void) close(s);		if (error == 0) {			(void) sigvec(SIGALRM, &osv, (struct sigvec *)0);			return XFER_SUCCESS;		}#ifdef DEBUG		if (debug >= 2)		  (void)fprintf(ddt,"error receiving zone transfer\n");#endif	    } else {		(void) close(s);#ifdef DEBUG		if (debug)		    (void)fprintf(ddt,		      "zone up-to-date, serial %d\n", zp_start.z_serial);#endif DEBUG		return XFER_UPTODATE;	    }	}	(void) sigvec(SIGALRM, &osv, (struct sigvec *)0);	if (error)		return XFER_TIMEOUT;	return XFER_FAIL;}/* * Set flag saying to read was interrupted * used for a read timer */void read_alarm(){	extern int read_interrupted;	read_interrupted = 1;} writemsg(rfd, msg, msglen)	int rfd;	u_char *msg;	int msglen;{	struct iovec iov[2];	u_short len = htons((u_short)msglen); 	iov[0].iov_base = (caddr_t)&len;	iov[0].iov_len = sizeof(len);	iov[1].iov_base = (caddr_t)msg;	iov[1].iov_len = msglen;	if (writev(rfd, iov, 2) != sizeof(len) + msglen) {#ifdef DEBUG	    if (debug)	      (void)fprintf(ddt,"write failed %d\n", errno);#endif	    return (-1);	}	return (0);}soa_zinfo(zp, cp, eom)	register struct zoneinfo *zp;	register u_char *cp;	u_char *eom;{	register int n;#ifdef AUTHEN	u_char *ocp;	ocp = cp;#endif AUTHEN	if (eom - cp < 3 * sizeof(u_short))		return (-1);#ifdef ULTRIXFUNC	cp += sizeof(u_short);	GETSHORT(zp->z_class, cp);	cp += sizeof(u_short);#else ULTRIXFUNC	cp += 3 * sizeof(u_short);#endif ULTRIXFUNC	if (eom - cp < sizeof(u_long))		return (-1);	cp += sizeof(u_long);	if ((n = dn_skipname(cp, eom)) == -1)		return (-1);	cp += n;	if ((n = dn_skipname(cp, eom)) == -1)		return (-1);	cp += n;	if (eom - cp < 5 * sizeof(u_long))		return (-1);	GETLONG(zp->z_serial, cp);	GETLONG(zp->z_refresh, cp);	gettime(&tt);	zp->z_time = tt.tv_sec + zp->z_refresh;	GETLONG(zp->z_retry, cp);	GETLONG(zp->z_expire, cp);	GETLONG(zp->z_minimum, cp);#ifdef AUTHEN	return(cp - ocp);#endif AUTHEN}gettime(ttp)struct timeval *ttp;{	if (gettimeofday(ttp, (struct timezone *)0) < 0)		syslog(LOG_ERR, "gettimeofday failed: %m");}/* * Parse the message, determine if it should be printed, and if so, print it * in .db file form. * Does minimal error checking on the message content. */print_output(msg, msglen, rrp)	u_char *msg;	int msglen;	u_char *rrp;{	register u_char *cp;	register HEADER *hp = (HEADER *) msg;	u_long addr, ttl;	int n, i, j, tab, result, class, type, dlen, n1;	u_char *cp1, data[BUFSIZ];	u_char buf[MAXDATA], *tmpdata, *tmpbuf;	u_char *temp_ptr;	/* used to get ttl for RR */	char *cdata, *origin, *proto, dname[MAXDNAME];	extern char *inet_ntoa(), *protocolname(), *servicename();	cp = rrp;	/*	 * Read the name of RR	 */	if ((n = dn_expand(msg, msg + msglen, cp, (u_char *) dname,		    sizeof(dname))) < 0) {		hp->rcode = FORMERR;		return (-1);	}	/*	 * Read the type, class, ttl, and dlen (length of data)	 */	cp += n;	GETSHORT(type, cp);	GETSHORT(class, cp);	GETLONG(ttl, cp);	GETSHORT(dlen, cp);	origin = index(dname, '.');	if (origin == NULL)		origin = "";	else		origin++;	/* move past the '.' */#ifdef DEBUG	if (debug > 2)		(void) fprintf(ddt, "print_output: dname %s type %d class %d ttl %d\n",		    dname, type, class, ttl);#endif	/*	 * Convert the resource record data into the internal database	 * format.  Set cp1 to be pointer to data.  Set n to length of	 * data.  Set cp past the data.	 */	switch (type) {	case T_A:	case T_WKS:	case T_HINFO:	case T_UINFO:	case T_TXT:	case T_UID:	case T_GID:		cp1 = cp;		n = dlen;		cp += n;		break;	case T_CNAME:	case T_MB:	case T_MG:	case T_MR:	case T_NS:	case T_PTR:		if ((n = dn_expand(msg, msg + msglen, cp, data,			    sizeof(data))) < 0) {			hp->rcode = FORMERR;			return (-1);		}		cp += n;		cp1 = data;		n = strlen((char *) data) + 1;		break;	case T_MINFO:	case T_SOA:		if ((n = dn_expand(msg, msg + msglen, cp, data,			    sizeof(data))) < 0) {			hp->rcode = FORMERR;			return (-1);		}		cp += n;		cp1 = data + (n = strlen((char *) data) + 1);		n1 = sizeof(data) - n;		if (type == T_SOA)			n1 -= 5 * sizeof(u_long);		if ((n = dn_expand(msg, msg + msglen, cp, cp1, n1)) < 0) {			hp->rcode = FORMERR;			return (-1);		}		cp += n;		cp1 += strlen((char *) cp1) + 1;		if (type == T_SOA) {			temp_ptr = cp + 4 * sizeof(u_long);			GETLONG(minimum_ttl, temp_ptr);			bcopy((char *) cp, (char *) cp1,			    n = 5 * sizeof(u_long));			cp += n;			cp1 += n;		}		n = cp1 - data;		cp1 = data;		break;	case T_MX:		/* grab preference */		bcopy((char *) cp, (char *) data, sizeof(u_short));		cp1 = data + sizeof(u_short);		cp += sizeof(u_short);		/* get name */		if ((n = dn_expand(msg, msg + msglen, cp, cp1,			    sizeof(data) - sizeof(u_short))) < 0)			return (-1);		cp += n;		/* compute end of data */		cp1 += strlen((char *) cp1) + 1;		/* compute size of data */		n = cp1 - data;		cp1 = data;		break;	default:#ifdef DEBUG		if (debug >= 3)			(void) fprintf(ddt, "unknown type %d\n", type);#endif		return ((cp - rrp) + dlen);	}	if (n > MAXDATA) {#ifdef DEBUG		if (debug)			(void) fprintf(ddt,			    "update type %d: %d bytes is too much data\n",			    type, n);#endif		hp->rcode = NOCHANGE;	/* XXX - FORMERR ??? */		return (-1);	}	/*	 * cdata is a pointer to the data.	 */	cdata = (char *) cp1;	result = cp - rrp;	/*	 * Only print one SOA per db file	 */	if (type == T_SOA) {		if (got_soa)			return result;		else			got_soa++;	}	/*	 * If the origin has changed, print the new origin	 */	if (strcasecmp(prev_origin, origin)) {		(void) strcpy(prev_origin, origin);		(void) fprintf(dbfp, "$ORIGIN %s.\n", origin);	}	tab = 0;	if (strcasecmp(prev_dname, dname)) {		/*		 * set the prev_dname to be the current dname, then cut off all		 * characters of dname after (and including) the first '.'		 */		char *cutp = index(dname, '.');		(void) strcpy(prev_dname, dname);		if (cutp)			*cutp = NULL;		if (dname[0] == 0) {			if (origin[0] == 0)				(void) fprintf(dbfp, ".\t");			else				(void) fprintf(dbfp, ".%s.\t", origin);	/* ??? */		} else			(void) fprintf(dbfp, "%s\t", dname);		if (strlen(dname) < 8)			tab = 1;	} else {		(void) putc('\t', dbfp);		tab = 1;	}	if (ttl != 0 && ttl != minimum_ttl)		(void) fprintf(dbfp, "%d\t", (int) ttl);	else if (tab)		(void) putc('\t', dbfp);	(void) fprintf(dbfp, "%s\t%s\t", p_class(class), p_type(type));	/*	 * Set cp back to the data.	 */	cp = (u_char *) cdata;	/*	 * Print type specific data	 */	switch (type) {	case T_A:		switch (class) {		case C_IN:		case C_HS:			GETLONG(n, cp);			n = htonl(n);			(void) fprintf(dbfp, "%s",			    inet_ntoa(*(struct in_addr *) & n));			break;		}		(void) fprintf(dbfp, "\n");		break;	case T_CNAME:	case T_MB:	case T_MG:	case T_MR:	case T_PTR:		if (cp[0] == '\0')			(void) fprintf(dbfp, ".\n");		else			(void) fprintf(dbfp, "%s.\n", cp);		break;	case T_NS:		cp = (u_char *) cdata;		if (cp[0] == '\0')			(void) fprintf(dbfp, ".\t");		else			(void) fprintf(dbfp, "%s.", cp);		(void) fprintf(dbfp, "\n");		break;	case T_HINFO:		if (n = *cp++) {			(void) fprintf(dbfp, "\"%.*s\"", (int) n, cp);			cp += n;		} else			(void) fprintf(dbfp, "\"\"");		if (n = *cp++)			(void) fprintf(dbfp, " \"%.*s\"", (int) n, cp);		else			(void) fprintf(dbfp, "\"\"");		(void) putc('\n', dbfp);		break;	case T_SOA:		(void) fprintf(dbfp, "%s.", cp);		cp += strlen((char *) cp) + 1;		(void) fprintf(dbfp, " %s. (\n", cp);		cp += strlen((char *) cp) + 1;		GETLONG(n, cp);		(void) fprintf(dbfp, "\t\t%lu", n);		GETLONG(n, cp);		(void) fprintf(dbfp, " %lu", n);		GETLONG(n, cp);		(void) fprintf(dbfp, " %lu", n);		GETLONG(n, cp);		(void) fprintf(dbfp, " %lu", n);		GETLONG(n, cp);		(void) fprintf(dbfp, " %lu )\n", n);		break;	case T_MX:		GETSHORT(n, cp);		(void) fprintf(dbfp, "%lu", n);		(void) fprintf(dbfp, " %s.\n", cp);		break;	case T_UINFO:	case T_TXT:		cp1 = cp;		(void) putc('"', dbfp);		while (cp1 < cp + dlen) {			if (n = (unsigned char) *cp1++) {				for (j = n ; j > 0 ; j--) {					if (*cp1 == '\n')						(void) putc('\\', dbfp);					(void) putc(*cp1++, dbfp);				}			}		}		(void) fputs("\"\n", dbfp);		break;	case T_UID:	case T_GID:		if (n == sizeof(u_long)) {			GETLONG(n, cp);			(void) fprintf(dbfp, "%lu\n", n);		}		break;	case T_WKS:		GETLONG(addr, cp);		addr = htonl(addr);		(void) fprintf(dbfp, "%s ",		    inet_ntoa(*(struct in_addr *) & addr));		proto = protocolname(*cp);		cp += sizeof(char);		(void) fprintf(dbfp, "%s ", proto);		i = 0;		while (cp < (u_char *) cdata + n) {			j = *cp++;			do {				if (j & 0200)					(void) fprintf(dbfp, " %s",					    servicename(i, proto));				j <<= 1;			} while (++i & 07);		}		(void) fprintf(dbfp, "\n");		break;	case T_MINFO:		(void) fprintf(dbfp, "%s.", cp);		cp += strlen((char *) cp) + 1;		(void) fprintf(dbfp, " %s.\n", cp);		break;	default:		(void) fprintf(dbfp, "???\n");	}	if (ferror(dbfp)) {		syslog(LOG_ERR, "%s: %m", tmpname);		exit(XFER_FAIL);	}	return result;}/* * Make a copy of a string and return a pointer to it. */char *savestr(str)	char *str;{	char *cp;	cp = malloc((unsigned)strlen(str) + 1);	if (cp == NULL) {		syslog(LOG_ERR, "savestr: %m");		exit(XFER_FAIL);	}	(void) strcpy(cp, str);	return (cp);}#define	YES	1#define	NO	0mkstemp(as)	char	*as;{	int	fd;	return (_gettemp(as, &fd) ? fd : -1);}char *mktemp(as)	char	*as;{	return(_gettemp(as, (int *)NULL) ? as : (char *)NULL);}static_gettemp(as, doopen)	char	*as;	register int	*doopen;{	extern int	errno;	register char	*start, *trv;	struct stat	sbuf;	u_int	pid;	pid = getpid();	/* extra X's get set to 0's */	for (trv = as; *trv; ++trv);	while (*--trv == 'X') {		*trv = (pid % 10) + '0';		pid /= 10;	}	/*	 * check for write permission on target directory; if you have	 * six X's and you can't write the directory, this will run for	 * a *very* long time.	 */	for (start = ++trv; trv > as && *trv != '/'; --trv);	if (*trv == '/') {		*trv = '\0';		if (stat(as, &sbuf) || !(sbuf.st_mode & S_IFDIR))			return(NO);		*trv = '/';	}	else if (stat(".", &sbuf) == -1)		return(NO);	for (;;) {		if (doopen) {		    if ((*doopen = open(as, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)			return(YES);		    if (errno != EEXIST)			return(NO);		}		else if (stat(as, &sbuf))			return(errno == ENOENT ? YES : NO);		/* tricky little algorithm for backward compatibility */		for (trv = start;;) {			if (!*trv)				return(NO);			if (*trv == 'z')				*trv++ = 'a';			else {				if (isdigit(*trv))					*trv = 'a';				else					++*trv;				break;			}		}	}	/*NOTREACHED*/}

⌨️ 快捷键说明

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