Index: /branches/stable/DNSDB.pm
===================================================================
--- /branches/stable/DNSDB.pm	(revision 421)
+++ /branches/stable/DNSDB.pm	(revision 422)
@@ -32,5 +32,5 @@
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
 
-$VERSION	= 1.0.2;	##VERSION##
+$VERSION	= 1.0.3;	##VERSION##
 @ISA		= qw(Exporter);
 @EXPORT_OK	= qw(
@@ -1315,4 +1315,14 @@
   $sql .= "default_" if $type eq 'y';
   $sql .= "records r ";
+
+  # whee!  multisort means just passing comma-separated fields in sortby!
+  my $newsort = '';
+  foreach my $sf (split /,/, $order) {
+    $sf = "r.$sf";
+    $sf =~ s/r\.type/t.alphaorder/;
+    $newsort .= ",$sf";
+  }
+  $newsort =~ s/^,//;
+
   $sql .= "INNER JOIN rectypes t ON r.type=t.val ";	# for sorting by type alphabetically
   if ($type eq 'y') {
@@ -1324,5 +1334,5 @@
   $sql .= " AND host ~* ?" if $filter;
   # use alphaorder column for "correct" ordering of sort-by-type instead of DNS RR type number
-  $sql .= " ORDER BY ".($order eq 'type' ? 't.alphaorder' : "r.$order")." $direction";
+  $sql .= " ORDER BY $newsort $direction";
   $sql .= " LIMIT $nrecs OFFSET ".($nstart*$nrecs) if $nstart ne 'all';
 
Index: /branches/stable/Makefile
===================================================================
--- /branches/stable/Makefile	(revision 421)
+++ /branches/stable/Makefile	(revision 422)
@@ -3,5 +3,5 @@
 
 PKGNAME=dnsadmin
-VERSION=1.0.2
+VERSION=1.0.3
 RELEASE=1
 
Index: /branches/stable/templates/reclist.tmpl
===================================================================
--- /branches/stable/templates/reclist.tmpl	(revision 421)
+++ /branches/stable/templates/reclist.tmpl	(revision 422)
@@ -44,5 +44,6 @@
 </tr>
 <tr class="darkrowheader">
-	<td colspan="4">Records</td>
+	<td colspan="3">Records</td>
+	<td align="center"><a href="textrecs.cgi?sid=<TMPL_VAR NAME=sid>&amp;id=<TMPL_VAR NAME=id>&amp;defrec=<TMPL_VAR NAME=defrec>">Plain text</a></td>
 <TMPL_IF record_create>	<td align="right"><a href="dns.cgi?sid=<TMPL_VAR NAME=sid>&amp;page=record&amp;parentid=<TMPL_VAR NAME=id>&amp;defrec=<TMPL_VAR NAME=defrec>&amp;recact=new">Add record</a></td></TMPL_IF>
 	<td align="right"><a href="dns.cgi?sid=<TMPL_VAR NAME=sid>&amp;page=log&amp;id=<TMPL_VAR NAME=id><TMPL_IF logdom>&amp;ltype=dom</TMPL_IF>">View log</a></td>
Index: /branches/stable/templates/textrecs.tmpl
===================================================================
--- /branches/stable/templates/textrecs.tmpl	(revision 422)
+++ /branches/stable/templates/textrecs.tmpl	(revision 422)
@@ -0,0 +1,40 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+    <head>
+	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+	<title><TMPL_IF orgname><TMPL_VAR NAME=orgname> - </TMPL_IF>DNS Administration</title>
+        <!-- General stylesheet for most content, all browsers -->
+        <link rel="stylesheet" type="text/css" href="templates/dns.css" />
+    </head>
+<body>
+
+<div id="stitle">
+Plain version of <TMPL_IF defrec>default <TMPL_IF revrec>reverse </TMPL_IF></TMPL_IF>records for <TMPL_VAR NAME=zone>.<br />
+Press the "Back" button to return to the standard record list.
+</div>
+
+<div id="main">
+<table cellspacing="3">
+<TMPL_IF reclist><TMPL_LOOP NAME=reclist>
+<tr>
+<TMPL_IF fwdzone>
+	<td><TMPL_VAR NAME=host></td>
+	<td><TMPL_VAR NAME=ttl></td>
+	<td><TMPL_VAR NAME=type></td>
+	<td><TMPL_VAR NAME=val></td>
+<TMPL_ELSE>
+	<td><TMPL_VAR NAME=val></td>
+	<td><TMPL_VAR NAME=ttl></td>
+	<td><TMPL_VAR NAME=type></td>
+	<td><TMPL_VAR NAME=host></td>
+</TMPL_IF>
+</tr>
+</TMPL_LOOP>
+<TMPL_ELSE>
+<tr><td colspan="4">No records found</td></tr>
+</TMPL_IF>
+</table>
+</div>
+
+</body>
+</html>
Index: /branches/stable/textrecs.cgi
===================================================================
--- /branches/stable/textrecs.cgi	(revision 422)
+++ /branches/stable/textrecs.cgi	(revision 422)
@@ -0,0 +1,110 @@
+#!/usr/bin/perl -w -T
+# Plaintext record list for DeepNet DNS Administrator
+##
+# $Id$
+# Copyright 2012 Kris Deugau <kdeugau@deepnet.cx>
+# 
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version. 
+# 
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+# 
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+##
+
+use strict;
+use warnings;
+
+use CGI::Carp qw (fatalsToBrowser);
+use CGI::Simple;
+use HTML::Template;
+use CGI::Session;
+use DBI;
+
+# don't remove!  required for GNU/FHS-ish install from tarball
+use lib '.';	##uselib##
+
+use DNSDB qw(:ALL);
+
+# Let's do these templates right...
+my $templatedir = "templates";
+
+# Set up the CGI object...
+my $q = new CGI::Simple;
+# ... and get query-string params as well as POST params if necessary
+$q->parse_query_string;
+
+# This is probably excessive fiddling, but it puts the parameters somewhere my fingers know about...
+my %webvar = $q->Vars;
+
+# shut up some warnings, in case we arrive somewhere we forgot to set this
+$webvar{defrec} = 'n' if !$webvar{defrec};	# non-default records
+#$webvar{revrec} = 'n' if !$webvar{revrec};	# non-reverse (domain) records
+
+# load some local system defaults (mainly DB connect info)
+# note this is not *absolutely* fatal, since there's a default dbname/user/pass in DNSDB.pm
+# we'll catch a bad DB connect string once we get to trying that
+##fixme:  pass params to loadConfig, and use them there, to allow one codebase to support multiple sites
+if (!loadConfig()) {
+  warn "Using default configuration;  unable to load custom settings: $DNSDB::errstr";
+}
+
+# Check the session and if we have a zone ID to retrieve.  Call a failure sub if not.
+my $sid = ($webvar{sid} ? $webvar{sid} : undef);
+my $session = new CGI::Session("driver:File", $sid, {Directory => $config{sessiondir}})
+	or die CGI::Session->errstr();
+do_not_pass_go() if !$sid;
+do_not_pass_go() if !$webvar{id};
+
+##fixme: quit throwing the database handle around, and put all the SQL and direct DB fiddling into DNSDB.pm
+# dbname, user, pass, host (optional)
+my ($dbh,$msg) = connectDB($config{dbname}, $config{dbuser}, $config{dbpass}, $config{dbhost});
+# Load config pieces from the database.  Ideally all but the DB user/pass/etc should be loaded here.
+initGlobals($dbh);
+
+my $zone;
+$zone = domainName($dbh, $webvar{id}) if $webvar{defrec} eq 'n';
+$zone = "group ".groupName($dbh, $webvar{id}) if $webvar{defrec} eq 'y';
+
+##fixme:  do we support both HTML-plain and true plaintext?  could be done, with another $webvar{}
+# Don't die on bad parameters.  Saves munging the return from getDomRecs.
+#my $page = HTML::Template->new(filename => "$templatedir/textrecs.tmpl",
+#	loop_context_vars => 1, global_vars => 1, die_on_bad_params => 0);
+#print "Content-type: text/html\n\n";
+
+print "Content-type: text/plain\n\n";
+print "Plaintext version of records for $zone.\n" if $webvar{defrec} eq 'n';
+print "Plaintext version of default records for $zone.\n" if $webvar{defrec} eq 'y';
+print qq(Press the "Back" button to return to the standard record list.\n\n);
+
+my $reclist = getDomRecs($dbh, $webvar{defrec}, $webvar{id}, 0, 'all', 'type,host', 'ASC');
+
+foreach my $rec (@$reclist) {
+  $rec->{type} = $typemap{$rec->{type}};
+  $rec->{val} .= '.' if $rec->{type} ne 'A' && $rec->{val} !~ /\.$/;
+  $rec->{host} .= '.' if $rec->{val} !~ /\.$/;
+  $rec->{val} = "$rec->{distance}  $rec->{val}" if $rec->{type} eq 'MX';
+  $rec->{val} = "$rec->{distance}  $rec->{weight}  $rec->{port}  $rec->{val}" if $rec->{type} eq 'SRV';
+  printf "%-45s\t%d\t%s\t%s\n", $rec->{host}, $rec->{ttl}, $rec->{type}, $rec->{val};
+}
+#$page->param(defrec => ($webvar{defrec} eq 'y'));
+#$page->param(revrec => ($webvar{revrec} eq 'y'));
+#$page->param(zone => $zone);
+#$page->param(reclist => $reclist);
+#$page->param(fwdzone => ($webvar{revrec} eq 'n'));
+#print $page->output;
+
+exit;
+
+sub do_not_pass_go {
+  my $webpath = $ENV{SCRIPT_NAME};
+  $webpath =~ s|/[^/]+$|/|;
+  print "Status: 302\nLocation: http://$ENV{HTTP_HOST}$webpath\n\n";
+  exit;
+}
