Index: /trunk/dns.cgi
===================================================================
--- /trunk/dns.cgi	(revision 639)
+++ /trunk/dns.cgi	(revision 640)
@@ -1079,6 +1079,4 @@
 } elsif ($webvar{page} eq 'bulkdomain' || $webvar{page} eq 'bulkrev') {
   # Bulk operations on domains.  Note all but group move are available on the domain list.
-##fixme:  do we care about bulk operations on revzones?  Move-to-group, activate, deactivate,
-# and delete should all be much rarer for revzones than for domains.
 
   changepage(page => "domlist", errmsg => "You are not permitted to make bulk zone changes")
@@ -1112,4 +1110,36 @@
   $page->param(maydelete => $permissions{admin} || $permissions{domain_delete});
 
+#} elsif ($webvar{page} eq 'confirmbulkdom' || $webvar{page} eq 'confirmbulkrev') {
+} elsif ($webvar{page} eq 'confirmbulk') {
+
+  changepage(page => "domlist", errmsg => "You are not permitted to make bulk zone changes")
+	unless ($permissions{admin} || $permissions{domain_edit} || $permissions{domain_create} || $permissions{domain_delete});
+
+  $page->param(bulkaction => $webvar{bulkaction});
+  $page->param(destgroup => $webvar{destgroup});
+  my @zlist;
+  my $rownum = 0;
+
+##fixme: this could probably be made more efficient, since this looks up 2 zone names for
+# each comparison during sort rather than slurping them in bulk once before doing the sort
+  # sort zones by zone name, not ID
+  sub zsort {
+    my $tmpa = ($a =~ /^dom/ ? $dnsdb->domainName($webvar{$a}) : $dnsdb->revName($webvar{$a}) );
+    my $tmpb = ($b =~ /^dom/ ? $dnsdb->domainName($webvar{$b}) : $dnsdb->revName($webvar{$b}) );
+    return $tmpa cmp $tmpb;
+  }
+  # eugh.  can't see a handy way to sort this mess by zone name the way it is on the submitting page.  :(
+  foreach my $input (sort zsort grep(/^(?:dom|rev)_/, keys %webvar) ) {
+    next unless $input =~ /^(dom|rev)_\d+$/;
+    my $fr = $1;
+    my %row = (zoneid => $webvar{$input},
+        zone => ($fr eq 'dom' ? $dnsdb->domainName($webvar{$input}) : $dnsdb->revName($webvar{$input}) ),
+        zvarname => $input,
+	newrow => ( (++$rownum) % 5 == 0 && $rownum != $perpage),
+	);
+    push @zlist, \%row;
+  }
+  $page->param(domtable => \@zlist);
+
 } elsif ($webvar{page} eq 'bulkchange') {
 
@@ -1120,18 +1150,25 @@
   }
 
+  # skip the changes if user did not confirm
+  my $wasrev = grep /^rev_/, keys %webvar;
+  changepage(page => ($wasrev ? "bulkrev" : "bulkdomain")) unless $webvar{okdel} eq 'y';
+
+  changepage(page => "domlist", errmsg => "You are not permitted to make bulk zone changes")
+	unless ($permissions{admin} || $permissions{domain_edit} || $permissions{domain_create} || $permissions{domain_delete});
+
   # per-action scope checks
   if ($webvar{bulkaction} eq 'move') {
-    changepage(page => "domlist", errmsg => "You are not permitted to bulk-move domains")
+    changepage(page => "domlist", errmsg => "You are not permitted to bulk-move zones")
 	unless ($permissions{admin} || ($permissions{domain_edit} && $permissions{domain_create} && $permissions{domain_delete}));
     my $newgname = $dnsdb->groupName($webvar{destgroup});
     $page->param(action => "Move to group $newgname");
   } elsif ($webvar{bulkaction} eq 'deactivate' || $webvar{bulkaction} eq 'activate') {
-    changepage(page => "domlist", errmsg => "You are not permitted to bulk-$webvar{bulkaction} domains")
+    changepage(page => "domlist", errmsg => "You are not permitted to bulk-$webvar{bulkaction} zones")
 	unless ($permissions{admin} || $permissions{domain_edit});
-    $page->param(action => "$webvar{bulkaction} domains");
+    $page->param(action => "$webvar{bulkaction} zones");
   } elsif ($webvar{bulkaction} eq 'delete') {
-    changepage(page => "domlist", errmsg => "You are not permitted to bulk-delete domains")
+    changepage(page => "domlist", errmsg => "You are not permitted to bulk-delete zones")
 	unless ($permissions{admin} || $permissions{domain_delete});
-    $page->param(action => "$webvar{bulkaction} domains");
+    $page->param(action => "$webvar{bulkaction} zones");
   } else {
     # unknown action, bypass actually doing anything.  it should not be possible in
Index: /trunk/templates/bulkdomain.tmpl
===================================================================
--- /trunk/templates/bulkdomain.tmpl	(revision 639)
+++ /trunk/templates/bulkdomain.tmpl	(revision 640)
@@ -10,5 +10,5 @@
 <fieldset>
 
-<input type="hidden" name="page" value="bulkchange" />
+<input type="hidden" name="page" value="confirmbulk" />
 <input type="hidden" name="offset" value="<TMPL_VAR NAME=offset>" />
 <input type="hidden" name="perpage" value="<TMPL_VAR NAME=perpage>" />
@@ -44,7 +44,7 @@
 <tr>
 <TMPL_LOOP NAME=domtable><td><input type="checkbox" name="<TMPL_IF fwdzone>dom<TMPL_ELSE>rev</TMPL_IF>_<TMPL_VAR NAME=zoneid>" value="<TMPL_VAR NAME=zoneid>" /> <TMPL_VAR NAME=zone></td>
-<TMPL_IF newrow></tr>
+<TMPL_IF newrow><TMPL_UNLESS __last__></tr>
 <tr>
-</TMPL_IF></TMPL_LOOP>
+</TMPL_UNLESS></TMPL_IF></TMPL_LOOP>
 </tr>
 </table>
Index: /trunk/templates/confirmbulk.tmpl
===================================================================
--- /trunk/templates/confirmbulk.tmpl	(revision 640)
+++ /trunk/templates/confirmbulk.tmpl	(revision 640)
@@ -0,0 +1,54 @@
+<body>
+<div id="main">
+
+<table class="wholepage"><tr>
+<TMPL_INCLUDE NAME="menu.tmpl">
+
+<td align="center" valign="top">
+
+<form action="<TMPL_VAR NAME=script_self>" method="post">
+<fieldset>
+
+<input type="hidden" name="page" value="bulkchange" />
+<input type="hidden" name="bulkaction" value="<TMPL_VAR NAME=bulkaction>" />
+<input type="hidden" name="destgroup" value="<TMPL_VAR NAME=destgroup>" />
+
+<table class="container">
+<tr><td>
+    <table border="0" cellspacing="2" cellpadding="2" width="100%">
+        <tr class="darkrowheader"><td colspan="3" align="center">Confirm Bulk Zone Changes</td></tr>
+
+        <tr class="datalinelight">
+                <td colspan="3" align="center">
+			<h3>Are you sure you want to <TMPL_VAR NAME=bulkaction> the following zones?</h3>
+                	<input type="radio" name="okdel" value="n" checked="checked" /> No &nbsp;
+			<input type="radio" name="okdel" value="y" /> Yes &nbsp;
+			<input type="submit" value=" Continue " />
+		</td>
+        </tr>
+        <tr class="darkrowheader">
+                <td align="center">Zones to change:</td>
+        </tr>
+	<tr class="datalinelight"><td>
+
+<table>
+<tr>
+<TMPL_LOOP NAME=domtable><td><input type="checkbox" name="<TMPL_VAR NAME=zvarname>" value="<TMPL_VAR NAME=zoneid>" checked="checked" /> <TMPL_VAR NAME=zone></td>
+<TMPL_IF newrow><TMPL_UNLESS __last__></tr>
+<tr>
+</TMPL_UNLESS></TMPL_IF></TMPL_LOOP>
+</tr>
+</table>
+
+	</td></tr>
+    </table>
+
+<!-- container -->
+</td></tr></table>
+
+</fieldset>
+</form>
+
+<!-- page -->
+</td></tr></table>
+
