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

📄 named-xfer.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
			    "serial %u lower than current\n",			    zp_start.z_serial));		return XFER_FAIL;	    }	}#ifdef POSIX_SIGNALS	(void) sigaction(SIGALRM, &osv, (struct sigaction *)0);#else	(void) sigvec(SIGALRM, &osv, (struct sigvec *)0);#endif	if (error)		return XFER_TIMEOUT;	return XFER_FAIL;}/* * Set flag saying to read was interrupted * used for a read timer */static SIG_FNread_alarm(){	read_interrupted = 1;} static intsoa_zinfo(zp, cp, eom)	register struct zoneinfo *zp;	register u_char *cp;	u_char *eom;{	register int n;	if (eom - cp < 3 * sizeof(u_int16_t) + sizeof(u_int32_t))		return (-1);	cp += 3 * sizeof(u_int16_t) + sizeof(u_int32_t);	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_int32_t))		return (-1);	GETLONG(zp->z_serial, cp);	GETLONG(zp->z_refresh, cp);	GETLONG(zp->z_retry, cp);	GETLONG(zp->z_expire, cp);	GETLONG(zp->z_minimum, cp);	return (0);}/* * 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. */static intprint_output(msg, msglen, rrp)	u_char *msg;	int msglen;	u_char *rrp;{	register u_char *cp;	register HEADER *hp = (HEADER *) msg;	u_int32_t addr, ttl;	int i, j, tab, result, class, type, dlen, n1, n;	u_char *cp1, data[BUFSIZ];	u_char *temp_ptr;	/* used to get ttl for RR */	char *cdata, *origin, *proto, dname[MAXDNAME];	char *ignore = "";#ifdef NO_GLUE	int lend, lenn;#endif /*NO_GLUE*/	cp = rrp;	if ((n = dn_expand(msg, msg + msglen, cp, (u_char *) dname,		    sizeof(dname))) < 0) {		hp->rcode = FORMERR;		return (-1);	}	cp += n;	GETSHORT(type, cp);	GETSHORT(class, cp);	GETLONG(ttl, cp);	GETSHORT(dlen, cp);	origin = strchr(dname, '.');	if (origin == NULL)		origin = "";	else		origin++;	/* move past the '.' */	dprintf(3, (ddt,		    "print_output: dname %s type %d class %d ttl %d\n",		    dname, type, class, ttl));	/*	 * Convert the resource record data into the internal database format.	 */	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:	case T_RP:		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_int32_t);		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_int32_t);			GETLONG(minimum_ttl, temp_ptr);			bcopy((char *) cp, (char *) cp1,			    n = 5 * sizeof(u_int32_t));			cp += n;			cp1 += n;		}		n = cp1 - data;		cp1 = data;		break;	case T_MX:	case T_AFSDB:		/* grab preference */		bcopy((char *) cp, (char *) data, sizeof(u_int16_t));		cp1 = data + sizeof(u_int16_t);		cp += sizeof(u_int16_t);		/* get name */		if ((n = dn_expand(msg, msg + msglen, cp, cp1,			    sizeof(data) - sizeof(u_int16_t))) < 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:		dprintf(3, (ddt, "unknown type %d\n", type));		return ((cp - rrp) + dlen);	}	if (n > MAXDATA) {		dprintf(1, (ddt,			    "update type %d: %d bytes is too much data\n",			    type, n));		hp->rcode = NOCHANGE;	/* XXX - FORMERR ??? */		return (-1);	}	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++;	}#ifdef NO_GLUE	/*	 * If they are trying to tell us info about something that is	 * not in the zone that we are transfering, then ignore it!	 * They don't have the authority to tell us this info.	 *	 * We have to do a bit of checking here - the name that we are	 * checking vs is fully qualified & may be in a subdomain of the	 * zone in question.  We also need to ignore any final dots.	 */ 	if (!samedomain(dname, domain)) {		(void) fprintf(dbfp, "; Ignoring info about %s, not in zone %s.\n",			dname, domain);		ignore = "; ";	}#endif /*NO_GLUE*/	/*	 * If the origin has changed, print the new origin	 */	if (strcasecmp(prev_origin, origin)) {		(void) strcpy(prev_origin, origin);		(void) fprintf(dbfp, "%s$ORIGIN %s.\n", ignore, 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 = strchr(dname, '.');		(void) strcpy(prev_dname, dname);		if (cutp)			*cutp = '\0';		if (dname[0] == 0) {			if (origin[0] == 0)				(void) fprintf(dbfp, "%s.\t", ignore);			else				(void) fprintf(dbfp, "%s.%s.\t",					ignore, origin);	/* ??? */		} else			(void) fprintf(dbfp, "%s%s\t", ignore, dname);		if (strlen(dname) < 8)			tab = 1;	} else {		(void) fprintf(dbfp, "%s\t", ignore);		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));	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, "%s\t\t%lu", ignore, 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:	case T_AFSDB:		GETSHORT(n, cp);		(void) fprintf(dbfp, "%lu", n);		(void) fprintf(dbfp, " %s.\n", cp);		break;	case T_TXT:		cp1 = cp + n;		(void) putc('"', dbfp);		while (cp < cp1) {			if (i = *cp++) {				for (j = i ; j > 0 && cp < cp1 ; j--) {					if ((*cp == '\n') || (*cp == '"')) {						(void) putc('\\', dbfp);					}					(void) putc(*cp++, dbfp);				}			}		}		(void) fputs("\"\n", dbfp);		break;	case T_UINFO:		(void) fprintf(dbfp, "\"%s\"\n", cp);		break;	case T_UID:	case T_GID:		if (n == sizeof(u_int32_t)) {			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:	case T_RP:		(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;}/*** SAMEDOMAIN -- Check whether a name belongs to a domain** ------------------------------------------------------****	Returns:**		TRUE if the given name lies in the domain.**		FALSE otherwise.****	Trailing dots are first removed from name and domain.**	Always compare complete subdomains, not only whether the**	domain name is the trailing string of the given name.****	"host.foobar.top" lies in "foobar.top" and in "top" and in ""**	but NOT in "bar.top"*/#define sameword(a,b) (strcasecmp(a,b) == 0)static intsamedomain(name, domain)char *name;				/* the name under consideration */char *domain;				/* the name of the domain */{	char namebuf[MAXDNAME];		/* copy of the name */	char domainbuf[MAXDNAME];	/* copy of the domain */	register int n;	register char *dot;	name = strcpy(namebuf, name);	n = strlen(name);	if (n > 0 && name[n-1] == '.')		name[n-1] = '\0';	domain = strcpy(domainbuf, domain);	n = strlen(domain);	if (n > 0 && domain[n-1] == '.')		domain[n-1] = '\0';	if (sameword(name, domain))		return(1);	if (sameword(domain, ""))		return(1);	dot = strchr(name, '.');	while (dot != NULL)	{		if (sameword(dot+1, domain))			return(1);		dot = strchr(dot+1, '.');	}	return(0);}#ifdef SHORT_FNAMES/*** This routine handles creating temporary files with mkstemp** in the presence of a 14 char filename system.  Pathconf()** does not work over NFS.*/filenamecpy(ddtfile, optarg)char *ddtfile, *optarg;{	int namelen, extra, len;	char *dirname, *filename;	/* determine the length of filename allowed */	if((dirname = strrchr(optarg, '/')) == NULL){		filename = optarg;	} else {		*dirname++ = '\0';		filename = dirname;	}	namelen = pathconf(dirname == NULL? "." : optarg, _PC_NAME_MAX);	if(namelen <= 0)		namelen = 255;  /* length could not be determined */	if(dirname != NULL)		*--dirname = '/';	/* copy a shorter name if it will be longer than allowed */	extra = (strlen(filename)+strlen(".XXXXXX")) - namelen;	if(extra > 0){		len = strlen(optarg) - extra;		(void) strncpy(ddtfile, optarg, len);		ddtfile[len] = '\0';	} else		(void) strcpy(ddtfile, optarg);}#endif /* SHORT_FNAMES */

⌨️ 快捷键说明

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