📄 named-xfer.c
字号:
"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 + -