Index: /trunk/DNSDB.pm
===================================================================
--- /trunk/DNSDB.pm	(revision 427)
+++ /trunk/DNSDB.pm	(revision 428)
@@ -3074,4 +3074,8 @@
 
 ## DNSDB::updateLoc()
+# Update details of a location.
+# Takes a database handle, location ID, group ID, short description,
+# long comments/notes, and comma/space-separated IP list
+# Returns a result code and message
 sub updateLoc {
   my $dbh = shift;
@@ -3116,8 +3120,44 @@
 
 ## DNSDB::delLoc()
-sub delLoc {}
+sub delLoc {
+  my $dbh = shift;
+  my $loc = shift;
+
+  # Allow transactions, and raise an exception on errors so we can catch it later.
+  # Use local to make sure these get "reset" properly on exiting this block
+  local $dbh->{AutoCommit} = 0;
+  local $dbh->{RaiseError} = 1;
+
+  my $oldloc = getLoc($dbh, $loc);
+  my $olddesc = ($oldloc->{description} ? $oldloc->{description} : $loc);
+  my $okmsg = "Deleted location ($olddesc, '".$oldloc->{iplist}."')";
+
+  eval {
+    # Check for records with this location first.  Deleting a location without deleting records
+    # tagged for that location will render them unpublished without other warning.
+    my ($r) = $dbh->selectrow_array("SELECT record_id FROM records WHERE location=? LIMIT 1", undef, ($loc) );
+    die "Records still exist in location $olddesc\n" if $r;
+    $dbh->do("DELETE FROM locations WHERE location=?", undef, ($loc) );
+    _log($dbh, entry => $okmsg);
+    $dbh->commit;
+  };
+  if ($@) {
+    my $msg = $@;
+    eval { $dbh->rollback; };
+    if ($config{log_failures}) {
+      _log($dbh, (entry => "Failed to delete location ($olddesc, '$oldloc->{iplist}'): $msg"));
+      $dbh->commit;
+    }
+    return ('FAIL', "Failed to delete location ($olddesc, '$oldloc->{iplist}'): $msg");
+  }
+
+  return ('OK',$okmsg);
+} # end delLoc()
 
 
 ## DNSDB::getLoc()
+# Get details about a location/view
+# Takes a database handle and location ID.
+# Returns a reference to a hash containing the group ID, IP list, description, and comments/notes
 sub getLoc {
   my $dbh = shift;
Index: /trunk/dns.cgi
===================================================================
--- /trunk/dns.cgi	(revision 427)
+++ /trunk/dns.cgi	(revision 428)
@@ -1362,7 +1362,7 @@
 #  }
 
-  if ($webvar{locact} eq 'new') {
-    # uuhhmm....
-  } elsif ($webvar{locact} eq 'add') {
+  $webvar{locact} = '' if !$webvar{locact};
+
+  if ($webvar{locact} eq 'add') {
     changepage(page => "loclist", errmsg => "You are not permitted to add locations/views", id => $webvar{parentid})
 	unless ($permissions{admin} || $permissions{location_create});
@@ -1430,4 +1430,34 @@
 
     show_msgs();
+  }
+
+} elsif ($webvar{page} eq 'delloc') {
+
+  changepage(page=> "loclist", errmsg => "You are not allowed to delete locations")
+	unless $permissions{admin} || $permissions{location_delete};
+
+  # security check - does the user have permission to access this entity?
+#  if (!check_scope(id => $webvar{id}, type => 'loc')) {
+#    changepage(page => "loclist", errmsg => "You are not permitted to <foo> the requested location/view");
+#  }
+
+  $page->param(locid => $webvar{locid});
+  my $locdata = getLoc($dbh, $webvar{locid});
+  $locdata->{description} = $webvar{locid} if !$locdata->{description};
+  # first pass = confirm y/n (sorta)
+  if (!defined($webvar{del})) {
+    $page->param(del_getconf => 1);
+    $page->param(location => $locdata->{description});
+  } elsif ($webvar{del} eq 'ok') {
+    my ($code,$msg) = delLoc($dbh, $webvar{locid});
+    if ($code eq 'OK') {
+      # success.  go back to the user list, do not pass "GO"
+      changepage(page => "loclist", resultmsg => $msg);
+    } else {
+      changepage(page => "loclist", errmsg => $msg);
+    }
+  } else {
+    # cancelled.  whee!
+    changepage(page => "loclist");
   }
 
