Changeset 813 for trunk/bind-import


Ignore:
Timestamp:
11/24/20 17:29:20 (4 years ago)
Author:
Kris Deugau
Message:

/trunk

Sixth sampled iteration of bind-import

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/bind-import

    r812 r813  
    3131
    3232my $zname = shift @ARGV;
     33die "usage: bind-import zonename\n" if !$zname;
    3334my $rev = 'n';
    3435my $zid;
     
    6667my $curlabel = '';
    6768
     69my $i = 0;
     70
    6871while (<>) {
    6972  chomp;
    7073  next if /^\s*$/;
    71   next if /^\s*;/;
     74  next if /^\s*;/;      # comments
     75  next if /^\s*\(/;     # SOA closing.  arguably should do some more targeted voodoo when parsing the SOA details
     76
    7277  if (my ($macro,$mdetail) = (/^\s*\$(TTL|ORIGIN|INCLUDE|GENERATE)\s+(.+)/) ) {
    7378    # macro sort of thing;  $TTL and $ORIGIN most common.  $INCLUDE is a thing, expect it to be rare in live use tho
     
    96101    next;
    97102  }
     103  my $origrec = $_;
    98104  # skip stale records that have no value
    99105  next if /^ip-192-168-1(12|20)-\d+/;
     
    101107  # records must begin in the first column, no leading whitespace
    102108  my ($name) = /^([\w\@_.-]+)\s/;
     109
     110print "$i ($_)\n\t$name";
     111# foo IN A 1.2.3.4
     112#   IN A 2.3.4.5
     113# =
     114# foo.zone. IN A 1.2.3.4
     115# foo.zone. IN A 2.3.4.5
     116
     117
     118  # magic name!
     119  $name = $zname if $name eq '@';
     120
    103121  # append zone name to record name if missing AND not dot-terminated;
    104122  # this happens automagically for forward zones, but not reverse because Reasons.  (fixme?)
    105123  # suck up and deal with the error if the dot-termiated name is out of zone;  should be
    106124  # impossible with valid BIND zone file but...
    107   $name .= ".$zname" if $name !~ /$zname$/ && $zname !~ /\.$/;
    108 $name = $zname if /^\s*IN/;
    109 $name = $zname if /^\@/;
     125  if ($name !~ /\.$/) {
     126    $name .= ".$zname" if $name !~ /$zname$/;
     127  } else {
     128    warn "skipping out-of-zone record:\n\t($_)\n" if $name !~ /$zname\.$/;
     129    next;
     130  }
     131
     132  # fatal error.  if there is no previous label, we can by definition not set
     133  # the current label based on it.  this can only happen on the very first
     134  # record, following records will *ALWAYS* have a previous label
     135  if (/^\s+[A-Z]/) {
     136    die "bad first record ($_):  no previous label\n" if !$prevlabel;
     137    $name = $prevlabel;
     138  }
     139
     140last if $i > 2;
     141
    110142  s/^([\w\@_.-]+)\s+//;
     143
     144$prevlabel = $curlabel;
    111145# by convention the optional TTL leads the optional class, but they're apparently swappable.
    112146  my ($ttl) = /^(\d+)?\s/;
     
    124158    }
    125159    if ($class ne 'IN') {
    126       print "Non-Internet class records not supported, you weirdo\n";
     160      warn "Non-Internet class ($class) records not supported:\n\t$origrec\n";
    127161      next;
    128162    }
     
    133167  my ($type) = /([A-Z-]+)\s/;
    134168  if (!$reverse_typemap{$type}) {
    135     print "Unknown type $type, skipping\n  ($_)\n";
     169    warn "Unknown type $type, skipping\n\t($_)\n";
    136170    next;
    137171  }
     
    162196
    163197  if ($type eq 'SOA') {
    164 
    165   }
     198    my ($ns, $adminmail) = ($rdata =~ /([\w.]+)\s+([\w.]+)\s+\(/);
     199    die "Can't parse gibberish SOAish record: $_\n" if !$ns;
     200    $rdata =~ s/([\w.]+)\s+([\w.]+)\s+\(\s*//;
     201
     202    # There are probably more efficient ways to do this but the SOA record
     203    # format is essentially character based, not line-based.
     204    # In theory the SOA serial etc may be spread over up to 5 lines, in any combination.
     205
     206    # Parse fields from $rdata if present
     207    my @soabits;
     208    my @soafirst = split /\s+/, $rdata;
     209    while (my $f = shift @soafirst) {
     210      last if $f !~ /^\d/;
     211      push @soabits, $f;
     212    }
     213
     214    # Read more lines if we don't have enough SOA fields filled
     215    while (scalar(@soabits) < 5) {
     216      my $tmp = <>;
     217      $tmp =~ s/^\s*//;
     218      my @tmpsoa = split /\s+/, $tmp;
     219      while (my $f = shift @tmpsoa) {
     220        last if $f !~ /^\d/;
     221        push @soabits, $f; 
     222      }
     223      if (scalar(@soabits) == 5) {
     224        last;
     225      }
     226    }
     227  } # SOA
    166228
    167229  # Quotes may arguably be syntactically required, but they're not actually part of the record data
    168   if ($itype == 16) {
     230  elsif ($type eq 'TXT') {
    169231    $rdata =~ s/^"//;
    170232    $rdata =~ s/"$//;
     
    172234
    173235# temp hack for hosts file
    174 if ($type eq 'A') {
     236elsif ($type eq 'A') {
    175237#  if ($amap{$name}) {
    176238#    print "urp:  dupe name $name $rdata\n";
     
    180242  push @{$namemap{$rdata}}, $name;
    181243}
    182 if ($type eq 'CNAME') {
     244elsif ($type eq 'CNAME') {
    183245  push @{$cmap{$rdata}}, $name;
    184246}
     
    198260    print "$code: $msg\n";
    199261  }
     262  $i++;
    200263}
    201264
Note: See TracChangeset for help on using the changeset viewer.