📄 import-tinydns.c
字号:
Name server for domain fqdn. tinydns-data creates 1. An NS record showing x.ns.fqdn as a name server for fqdn. 2. An A record showing ip as the IP address of x.ns.fqdn.**************************************************************************************************/static voidtinydns_amp(void){ ZONE *z; char *fqdn = field[0], *ip = field[1], *x = field[2], *ttl = field[3]; char hostname[DNS_MAXNAMELEN + 1] = "", buf[DNS_MAXNAMELEN + 1]; if (!fqdn || !strlen(fqdn)) return (void)Warnx("%s:%u: %s", filename, lineno, _("fqdn field empty")); if (!zone_ok(fqdn)) return; if (!(z = find_host_zone(fqdn, hostname))) return (void)Warnx("%s:%u: %s: %s", filename, lineno, fqdn, _("fqdn does not match any zones")); import_zone_id = z->id; /* Create NS record */ if (x && strlen(x)) { if (strchr(x, '.')) strncpy(buf, x, sizeof(buf)-1); else snprintf(buf, sizeof(buf), "%s.ns", x); if (LASTCHAR(buf) != '.') strcat(buf, "."); import_rr(hostname, "NS", buf, 0, ttl ? atol(ttl) : z->ttl); } else { strncpy(buf, "ns", sizeof(buf)-1); import_rr(hostname, "NS", buf, 0, ttl ? atol(ttl) : z->ttl); } /* Create A record if 'ip' is present */ if (ip && strlen(ip)) import_rr(buf, "A", ip, 0, ttl ? atol(ttl) : z->ttl);}/*--- tinydns_amp() -----------------------------------------------------------------------------*//************************************************************************************************** TINYDNS_EQUAL =fqdn:ip:ttl:timestamp:lo Host 'fqdn' with IP address 'ip'. Creates: 1. An A record showing 'ip' as the IP address of 'fqdn' 2. A PTR record showing 'fqdn' as the name of d.c.b.a.in-addr.arpa if 'ip' is a.b.c.d. Remember to specify name servers for some suffix of 'fqdn'; otherwise tinydns will not respond to queries about 'fqdn'. The same comment applies to other records described below. Similarly, remember to specify name servers for some suffix of d.c.b.a.in-addr.arpa, if that domain has been delegated to you. Example: =button.panic.mil:1.8.7.108 creates an A record showing 1.8.7.108 as the IP address of button.panic.mil, and a PTR record showing button.panic.mil as the name of 108.7.8.1.in-addr.arpa.**************************************************************************************************/static voidtinydns_equal(void){ ZONE *z; char *fqdn = field[0], *ip = field[1], *ttl = field[2]; char hostname[DNS_MAXNAMELEN + 1] = ""; if (!fqdn || !strlen(fqdn)) return (void)Warnx("%s:%u: %s", filename, lineno, _("fqdn field empty")); if (!zone_ok(fqdn)) return; if (!(z = find_host_zone(fqdn, hostname))) return (void)Warnx("%s:%u: %s: %s", filename, lineno, fqdn, _("fqdn does not match any zones")); import_zone_id = z->id; /* Create A record showing 'ip' as the IP address of 'fqdn' */ import_rr(fqdn, "A", ip, 0, ttl ? atol(ttl) : z->ttl); /* Create PTR record if we can find an appropriate in-addr.arpa zone */ if ((z = find_arpa_zone(ip, hostname))) { import_zone_id = z->id; import_rr(hostname, "PTR", fqdn, 0, ttl ? atol(ttl) : z->ttl); } else { char buf[DNS_MAXNAMELEN + 1], *p, *a, *b, *c, *d; strncpy(buf, ip, sizeof(buf)-1); p = buf; if (!(a = strsep(&p, ".")) || !(b = strsep(&p, ".")) || !(c = strsep(&p, ".")) || !(d = strsep(&p, "."))) return; Warnx("%s:%u: %s.%s.%s.%s.in-addr.arpa: %s", filename, lineno, d, c, b, a, _("no matching zone for PTR record")); }}/*--- tinydns_equal() ---------------------------------------------------------------------------*//************************************************************************************************** TINYDNS_AT @fqdn:ip:x:dist:ttl:timestamp:lo Mail exchanger for 'fqdn'. Creates: 1. An MX record showing x.mx.fqdn as a mail exchanger for 'fqdn' at distance 'dist' and 2. An A record showing 'ip' as the IP address of x.mx.fqdn. You may omit dist; the default distance is 0. If 'x' contains a dot then it is treated specially; see above. You may create several MX records for 'fqdn', with a different 'x' for each server. Make sure to arrange for the SMTP server on each IP address to accept mail for 'fqdn'. Example: @panic.mil:1.8.7.88:mail.panic.mil creates an MX record showing mail.panic.mil as a mail exchanger for panic.mil at distance 0, and an A record showing 1.8.7.88 as the IP address of mail.panic.mil.**************************************************************************************************/static voidtinydns_at(void){ ZONE *z; char *fqdn = field[0], *ip = field[1], *x = field[2], *dist = field[3], *ttl = field[4]; char hostname[DNS_MAXNAMELEN + 1] = "", mx[DNS_MAXNAMELEN + 1] = ""; if (!fqdn || !strlen(fqdn)) return (void)Warnx("%s:%u: %s", filename, lineno, _("fqdn field empty")); if (!zone_ok(fqdn)) return; if (!x || !strlen(x)) return (void)Warnx("%s:%u: %s", filename, lineno, _("no mail exchanger specified")); if (!(z = find_host_zone(fqdn, hostname))) return (void)Warnx("%s:%u: %s: %s", filename, lineno, fqdn, _("fqdn does not match any zones")); import_zone_id = z->id; /* Create MX record showing 'x'.mx.fqdn as MX for 'fqdn' */ if (strchr(x, '.')) strncpy(mx, x, sizeof(mx)-1); else snprintf(mx, sizeof(mx), "%s.mx.%s", x, z->origin); if (LASTCHAR(mx) != '.') strcat(mx, "."); import_rr(hostname, "MX", mx, dist ? atol(dist) : 0, ttl ? atol(ttl) : z->ttl); /* Create A record for 'mx' */ if (ip && strlen(ip)) { if (!(z = find_host_zone(mx, hostname))) return (void)Warnx("%s:%u: %s: %s", filename, lineno, fqdn, _("fqdn does not match any zones")); import_zone_id = z->id; import_rr(mx, "A", ip, 0, ttl ? atol(ttl) : z->ttl); }}/*--- tinydns_at() ------------------------------------------------------------------------------*//************************************************************************************************** TINYDNS_APOS 'fqdn:str:ttl:timestamp:lo Creates a TXT record for 'fqdn' containing the string 'str'. You may use octal \nnn codes to include arbitrary bytes inside 'str'; for example, \072 is a colon.**************************************************************************************************/static voidtinydns_apos(void){ ZONE *z; char *fqdn = field[0], *str = field[1], *ttl = field[2], *txt; char hostname[DNS_MAXNAMELEN + 1] = ""; register char *s, *d; if (!fqdn || !strlen(fqdn)) return (void)Warnx("%s:%u: %s", filename, lineno, _("fqdn field empty")); if (!zone_ok(fqdn)) return; if (!str || !strlen(str)) return (void)Warnx("%s:%u: %s", filename, lineno, _("no text data specified")); if (!(z = find_host_zone(fqdn, hostname))) return (void)Warnx("%s:%u: %s: %s", filename, lineno, fqdn, _("fqdn does not match any zones")); import_zone_id = z->id; /* Unescape octal chars */ if (!(txt = malloc(strlen(str) + 1))) Err("malloc"); for (s = str, d = txt; *s; s++) { if (s[0] == '\\' && (s[1] >= '0' && s[1] <= '7') && (s[2] >= '0' && s[2] <= '7') && (s[3] >= '0' && s[3] <= '7')) { *d++ = strtol(s + 1, NULL, 8); s += 3; } else *d++ = *s; } *d = '\0'; import_rr(hostname, "TXT", txt, 0, ttl ? atol(ttl) : z->ttl);}/*--- tinydns_apos() ----------------------------------------------------------------------------*//************************************************************************************************** TINYDNS_CARET ^fqdn:p:ttl:timestamp:lo PTR record for fqdn. tinydns-data creates a PTR record for fqdn pointing to the domain name p.**************************************************************************************************/static voidtinydns_caret(void){ ZONE *z; char *fqdn = field[0], *p = field[1], *ttl = field[2]; char hostname[DNS_MAXNAMELEN + 1] = "", ptr[DNS_MAXNAMELEN + 1] = ""; if (!fqdn || !strlen(fqdn)) return (void)Warnx("%s:%u: %s", filename, lineno, _("fqdn field empty")); if (!zone_ok(fqdn)) return; if (!p || !strlen(p)) return (void)Warnx("%s:%u: %s", filename, lineno, _("no PTR data specified")); strncpy(ptr, p, sizeof(ptr)-1); if (strchr(ptr, '.') && LASTCHAR(ptr) != '.') strcat(ptr, "."); if (!(z = find_host_zone(fqdn, hostname))) return (void)Warnx("%s:%u: %s: %s", filename, lineno, fqdn, _("fqdn does not match any zones")); import_zone_id = z->id; import_rr(hostname, "PTR", ptr, 0, ttl ? atol(ttl) : z->ttl);}/*--- tinydns_caret() ---------------------------------------------------------------------------*//************************************************************************************************** TINYDNS_C Cfqdn:p:ttl:timestamp:lo Creates a CNAME record for 'fqdn' pointing to the domain name 'p'.**************************************************************************************************/static voidtinydns_C(void){ ZONE *z; char *fqdn = field[0], *p = field[1], *ttl = field[2]; char hostname[DNS_MAXNAMELEN + 1] = "", cname[DNS_MAXNAMELEN + 1] = ""; if (!fqdn || !strlen(fqdn)) return (void)Warnx("%s:%u: %s", filename, lineno, _("fqdn field empty")); if (!zone_ok(fqdn)) return; if (!p || !strlen(p)) return (void)Warnx("%s:%u: %s", filename, lineno, _("no PTR data specified")); strncpy(cname, p, sizeof(cname)-1); if (strchr(cname, '.') && LASTCHAR(cname) != '.') strcat(cname, "."); if (!(z = find_host_zone(fqdn, hostname))) return (void)Warnx("%s:%u: %s: %s", filename, lineno, fqdn, _("fqdn does not match any zones")); import_zone_id = z->id; import_rr(hostname, "CNAME", cname, 0, ttl ? atol(ttl) : z->ttl);}/*--- tinydns_C() -------------------------------------------------------------------------------*//************************************************************************************************** TINYDNS_COLON :fqdn:n:rdata:ttl:timestamp:lo Generic record for 'fqdn'. Creates a record of type 'n' for 'fqdn' showing 'rdata'. 'n' must be an integer between 1 and 65535; it must not be 2 (NS), 5 (CNAME), 6 (SOA), 12 (PTR), 15 (MX), or 252 (AXFR). The proper format of 'rdata' depends on 'n'. You may use octal \nnn codes to include arbitrary bytes inside 'rdata'.**************************************************************************************************/static voidtinydns_colon(void){ ZONE *z; char *fqdn = field[0]; /* *n = field[1], *rdata = field[2], *ttl = field[3]; */ char hostname[DNS_MAXNAMELEN + 1] = ""; if (!fqdn || !strlen(fqdn)) return (void)Warnx("%s:%u: %s", filename, lineno, _("fqdn field empty")); if (!zone_ok(fqdn)) return; if (!(z = find_host_zone(fqdn, hostname))) return (void)Warnx("%s:%u: %s: %s", filename, lineno, fqdn, _("fqdn does not match any zones")); Warnx("%s:%u: %s: %s", filename, lineno, fqdn, _("generic record type not supported"));}/*--- tinydns_colon() ---------------------------------------------------------------------------*//************************************************************************************************** IMPORT_TINYDNS Imports a tinydns-data format file. Works in two passes: The first pass creates all SOA records, the second pass creates all RR records.**************************************************************************************************/voidimport_tinydns(char *datafile, char *import_zone){ struct stat st; FILE *fp; char buf[4096], *b; int n; /* Clear zone list */ for (n = 0; n < numZones; n++) { Free(Zones[n]->origin); if (Zones[n]->ns) Free(Zones[n]->ns); if (Zones[n]->mbox) Free(Zones[n]->mbox); Free(Zones[n]); } if (Zones) Free(Zones); Zones = NULL; numZones = 0; /* Reset globals and open input file */ lineno = 0; filename = datafile; if (import_zone) strncpy(tinydns_zone, import_zone, sizeof(tinydns_zone)-1); else tinydns_zone[0] = '\0'; if (stat(filename, &st)) return (void)Warn("%s", filename); if (!(fp = fopen(filename, "r"))) return (void)Warn("%s", filename); strftime(buf, sizeof(buf)-1, "%Y%m%d", localtime(&st.st_mtime)); default_serial = atoi(buf); /* Pass 1: Search for '.' and 'Z' lines; create SOA records */ while (fgets(buf, sizeof(buf), fp)) { lineno++; strtrim(buf); if (strlen(buf) < 2) continue; buf[0] = toupper(buf[0]); if (buf[0] == '.' || buf[0] == 'Z') tinydns_add_soa(buf); } if (!numZones) { if (import_zone) Warnx("%s: %s: %s", filename, import_zone, _("no zone data found")); else Warnx("%s: %s", filename, _("no zones found")); return; } qsort(Zones, numZones, sizeof(ZONE *), zonecmp); /* Load and/or create zones */ for (n = 0; n < numZones; n++) create_zone(Zones[n]); if (!import_zone) Notice("%s: %u %s", filename, numZones, _("zones")); /* Pass 2: Insert resource records */ rewind(fp); lineno = 0; while (fgets(buf, sizeof(buf), fp)) { lineno++; strtrim(buf); if (strlen(buf) < 2) continue; buf[0] = toupper(buf[0]); for (n = 0; n < MAX_FIELDS; n++) /* Reset fields */ field[n] = (char *)NULL; for (n = 0, b = buf + 1; n < MAX_FIELDS; n++) /* Load fields */ if (!(field[n] = strsep(&b, ":"))) break; switch (buf[0]) { case '.': tinydns_dot(); break; case '&': tinydns_amp(); break; case '=': tinydns_equal(); break; case '+': tinydns_plus(); break; case '@': tinydns_at(); break; case '#': /* Comment line */ break; case '-': /* Ignored (by tinydns-data) */ break; case '\'': tinydns_apos(); break; case '^': tinydns_caret(); break; case 'C': tinydns_C(); break; case 'Z': /* Ignored (SOA record; already processed on first pass) */ break; case ':': tinydns_colon(); break; default: Warnx("%s:%u: %s (0x%X)", filename, lineno, _("unknown line type"), buf[0]); break; } } fclose(fp); if (import_zone) Notice("%s: %s: %s", filename, import_zone, _("zone imported"));}/*--- import_tinydns() --------------------------------------------------------------------------*/#endif /* TINYDNS *//* vi:set ts=3: *//* NEED_PO */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -