From aa4a3737cab739569d421ba5aa5a8b515a854e84 Mon Sep 17 00:00:00 2001 From: CSRG Date: Mon, 26 Apr 1993 08:06:27 -0800 Subject: [PATCH] BSD 4_4_Lite2 development Work on file usr/src/contrib/bind-4.9.2/contrib/misc/updatedns.shar Synthesized-from: CSRG/cd3/4.4BSD-Lite2 --- .../bind-4.9.2/contrib/misc/updatedns.shar | 717 ++++++++++++++++++ 1 file changed, 717 insertions(+) create mode 100644 usr/src/contrib/bind-4.9.2/contrib/misc/updatedns.shar diff --git a/usr/src/contrib/bind-4.9.2/contrib/misc/updatedns.shar b/usr/src/contrib/bind-4.9.2/contrib/misc/updatedns.shar new file mode 100644 index 0000000000..1995d24318 --- /dev/null +++ b/usr/src/contrib/bind-4.9.2/contrib/misc/updatedns.shar @@ -0,0 +1,717 @@ +#From: gdmr@dcs.ed.ac.uk +#Date: Mon, 26 Apr 93 11:03:57 BST +#Message-Id: <5447.9304261003@bruray.dcs.ed.ac.uk> +#To: Paul A Vixie +#Subject: Re: send me your tools +# +#In article <9304251928.AA09770@cognition.pa.dec.com>, you write: +#> ... if you have something which converts to/from /etc/hosts to/from +#> hosts.txt to/from zone files ... +# +#Here (appended) is my /etc/hosts-to-zonefiles converter. There were a couple +#of reasons I wrote it (apart from /etc/hosts format being well understood by +#our system support people): +# +# it only generates stuff for configured-in networks (which doesn't +# actually matter to us now, but did at the time I wrote it); and +# +# it does something reasonable for multi-homed hosts +# +#There's some documentation at the top of the source file, and an example +#configuration file (which happens to be a copy of our working one). +#-- +#George D M Ross, Department of Computer Science, University of Edinburgh +# Kings Buildings, Mayfield Road, Edinburgh, Scotland, EH9 3JZ +#Mail: gdmr@dcs.ed.ac.uk Voice: 031-650 5147 Fax: 031-667 7209 + +#! /bin/sh +# This is a shell archive. Remove anything before this line, then unpack +# it by saving it into a file and typing "sh file". To overwrite existing +# files, type "sh file -c". You can also feed this as standard input via +# unshar, or by typing "sh Configure-example <<'END_OF_Configure-example' +X# makeDNS configuration file for cs & cs1 +X# +X# domains -- format is +X#"0.0.0.0" domain zone-file headers-file "other"-zone-file MX-file +X0.0.0.0 dcs.ed.ac.uk New/zone.cs Headers/cs New/zone.cs.L +X +X# wires -- format is +X# subnet mask zone-file reverse-headers-file domain +X129.215.36.0 255.255.255.0 /dev/null /dev/null dcs.ed.ac.uk +X129.215.56.0 255.255.255.0 /dev/null /dev/null dcs.ed.ac.uk +X# +X129.215.160.0 255.255.255.0 New/zone.160 Headers/reverse dcs.ed.ac.uk +X129.215.64.0 255.255.255.0 New/zone.64 Headers/reverse dcs.ed.ac.uk +X129.215.32.0 255.255.255.0 New/zone.32 Headers/reverse dcs.ed.ac.uk +X129.215.96.0 255.255.255.0 New/zone.96 Headers/reverse dcs.ed.ac.uk +X129.215.224.0 255.255.255.0 New/zone.224 Headers/reverse dcs.ed.ac.uk +X129.215.216.0 255.255.255.0 New/zone.216 Headers/reverse dcs.ed.ac.uk +X129.215.212.0 255.255.255.0 New/zone.212 Headers/reverse dcs.ed.ac.uk +X129.215.124.0 255.255.255.0 New/zone.124 Headers/reverse dcs.ed.ac.uk +X129.215.252.0 255.255.255.0 New/zone.252 Headers/reverse dcs.ed.ac.uk +X129.215.2.0 255.255.255.0 New/zone.2 Headers/reverse dcs.ed.ac.uk +X129.215.18.0 255.255.255.0 New/zone.18 Headers/reverse dcs.ed.ac.uk +X129.215.74.0 255.255.255.0 New/zone.74 Headers/reverse dcs.ed.ac.uk +X129.215.202.0 255.255.255.0 New/zone.202 Headers/reverse dcs.ed.ac.uk +X129.215.42.0 255.255.255.0 New/zone.42 Headers/reverse dcs.ed.ac.uk +X129.215.90.0 255.255.255.0 New/zone.90 Headers/reverse dcs.ed.ac.uk +X129.215.218.0 255.255.255.0 New/zone.218 Headers/reverse dcs.ed.ac.uk +X129.215.58.0 255.255.255.0 New/zone.58 Headers/reverse dcs.ed.ac.uk +X129.215.186.0 255.255.255.0 New/zone.186 Headers/reverse dcs.ed.ac.uk +X# +X192.41.110.0 255.255.255.0 New/zone.41.110 Headers/reverse dcs.ed.ac.uk +X192.41.131.0 255.255.255.0 New/zone.41.131 Headers/reverse dcs.ed.ac.uk +END_OF_Configure-example +if test 1831 -ne `wc -c Makefile <<'END_OF_Makefile' +Xall: makeDNS makeHS +X +XmakeDNS: makeDNS.c +X cc -O -o makeDNS makeDNS.c +X strip makeDNS +X +XmakeHS: makeHS.c +X cc -O -o makeHS makeHS.c +X strip makeHS +END_OF_Makefile +if test 141 -ne `wc -c makeDNS.c <<'END_OF_makeDNS.c' +X/* makeDNS.c -- generate DNS RRs from /etc/hosts +X * Copyright (c) 1991, 1992 Department of Computer Science, University of +X * Edinburgh. Non-commercial use and redistribution is permitted provided this +X * notice remains intact and any modifications are flagged. +X * +X * This software is offered "as is", with no warranty or support whatsoever. +X * Please send comments to gdmr@dcs.ed.ac.uk. +X */ +X +X/* Generate a set of DNS RR files from /etc/hosts and some configuration +X * files, under a reasonable set of assumptions. The program expects to +X * be running in the target directory. It reads the file ".configure" in +X * that directory. The file consists of a sequence of "wire" records, one +X * per line, each one listing the network number, netmask, RR file, header +X * file and full domain name for all hosts on that wire. Alternatively, +X * a "domain" record consists of 0.0.0.0 as network number, domain, RR file +X * and header file. +X * +X * The /etc/hosts file is read in, and hosts are added to a 2-way linked list, +X * sorted alphabetically by host name (ordering in the DNS doesn't matter, +X * and this sorting allows the program's assumptions to be implemented). +X * Primary names are held with their corresponding IP address, while aliases +X * have the name of the corresponding primary. +X * +X * Once the hosts file has been read in, the output files are opened and +X * the constant header information is written (with the sequence number +X * properly updated). The hosts list is then scanned in ascending order +X * and the corresponding entries written according to the following +X * heuristics: if a host name has as its leading component one of the +X * preceding hosts then it is assumed to be a second interface on a +X * multi-homed host, and an additional A record is written; and the domain +X * of a host is taken to be that of its first A record, as defined in the +X * corresponding "wire" entry. Finally the program exits with a zero status. +X * +X * Should any errors occur, the program will exit with a non-zero status. +X */ +X +X#define HOSTS "/etc/hosts" +X#define CONFIG "Configure" +X#define LOG "Log" +X#define MAXWIRE 63 +X#define MAXDOMAIN 5 +X#define LINEBUFFER 120 +X +X#include +X#include +X#include +X#include +X#include +X#include +X#include +X +Xtypedef struct _domain { +X char *domainname; +X char *RRfile; +X char *headerfile; +X char *otherZonefile; +X char *MXfile; +X FILE *file; +X FILE *other; +X char *MXdata; +X} domain; +X +Xtypedef struct _wire { +X long number; +X long netmask; +X char *RRfile; +X char *headerfile; +X char *domainname; +X FILE *file; +X domain *d; +X} wire; +X +Xtypedef struct _host { +X struct _host *forward; +X struct _host *backward; +X long IP; +X char *name; +X struct _host *primary; +X wire *w; +X} host; +X +Xstatic host *hostlist; +Xstatic wire wireTable[MAXWIRE]; +Xstatic domain domainTable[MAXDOMAIN]; +Xstatic int domains, wires; +X +Xvoid readconfig(); +Xvoid readhosts(); +Xvoid printhosts(); +Xvoid openfiles(); +Xvoid closefiles(); +X +Xmain() +X{ readconfig(); +X readhosts(); +X openfiles(); +X printhosts(); +X closefiles(); +X return 0; +X} +X +Xstatic void addhost(h) +Xhost *h; +X{ host *x; +X if (hostlist == NULL) { +X /* List empty, easy case */ +X h->forward = NULL; +X h->backward = NULL; +X hostlist = h; +X return; +X } +X x = hostlist; +X /* Skip to insertion point */ +X while (strcmp(x->name, h->name) < 0) { +X if (x->forward) { +X /* More, skip */ +X x = x->forward; +X } +X else { +X /* Add at the tail of the list */ +X h->forward = NULL; +X h->backward = x; +X x->forward = h; +X return; +X } +X } +X /* Sanity check: duplicate? */ +X if (!strcmp(x->name, h->name)) { +X (void) fprintf(stderr, "%s duplicate!\n", h->name); +X return; +X } +X /* Insert before x */ +X h->forward = x; +X h->backward = x->backward; +X if (x->backward) x->backward->forward = h; /* Middle */ +X else hostlist = h; /* Head */ +X x->backward = h; +X} +X +Xstatic long IPconvert(ch) +Xchar **ch; +X{ long N1, N2, N3, N4; +X N1 = strtol(*ch, ch, 10); (*ch)++; +X N2 = strtol(*ch, ch, 10); (*ch)++; +X N3 = strtol(*ch, ch, 10); (*ch)++; +X N4 = strtol(*ch, ch, 10); (*ch)++; +X return (N1 << 24) | (N2 << 16) | (N3 << 8) | N4; +X} +X +Xstatic char *extractname(ch) +Xchar **ch; +X{ char *it; +X char *name; +X int n = 0; +X while (isspace(**ch)) (*ch)++; +X if (**ch == '\0' || **ch == '#') return NULL; +X it = *ch; +X while (!isspace(**ch)) { +X (*ch)++; +X n++; +X } +X **ch = '\0'; (*ch)++; +X name = (char *) malloc(n + 1); +X strcpy(name, it); +X return name; +X} +X +Xstatic wire *findWire(IP) +Xlong IP; +X{ int n; +X wire *w; +X if (IP == 0) return NULL; +X for (n = 0, w = wireTable; n < wires; n++, w++) { +X if ((IP & w->netmask) == w->number) { +X return w; +X } +X } +X return NULL; +X} +X +Xstatic domain *findDomain(name) +Xchar *name; +X{ int n; +X domain *d; +X for (n = 0, d = domainTable; n < domains; n++, d++) { +X if (!strcmp(name, d->domainname)) { +X return d; +X } +X } +X return NULL; +X} +X +Xstatic void readhosts() +X{ FILE *hosts; +X host *h, *ph; +X char *ch; +X char buffer[LINEBUFFER]; +X long IP; +X char *primary; +X char *alias; +X wire *w; +X +X if ((hosts = fopen(HOSTS, "r")) == NULL) { +X (void) fprintf(stderr, "Failed to open %s\n", HOSTS); +X exit(1); +X } +X +X for (;;) { +X if ((ch = fgets(buffer, LINEBUFFER, hosts)) == NULL) break; +X while (isspace(*ch)) ch++; +X if (*ch == '\0' || *ch == '#') continue; +X IP = IPconvert(&ch); +X if ((w = findWire(IP)) == NULL) continue; +X primary = extractname(&ch); +X ph = (host *) malloc(sizeof(host)); +X ph->IP = IP; +X ph->w = w; +X ph->name = primary; +X ph->primary = NULL; +X addhost(ph); +X while (*ch != '\0') { +X alias = extractname(&ch); +X if (alias == NULL) break; +X h = (host *) malloc(sizeof(host)); +X h->IP = 0; +X h->w = w; +X h->name = alias; +X h->primary = ph; +X addhost(h); +X } +X } +X (void) fclose(hosts); +X} +X +Xstatic host *findPrincipal(like) +Xhost *like; +X{ host *h; +X int l, n; +X +X h = like->backward; +X l = strlen(like->name); +X while (h) { +X if (*(h->name) != *(like->name)) return NULL; +X n = strlen(h->name); +X if ((n < l) && !isalnum(like->name[n]) && +X !strncmp(h->name, like->name, n)) { +X return h; +X } +X h = h->backward; +X } +X return NULL; +X} +X +X#define printIP(file, IP) \ +X (void) fprintf(file, "%d.%d.%d.%d", \ +X (IP >> 24) & 255, (IP >> 16) & 255, (IP >> 8) & 255, IP & 255) +X +X/* printhosts has four cases: +X * 1 IP address, no principal entry -- write the name as it stands, plus +X * the reverse name, again as it stands. +X * 2 IP address plus principal entry -- write out the address as for the +X * principal entry, plus the current name as another A RR. Write the +X * reverse entry as pointing to the principal name. +X * 3 alias, no principal entry -- write a CNAME RR pointing to the primary. +X * 4 alias plus principal entry -- write an A RR with the primary's address. +X * +X * For example, suppose the /etc/hosts file has the following: +X * 129.215.64.48 baleshare baleshare-b agfahost +X * 29.215.160.155 baleshare-gw baleshare-a +X * Then baleshare is case 1, baleshare-gw is case 2, baleshare-a and +X * baleshare-b are case 4, and agfahost is case 3. Confused? BTW, changing +X * baleshare-gw to fred, say, would break the algorithm -- the main name of the +X * second interface better be related to the main name of the first! +X */ +X +Xvoid printhosts() +X{ host *h, *m, *x; +X wire *w; +X FILE *f; +X int dotted; +X +X h = hostlist; +X while (h) { +X m = findPrincipal(h); +X if (h->IP) { +X if (m) { +X /* Case 2 */ +X /* A RR for name */ +X (void) fprintf(m->w->d->file, +X "%-23s IN\tA\t", h->name); +X printIP(m->w->d->file, h->IP); +X (void) putc('\n', m->w->d->file); +X if (m->w->d->MXdata) { +X (void) fputs(m->w->d->MXdata, +X m->w->d->file); +X } +X /* A RR for principal's name */ +X (void) fprintf(m->w->d->file, +X "%-23s IN\tA\t", m->name); +X printIP(m->w->d->file, h->IP); +X (void) putc('\n', m->w->d->file); +X /* back-pointer -> principal */ +X (void) fprintf(h->w->file, +X "%d\tIN\tPTR\t%s.%s.\n", +X h->IP & (~h->w->netmask), +X m->name, m->w->d->domainname); +X if (m->w->d->other) { +X (void) fprintf(m->w->d->other, +X "%-23s IN\tCNAME\t%s.%s.\n", +X h->name, m->name, +X m->w->d->domainname); +X } +X } +X else { +X /* Case 1 */ +X dotted = (int) index(h->name, '.'); +X if (!dotted) { +X (void) fprintf(h->w->d->file, +X "%-23s IN\tA\t", h->name); +X printIP(h->w->d->file, h->IP); +X (void) putc('\n', h->w->d->file); +X if (h->w->d->MXdata) { +X (void) fputs(h->w->d->MXdata, +X h->w->d->file); +X } +X if (h->w->d->other) { +X (void) fprintf(h->w->d->other, +X "%-23s IN\tCNAME\t%s.%s.\n", +X h->name, h->name, +X h->w->d->domainname); +X } +X } +X (void) fprintf(h->w->file, +X dotted ? "%d\tIN\tPTR\t%s\n" +X : "%d\tIN\tPTR\t%s.%s.\n", +X h->IP & (~h->w->netmask), +X h->name, h->w->d->domainname); +X } +X } +X else { +X if (m) { +X /* Case 4 */ +X (void) fprintf(m->w->d->file, +X "%-23s IN\tA\t", h->name); +X printIP(m->w->d->file, h->primary->IP); +X (void) putc('\n', m->w->d->file); +X if (m->w->d->MXdata) { +X (void) fputs(m->w->d->MXdata, +X m->w->d->file); +X } +X if (m->w->d->other) { +X (void) fprintf(m->w->d->other, +X "%-23s IN\tCNAME\t%s.%s.\n", +X h->name, m->name, +X m->w->d->domainname); +X } +X } +X else { +X /* Case 3 */ +X x = findPrincipal(h->primary); +X if (!x) x = h->primary; +X (void) fprintf(x->w->d->file, +X "%-23s IN\tCNAME\t%s.%s.\n", +X h->name, x->name, +X x->w->d->domainname); +X if (x->w->d->other) { +X (void) fprintf(x->w->d->other, +X "%-23s IN\tCNAME\t%s.%s.\n", +X h->name, x->name, +X x->w->d->domainname); +X } +X } +X } +X h = h->forward; +X } +X} +X +Xstatic void readconfig() +X{ FILE *config; +X long IP; +X char *ch; +X char buffer[LINEBUFFER]; +X wire *w; +X domain *d; +X +X if ((config = fopen(CONFIG, "r")) == NULL) { +X (void) fprintf(stderr, "Failed to open %s\n", CONFIG); +X exit(1); +X } +X for (;;) { +X if ((ch = fgets(buffer, LINEBUFFER, config)) == NULL) break; +X while (isspace(*ch)) ch++; +X if (*ch == '\0' || *ch == '#') continue; +X IP = IPconvert(&ch); +X if (IP) { +X /* Wire record */ +X w = wireTable + wires++; +X w->number = IP; +X w->netmask = IPconvert(&ch); +X w->RRfile = extractname(&ch); +X w->headerfile = extractname(&ch); +X w->domainname = extractname(&ch); +X w->file = stderr; /* meantime */ +X w->d = findDomain(w->domainname); +X if (!w->d) { +X (void) fprintf(stderr, "Undefined domain %s:\n", +X w->domainname); +X (void) fputs(buffer, stderr); +X (void) fputc('\n', stderr); +X exit(2); +X } +X } +X else { +X /* Domain record */ +X d = domainTable + domains++; +X d->domainname = extractname(&ch); +X d->RRfile = extractname(&ch); +X d->headerfile = extractname(&ch); +X d->otherZonefile = extractname(&ch); +X d->MXfile = extractname(&ch); +X d->file = stderr; /* meantime */ +X d->other = NULL; +X d->MXdata = NULL; +X } +X } +X (void) fclose(config); +X} +X +Xstatic void writeheader(f, h, MXdata) +XFILE *f; +Xchar *h; +Xchar *MXdata; +X{ static struct passwd *pwd; +X time_t tt; +X static struct tm *ttm; +X static char *t; +X static char stamp[20]; +X FILE *hf, *l; +X char buffer[LINEBUFFER]; +X +X if (!pwd) { +X pwd = getpwuid(getuid()); +X endpwent(); +X tt = time(NULL); +X ttm = localtime(&tt); +X (void) sprintf(stamp, "%d%3.3d%3.3d", +X ttm->tm_year, ttm->tm_yday, +X ((60 * ttm->tm_hour) + ttm->tm_min) >> 1); +X t = asctime(ttm); +X if (l = fopen(LOG, "a")) { +X fprintf(l, "Generated by %s on %s", pwd->pw_name, t); +X fclose(l); +X } +X } +X (void) fprintf(f, ";; Generated by %s on %s\n", pwd->pw_name, t); +X if ((hf = fopen(h, "r")) == NULL) { +X (void) fprintf(stderr, "Can't open header file %s\n", h); +X exit(4); +X } +X (void) fprintf(f, ";; Including %s\n", h); +X for (;;) { +X if (fgets(buffer, LINEBUFFER, hf) == NULL) break; +X (void) fprintf(f, buffer, stamp); +X } +X (void) fclose(hf); +X (void) fprintf(f, ";; End of %s\n\n", h); +X if (MXdata) { +X (void) fputc('@', f); +X (void) fputs(MXdata, f); +X (void) fputc('\n', f); +X } +X} +X +Xstatic void openfiles() +X{ int i; +X int MXfd; +X int MXsize; +X wire *w; +X domain *d; +X +X for (i = 0, d = domainTable; i < domains; i++, d++) { +X if ((d->file = fopen(d->RRfile, "w")) == NULL) { +X (void) fprintf(stderr, "Can't open %s\n", d->RRfile); +X exit(3); +X } +X if (d->otherZonefile) { +X if ((d->other = fopen(d->otherZonefile, "w")) == NULL) { +X (void) fprintf(stderr, "Can't open %s\n", +X d->otherZonefile); +X exit(3); +X } +X } +X if (d->MXfile) { +X if ((MXfd = open(d->MXfile, O_RDONLY, 0)) < 0) { +X (void) fprintf(stderr, "Can't open %s\n", +X d->MXfile); +X exit(3); +X } +X d->MXdata = (char *) malloc(2048); +X if ((MXsize = read(MXfd, d->MXdata, 2048)) < 0) { +X (void) fprintf(stderr, +X "Couldn't read from %s\n", +X d->MXfile); +X exit(3); +X } +X (void) close(MXfd); +X *(d->MXdata + MXsize) = '\0'; +X } +X writeheader(d->file, d->headerfile, d->MXdata); +X if (d->otherZonefile) +X writeheader(d->other, d->headerfile, d->MXdata); +X } +X for (i = 0, w = wireTable; i < wires; i++, w++) { +X if ((w->file = fopen(w->RRfile, "w")) == NULL) { +X exit(3); +X } +X writeheader(w->file, w->headerfile, (char *) 0); +X } +X} +X +Xstatic void closefiles() +X{ int i; +X domain *d; +X wire *w; +X +X for (i = 0, d = domainTable; i < domains; i++, d++) { +X (void) fclose(d->file); +X if (d->other) (void) fclose(d->other); +X } +X for (i = 0, w = wireTable; i < wires; i++, w++) { +X (void) fclose(w->file); +X } +X} +END_OF_makeDNS.c +if test 13157 -ne `wc -c makeHS.c <<'END_OF_makeHS.c' +X/* Copy stdin to stdout, substituting any %s for the current timestamp +X * (hacked out of makeDNS.c). The idea is that the HS-class header should +X * just $INCLUDE anything it needs, which will have been generated separately. +X */ +X +X#include +X#include +X#include +X#include +X +X#define LINEBUFFER 120 +X#define LOG "/dev/tty" +X +Xint main() +X{ time_t tt; +X struct tm *ttm; +X char *t; +X char stamp[20]; +X char buffer[LINEBUFFER]; +X +X tt = time(NULL); +X ttm = localtime(&tt); +X (void) sprintf(stamp, "%d%3.3d%3.3d", +X ttm->tm_year, ttm->tm_yday, +X ((60 * ttm->tm_hour) + ttm->tm_min) >> 1); +X t = asctime(ttm); +X +X (void) printf(";; Generated on %s\n", t); +X +X for (;;) { +X if (fgets(buffer, LINEBUFFER, stdin) == NULL) break; +X (void) printf(buffer, stamp); +X } +X return 0; +X} +END_OF_makeHS.c +if test 789 -ne `wc -c updateDNS <<'END_OF_updateDNS' +X#! /bin/sh +Xcd /var/named.Primary +X/usr/local/etc/makeDNS +Xecho "Update DNS database" +Xif [ $? != 0 ] ; then +X exit +Xfi +X/bin/cp New/zone.* . +Xif [ $? != 0 ] ; then +X exit +Xfi +Xecho "Reload DNS server" +Xkill -HUP `cat /etc/named.pid` +END_OF_updateDNS +if test 222 -ne `wc -c