Changeset 709


Ignore:
Timestamp:
03/09/16 15:38:09 (9 years ago)
Author:
Kris Deugau
Message:

/trunk

Tweak addLoc() to optionally accept a suggested or required location
ID and a flag to indicate of the ID is "must choose this or fail" or
"next available after this". Update the automatic-location-ID-finder
code to start with the requested ID.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/DNSDB.pm

    r708 r709  
    37073707  my $self = shift;
    37083708  my $dbh = $self->{dbh};
    3709   my $grp = shift;
    3710   my $shdesc = shift;
    3711   my $comments = shift;
    3712   my $iplist = shift;
     3709  my %args = @_;
     3710
     3711  my $grp = $args{group};
     3712  my $shdesc = $args{desc};
     3713  my $comments = $args{comments};
     3714  my $iplist = $args{iplist};
    37133715
    37143716  # $shdesc gets set to the generated location ID if possible, but these can be de-undefined here.
     
    37163718  $iplist = '' if !$iplist;
    37173719
    3718   my $loc;
     3720  # allow requesting a specific location entry.
     3721  my $loc = $args{loc};
    37193722
    37203723  # Generate a location ID.  This is, by spec, a two-character widget.  We'll use [a-z][a-z]
    37213724  # for now;  676 locations should satisfy all but the largest of the huge networks.
    3722   # Not sure whether these are case-sensitive, or what other rules might apply - in any case
    3723   # the absolute maximum is 16K (256*256) since it's parsed by tinydns as a two-character field.
    3724 
    3725   # and just to be as clear as possible;  as per http://cr.yp.to/djbdns/tinydns-data.html:
     3725
     3726  # just to be as clear as possible;  as per http://cr.yp.to/djbdns/tinydns-data.html:
    37263727
    37273728#For versions 1.04 and above: You may include a client location on each line. The line is ignored for clients
     
    37323733#means that IP addresses starting with ipprefix are in location lo. lo is a sequence of one or two ASCII letters.
    37333734
    3734   # so locations could probably include both upper and lower case.
     3735  # this has been confirmed by experiment;  locations "lo", "Lo", and "lO" are all distinct.
    37353736
    37363737# add just after "my $origloc = $loc;":
     
    37543755  eval {
    37553756    # Get the "last" location.  Note this is the only use for loc_id, because selecting on location Does Funky Things
    3756     ($loc) = $dbh->selectrow_array("SELECT location FROM locations ORDER BY loc_id DESC LIMIT 1");
    3757     ($loc) = ($loc =~ /^(..)/) if $loc;
    3758     my $origloc = $loc;
    3759     $loc = 'aa' if !$loc;       
     3757    my ($newloc) = $dbh->selectrow_array("SELECT location FROM locations ORDER BY loc_id DESC LIMIT 1");
     3758
     3759    no warnings qw(uninitialized);
     3760
     3761    my $ecnt = $dbh->prepare("SELECT count(*) FROM locations WHERE location LIKE ?");
     3762
     3763    if ($loc) {
     3764      $ecnt->execute($loc);
     3765      if (($ecnt->fetchrow_array())[0]) {
     3766        # too bad, so sad, requested location is unavailable.
     3767##fixme:  known failure case:  caller requests a location ID that is not two characters.
     3768        die "Requested location is already defined\n" if $args{reqonly};
     3769        # fall back to autoincrement
     3770      }
     3771      $newloc = $loc;
     3772    }
     3773
     3774    # Either the requested location ID is unavailable and the caller isn't too attached
     3775    # to it, OR, the caller hasn't specified a location ID.  (The second case should be
     3776    # far more common.)  Find the "next available" location identifier.
     3777
     3778    ($newloc) = ($newloc =~ /^(..)/) if $newloc;
     3779    my $origloc = $newloc;
     3780    $newloc = 'aa' if !$newloc;
    37603781    # Make a change...
    3761     $loc++;
    37623782    # ... and keep changing if it exists
    3763     while ($dbh->selectrow_array("SELECT count(*) FROM locations WHERE location LIKE ?", undef, ($loc.'%'))) {
    3764       $loc++;
    3765       ($loc) = ($loc =~ /^(..)/);
    3766       die "too many locations in use, can't add another one\n" if $loc eq $origloc;
     3783    while ($dbh->selectrow_array("SELECT count(*) FROM locations WHERE location LIKE ?", undef, ($newloc.'%'))) {
     3784      $newloc++;
     3785      ($newloc) = ($newloc =~ /^(..)/);
     3786      die "too many locations in use, can't add another one\n" if $newloc eq $origloc;
    37673787##fixme: really need to handle this case faster somehow
    37683788#if $loc eq $origloc die "<thwap> bad admin:  all locations used, your network is too fragmented";
    37693789    }
    3770     # And now we should have a unique location.  tinydns fundamentally limits the
    3771     # number of these but there's no doc on what characters are valid.
    3772     $shdesc = $loc if !$shdesc;
     3790    # And now we should have a unique location.
     3791    $shdesc = $newloc if !$shdesc;
    37733792    $dbh->do("INSERT INTO locations (location, group_id, iplist, description, comments) VALUES (?,?,?,?,?)",
    3774         undef, ($loc, $grp, $iplist, $shdesc, $comments) );
     3793        undef, ($newloc, $grp, $iplist, $shdesc, $comments) );
    37753794    $self->_log(entry => "Added location ($shdesc, '$iplist')");
     3795    $loc = $newloc;
    37763796    $dbh->commit;
    37773797  };
  • trunk/dns.cgi

    r706 r709  
    15251525        unless ($permissions{admin} || $permissions{location_create});
    15261526
    1527     my ($code,$msg) = $dnsdb->addLoc($curgroup, $webvar{locname}, $webvar{comments}, $webvar{iplist});
     1527    my ($code,$msg) = $dnsdb->addLoc(group => $curgroup, desc => $webvar{locname},
     1528        comments => $webvar{comments}, iplist => $webvar{iplist});
    15281529
    15291530    if ($code eq 'OK' || $code eq 'WARN') {
Note: See TracChangeset for help on using the changeset viewer.