mirror of
https://github.com/zerotier/edge.git
synced 2026-05-22 16:25:05 -07:00
4202 lines
97 KiB
Perl
Executable File
4202 lines
97 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
#
|
|
# Copyright 2007-2014 SPARTA, Inc. All rights reserved. See the COPYING
|
|
# file distributed with this software for details.
|
|
#
|
|
# DNSSEC-Tools: rollrec-editor
|
|
#
|
|
# rollrec-editor provides the capability for easy management of rollrec
|
|
# files in a GUI. New rollrecs may be created and existing rollrecs may
|
|
# be modified or deleted from rollrec-editor. Only a subset of rollrec
|
|
# fields may be modified by rollrec-editor.
|
|
#
|
|
#
|
|
# TODO:
|
|
# - undo command
|
|
#
|
|
# - quit editor command works, but the exit(0) call generates
|
|
# a segmentation fault
|
|
#
|
|
|
|
use strict;
|
|
|
|
use Net::DNS::SEC::Tools::dnssectools;
|
|
use Net::DNS::SEC::Tools::conf;
|
|
use Net::DNS::SEC::Tools::rollmgr;
|
|
use Net::DNS::SEC::Tools::rolllog;
|
|
use Net::DNS::SEC::Tools::rollrec;
|
|
use Net::DNS::SEC::Tools::BootStrap;
|
|
|
|
use Getopt::Long qw(:config no_ignore_case_always);
|
|
|
|
#
|
|
# Version information.
|
|
#
|
|
my $NAME = "rollrec-editor";
|
|
my $VERS = "$NAME version: 2.1.0";
|
|
my $DTVERS = "DNSSEC-Tools Version: 2.2.3";
|
|
|
|
######################################################################
|
|
#
|
|
# DESTROY THESE DATA!!!
|
|
#
|
|
# These data are part of the undo code that was carried over from
|
|
# signset-editor. When the undo code is rewritten here, these
|
|
# variables should be either deleted or renamed.
|
|
#
|
|
|
|
my %key_lists;
|
|
my @ssnames;
|
|
my @krnames;
|
|
|
|
######################################################################
|
|
#
|
|
# Detect required Perl modules.
|
|
#
|
|
dnssec_tools_load_mods(
|
|
'Tk' => "",
|
|
'Tk::Dialog' => "",
|
|
'Tk::DialogBox' => "",
|
|
'Tk::FileSelect' => "",
|
|
'Tk::Pane' => "",
|
|
'Tk::Table' => "",
|
|
);
|
|
|
|
#######################################################################
|
|
#
|
|
# program (non-GUI) data
|
|
#
|
|
|
|
#
|
|
# Variables for command options.
|
|
#
|
|
my %options = (); # Filled option array.
|
|
my @opts =
|
|
(
|
|
"ignore-warns", # Ignore-edit-warnings flag.
|
|
"no-filter", # No-name-filtering flag.
|
|
"columns=i", # Columns in button window.
|
|
|
|
"Version", # Display the version number.
|
|
"help", # Give a usage message and exit.
|
|
);
|
|
|
|
#
|
|
# Flags for options.
|
|
#
|
|
my $givewarnings = 1; # Give-warnings flag.
|
|
my $namefilter = 1; # Use-name-filter flag (FS).
|
|
|
|
#
|
|
# File name variables.
|
|
#
|
|
my $rrfile = "dummy"; # Rollrec file we're examining.
|
|
my $curnode = "dummy"; # Node of rrfile.
|
|
|
|
#
|
|
# Lists of rollrecs.
|
|
#
|
|
my %rollrecs = (); # Rollrec hash.
|
|
my @rollrecs = (); # Rollrec array.
|
|
my @rrnames = (); # List of rollrec names.
|
|
my $numrrnames; # Number of rollrec names.
|
|
my $modified = 0; # Modified-rrfile flag.
|
|
my %modified = (); # Modified-rollrecs hash.
|
|
|
|
###########################################################################
|
|
#
|
|
# Undo data.
|
|
#
|
|
|
|
my @undo_stack; # Stack for undo commands.
|
|
|
|
###########################################################################
|
|
#
|
|
# Tk GUI data
|
|
#
|
|
|
|
########################################################
|
|
#
|
|
# Main window data.
|
|
#
|
|
my $MAINTITLE = "DNSSEC-Tools Rollrec Editor";
|
|
|
|
my $title = "dummy"; # Node for title.
|
|
my $modset = 0; # Flag for (modified) title.
|
|
|
|
#
|
|
# The main window and help window.
|
|
#
|
|
my $wm; # Main window.
|
|
my $helpwin; # Help window.
|
|
my $inhelpwind = 0; # Showing help window flag.
|
|
|
|
#
|
|
# The contents of the main window and its frames.
|
|
#
|
|
my $mbar; # Menubar frame.
|
|
my $rrfl; # Keyrec frame.
|
|
my $body; # Window body frame.
|
|
my $null; # Empty frame.
|
|
|
|
########################################################
|
|
#
|
|
# Menubar and menu data.
|
|
#
|
|
|
|
#
|
|
# Menu item widgets.
|
|
#
|
|
my $fm_open; # Open keyrec file item.
|
|
my $fm_save; # Save keyrec file item.
|
|
my $fm_svas; # Save-as keyrec file item.
|
|
my $fm_quit; # Quit file item.
|
|
|
|
my $em_undo; # Undo edit item.
|
|
|
|
my $cm_create; # Create a rollrec.
|
|
my $cm_delete; # Delete selected rollrecs.
|
|
my $cm_modify; # Modify selected rollrecs.
|
|
my $cm_merger; # Merge two rollrec files.
|
|
my $cm_rename; # Rename selected rollrec.
|
|
my $cm_verify; # Verify a rollrec file.
|
|
|
|
my $vw_selall; # Select all rollrecs set item.
|
|
my $vw_closeall; # Close rollrec edit windows.
|
|
my $vw_raiser; # Raise rollrec edit windows.
|
|
|
|
my $tog_ignwarn; # Ignore-Edit-Warning toggle.
|
|
my $tog_namefilt = 1; # Use-name-filter toggle.
|
|
|
|
my $hm_help; # Help item.
|
|
|
|
#
|
|
# Labels for toggles in the Options menu.
|
|
#
|
|
my $IGNORE_ON = "Ignore Edit Warnings";
|
|
my $IGNORE_OFF = "Don't Ignore Edit Warnings";
|
|
my $FILTER_OFF = "Don't Filter Name Selection";
|
|
my $FILTER_ON = "Filter Name Selection";
|
|
|
|
########################################################
|
|
#
|
|
# Button window data.
|
|
#
|
|
|
|
#
|
|
# Column and row data for button windows.
|
|
#
|
|
my $DEFCOLS = 4; # Default columns in button table.
|
|
my $MAXCOLS = 12; # Maximum allowable button columns.
|
|
my $MINCOLS = 3; # Minimum allowable button columns.
|
|
|
|
my $numcols; # Current number of table cols.
|
|
my $numrows; # Current number of table rows.
|
|
|
|
my $columncount = $DEFCOLS; # Column count.
|
|
|
|
#
|
|
# Font data for text in button window.
|
|
#
|
|
my $fontsize = 18;
|
|
my $font = "*-*-bold-r-*-*-$fontsize-*-*-*-*-*-*-*";
|
|
|
|
#
|
|
# Colors for selected/unselected button in button window.
|
|
#
|
|
my $RRTAB_UNSEL = 'white';
|
|
my $RRTAB_SEL = 'blue';
|
|
|
|
########################################################
|
|
#
|
|
# Edit window data.
|
|
#
|
|
|
|
#
|
|
# Row and column constants for the edit-window tables.
|
|
#
|
|
my $COL_FIELD = 0; # Edit table's label column.
|
|
my $COL_DATA = 1; # Edit table's data column.
|
|
|
|
my $ROW_TYPE = 0; # Type row.
|
|
my $ROW_ZONENAME = 1; # Zonename row.
|
|
my $ROW_ZONEFILE = 2; # Zonefile row.
|
|
my $ROW_KEYREC = 3; # Keyrec row.
|
|
my $ROW_ZONEGROUP = 4; # Zonegroup row.
|
|
my $ROW_ADMIN = 5; # Administrator's email row.
|
|
my $ROW_DIR = 6; # Directory row.
|
|
my $ROW_DISPLAY = 7; # Display row.
|
|
my $ROW_LOG = 8; # Loglevel col.
|
|
my $ROW_MAXTTL = 9; # Maxttl row.
|
|
my $ROW_ZSARGS = 10; # Zsargs row.
|
|
|
|
my $ROW_FIRST = $ROW_TYPE; # Edit table's first row.
|
|
my $ROW_LAST = $ROW_ZSARGS; # Edit table's last row.
|
|
|
|
my $ROW_MSG = ($ROW_LAST + 1); # Message line - after ROW_LAST.
|
|
|
|
#
|
|
# Labels for the field-column entries of the edit-window tables.
|
|
#
|
|
# These MUST correspond to the $ROW_ constants!
|
|
#
|
|
my @ET_LABELS =
|
|
(
|
|
"Type",
|
|
"Zonename",
|
|
"Zonefile",
|
|
"Keyrec",
|
|
"Zonegroup",
|
|
"Admin Email",
|
|
"Directory",
|
|
"Display Flag",
|
|
"Logging Level",
|
|
"Max-TTL",
|
|
"Zonesigner Arguments",
|
|
"dummy", # Dummy label, just ensures message row is created.
|
|
);
|
|
|
|
#
|
|
# These are the rollrec fields that are editable.
|
|
#
|
|
my @EDITFIELDS =
|
|
(
|
|
'administrator',
|
|
'directory',
|
|
'display',
|
|
'keyrec',
|
|
'loglevel',
|
|
'maxttl',
|
|
'zonefile',
|
|
'zonegroup',
|
|
'zonename',
|
|
'zsargs'
|
|
);
|
|
|
|
#
|
|
# Constants for message text colors.
|
|
#
|
|
my $NORMALCOLOR = "black"; # Color for normal messages.
|
|
my $WARNCOLOR = "yellow"; # Color for warning messages.
|
|
my $ERRCOLOR = "red"; # Color for error messages.
|
|
|
|
my $rrnametab; # Rollrec name table widget.
|
|
|
|
my %editwinds; # Rollrec edit windows.
|
|
my %edittabs = (); # Edit-area tables.
|
|
my %renwinds = (); # Rollrec rename windows.
|
|
my %rentabs = (); # Rename something or another.
|
|
|
|
my %editrbs; # Type radiobutton values for edit windows.
|
|
my %editdfs; # Display flag radiobutton vals for edit winds.
|
|
|
|
###########################################################################
|
|
|
|
main();
|
|
exit(0);
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: main()
|
|
#
|
|
sub main
|
|
{
|
|
my $argc = @ARGV;
|
|
|
|
erraction(ERR_EXIT);
|
|
|
|
#
|
|
# Check our options.
|
|
#
|
|
doopts();
|
|
|
|
#
|
|
# Get the rollrec filename and the path's node.
|
|
#
|
|
$rrfile = $ARGV[0];
|
|
$curnode = getnode($rrfile);
|
|
settitle($curnode);
|
|
|
|
#
|
|
# Ensure this rollrec file actually exists.
|
|
#
|
|
if(! -e $rrfile)
|
|
{
|
|
print STDERR "$rrfile does not exist\n";
|
|
exit(1);
|
|
}
|
|
|
|
#
|
|
# Build the main window.
|
|
#
|
|
buildmainwind();
|
|
|
|
#
|
|
# Start the whole shebang rollin'.
|
|
#
|
|
MainLoop();
|
|
}
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Routine: doopts()
|
|
#
|
|
# Purpose: This routine gets the options from the command line.
|
|
#
|
|
sub doopts
|
|
{
|
|
my $argc = @ARGV; # Number of command line arguments.
|
|
|
|
usage() if($argc == 0);
|
|
|
|
GetOptions(\%options,@opts) || usage();
|
|
|
|
#
|
|
# Show the version number or help info if requested.
|
|
#
|
|
version() if(defined($options{'Version'}));
|
|
usage() if(defined($options{'help'}));
|
|
|
|
#
|
|
# Set some flags based on the command line.
|
|
#
|
|
$givewarnings = 0 if(defined($options{'ignore-warns'}));
|
|
$namefilter = 0 if(defined($options{'no-filter'}));
|
|
|
|
#
|
|
# Check for the column-count option.
|
|
#
|
|
if(defined($options{'columns'}))
|
|
{
|
|
$columncount = $options{'columns'};
|
|
if(($columncount < $MINCOLS) || ($columncount > $MAXCOLS))
|
|
{
|
|
print STDERR "column count must be between $MINCOLS and $MAXCOLS\n";
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: buildmainwind()
|
|
#
|
|
# Purpose: Create and initialize the main window.
|
|
#
|
|
sub buildmainwind
|
|
{
|
|
my $file; # File menu.
|
|
my $edit; # Edit menu.
|
|
my $cmds; # Commands menu.
|
|
my $view; # Rollrecs menu.
|
|
my $opts; # Options menu.
|
|
my $help; # Help menu.
|
|
|
|
my $curfile; # Current keyrec.
|
|
my $nulline; # Empty line.
|
|
|
|
#
|
|
# Create the main window and set its size.
|
|
#
|
|
$wm = MainWindow->new(-title => $MAINTITLE);
|
|
|
|
#
|
|
# Get the keyrec file info. No error message; it was given below.
|
|
#
|
|
exit(1) if(readrrf($rrfile) == 0);
|
|
|
|
#
|
|
# Create the frames we'll need.
|
|
#
|
|
$mbar = $wm->Frame(-relief => 'raised', -borderwidth => 1);
|
|
$rrfl = $wm->Frame(-relief => 'raised', -borderwidth => 1);
|
|
$body = $wm->Frame(-relief => 'raised', -borderwidth => 1);
|
|
$null = $wm->Frame(-relief => 'raised', -borderwidth => 1);
|
|
|
|
$mbar->pack(-fill => 'x');
|
|
$rrfl->pack(-fill => 'x');
|
|
$body->pack(-fill => 'x');
|
|
$null->pack(-fill => 'x');
|
|
|
|
#
|
|
# Create our menus.
|
|
#
|
|
$file = $mbar->Menubutton(-text => 'File',
|
|
-tearoff => 0,
|
|
-underline => 0);
|
|
$edit = $mbar->Menubutton(-text => 'Edit',
|
|
-tearoff => 0,
|
|
-underline => 0);
|
|
$cmds = $mbar->Menubutton(-text => 'Commands',
|
|
-tearoff => 0,
|
|
-underline => 0);
|
|
$view = $mbar->Menubutton(-text => 'View',
|
|
-tearoff => 0,
|
|
-underline => 0);
|
|
$opts = $mbar->Menubutton(-text => 'Options',
|
|
-tearoff => 0,
|
|
-underline => 0);
|
|
$help = $mbar->Menubutton(-text => 'Help',
|
|
-tearoff => 0,
|
|
-underline => 0);
|
|
|
|
##################################################
|
|
#
|
|
# Add the File menu entries.
|
|
#
|
|
$fm_open = $file->command(-label => 'Open...',
|
|
-command => \&file_open,
|
|
-accelerator => 'Ctrl+O',
|
|
-underline => 0);
|
|
$fm_save = $file->command(-label => 'Save',
|
|
-command => \&file_save,
|
|
-accelerator => 'Ctrl+S',
|
|
-underline => 0);
|
|
$fm_svas = $file->command(-label => 'Save As...',
|
|
-command => \&file_saveas,
|
|
-underline => 0);
|
|
$file->separator();
|
|
$fm_quit = $file->command(-label => 'Quit',
|
|
-command => \&file_quit,
|
|
-accelerator => 'Ctrl+Q',
|
|
-underline => 0);
|
|
$file->pack(-side => 'left');
|
|
|
|
$wm->bind('<Control-Key-o>',\&file_open);
|
|
$wm->bind('<Control-Key-s>',\&file_save);
|
|
$wm->bind('<Control-Key-q>',\&file_quit);
|
|
|
|
##################################################
|
|
#
|
|
# Add the Edit menu entries.
|
|
#
|
|
$em_undo = $edit->command(-label => 'Undo Changes',
|
|
-command => \&edit_undo,
|
|
-accelerator => 'Ctrl+U',
|
|
-state => 'disabled',
|
|
-underline => 0);
|
|
$edit->pack(-side => 'left');
|
|
|
|
$wm->bind('<Control-Key-u>',\&edit_undo);
|
|
|
|
##################################################
|
|
#
|
|
# Add the Commands menu entries.
|
|
#
|
|
$cm_create = $cmds->command(-label => 'New Rollrec...',
|
|
-command => \&cmds_create,
|
|
-accelerator => 'Ctrl+N',
|
|
-underline => 0);
|
|
|
|
$cm_delete = $cmds->command(-label => 'Delete Selected Rollrecs',
|
|
-command => \&cmds_delete,
|
|
-accelerator => 'Ctrl+D',
|
|
-underline => 0);
|
|
|
|
$cm_modify = $cmds->command(-label => 'Edit Selected Rollrecs...',
|
|
-command => \&cmds_modify,
|
|
-accelerator => 'Ctrl+E',
|
|
-underline => 0);
|
|
$cmds->separator();
|
|
|
|
###################
|
|
|
|
$cm_rename = $cmds->command(-label => 'Rename Selected Rollrec...',
|
|
-command => \&cmds_rename,
|
|
-underline => 0);
|
|
|
|
$cmds->separator();
|
|
|
|
###################
|
|
|
|
$cm_merger = $cmds->command(-label => 'Merge Rollrec Files...',
|
|
-command => \&cmds_merger,
|
|
-accelerator => 'Ctrl+M',
|
|
-underline => 0);
|
|
|
|
$cm_verify = $cmds->command(-label => 'Verify Rollrec File',
|
|
-command => [\&cmds_verify, 0],
|
|
-accelerator => 'Ctrl+V',
|
|
-underline => 0);
|
|
|
|
$cm_verify = $cmds->command(-label => 'Summarize Problems',
|
|
-command => [\&cmds_verify, 1],
|
|
-underline => 0);
|
|
|
|
$cmds->pack(-side => 'left');
|
|
|
|
$wm->bind('<Control-Key-n>',\&cmds_create);
|
|
$wm->bind('<Control-Key-d>',\&cmds_delete);
|
|
$wm->bind('<Control-Key-e>',\&cmds_modify);
|
|
$wm->bind('<Control-Key-m>',\&cmds_merger);
|
|
$wm->bind('<Control-Key-v>',\&cmds_verify);
|
|
|
|
##################################################
|
|
#
|
|
# Add the Rollrecs menu entries.
|
|
#
|
|
$vw_selall = $view->command(-label => 'Select All Rollrecs',
|
|
-command => \&view_selall,
|
|
-accelerator => 'Ctrl+A',
|
|
-underline => 0);
|
|
$vw_raiser = $view->command(-label => 'Reveal Rollrec Edit Windows',
|
|
-command => \&view_raiser,
|
|
-accelerator => 'Ctrl+R',
|
|
-underline => 0);
|
|
$vw_closeall = $view->command(-label =>'Close Rollrec Edit Windows',
|
|
-command => \&view_closeall,
|
|
-accelerator => 'Ctrl+K',
|
|
-underline => 0);
|
|
|
|
$view->pack(-side => 'left');
|
|
|
|
$wm->bind('<Control-Key-a>',\&view_selall);
|
|
$wm->bind('<Control-Key-k>',\&view_closeall);
|
|
$wm->bind('<Control-Key-r>',\&view_raiser);
|
|
|
|
##################################################
|
|
#
|
|
# Add the Options menu entries.
|
|
#
|
|
$tog_ignwarn = $opts->command(-label => $IGNORE_ON,
|
|
-command => \&toggle_ignwarn,
|
|
-underline => 0);
|
|
$opts->pack(-side => 'left');
|
|
|
|
$namefilter = 1;
|
|
$tog_namefilt = $opts->command(-label => $FILTER_OFF,
|
|
-command => \&toggle_namefilt,
|
|
-underline => 0);
|
|
$opts->pack(-side => 'left');
|
|
|
|
$opts->command(-label => 'Columns in Button Window',
|
|
-command => [\&set_btncols, 0],
|
|
-underline => 0);
|
|
$opts->pack(-side => 'left');
|
|
|
|
|
|
#
|
|
# Set the menu labels based on default values and options.
|
|
#
|
|
$givewarnings = !$givewarnings;
|
|
toggle_ignwarn();
|
|
|
|
##################################################
|
|
#
|
|
# Add the Help menu entries.
|
|
#
|
|
$hm_help = $help->command(-label => 'Help',
|
|
-command => \&help_help,
|
|
-accelerator => 'Ctrl+H',
|
|
-underline => 0);
|
|
$help->pack(-side => 'right');
|
|
|
|
$wm->bind('<Control-Key-h>',\&help_help);
|
|
|
|
##################################################
|
|
#
|
|
# Create a line holding the current rollrec filename.
|
|
#
|
|
|
|
$curfile = $rrfl->Label(-text => "Editing Rollrec File: ");
|
|
$curfile->pack(-side => 'left');
|
|
$curfile = $rrfl->Label(-textvariable => \$title);
|
|
$curfile->pack(-side => 'left');
|
|
$rrfl->pack(-side => 'top', -fill => 'x');
|
|
|
|
##################################################
|
|
#
|
|
# Create a table to hold the button window.
|
|
#
|
|
buildtable(42);
|
|
|
|
#
|
|
# Create a line holding the current rollrec filename.
|
|
#
|
|
$nulline = $null->Label(-text => " ");
|
|
$nulline->pack();
|
|
$null->pack(-side => 'top', -fill => 'x');
|
|
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: buildtable()
|
|
#
|
|
# Purpose: Rebuild the rollrec name table. This also re-reads the
|
|
# current rollrec file, so the list of rollrec names may
|
|
# increase or shrink depending on the state of that file.
|
|
#
|
|
sub buildtable
|
|
{
|
|
my $readflag = shift; # Rollrec-read flag.
|
|
|
|
my $cnt = 0; # Count of rollrec names added.
|
|
|
|
#
|
|
# Create a brand new table.
|
|
#
|
|
maketable();
|
|
|
|
#
|
|
# Read the list of rollrec names.
|
|
#
|
|
readrrf($rrfile,1) if($readflag);
|
|
return if($numrrnames == 0);
|
|
|
|
#
|
|
# Ensure the rollrec name list is sorted.
|
|
#
|
|
@rrnames = sort(@rrnames);
|
|
|
|
#
|
|
# Re-populate and update the table.
|
|
#
|
|
for(my $ind = 0; $ind < $numrrnames; $ind++)
|
|
{
|
|
my $btn; # Button widget.
|
|
|
|
my $row; # Cell's row index.
|
|
my $col; # Cell's column index.
|
|
|
|
#
|
|
# Get the column and row indices.
|
|
#
|
|
($col,$row) = ind2cr($ind);
|
|
|
|
$btn = $rrnametab->Button(-text => "$rrnames[$ind]",
|
|
-font => $font,
|
|
-anchor => 'w',
|
|
-state => 'normal',
|
|
-command => [\&rrname_toggle,
|
|
$ind],
|
|
-background => $RRTAB_UNSEL);
|
|
|
|
$rrnametab->put($row,$col,$btn);
|
|
}
|
|
|
|
$rrnametab->update();
|
|
|
|
#
|
|
# Pack it all up.
|
|
#
|
|
$rrnametab->pack(-fill => 'both', -expand => 1);
|
|
$body->pack(-fill => 'both', -expand => 1);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: rrname_select()
|
|
#
|
|
# Purpose: A rollrec name's button has been pushed. Figure out what
|
|
# to do with it...
|
|
#
|
|
sub rrname_select
|
|
{
|
|
my $rrind = shift; # Rollrec's name index.
|
|
|
|
my $btn; # Selected button.
|
|
|
|
#
|
|
# Get the rollrec's button.
|
|
#
|
|
$btn = getbutton($rrind);
|
|
|
|
#
|
|
# ... and set the button's color.
|
|
#
|
|
$btn->configure(-activebackground => $RRTAB_SEL, -background => $RRTAB_SEL);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: rrname_deselect()
|
|
#
|
|
# Purpose: A rollrec name's button has been pushed. Figure out what
|
|
# to do with it...
|
|
#
|
|
sub rrname_deselect
|
|
{
|
|
my $rrind = shift; # Rollrec's name index.
|
|
|
|
my $btn; # Selected button.
|
|
|
|
#
|
|
# Get the rollrec's button.
|
|
#
|
|
$btn = getbutton($rrind);
|
|
|
|
#
|
|
# ... and set the button's color.
|
|
#
|
|
$btn->configure(-activebackground => $RRTAB_UNSEL, -background => $RRTAB_UNSEL);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: rrname_toggle()
|
|
#
|
|
# Purpose: A rollrec name's button has been pushed. Figure out what
|
|
# to do with it...
|
|
#
|
|
sub rrname_toggle
|
|
{
|
|
my $rrind = shift; # Rollrec's name index.
|
|
|
|
my $rowind; # Cell's row index.
|
|
my $colind; # Cell's column index.
|
|
|
|
my $btn; # Selected button.
|
|
my $bgclr; # New button background color.
|
|
|
|
#
|
|
# Get the rollrec's button.
|
|
#
|
|
$btn = getbutton($rrind);
|
|
|
|
#
|
|
# Choose an appropriate background color given the button's
|
|
# current state...
|
|
#
|
|
$bgclr = $btn->cget(-background);
|
|
$bgclr = ($bgclr eq $RRTAB_SEL) ? $RRTAB_UNSEL : $RRTAB_SEL;
|
|
|
|
#
|
|
# ... and set the button's color.
|
|
#
|
|
$btn->configure(-activebackground => $bgclr, -background => $bgclr);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: getbutton()
|
|
#
|
|
# Purpose: Return a rollrec's button widget given the name's index into
|
|
# @rrnames.
|
|
#
|
|
sub getbutton
|
|
{
|
|
my $rrind = shift; # Rollrec's name index.
|
|
|
|
my $rowind; # Cell's row index.
|
|
my $colind; # Cell's column index.
|
|
|
|
#
|
|
# Get the column and row indices.
|
|
#
|
|
($colind,$rowind) = ind2cr($rrind);
|
|
|
|
#
|
|
# Return the proper button widget.
|
|
#
|
|
return($rrnametab->get($rowind,$colind));
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: selected_rrnames()
|
|
#
|
|
# Purpose: Return a list of the selected rollrec names buttons.
|
|
#
|
|
sub selected_rrnames
|
|
{
|
|
my @selected = (); # Selected rollrec names.
|
|
|
|
my $col; # Column index.
|
|
my $row; # Row index.
|
|
my $btn; # Rollrec button.
|
|
|
|
for(my $ind=0; $ind < $numrrnames; $ind++)
|
|
{
|
|
($col,$row) = ind2cr($ind);
|
|
$btn = $rrnametab->get($row,$col);
|
|
|
|
push @selected, $ind if($btn->cget(-background) eq $RRTAB_SEL);
|
|
}
|
|
|
|
return(sort(@selected));
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: ind2cr()
|
|
#
|
|
# Purpose: Convert a rollrec name table index to its table rows and
|
|
# column indices.
|
|
#
|
|
sub ind2cr
|
|
{
|
|
my $nind = shift; # Rollrec name index.
|
|
my $col; # Column index.
|
|
my $row; # Row index.
|
|
|
|
$col = int($nind / $numrows);
|
|
$row = $nind % $numrows;
|
|
|
|
return($col,$row);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: maketable()
|
|
#
|
|
# Purpose: Create the rollrec name table.
|
|
#
|
|
sub maketable
|
|
{
|
|
#
|
|
# Don't do anything if we don't have any rollrec names.
|
|
#
|
|
return if($numrrnames == 0);
|
|
|
|
#
|
|
# Calculate the size of the button table.
|
|
#
|
|
if($numrrnames != 0)
|
|
{
|
|
$numrows = int($numrrnames / $columncount);
|
|
$numrows++ if(($numrrnames % $columncount) != 0);
|
|
|
|
$numcols = $columncount;
|
|
}
|
|
|
|
#
|
|
# Destroy the rollrec-name table's widgets.
|
|
#
|
|
if($rrnametab)
|
|
{
|
|
$rrnametab->clear;
|
|
$rrnametab->destroy;
|
|
}
|
|
|
|
#
|
|
# Create the new button table.
|
|
#
|
|
$rrnametab = $body->Table(-rows => $numrows,
|
|
-columns => $numcols,
|
|
-scrollbars => 'e',
|
|
-relief => 'raised',
|
|
-borderwidth => 1,
|
|
-fixedrows => 0,
|
|
-takefocus => 1,
|
|
);
|
|
|
|
}
|
|
|
|
##############################################################################
|
|
#
|
|
# Menu widget interface routines.
|
|
#
|
|
##############################################################################
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: file_open()
|
|
#
|
|
sub file_open
|
|
{
|
|
my $fowin; # File-open widget.
|
|
my %fsopts = (); # FileSelect() options.
|
|
my $newfile; # New file name.
|
|
|
|
#
|
|
# Warn the user if this file has been modified. We'll also give
|
|
# the user a chance to save the file, not save the file, or cancel
|
|
# the process of opening the new file.
|
|
#
|
|
if($modified)
|
|
{
|
|
my $dlg; # Warning dialog widget.
|
|
my $ret; # Warning response.
|
|
|
|
$dlg = $wm->Dialog(-title => 'Warning',
|
|
-text => "$curnode has been modified; save before proceeding?",
|
|
-buttons => ["Save","Don't Save","Cancel"]);
|
|
$ret = $dlg->Show();
|
|
|
|
return if($ret eq "Cancel");
|
|
|
|
rollrec_close() if($ret eq "Save");
|
|
}
|
|
|
|
#
|
|
# Set up options for FileSelect.
|
|
#
|
|
%fsopts = (-directory => '.');
|
|
$fsopts{'-filter'} = '*.rrf' if($namefilter);
|
|
|
|
#
|
|
# Prompt for the new file. Return to our caller if nothing was chosen.
|
|
#
|
|
$fowin = $wm->FileSelect(%fsopts);
|
|
$newfile = $fowin->Show;
|
|
return if($newfile eq "");
|
|
|
|
#
|
|
# Save the new filename and its node.
|
|
#
|
|
$rrfile = $newfile;
|
|
$curnode = getnode($rrfile);
|
|
settitle($curnode);
|
|
|
|
#
|
|
# Read the new rollrec file and rebuild the button window.
|
|
#
|
|
if(readrrf($rrfile))
|
|
{
|
|
buildtable(0);
|
|
}
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: file_save()
|
|
#
|
|
sub file_save
|
|
{
|
|
return if(!$modified);
|
|
|
|
#
|
|
# Save and re-open the rollrec file.
|
|
#
|
|
rollrec_close();
|
|
readrrf($rrfile);
|
|
|
|
#
|
|
# Mark the rollrecs as saved.
|
|
#
|
|
$modified = 0;
|
|
$modset = 0;
|
|
rrsaved();
|
|
|
|
#
|
|
# Disable the undo menu option, reset our undo stack, and mark
|
|
# the file as unmodified.
|
|
#
|
|
$em_undo->configure(-state => 'disabled');
|
|
@undo_stack = ();
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: file_saveas()
|
|
#
|
|
sub file_saveas
|
|
{
|
|
my $fowin; # File-open widget.
|
|
my $newfile; # New file's name.
|
|
my %fsopts; # FileSelect() options.
|
|
|
|
#
|
|
# Set up options for FileSelect.
|
|
#
|
|
%fsopts = (-directory => '.');
|
|
$fsopts{'-filter'} = '*.rrf' if($namefilter);
|
|
|
|
#
|
|
# Prompt for the new file.
|
|
#
|
|
$fowin = $wm->FileSelect(%fsopts);
|
|
$newfile = $fowin->Show;
|
|
return if($newfile eq "");
|
|
|
|
#
|
|
# Make sure the user *really* wants to overwrite an existing file.
|
|
# Continue if they do, return if they don't.
|
|
#
|
|
if(-e $newfile)
|
|
{
|
|
my $dlg; # Warning dialog widget.
|
|
my $ret; # Warning response.
|
|
|
|
$dlg = $wm->Dialog(-title => 'Warning',
|
|
-text => "$newfile already exists; overwrite?",
|
|
-buttons => ["Overwrite","Cancel"]);
|
|
$ret = $dlg->Show();
|
|
|
|
return if($ret eq "Cancel");
|
|
}
|
|
|
|
#
|
|
# Save the file.
|
|
#
|
|
rollrec_saveas($newfile);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: file_quit()
|
|
#
|
|
sub file_quit
|
|
{
|
|
#
|
|
# Destroy the rollrec name table's widgets.
|
|
#
|
|
if($rrnametab)
|
|
{
|
|
$rrnametab->clear;
|
|
$rrnametab->destroy;
|
|
}
|
|
|
|
#
|
|
# Warn the user if this file has been modified. We'll also give
|
|
# the user a chance to save the file, not save the file, or cancel
|
|
# the process of opening the new file.
|
|
#
|
|
if($modified)
|
|
{
|
|
my $dlg; # Warning dialog widget.
|
|
my $ret; # Warning response.
|
|
|
|
$dlg = $wm->Dialog(-title => 'Warning',
|
|
-text => "$curnode has been modified; save before proceeding?",
|
|
-buttons => ["Save","Don't Save","Cancel"]);
|
|
$ret = $dlg->Show();
|
|
|
|
return if($ret eq "Cancel");
|
|
|
|
rollrec_close() if($ret eq "Save");
|
|
}
|
|
else
|
|
{
|
|
rollrec_discard();
|
|
}
|
|
|
|
#
|
|
# Destroy the main window. This will cause MainLoop() to return,
|
|
# leading to the program exiting.
|
|
#
|
|
$wm->destroy;
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: edit_undo()
|
|
#
|
|
sub edit_undo
|
|
{
|
|
my $undohash; # First hash from undo stack.
|
|
|
|
my $type; # Undo type.
|
|
my $op; # Undo operation.
|
|
my $field; # Undo field.
|
|
my $value; # Undo value.
|
|
|
|
#
|
|
# Ensure we have something to undo.
|
|
#
|
|
return if(@undo_stack == 0);
|
|
|
|
#
|
|
# Get the undo entry fields.
|
|
#
|
|
$undohash = shift @undo_stack;
|
|
$type = $undohash->{'type'};
|
|
$op = $undohash->{'op'};
|
|
$field = $undohash->{'field'};
|
|
$value = $undohash->{'value'};
|
|
|
|
#
|
|
# Undo based on the operation. This means that creates are deleted,
|
|
# deletes are re-created, and modifies are returned to the old ways.
|
|
#
|
|
if($op eq "create")
|
|
{
|
|
my @signset; # Signing set's keyrecs.
|
|
|
|
#
|
|
# Since we can only create signing sets, that's the only
|
|
# create operation we'll be able to undo.
|
|
#
|
|
if($type eq "signing_set")
|
|
{
|
|
#
|
|
# Delete the signing set name from each keyrec
|
|
# in the set.
|
|
#
|
|
@signset = keyrec_signsets($field);
|
|
foreach my $kr (@signset)
|
|
{
|
|
keyrec_signset_delkey($field,$kr);
|
|
}
|
|
|
|
#
|
|
# Delete the signing set name from our list of names.
|
|
#
|
|
for(my $ind=0; $ind < @ssnames; $ind++)
|
|
{
|
|
if($ssnames[$ind] eq $field)
|
|
{
|
|
splice @ssnames, $ind, 1;
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
elsif($op eq "delete")
|
|
{
|
|
my @signset; # Signing set's keyrecs.
|
|
|
|
#
|
|
# If the signing set was deleted, we'll add the signing set
|
|
# to each keyrec in the set.
|
|
# If the keyrec was deleted, we'll add each signing set in
|
|
# the record to the named keyrec.
|
|
#
|
|
if($type eq "signing_set")
|
|
{
|
|
#
|
|
# Add the signing set name to each keyrec in the set.
|
|
#
|
|
@signset = split / /, $value;
|
|
foreach my $kr (sort(@signset))
|
|
{
|
|
keyrec_signset_addkey($field,$kr);
|
|
}
|
|
|
|
#
|
|
# Add the new set's name to the list of signing sets.
|
|
#
|
|
push @ssnames, $field;
|
|
@ssnames = sort(@ssnames);
|
|
}
|
|
elsif($type eq "keyrec")
|
|
{
|
|
#
|
|
# Add each signing set name to the keyrec.
|
|
#
|
|
@signset = split / /, $value;
|
|
|
|
foreach my $ssn (@signset)
|
|
{
|
|
keyrec_signset_addkey($ssn,$field);
|
|
}
|
|
|
|
#
|
|
# Add the keyrec's set list back to the keyrec list.
|
|
#
|
|
$key_lists{$field} = $value;
|
|
push @krnames, $field;
|
|
@krnames = sort(@krnames);
|
|
}
|
|
|
|
}
|
|
elsif($op eq "modify")
|
|
{
|
|
#
|
|
# Handle the modify command for signing sets.
|
|
#
|
|
if($type eq "signing_set")
|
|
{
|
|
my @keylist; # List of keys.
|
|
my $newlist; # Keys to be replaced.
|
|
|
|
#
|
|
# Delete the keys from the signing set.
|
|
#
|
|
$newlist = keyrec_recval($field,'keys');
|
|
@keylist = split / /, $newlist;
|
|
foreach my $key (@keylist)
|
|
{
|
|
keyrec_signset_delkey($field,$key);
|
|
}
|
|
|
|
#
|
|
# Restore the old keys to the signing set.
|
|
#
|
|
@keylist = split / /, $value;
|
|
foreach my $key (@keylist)
|
|
{
|
|
keyrec_signset_addkey($field,$key);
|
|
}
|
|
}
|
|
elsif($type eq "keyrec")
|
|
{
|
|
#
|
|
# Handle the modify command for keys.
|
|
#
|
|
my $kk = $field; # Key we're undoing.
|
|
|
|
#
|
|
# Go through all the signing sets to see which need
|
|
# an undo operation.
|
|
#
|
|
foreach my $set (keyrec_signsets())
|
|
{
|
|
my $kfound; # Key-found flag.
|
|
my $sfound = 0; # Set-found flag.
|
|
my @undosets = split / /, $value;
|
|
|
|
#
|
|
# Figure out if this set holds this key.
|
|
#
|
|
$kfound = keyrec_signset_haskey($set,$kk);
|
|
|
|
#
|
|
# Go through the undo set to see if it
|
|
# contains this set.
|
|
#
|
|
foreach my $sset (@undosets)
|
|
{
|
|
if($set eq $sset)
|
|
{
|
|
$sfound = 1;
|
|
last;
|
|
}
|
|
}
|
|
|
|
#
|
|
# If the set is in the undo set and it doesn't
|
|
# have the key, add it back in.
|
|
# If the set is not in the undo set and it has
|
|
# the key, take it back out.
|
|
#
|
|
if($sfound)
|
|
{
|
|
if(!$kfound)
|
|
{
|
|
keyrec_signset_addkey($set,$kk);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if($kfound)
|
|
{
|
|
keyrec_signset_delkey($set,$kk);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Disable the undo menu option if this was the last undo item.
|
|
#
|
|
$em_undo->configure(-state => 'disabled') if(@undo_stack == 0);
|
|
|
|
#
|
|
# Update the window and decrement our modifications counter.
|
|
#
|
|
$modified--;
|
|
settitle($curnode);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: undo_add()
|
|
#
|
|
sub undo_add
|
|
{
|
|
my %undo = (); # Undo hash.
|
|
|
|
#
|
|
# Add the arguments to our undo hash.
|
|
#
|
|
$undo{'type'} = shift;
|
|
$undo{'op'} = shift;
|
|
$undo{'field'} = shift;
|
|
$undo{'value'} = shift;
|
|
|
|
#
|
|
# Add the undo hash to the beginning of the undo stack.
|
|
#
|
|
unshift @undo_stack, \%undo;
|
|
|
|
#
|
|
# Make sure the undo menu option is enabled.
|
|
#
|
|
$em_undo->configure(-state => 'normal');
|
|
|
|
return;
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: cmds_create()
|
|
#
|
|
sub cmds_create
|
|
{
|
|
my $dlg; # Dialog box.
|
|
my $lab; # Label widget.
|
|
my $ent; # Entry widget.
|
|
my $ret; # Dialog box return.
|
|
|
|
my $rrn; # New rollrec's name.
|
|
|
|
# print STDERR "cmds_create: down in New Rollrec\n";
|
|
|
|
#
|
|
# Create a new dialog box to get the name of the new rollrec entry.
|
|
#
|
|
$dlg = $wm->DialogBox(-title => 'New Rollrec Name',
|
|
-buttons => ["Create", "Cancel" ]);
|
|
|
|
#
|
|
# Add a description...
|
|
#
|
|
$lab = $dlg->add('Label', -text => 'Enter new rollrec name: ');
|
|
$lab->pack(-side => 'left');
|
|
|
|
#
|
|
# ... and a text entry slot, focus on the entry ...
|
|
#
|
|
$ent = $dlg->add('Entry');
|
|
$ent->pack(-side => 'left');
|
|
$dlg->configure(-focus => $ent);
|
|
|
|
#
|
|
# ... mix, stir, and *voila*! We've got a dialog box.
|
|
#
|
|
$ret = $dlg->Show();
|
|
|
|
#
|
|
# Drop out if the user changed their mind.
|
|
#
|
|
return if($ret eq "Cancel");
|
|
|
|
#
|
|
# Get the user's requested name.
|
|
#
|
|
$rrn = $ent->get();
|
|
|
|
#
|
|
# Give a warning if this rollrec already exists.
|
|
#
|
|
if(rollrec_exists($rrn,'zonefile'))
|
|
{
|
|
my $dlg; # Warning dialog widget.
|
|
my $ret; # Warning response.
|
|
|
|
$dlg = $wm->Dialog(-title => 'Warning',
|
|
-text => "Rollrec $rrn already exists",
|
|
-buttons => ["Re-enter Name", "Cancel" ]);
|
|
$ret = $dlg->Show();
|
|
|
|
#
|
|
# Drop out if the user changed their mind.
|
|
#
|
|
return if($ret eq "Cancel");
|
|
|
|
#
|
|
# Let the user try again.
|
|
#
|
|
cmds_create();
|
|
}
|
|
|
|
#
|
|
# Set up an edit window for the zone name.
|
|
#
|
|
editwindow($rrn,1);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: cmds_delete()
|
|
#
|
|
sub cmds_delete
|
|
{
|
|
my @selected = (); # Selected rollrec indices.
|
|
my @selnames = (); # Selected rollrec names
|
|
my $numsel; # Number of selected rollrecs.
|
|
|
|
my $ret; # Warning response.
|
|
|
|
my $dlg; # Warning dialog widget.
|
|
my $nametab; # Name table.
|
|
my $lab; # Label for table.
|
|
my $rowind = 0; # Name table row index.
|
|
|
|
# print STDERR "cmds_delete: down in Delete Selected Rollrecs\n";
|
|
|
|
#
|
|
# Get the list of selected rollrec indices.
|
|
#
|
|
@selected = selected_rrnames();
|
|
$numsel = @selected;
|
|
|
|
#
|
|
# Build the dialog box.
|
|
#
|
|
$dlg = $wm->DialogBox(-title => 'Delete Warning',
|
|
-buttons => ["Delete", "Cancel" ]);
|
|
|
|
#
|
|
# Add a description.
|
|
#
|
|
$lab = $dlg->add('Label', -text => ' Delete the following rollrecs:');
|
|
$lab->pack(-anchor => 'w', -side => 'top');
|
|
|
|
#
|
|
# Build a table to hold the rollrec names.
|
|
#
|
|
$nametab = $dlg->Table(-rows => $numsel,
|
|
-columns => 1,
|
|
-relief => 'raised',
|
|
-scrollbars => '',
|
|
-borderwidth => 1,
|
|
-fixedrows => 0,
|
|
-takefocus => 1,
|
|
);
|
|
|
|
#
|
|
# Add the selected rollrec names to the table.
|
|
#
|
|
foreach my $ind (sort {$a <=> $b} @selected)
|
|
{
|
|
my $txt; # Label text.
|
|
|
|
$txt = " $rrnames[$ind]";
|
|
|
|
$lab = $nametab->Label(-text => $txt,-anchor => 'w');
|
|
$lab->pack(-fill => 'x', -side => 'top');
|
|
|
|
$nametab->put($rowind,0,$lab);
|
|
$rowind++;
|
|
}
|
|
|
|
#
|
|
# Pack the name table.
|
|
#
|
|
$nametab->pack(-side => 'top');
|
|
|
|
#
|
|
# Display the dialog box.
|
|
#
|
|
$ret = $dlg->Show();
|
|
|
|
#
|
|
# Check for a "don't do this" response.
|
|
#
|
|
return if($ret eq "Cancel");
|
|
|
|
#
|
|
# Delete and deselect the selected rollrecs.
|
|
#
|
|
foreach my $rrind (sort {$a <=> $b} @selected)
|
|
{
|
|
rollrec_del($rrnames[$rrind]);
|
|
rrname_deselect($rrind);
|
|
}
|
|
|
|
#
|
|
# Delete the selected rollrec names from the list of rollrecs.
|
|
#
|
|
foreach my $rrind (sort {$b <=> $a} @selected)
|
|
{
|
|
splice @rrnames, $rrind, 1;
|
|
$numrrnames--;
|
|
}
|
|
|
|
#
|
|
# Rebuild the button table.
|
|
#
|
|
buildtable(0);
|
|
|
|
#
|
|
# Set the modified flag.
|
|
#
|
|
$modified++;
|
|
settitle($title);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: cmds_modify()
|
|
#
|
|
# Purpose: This routine creates edit windows for the selected rollrecs.
|
|
#
|
|
sub cmds_modify
|
|
{
|
|
my @selected = (); # Selected rollrec names.
|
|
my $numsel; # Number of selected rollrecs.
|
|
|
|
# print STDERR "cmds_modify: down in Edit Selected Rollrecs\n";
|
|
|
|
#
|
|
# Get the list of selected rollrec names.
|
|
#
|
|
@selected = selected_rrnames();
|
|
$numsel = @selected;
|
|
|
|
#
|
|
# Create the edit windows.
|
|
#
|
|
foreach my $rrind (sort(@selected))
|
|
{
|
|
editwindow($rrnames[$rrind],0);
|
|
}
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: cmds_merger()
|
|
#
|
|
# Purpose: This routine merges two rollrec files.
|
|
#
|
|
sub cmds_merger
|
|
{
|
|
my $curfile = $rrfile; # Current rollrec file.
|
|
my $newfile; # New rollrec file.
|
|
|
|
my @curnames = (); # Rollrec names from cur file.
|
|
my %curnames = (); # Rollrec name hash -- cur file.
|
|
my @newnames = (); # Rollrec names from new file.
|
|
|
|
my @dupnames = (); # Duplicated rollrec names.
|
|
|
|
my %currrs = (); # Saved rollrecs from cur file.
|
|
my %newrrs = (); # Saved rollrecs from new file.
|
|
|
|
my $fswin; # FileSelect window widget.
|
|
my %fsopts; # Options for FileSelect.
|
|
my $name; # Rollrec name.
|
|
my $rref; # Rollrec reference.
|
|
|
|
# print STDERR "cmds_merger: down in Merge Rollrec Files\n";
|
|
|
|
#
|
|
# Ensure that the currently loaded rollrec matches the version on
|
|
# disk. If not, don't let the merge happen.
|
|
#
|
|
if($modified)
|
|
{
|
|
errorbox_multi("$curfile has been modified. Unable to merge until changes have been saved");
|
|
return;
|
|
}
|
|
|
|
#
|
|
# Save the rollrec data from the currently open rollrec file.
|
|
#
|
|
@curnames = rollrec_names();
|
|
foreach $name (@curnames)
|
|
{
|
|
$rref = rollrec_fullrec($name);
|
|
$currrs{$name} = $rref;
|
|
$curnames{$name} = 1;
|
|
}
|
|
|
|
#
|
|
# Set up options for FileSelect.
|
|
#
|
|
%fsopts = (
|
|
-directory => '.',
|
|
-filelabel => 'File To Be Merged'
|
|
);
|
|
$fsopts{'-filter'} = '*.rrf' if($namefilter);
|
|
|
|
#
|
|
# Get the name of the file to be merged with the current file.
|
|
# We'll call this the "new" file.
|
|
#
|
|
while(42)
|
|
{
|
|
my $cdev; # Current rollrec's filesys devicenum.
|
|
my $cino; # Current rollrec's inode number.
|
|
my $ndev; # New rollrec's filesys devicenum.
|
|
my $nino; # New rollrec's inode number.
|
|
|
|
#
|
|
# Let the user select a new file.
|
|
#
|
|
$fswin = $wm->FileSelect(%fsopts);
|
|
$newfile = $fswin->Show;
|
|
|
|
#
|
|
# Return if the user canceled out of the dialog.
|
|
#
|
|
return if($newfile eq '');
|
|
|
|
#
|
|
# Get the file info for the current and new rollrec files.
|
|
#
|
|
($cdev,$cino) = stat($curfile);
|
|
($ndev,$nino) = stat($newfile);
|
|
|
|
#
|
|
# Drop out of the loop if the two files have different
|
|
# inode numbers or file system device numbers.
|
|
#
|
|
last if(($cino != $nino) || ($cdev != $ndev));
|
|
|
|
#
|
|
# Give an error message about the two files.
|
|
#
|
|
errorbox_multi("Cannot merge a rollrec file with itself.\nCurrent rollrec - $curfile\nNew rollrec - $newfile");
|
|
}
|
|
|
|
#
|
|
# Ensure the new file is actually a rollrec file.
|
|
#
|
|
if(dt_filetype($newfile) ne "rollrec")
|
|
{
|
|
my $curnode = getnode($newfile);
|
|
|
|
errorbox("$curnode is not a rollrec file; unable to continue merge");
|
|
return;
|
|
}
|
|
|
|
#
|
|
# Read the new file. If we couldn't read it, we'll put up a dialog
|
|
# box explaining the problem.
|
|
#
|
|
if(rollrec_read($newfile) < 0)
|
|
{
|
|
my $curnode = getnode($newfile);
|
|
|
|
errorbox_multi("Unable to read rollrec file $curnode. Check to ensure the file exists and is readable.\nComplete path - $newfile");
|
|
return;
|
|
}
|
|
|
|
#
|
|
# Save the rollrec data from the new rollrec file.
|
|
#
|
|
@newnames = rollrec_names();
|
|
foreach $name (@newnames)
|
|
{
|
|
$rref = rollrec_fullrec($name);
|
|
$newrrs{$name} = $rref;
|
|
}
|
|
|
|
#
|
|
# Check for overlapping names in the two rollrecs.
|
|
#
|
|
foreach $name (@newnames)
|
|
{
|
|
push @dupnames, $name if(defined($curnames{$name}));
|
|
}
|
|
|
|
#
|
|
# Re-read the original file.
|
|
#
|
|
rollrec_close();
|
|
rollrec_read($rrfile);
|
|
|
|
#
|
|
# If we've got any duplicate names, we'll report them and let the
|
|
# user decide whether or not to continue.
|
|
#
|
|
if(@dupnames)
|
|
{
|
|
my $ret; # Dialog's value.
|
|
|
|
$ret = dbx_dups(@dupnames);
|
|
|
|
return if($ret eq "Cancel");
|
|
}
|
|
|
|
#
|
|
# Add the non-overlapping rollrecs to the current rollrec file.
|
|
#
|
|
foreach $name (@newnames)
|
|
{
|
|
my $rref; # Ref to rollrec.
|
|
|
|
#
|
|
# Skip the overlapping rollrecs.
|
|
#
|
|
next if(defined($curnames{$name}));
|
|
|
|
#
|
|
# Add rollrec to the in-memory version of the rollrec file.
|
|
#
|
|
$rref = $newrrs{$name};
|
|
rollrec_add($rref->{'rollrec_type'},$name,$rref);
|
|
}
|
|
|
|
#
|
|
# Rebuild the button table.
|
|
#
|
|
@rrnames = rollrec_names();
|
|
$numrrnames = @rrnames;
|
|
buildtable(0);
|
|
|
|
#
|
|
# Set the modified flag.
|
|
#
|
|
$modified++;
|
|
settitle($title);
|
|
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: cmds_rename()
|
|
#
|
|
# Purpose: This routine creates the rename rollrec window for the
|
|
# selected rollrec.
|
|
#
|
|
sub cmds_rename
|
|
{
|
|
my @selected = (); # Selected rollrec names.
|
|
my $numsel; # Number of selected rollrecs.
|
|
my $rrind; # Index of selected rollrec.
|
|
my $dbx; # Error dialog box.
|
|
|
|
# print STDERR "cmds_rename: down in Rename Selected Rollrec\n";
|
|
|
|
#
|
|
# Get the list of selected rollrec names.
|
|
#
|
|
@selected = selected_rrnames();
|
|
$numsel = @selected;
|
|
|
|
#
|
|
# Complain if there wasn't a selected rollrec.
|
|
#
|
|
if($numsel == 0)
|
|
{
|
|
$dbx = $wm->Dialog(-title => 'Rename Selected Rollrec',
|
|
-text => "One rollrec must be selected to use the Rename Rollrec command",
|
|
-buttons => ["Okay"]);
|
|
$dbx->Show();
|
|
return;
|
|
}
|
|
|
|
#
|
|
# Complain if there was more than one selected rollrec.
|
|
#
|
|
if($numsel > 1)
|
|
{
|
|
$dbx = $wm->Dialog(-title => 'Rename Selected Rollrec',
|
|
-text => "A single rollrec must be selected to use the Rename Rollrec command",
|
|
-buttons => ["Okay"]);
|
|
$dbx->Show();
|
|
return;
|
|
}
|
|
|
|
#
|
|
# Let user know that modified rollrecs must be saved prior to the
|
|
# rollrec rename. If the user is okay with this, we'll save the
|
|
# contents of the rollrec.
|
|
#
|
|
if($modified)
|
|
{
|
|
my $dret; # Return value from dialog.
|
|
|
|
$dbx = $wm->Dialog(-title => 'Rename Selected Rollrec',
|
|
-text => "The rollrec file has been modified. In order to rename the selected rollrec, the changes will be saved to the rollrec file",
|
|
-buttons => ["Okay", "Cancel"]);
|
|
|
|
$dret = $dbx->Show();
|
|
return if($dret eq 'Cancel');
|
|
|
|
file_save();
|
|
}
|
|
|
|
#
|
|
# Create the rename-rollrec window.
|
|
#
|
|
$rrind = $selected[0];
|
|
renamewindow($rrnames[$rrind]);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: cmds_verify()
|
|
#
|
|
# Purpose: This routine verifies a rollrec file. If the summary flag
|
|
# was given, then a dialog box will be created that contains
|
|
# the names and error counts of each bad rollrec. If the
|
|
# summary flag wasn't given, then an edit window will be
|
|
# put up for each bad rollrec.
|
|
#
|
|
sub cmds_verify
|
|
{
|
|
my $summary = shift; # Summary-only flag.
|
|
|
|
my %errcnts = (); # Counts of errors.
|
|
my $errcnt = 0; # Rollrecs with errors.
|
|
|
|
my $dbx; # Dialog box.
|
|
my $rrtab; # Bad rollrec table.
|
|
my $lab; # Label for table.
|
|
my $rowind = 0; # Error table row index.
|
|
|
|
my $errrows; # Rows in table.
|
|
my $sbars = 'e'; # Scrollbars.
|
|
|
|
# print STDERR "cmds_verify: down in Verify Rollrec File\n";
|
|
|
|
#
|
|
# See if any rollrecs have problems.
|
|
#
|
|
foreach my $rrn (reverse(sort(@rrnames)))
|
|
{
|
|
my $errors = 0; # Errors for rollrec.
|
|
my $warns = 0; # Warnings for rollrec.
|
|
my $problems; # Errs and/or warns for rollrec.
|
|
|
|
#
|
|
# Check this rollrec.
|
|
#
|
|
($warns,$errors) = goodrollrec($rrn,0);
|
|
|
|
#
|
|
# Get the count of rollrec problems. If there were any
|
|
# problems, add 'em to the error count hash.
|
|
#
|
|
$problems = $errors;
|
|
$problems += $warns if($givewarnings);
|
|
if($problems)
|
|
{
|
|
$errcnts{$rrn}{'warns'} = $warns;
|
|
$errcnts{$rrn}{'errors'} = $errors;
|
|
|
|
$errcnt++;
|
|
}
|
|
|
|
#
|
|
# If there were problems and the user wants more than a
|
|
# summary, we'll put up an edit window for the rollrec
|
|
# and mark up its problem fields.
|
|
#
|
|
if($problems && !$summary)
|
|
{
|
|
editwindow($rrn,0);
|
|
goodrollrec($rrn,1);
|
|
}
|
|
}
|
|
|
|
#
|
|
# If there weren't any errors, we'll put up a dialog box saying so
|
|
# and then return once it's dismissed.
|
|
#
|
|
if($errcnt == 0)
|
|
{
|
|
$dbx = $wm->Dialog(-title => 'Rollrecs Valid',
|
|
-text => "Rollrecs passed validity checks",
|
|
-buttons => ["Done"]);
|
|
$dbx->Show();
|
|
return;
|
|
}
|
|
|
|
#
|
|
# Return if the user doesn't want an error summary.
|
|
#
|
|
return if(!$summary);
|
|
|
|
#
|
|
# Get the row count, which is the number of erring rollrecs plus
|
|
# a header row.
|
|
# If there's only a few rows, we'll dump the scrollbar.
|
|
#
|
|
$errrows = $errcnt + 1;
|
|
$sbars = '' if($errrows < 4);
|
|
|
|
#
|
|
# Build a dialog box to hold an error summary.
|
|
#
|
|
$dbx = $wm->DialogBox(-title => 'Rollrecs With Errors',
|
|
-buttons => ["Done"]);
|
|
|
|
#
|
|
# Build a table to hold the rollrec names.
|
|
#
|
|
$rrtab = $dbx->Table(-rows => $errrows,
|
|
-columns => 3,
|
|
-relief => 'raised',
|
|
-scrollbars => $sbars,
|
|
-borderwidth => 1,
|
|
-fixedrows => 0,
|
|
-takefocus => 1,
|
|
);
|
|
|
|
#
|
|
# Add some column headers.
|
|
#
|
|
$lab = $rrtab->Label(-text => 'Rollrec');
|
|
$rrtab->put($rowind,0,$lab);
|
|
$lab = $rrtab->Label(-text => 'Warnings');
|
|
$rrtab->put($rowind,1,$lab);
|
|
$lab = $rrtab->Label(-text => 'Errors');
|
|
$rrtab->put($rowind,2,$lab);
|
|
$rowind++;
|
|
|
|
#
|
|
# Add the selected rollrec names to the table.
|
|
#
|
|
foreach my $rrn (sort(keys(%errcnts)))
|
|
{
|
|
my $err = $errcnts{$rrn}{'errors'};
|
|
my $wrn = $errcnts{$rrn}{'warns'};
|
|
|
|
$lab = $rrtab->Label(-text => $rrn);
|
|
$rrtab->put($rowind,0,$lab);
|
|
$lab = $rrtab->Label(-text => $wrn);
|
|
$rrtab->put($rowind,1,$lab);
|
|
$lab = $rrtab->Label(-text => $err);
|
|
$rrtab->put($rowind,2,$lab);
|
|
$rowind++;
|
|
}
|
|
|
|
#
|
|
# Pack the error table.
|
|
#
|
|
$rrtab->pack(-side => 'top');
|
|
|
|
#
|
|
# Display the dialog box.
|
|
#
|
|
$dbx->Show();
|
|
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: view_selall()
|
|
#
|
|
# Purpose: This routine selects/deselects all rollrec names.
|
|
# If any names are selected, the remainder will be selected.
|
|
# If all names are selected, they will all be deselected.
|
|
#
|
|
sub view_selall
|
|
{
|
|
my @selected = (); # Selected rollrec names.
|
|
|
|
# print STDERR "view_selall: down in Select All Rollrecs\n";
|
|
|
|
#
|
|
# Get the list of selected rollrec names.
|
|
#
|
|
@selected = selected_rrnames();
|
|
|
|
#
|
|
# If all the names are selected, we'll deselect everything.
|
|
# If not all the names are selected, we'll select them all.
|
|
#
|
|
if(@selected == $numrrnames)
|
|
{
|
|
#
|
|
# Unselect all names.
|
|
#
|
|
for(my $ind = 0; $ind < $numrrnames; $ind++)
|
|
{
|
|
rrname_deselect($ind);
|
|
}
|
|
$vw_selall->configure(-label => 'Select All Rollrecs');
|
|
}
|
|
else
|
|
{
|
|
#
|
|
# Select all names.
|
|
#
|
|
for(my $ind=0; $ind < $numrrnames; $ind++)
|
|
{
|
|
my $col; # Column index.
|
|
my $row; # Row index.
|
|
my $btn; # Rollrec button.
|
|
|
|
($col,$row) = ind2cr($ind);
|
|
$btn = $rrnametab->get($row,$col);
|
|
|
|
rrname_select($ind) if($btn->cget(-background) eq $RRTAB_UNSEL);
|
|
}
|
|
$vw_selall->configure(-label => 'Unselect All Rollrecs');
|
|
|
|
}
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: view_raiser()
|
|
#
|
|
# Purpose: This routine brings the rollrec edit windows to the front.
|
|
#
|
|
sub view_raiser
|
|
{
|
|
|
|
# print STDERR "view_raiser: down in Raise Rollrec Edit Windows\n";
|
|
|
|
#
|
|
# Raise the edit windows.
|
|
#
|
|
foreach my $rrn (reverse(sort(keys(%editwinds))))
|
|
{
|
|
$editwinds{$rrn}->raise;
|
|
}
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: view_closeall()
|
|
#
|
|
# Purpose: This routine closes the selected rollrec edit windows.
|
|
# The rollrec's buttons are deselected as well.
|
|
#
|
|
sub view_closeall
|
|
{
|
|
# print STDERR "view_closeall: down in Close All Selected Rollrecs\n";
|
|
|
|
#
|
|
# Destroy all edit windows and remove them from the edit-window list.
|
|
#
|
|
foreach my $rrn (sort(keys(%editwinds)))
|
|
{
|
|
editbegone($rrn);
|
|
}
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: view_closeone()
|
|
#
|
|
# Purpose: This routine closes the current rollrec edit window.
|
|
# The rollrec's button is deselected as well.
|
|
#
|
|
sub view_closeone
|
|
{
|
|
my $rrn = shift;
|
|
|
|
# print STDERR "view_closeone: down in Close Selected Rollrec\n";
|
|
editbegone($rrn);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: editwindow()
|
|
#
|
|
# Purpose: This routine creates a new rollrec-edit window.
|
|
#
|
|
sub editwindow
|
|
{
|
|
my $rrn = shift; # Name of rollrec to edit.
|
|
my $newflag = shift; # New-rollrec flag.
|
|
|
|
my $editwin; # Edit window.
|
|
my $eframe; # Edit frame.
|
|
my $edittab; # Edit table.
|
|
my $etlen = @ET_LABELS; # Row-length of table.
|
|
|
|
my $frm; # Frame widget.
|
|
my $lab; # Label widget.
|
|
my $ent; # Entry widget.
|
|
my $rb; # Radiobutton widget.
|
|
my $btn; # Button widget.
|
|
my $casca; # Cascading menu widget.
|
|
|
|
my $rrec; # Rollrec reference.
|
|
my $llev; # Logging level.
|
|
|
|
# print STDERR "editwindow: down in Edit Selected Rollrecs\n";
|
|
|
|
#
|
|
# If we've already got an edit window for this rollrec, we'll raise
|
|
# that window and return.
|
|
#
|
|
if(defined($editwinds{$rrn}))
|
|
{
|
|
$editwinds{$rrn}->focus;
|
|
return;
|
|
}
|
|
|
|
#
|
|
# Get this rollrec's data.
|
|
#
|
|
$rrec = rollrec_fullrec($rrn);
|
|
|
|
#
|
|
# If this is a new rollrec, we'll set some defaults.
|
|
#
|
|
if(!rollrec_exists($rrn))
|
|
{
|
|
$rrec->{'rollrec_type'} = 'roll';
|
|
$rrec->{'keyrec'} = "$rrn.krf";
|
|
$rrec->{'zonefile'} = "$rrn.signed";
|
|
$rrec->{'zonename'} = "$rrn";
|
|
}
|
|
|
|
#
|
|
# Add the rollrec's data to the %rollrecs hash.
|
|
#
|
|
$rollrecs{$rrn}{'administrator'} = $rrec->{'administrator'};
|
|
$rollrecs{$rrn}{'directory'} = $rrec->{'directory'};
|
|
$rollrecs{$rrn}{'display'} = $rrec->{'display'};
|
|
$rollrecs{$rrn}{'keyrec'} = $rrec->{'keyrec'};
|
|
$rollrecs{$rrn}{'loglevel'} = $rrec->{'loglevel'};
|
|
$rollrecs{$rrn}{'maxttl'} = $rrec->{'maxttl'};
|
|
$rollrecs{$rrn}{'rollrec_type'} = $rrec->{'rollrec_type'};
|
|
$rollrecs{$rrn}{'zonefile'} = $rrec->{'zonefile'};
|
|
$rollrecs{$rrn}{'zonegroup'} = $rrec->{'zonegroup'};
|
|
|
|
if(!defined($rrec->{'zonename'}))
|
|
{
|
|
$rollrecs{$rrn}{'zonename'} = $rrn;
|
|
}
|
|
else
|
|
{
|
|
$rollrecs{$rrn}{'zonename'} = $rrec->{'zonename'};
|
|
}
|
|
|
|
#
|
|
# Set up the radio buttons' data areas for the record type and
|
|
# the display flag.
|
|
#
|
|
$editrbs{$rrn} = $rollrecs{$rrn}{'rollrec_type'} eq 'roll' ? 1 : 0;
|
|
if(!exists($rollrecs{$rrn}{'display'}) ||
|
|
!defined($rollrecs{$rrn}{'display'}))
|
|
{
|
|
$editdfs{$rrn} = -1;
|
|
}
|
|
elsif($rollrecs{$rrn}{'display'} == 0)
|
|
{
|
|
$editdfs{$rrn} = 0;
|
|
}
|
|
elsif($rollrecs{$rrn}{'display'} == 1)
|
|
{
|
|
$editdfs{$rrn} = 1;
|
|
}
|
|
|
|
#
|
|
# Create a new window to hold our edit session. Bind up some
|
|
# key accelerators, too.
|
|
#
|
|
$editwin = MainWindow->new(-relief => 'raised',
|
|
-title => "$rrn",
|
|
-borderwidth => 1);
|
|
|
|
$editwin->bind('<Control-Key-q>', \&file_quit);
|
|
$editwin->bind('<Control-Key-w>', [\&editbegone, $rrn]);
|
|
$editwin->bind('<Control-Key-c>', \&view_closeone);
|
|
$editwin->bind('<Control-Key-k>', \&view_closeall);
|
|
|
|
#
|
|
# Now make the containers for the window.
|
|
#
|
|
$eframe = $editwin->Frame(-relief => 'raised', -borderwidth => 1);
|
|
$eframe->pack(-fill => 'x');
|
|
|
|
#
|
|
# Create a table to hold the rollrec data.
|
|
#
|
|
$edittab = $eframe->Table(-rows => $etlen,
|
|
-columns => 2,
|
|
-relief => 'raised',
|
|
-scrollbars => '',
|
|
-borderwidth => 1,
|
|
-fixedrows => 0,
|
|
-takefocus => 1,
|
|
);
|
|
|
|
#----------------
|
|
#
|
|
# Set the field column.
|
|
#
|
|
for(my $ind = $ROW_FIRST; $ind <= $ROW_LAST; $ind++)
|
|
{
|
|
$lab = $eframe->Label(-text => $ET_LABELS[$ind],-anchor => 'w');
|
|
$lab->pack(-fill => 'x', -side => 'top');
|
|
$edittab->put($ind,$COL_FIELD,$lab);
|
|
}
|
|
|
|
#----------------
|
|
#
|
|
# Record type: Add the stuff for the record type.
|
|
#
|
|
$frm = $eframe->Frame(-relief => 'raised', -borderwidth => 1);
|
|
$rb = $frm->Radiobutton(-text => 'Roll',
|
|
-variable => \$editrbs{$rrn},
|
|
-value => 1);
|
|
$rb->pack(-fill => 'x', -side => 'left');
|
|
$rb = $frm->Radiobutton(-text => 'Skip',
|
|
-variable => \$editrbs{$rrn},
|
|
-value => 0);
|
|
$rb->pack(-fill => 'x', -side => 'left');
|
|
$frm->pack(-fill => 'x', -side => 'top');
|
|
$edittab->put($ROW_TYPE,$COL_DATA,$frm);
|
|
|
|
#----------------
|
|
#
|
|
# Zonename: Add the stuff for the rollrec's zonename.
|
|
#
|
|
$ent = $eframe->Entry(-textvariable => \$rollrecs{$rrn}{'zonename'});
|
|
$ent->pack(-fill => 'x', -side => 'top');
|
|
$edittab->put($ROW_ZONENAME,$COL_DATA,$ent);
|
|
|
|
#----------------
|
|
#
|
|
# Zonefile: Add the stuff for the rollrec's zonefile.
|
|
#
|
|
$ent = $eframe->Entry(-textvariable => \$rollrecs{$rrn}{'zonefile'});
|
|
$ent->pack(-fill => 'x', -side => 'top');
|
|
$edittab->put($ROW_ZONEFILE,$COL_DATA,$ent);
|
|
|
|
#----------------
|
|
#
|
|
# Keyrec: Add the stuff for the rollrec's keyrec.
|
|
#
|
|
$ent = $eframe->Entry(-textvariable => \$rollrecs{$rrn}{'keyrec'});
|
|
$ent->pack(-fill => 'x', -side => 'top');
|
|
$edittab->put($ROW_KEYREC,$COL_DATA,$ent);
|
|
|
|
#----------------
|
|
#
|
|
# Zonegroup: Add the stuff for the rollrec's zonegroup.
|
|
#
|
|
$ent = $eframe->Entry(-textvariable => \$rollrecs{$rrn}{'zonegroup'});
|
|
$ent->pack(-fill => 'x', -side => 'top');
|
|
$edittab->put($ROW_ZONEGROUP,$COL_DATA,$ent);
|
|
|
|
#----------------
|
|
#
|
|
# Administrator: Add the stuff for the rollrec's admin mail.
|
|
#
|
|
$ent = $eframe->Entry(-textvariable => \$rollrecs{$rrn}{'administrator'});
|
|
$ent->pack(-fill => 'x', -side => 'top');
|
|
$edittab->put($ROW_ADMIN,$COL_DATA,$ent);
|
|
|
|
#----------------
|
|
#
|
|
# Directory: Add the stuff for the rollrec's directory.
|
|
#
|
|
$ent = $eframe->Entry(-textvariable => \$rollrecs{$rrn}{'directory'});
|
|
$ent->pack(-fill => 'x', -side => 'top');
|
|
$edittab->put($ROW_DIR,$COL_DATA,$ent);
|
|
|
|
#----------------
|
|
#
|
|
# Display: Add the stuff for the rollrec's display flag.
|
|
#
|
|
$frm = $eframe->Frame(-relief => 'raised', -borderwidth => 1);
|
|
$rb = $frm->Radiobutton(-text => 'On',
|
|
-variable => \$editdfs{$rrn},
|
|
-value => 1);
|
|
$rb->pack(-fill => 'x', -side => 'left');
|
|
$rb = $frm->Radiobutton(-text => 'Off',
|
|
-variable => \$editdfs{$rrn},
|
|
-value => 0);
|
|
$rb->pack(-fill => 'x', -side => 'left');
|
|
$rb = $frm->Radiobutton(-text => 'Default',
|
|
-variable => \$editdfs{$rrn},
|
|
-value => -1);
|
|
$rb->pack(-fill => 'x', -side => 'left');
|
|
$frm->pack(-fill => 'x', -side => 'top');
|
|
$edittab->put($ROW_DISPLAY,$COL_DATA,$frm);
|
|
|
|
#----------------
|
|
#
|
|
# Logging level: Add the stuff for the rollrec's log level.
|
|
#
|
|
|
|
#
|
|
# Get the label for the logging level's menu button. If it's defined
|
|
# in the rollrec, we'll make sure we have the string value. If we
|
|
# can't convert it, we'll use a dummy error value. If it isn't
|
|
# defined in the rollrec, we'll use "default" for the button label.
|
|
#
|
|
if(defined($rollrecs{$rrn}{'loglevel'}))
|
|
{
|
|
$llev = rolllog_str($rollrecs{$rrn}{'loglevel'});
|
|
if($llev eq '')
|
|
{
|
|
$llev = '<bad value in rollrec file>';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$llev = 'default';
|
|
}
|
|
|
|
#
|
|
# Create the menu button.
|
|
#
|
|
$ent = $eframe->Menubutton(-text => $llev,
|
|
-tearoff => 0);
|
|
|
|
#
|
|
# Add a new radiobutton for each logging level.
|
|
#
|
|
$casca = $ent->cascade(-label => '');
|
|
foreach $llev (rolllog_levels())
|
|
{
|
|
$casca->radiobutton(-label => "$llev",
|
|
-variable => \$rollrecs{$rrn}{'loglevel'},
|
|
-command => [\&setloglvl, $ent, $llev]);
|
|
}
|
|
|
|
#
|
|
# Add a default entry.
|
|
#
|
|
$casca->radiobutton(-label => "default",
|
|
-variable => \$rollrecs{$rrn}{'loglevel'},
|
|
-command => [\&setloglvl, $ent, 'default']);
|
|
|
|
#
|
|
# Make it all available to the user.
|
|
#
|
|
$ent->pack(-fill => 'x', -side => 'top');
|
|
$edittab->put($ROW_LOG,$COL_DATA,$ent);
|
|
|
|
#----------------
|
|
#
|
|
# Max-TTL: Add the stuff for the rollrec's maximum TTL.
|
|
#
|
|
$ent = $eframe->Entry(-textvariable => \$rollrecs{$rrn}{'maxttl'});
|
|
$ent->pack(-fill => 'x', -side => 'top');
|
|
$edittab->put($ROW_MAXTTL,$COL_DATA,$ent);
|
|
|
|
#----------------
|
|
#
|
|
# ZSArgs: Add the stuff for the rollrec's zonesigner arguments.
|
|
#
|
|
$ent = $eframe->Entry(-textvariable => \$rollrecs{$rrn}{'zsargs'});
|
|
$ent->pack(-fill => 'x', -side => 'top');
|
|
$edittab->put($ROW_ZSARGS,$COL_DATA,$ent);
|
|
|
|
#----------------
|
|
#
|
|
# Done adding our data. Do another pack, just for kicks.
|
|
#
|
|
$edittab->pack(-side => 'top');
|
|
|
|
#
|
|
# Add a button to dismiss the window.
|
|
#
|
|
$btn = $eframe->Button(-text => 'Save',
|
|
-command => [\&editsaver, $rrn, $newflag]);
|
|
$btn->pack(-side => 'left', -fill => 'x', -expand => 1);
|
|
$btn = $eframe->Button(-text => 'Cancel',
|
|
-command => [\&editbegone, $rrn]);
|
|
$btn->pack(-side => 'left', -fill => 'x', -expand => 1);
|
|
|
|
#
|
|
# Save the new edit window in the hash table of edit windows.
|
|
#
|
|
$editwinds{$rrn} = $editwin;
|
|
$edittabs{$rrn} = $edittab;
|
|
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: renamewindow()
|
|
#
|
|
# Purpose: This routine creates a new rollrec-rename window.
|
|
#
|
|
sub renamewindow
|
|
{
|
|
my $rrn = shift; # Name of rollrec to rename.
|
|
my $dbx; # Error dialog box.
|
|
|
|
my $renwin; # Rename window.
|
|
|
|
##########
|
|
|
|
my $rframe; # Rename frame.
|
|
my $rentab; # Rename table.
|
|
|
|
my $frm; # Frame widget.
|
|
my $lab; # Label widget.
|
|
my $ent; # Entry widget.
|
|
my $btn; # Button widget.
|
|
|
|
# print STDERR "renamewindow: down in Rename Rollrec\n";
|
|
|
|
#
|
|
# If there's a rename window for this rollrec, we'll give an error
|
|
# and return.
|
|
#
|
|
if(defined($renwinds{$rrn}))
|
|
{
|
|
$dbx = $wm->Dialog(-title => 'Rename Selected Rollrec',
|
|
-text => "This rollrec is already being renamed",
|
|
-buttons => ["Okay"]);
|
|
$dbx->Show();
|
|
return;
|
|
}
|
|
|
|
#
|
|
# If there's an edit window for this rollrec, we'll give an error
|
|
# and return.
|
|
#
|
|
if(defined($editwinds{$rrn}))
|
|
{
|
|
$dbx = $wm->Dialog(-title => 'Rename Selected Rollrec',
|
|
-text => "Unable to rename a rollrec while it is being edited",
|
|
-buttons => ["Okay"]);
|
|
$dbx->Show();
|
|
return;
|
|
}
|
|
|
|
#
|
|
# Create a new window to hold our rename session. Bind up some
|
|
# key accelerators, too.
|
|
#
|
|
$renwin = MainWindow->new(-relief => 'raised',
|
|
-title => "Rename $rrn",
|
|
-borderwidth => 1);
|
|
|
|
$renwin->bind('<Control-Key-q>', \&file_quit);
|
|
$renwin->bind('<Control-Key-w>', [\&renamebegone, $rrn]);
|
|
|
|
#
|
|
# Now make the containers for the window.
|
|
#
|
|
$rframe = $renwin->Frame(-relief => 'raised', -borderwidth => 1);
|
|
$rframe->pack(-fill => 'x');
|
|
|
|
#
|
|
# Create a table to hold the rollrec data.
|
|
#
|
|
$rentab = $rframe->Table(-rows => 2,
|
|
-columns => 2,
|
|
-relief => 'raised',
|
|
-scrollbars => '',
|
|
-borderwidth => 1,
|
|
-fixedrows => 0,
|
|
-takefocus => 1,
|
|
);
|
|
|
|
#
|
|
# Add the label column.
|
|
#
|
|
$lab = $rframe->Label(-text => 'New rollrec name',-anchor => 'w');
|
|
$lab->pack(-fill => 'x', -side => 'top');
|
|
$rentab->put(0,0,$lab);
|
|
|
|
#
|
|
# Add the empty field for the rollrec's new name.
|
|
#
|
|
$rollrecs{$rrn}{'newname'} = '';
|
|
$ent = $rframe->Entry(-textvariable => \$rollrecs{$rrn}{'newname'});
|
|
$ent->pack(-fill => 'x', -side => 'top');
|
|
$rentab->put(0,1,$ent);
|
|
|
|
#
|
|
# Done adding our data. Do another pack, just for kicks.
|
|
#
|
|
$rentab->pack(-side => 'top');
|
|
|
|
#
|
|
# Add a button to dismiss the window.
|
|
#
|
|
$btn = $rframe->Button(-text => 'Rename',
|
|
-command => [\&renamesaver, $rrn]);
|
|
$btn->pack(-side => 'left', -fill => 'x', -expand => 1);
|
|
$btn = $rframe->Button(-text => 'Cancel',
|
|
-command => [\&renamebegone, $rrn]);
|
|
$btn->pack(-side => 'left', -fill => 'x', -expand => 1);
|
|
|
|
#
|
|
# Save the new rename window in the hash table of rename windows.
|
|
#
|
|
$renwinds{$rrn} = $renwin;
|
|
$rentabs{$rrn} = $rentab;
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: setloglvl()
|
|
#
|
|
# Purpose: Set the logging level label in an edit window's menu button.
|
|
#
|
|
sub setloglvl
|
|
{
|
|
my $ent = shift; # Menu label to change.
|
|
my $llev = shift; # New menu label.
|
|
|
|
$ent->configure(-text => $llev);
|
|
}
|
|
|
|
##############################################################################
|
|
#
|
|
# Utility routines
|
|
#
|
|
##############################################################################
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: readrrf()
|
|
#
|
|
sub readrrf
|
|
{
|
|
my $rrf = shift; # Rollrec file.
|
|
my @names; # Rollrec names.
|
|
|
|
#
|
|
# If the specified file doesn't exist, ask the user if we should
|
|
# continue or quit.
|
|
#
|
|
if(! -e $rrf)
|
|
{
|
|
my $dlg; # Warning dialog widget.
|
|
my $ret; # Warning response.
|
|
|
|
$dlg = $wm->Dialog(-title => 'Warning',
|
|
-text => "$curnode does not exist",
|
|
-buttons => ["Continue", "Quit" ]);
|
|
$ret = $dlg->Show();
|
|
|
|
return(1) if($ret eq "Continue");
|
|
|
|
file_quit();
|
|
}
|
|
|
|
#
|
|
# Ensure the file is actually a rollrec file.
|
|
#
|
|
if(dt_filetype($rrf) ne "rollrec")
|
|
{
|
|
my $curnode = getnode($rrf);
|
|
|
|
errorbox("$curnode is not a rollrec file; unable to continue");
|
|
return(0);
|
|
}
|
|
|
|
#
|
|
# Zap the old data.
|
|
#
|
|
@rrnames = ();
|
|
@rollrecs = ();
|
|
|
|
#
|
|
# Get data from the rollrec file.
|
|
#
|
|
rollrec_read($rrf);
|
|
@rrnames = rollrec_names();
|
|
$numrrnames = @rrnames;
|
|
|
|
#
|
|
# Initialize the rollrecs hash for each rollrec.
|
|
#
|
|
foreach my $rrn (@rrnames)
|
|
{
|
|
my $rrec; # This rollrec's data.
|
|
|
|
#
|
|
# Get this rollrec's data.
|
|
#
|
|
$rrec = rollrec_fullrec($rrn);
|
|
|
|
#
|
|
# Add the rollrec's data to the %rollrecs hash.
|
|
#
|
|
$rollrecs{$rrn}{'administrator'} = $rrec->{'administrator'};
|
|
$rollrecs{$rrn}{'directory'} = $rrec->{'directory'};
|
|
$rollrecs{$rrn}{'display'} = $rrec->{'display'};
|
|
$rollrecs{$rrn}{'keyrec'} = $rrec->{'keyrec'};
|
|
$rollrecs{$rrn}{'loglevel'} = $rrec->{'loglevel'};
|
|
$rollrecs{$rrn}{'maxttl'} = $rrec->{'maxttl'};
|
|
$rollrecs{$rrn}{'rollrec_type'} = $rrec->{'rollrec_type'};
|
|
$rollrecs{$rrn}{'zonefile'} = $rrec->{'zonefile'};
|
|
$rollrecs{$rrn}{'zonegroup'} = $rrec->{'zonegroup'};
|
|
$rollrecs{$rrn}{'zonename'} = $rrec->{'zonename'};
|
|
$rollrecs{$rrn}{'zsargs'} = $rrec->{'zsargs'};
|
|
|
|
#
|
|
# Set up the radio buttons' data areas for the record type and
|
|
# the display flag.
|
|
#
|
|
$editrbs{$rrn} = $rollrecs{$rrn}{'rollrec_type'} eq 'roll' ? 1 : 0;
|
|
if(!exists($rollrecs{$rrn}{'display'}) ||
|
|
!defined($rollrecs{$rrn}{'display'}))
|
|
{
|
|
$editdfs{$rrn} = -1;
|
|
}
|
|
elsif($rollrecs{$rrn}{'display'} == 0)
|
|
{
|
|
$editdfs{$rrn} = 0;
|
|
}
|
|
elsif($rollrecs{$rrn}{'display'} == 1)
|
|
{
|
|
$editdfs{$rrn} = 1;
|
|
}
|
|
}
|
|
|
|
#
|
|
# Reset the modified-keyrec file flag.
|
|
#
|
|
$modified = 0;
|
|
settitle($curnode);
|
|
return(1);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: getnode()
|
|
#
|
|
# Purpose: Get the node of a pathname.
|
|
#
|
|
sub getnode
|
|
{
|
|
my $path = shift; # Path to nodify.
|
|
|
|
my @pathelts; # Path elements.
|
|
my $pathnode; # Last path elements.
|
|
|
|
@pathelts = split /\//, $path;
|
|
$pathnode = pop @pathelts;
|
|
|
|
return($pathnode);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: editsaver()
|
|
#
|
|
# Purpose: Save a rollrec and get rid of its edit window.
|
|
#
|
|
sub editsaver
|
|
{
|
|
my $rrn = shift; # Name of rollrec to save.
|
|
my $newflag = shift; # New-rollrec flag.
|
|
|
|
# print STDERR "editsaver: saver rollrec edits for $rrn\n";
|
|
|
|
$rollrecs{$rrn}{'display'} = $editdfs{$rrn};
|
|
|
|
#
|
|
# If this is a valid rollrec, we'll get rid of the edit window
|
|
# and save the data. If this is a new rollrec, we'll also add
|
|
# a rollrec button to the main window.
|
|
#
|
|
if(goodrollrec($rrn,1))
|
|
{
|
|
#
|
|
# If this is a new rollrec, add the name to the rollrec
|
|
# list and then rebuild the main button table.
|
|
#
|
|
if($newflag)
|
|
{
|
|
push @rrnames, $rrn;
|
|
$numrrnames++;
|
|
buildtable(0);
|
|
}
|
|
|
|
#
|
|
# Get rid of the edit window and save the rollrec data.
|
|
#
|
|
editbegone($rrn);
|
|
saverollrec($rrn);
|
|
}
|
|
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: renamesaver()
|
|
#
|
|
# Purpose: Save a rollrec and get rid of its rename window.
|
|
#
|
|
sub renamesaver
|
|
{
|
|
my $rrn = shift; # Name of rollrec to save.
|
|
my $newname; # New rollrec name.
|
|
my $newname2; # Copy of new rollrec name.
|
|
|
|
# print STDERR "renamesaver: rename rollrec edits for $rrn\n";
|
|
|
|
$newname = $rollrecs{$rrn}{'newname'};
|
|
|
|
#
|
|
# Ensure a new name was given.
|
|
#
|
|
if($newname eq '')
|
|
{
|
|
errorbox("A new rollrec name must be given");
|
|
delete $renwinds{$rrn};
|
|
delete $rentabs{$rrn};
|
|
return;
|
|
}
|
|
|
|
#
|
|
# Ensure a *valid* new name was given.
|
|
#
|
|
$newname2 = $newname;
|
|
$newname2 =~ s/[a-zA-Z0-9\/\-+_.,: \@\t]//g;
|
|
if(length($newname2) > 0)
|
|
{
|
|
errorbox("\"$newname\" is an invalid rollrec name");
|
|
delete $renwinds{$rrn};
|
|
delete $rentabs{$rrn};
|
|
return;
|
|
}
|
|
|
|
#
|
|
# Rename the rollrec.
|
|
#
|
|
rollrec_rename($rrn,$newname);
|
|
$modified = 1;
|
|
|
|
#
|
|
# Write the rollrec file contents and rebuild our rollrec list.
|
|
#
|
|
rollrec_close();
|
|
buildtable(1);
|
|
|
|
#
|
|
# Get rid of the rename window.
|
|
#
|
|
renamebegone($rrn,$newname);
|
|
$modified = 0;
|
|
}
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Routine: goodrollrec()
|
|
#
|
|
# Purpose: Ensure that the rollrec has valid data.
|
|
#
|
|
# The following fields may be empty:
|
|
# - administrator
|
|
# - directory
|
|
# - display
|
|
# - loglevel
|
|
# - maxttl
|
|
# - zonegroup
|
|
#
|
|
# Error checks are:
|
|
# - empty zonename field
|
|
# - invalid logging level
|
|
# - non-positive maxttl
|
|
# - invalid display value
|
|
# - zone file is not a regular file
|
|
# - keyrec file is not a regular file
|
|
#
|
|
# Warning checks are:
|
|
# - zone directory doesn't exist
|
|
# - zone directory isn't a directory
|
|
# - zone file doesn't exist
|
|
# - zone file isn't a regular file
|
|
# - keyrec file doesn't exist
|
|
# - keyrec file isn't a regular file
|
|
#
|
|
sub goodrollrec
|
|
{
|
|
my $rrn = shift; # Name of the rollrec.
|
|
my $upd = shift; # Update-window flag.
|
|
|
|
# print STDERR "goodrollrec: down in ($rrn)\n";
|
|
|
|
my $errors = 0; # Error count.
|
|
my $warns = 0; # Warning count.
|
|
my $problems = 0; # Problem count.
|
|
|
|
my $admin; # Administrator email address.
|
|
my $dispflag; # Display flag.
|
|
my $krfile; # Keyrec file.
|
|
my $loglevel; # Logging level.
|
|
my $maxttl; # Maximum TTL.
|
|
my $zonedir; # Directory.
|
|
my $zonefile; # Zonefile.
|
|
my $zonegroup; # Zonegroup.
|
|
my $zonename; # Zonename.
|
|
my $zsargs; # Zonesigner arguments.
|
|
|
|
#
|
|
# Reset the message fields.
|
|
#
|
|
if($upd)
|
|
{
|
|
addmsg($rrn,$COL_FIELD,0,' ');
|
|
addmsg($rrn,$COL_DATA,0,' ');
|
|
}
|
|
|
|
#
|
|
# Strip all whitespace from the beginning and end of the fields.
|
|
#
|
|
foreach my $fld (@EDITFIELDS)
|
|
{
|
|
next if(!exists($rollrecs{$rrn}{$fld}) ||
|
|
($rollrecs{$rrn}{$fld} eq ''));
|
|
$rollrecs{$rrn}{$fld} =~ s/^[ \t]*//;
|
|
$rollrecs{$rrn}{$fld} =~ s/[ \t]*$//;
|
|
}
|
|
|
|
#
|
|
# Get the rollrec data.
|
|
#
|
|
$admin = $rollrecs{$rrn}{'administrator'};
|
|
$dispflag = $rollrecs{$rrn}{'display'};
|
|
$krfile = $rollrecs{$rrn}{'keyrec'};
|
|
$loglevel = $rollrecs{$rrn}{'loglevel'};
|
|
$maxttl = $rollrecs{$rrn}{'maxttl'};
|
|
$zonedir = $rollrecs{$rrn}{'directory'};
|
|
$zonefile = $rollrecs{$rrn}{'zonefile'};
|
|
$zonegroup = $rollrecs{$rrn}{'zonegroup'};
|
|
$zsargs = $rollrecs{$rrn}{'zsargs'};
|
|
if(!defined($rollrecs{$rrn}{'zonename'}))
|
|
{
|
|
$zonename = $rrn;
|
|
}
|
|
else
|
|
{
|
|
$zonename = $rollrecs{$rrn}{'zonename'};
|
|
}
|
|
|
|
#
|
|
# Reset all the label colors.
|
|
#
|
|
if($upd)
|
|
{
|
|
fieldcolor($ROW_ZONEFILE,$rrn,$NORMALCOLOR);
|
|
fieldcolor($ROW_KEYREC,$rrn,$NORMALCOLOR);
|
|
fieldcolor($ROW_ZONEGROUP,$rrn,$NORMALCOLOR);
|
|
fieldcolor($ROW_ADMIN,$rrn,$NORMALCOLOR);
|
|
fieldcolor($ROW_DIR,$rrn,$NORMALCOLOR);
|
|
fieldcolor($ROW_DISPLAY,$rrn,$NORMALCOLOR);
|
|
fieldcolor($ROW_LOG,$rrn,$NORMALCOLOR);
|
|
fieldcolor($ROW_MAXTTL,$rrn,$NORMALCOLOR);
|
|
fieldcolor($ROW_ZSARGS,$rrn,$NORMALCOLOR);
|
|
}
|
|
|
|
#
|
|
# Check the zonename.
|
|
#
|
|
if($zonename eq '')
|
|
{
|
|
errval($ROW_ZONENAME,$rrn,"no zone name specified") if($upd);
|
|
$errors++;
|
|
}
|
|
|
|
#
|
|
# Check the zone file.
|
|
#
|
|
if($zonefile eq '')
|
|
{
|
|
errval($ROW_ZONEFILE,$rrn,"no zone file specified") if($upd);
|
|
$errors++;
|
|
}
|
|
else
|
|
{
|
|
if((!-e $zonefile) && $givewarnings)
|
|
{
|
|
warnval($ROW_ZONEFILE,$rrn,"zone file \"$zonefile\" does not exist") if($upd);
|
|
$warns++;
|
|
}
|
|
elsif((!-f $zonefile) && $givewarnings)
|
|
{
|
|
warnval($ROW_ZONEFILE,$rrn,"zone file \"$zonefile\" is not a regular file") if($upd);
|
|
$warns++;
|
|
}
|
|
}
|
|
|
|
#
|
|
# Check the keyrec file.
|
|
#
|
|
if($krfile eq '')
|
|
{
|
|
errval($ROW_KEYREC,$rrn,"no keyrec file specified") if($upd);
|
|
$errors++;
|
|
}
|
|
else
|
|
{
|
|
if((!-e $krfile) && $givewarnings)
|
|
{
|
|
warnval($ROW_KEYREC,$rrn,"keyrec file \"$krfile\" does not exist") if($upd);
|
|
$warns++;
|
|
}
|
|
elsif((!-f $krfile) && $givewarnings)
|
|
{
|
|
warnval($ROW_KEYREC,$rrn,"keyrec file \"$krfile\" is not a regular file") if($upd);
|
|
$warns++;
|
|
}
|
|
}
|
|
|
|
#
|
|
# No validity checks for the zonegroup.
|
|
#
|
|
|
|
#
|
|
# No validity checks for the administrator.
|
|
#
|
|
|
|
#
|
|
# Check the directory.
|
|
#
|
|
if(exists($rollrecs{$rrn}{'directory'}))
|
|
{
|
|
if(($rollrecs{$rrn}{'directory'}) ne '')
|
|
{
|
|
if(!-e $zonedir)
|
|
{
|
|
warnval($ROW_DIR,$rrn,"directory \"$zonedir\" does not exist") if($upd);
|
|
$warns++;
|
|
}
|
|
elsif(!-d $zonedir)
|
|
{
|
|
warnval($ROW_DIR,$rrn,"directory \"$zonedir\" is not a directory") if($upd);
|
|
$warns++;
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Make sure we've got a valid display flag.
|
|
#
|
|
if(defined($dispflag))
|
|
{
|
|
if(($dispflag != 0) && ($dispflag != 1) && ($dispflag != -1))
|
|
{
|
|
errval($ROW_DISPLAY,$rrn,"invalid display flag \"$dispflag\"") if($upd);
|
|
$errors++;
|
|
}
|
|
}
|
|
|
|
#
|
|
# Make sure we've got a valid logging level.
|
|
#
|
|
if(exists($rollrecs{$rrn}{'loglevel'}))
|
|
{
|
|
if(($rollrecs{$rrn}{'loglevel'} ne '') &&
|
|
($rollrecs{$rrn}{'loglevel'} ne 'default'))
|
|
{
|
|
if(rolllog_level($loglevel,0) < 0)
|
|
{
|
|
errval($ROW_LOG,$rrn,"invalid loglevel \"$loglevel\"") if($upd);
|
|
$errors++;
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Make sure we've got a valid maximum TTL.
|
|
#
|
|
if(exists($rollrecs{$rrn}{'maxttl'}))
|
|
{
|
|
if($rollrecs{$rrn}{'maxttl'} ne '')
|
|
{
|
|
if($maxttl < 1)
|
|
{
|
|
errval($ROW_MAXTTL,$rrn,"invalid maxttl \"$maxttl\"") if($upd);
|
|
$errors++;
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# No error checks for zonesigner arguments.
|
|
#
|
|
|
|
#
|
|
# If we found any errors or warnings, we'll add a message about them.
|
|
#
|
|
if($upd)
|
|
{
|
|
addmsg($rrn,$COL_FIELD,$errors,"error") if($errors);
|
|
addmsg($rrn,$COL_DATA,$warns,"warn") if($warns);
|
|
}
|
|
|
|
#
|
|
# Add the warning count to the error count if we shouldn't ignore
|
|
# warnings
|
|
#
|
|
$problems = $errors;
|
|
$problems += $warns if($givewarnings);
|
|
|
|
#
|
|
# If we've found this rollrec is good, we'll make some adjustments.
|
|
#
|
|
if(!$errors)
|
|
{
|
|
#
|
|
# Delete the administrator if it's empty.
|
|
#
|
|
if($rollrecs{$rrn}{'administrator'} eq '')
|
|
{
|
|
delete $rollrecs{$rrn}{'administrator'};
|
|
}
|
|
|
|
#
|
|
# Delete the directory if it's empty.
|
|
#
|
|
if(($rollrecs{$rrn}{'directory'}) eq '')
|
|
{
|
|
delete $rollrecs{$rrn}{'directory'};
|
|
}
|
|
|
|
#
|
|
# Delete the loglevel if it's empty or the default was chosen.
|
|
#
|
|
if(($rollrecs{$rrn}{'loglevel'} eq '') ||
|
|
($rollrecs{$rrn}{'loglevel'} eq 'default'))
|
|
{
|
|
delete $rollrecs{$rrn}{'loglevel'};
|
|
}
|
|
|
|
#
|
|
# Delete the max-ttl if it's empty.
|
|
#
|
|
if($rollrecs{$rrn}{'maxttl'} eq '')
|
|
{
|
|
delete $rollrecs{$rrn}{'maxttl'};
|
|
}
|
|
|
|
#
|
|
# Delete the zonegroup if it's empty.
|
|
#
|
|
if(($rollrecs{$rrn}{'zonegroup'}) eq '')
|
|
{
|
|
delete $rollrecs{$rrn}{'zonegroup'};
|
|
}
|
|
|
|
#
|
|
# Delete the zsargs if it's empty.
|
|
#
|
|
if($rollrecs{$rrn}{'zsargs'} eq '')
|
|
{
|
|
delete $rollrecs{$rrn}{'zsargs'};
|
|
}
|
|
|
|
}
|
|
|
|
return($warns,$errors) if(!$upd);
|
|
return(!$problems);
|
|
}
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Routine: saverollrec()
|
|
#
|
|
# Purpose: Save the rollrec's data into the rollrec module data.
|
|
#
|
|
#
|
|
sub saverollrec
|
|
{
|
|
my $rrn = shift; # Name of the rollrec.
|
|
|
|
my $typestr; # Calculated rollrec type.
|
|
|
|
# print STDERR "saverollrec: down in ($rrn)\n";
|
|
|
|
#
|
|
# Get the rollrec type from %editrbs.
|
|
#
|
|
$typestr = $editrbs{$rrn} ? "roll" : "skip";
|
|
|
|
#
|
|
# Get the display flag from %editdfs.
|
|
#
|
|
if(!exists($editdfs{$rrn}) || !defined($editdfs{$rrn}) ||
|
|
($editdfs{$rrn} == -1))
|
|
{
|
|
delete($rollrecs{$rrn}{'display'});
|
|
}
|
|
elsif($editdfs{$rrn} == 0)
|
|
{
|
|
$rollrecs{$rrn}{'display'} = 0;
|
|
}
|
|
elsif($editdfs{$rrn} == 1)
|
|
{
|
|
$rollrecs{$rrn}{'display'} = 1;
|
|
}
|
|
|
|
#
|
|
# Set the rollrec's type.
|
|
#
|
|
rollrec_rectype($rrn,$typestr);
|
|
|
|
#
|
|
# Save the fields into the rollrec itself. If the field exists
|
|
# in %rollrecs{$rrn}, we'll save the value. If the field does
|
|
# not exist, we'll delete the field.
|
|
#
|
|
foreach my $field (@EDITFIELDS)
|
|
{
|
|
if(exists($rollrecs{$rrn}{$field}))
|
|
{
|
|
rollrec_setval($rrn,$field,$rollrecs{$rrn}{$field});
|
|
}
|
|
else
|
|
{
|
|
rollrec_delfield($rrn,$field);
|
|
}
|
|
}
|
|
|
|
#
|
|
# Mark this rollrec as having been modified.
|
|
#
|
|
rrmodified($rrn);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: rrmodified()
|
|
#
|
|
# Purpose: Mark a rollrec as having been modified.
|
|
#
|
|
sub rrmodified
|
|
{
|
|
my $rrn = shift; # Modified rollrec.
|
|
|
|
#
|
|
# Increment the modified-keyrec flag.
|
|
#
|
|
$modified++;
|
|
$modified{$rrn} = 1;
|
|
|
|
settitle($title);
|
|
|
|
#
|
|
# Re-populate and update the table.
|
|
#
|
|
for(my $ind = 0; $ind < $numrrnames; $ind++)
|
|
{
|
|
my $row; # Cell's row index.
|
|
my $col; # Cell's column index.
|
|
|
|
my $btn; # Button widget.
|
|
my $name; # Label of button.
|
|
|
|
#
|
|
# Get the column and row indices.
|
|
#
|
|
($col,$row) = ind2cr($ind);
|
|
|
|
#
|
|
# Get this button's label.
|
|
#
|
|
$btn = $rrnametab->get($row,$col);
|
|
$name = $btn->cget(-text);
|
|
|
|
#
|
|
# Modify the name of just the button we're looking for.
|
|
#
|
|
next if($name ne $rrn);
|
|
$btn->configure(-text => "* $name");
|
|
}
|
|
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: rrsaved()
|
|
#
|
|
# Purpose: Mark the rollrecs as having been saved.
|
|
#
|
|
sub rrsaved
|
|
{
|
|
#
|
|
# Re-populate and update the table.
|
|
#
|
|
# print STDERR "rrsaved: numrrnames - $numrrnames\n";
|
|
for(my $ind = 0; $ind < $numrrnames; $ind++)
|
|
{
|
|
my $row; # Cell's row index.
|
|
my $col; # Cell's column index.
|
|
|
|
my $btn; # Button widget.
|
|
my $name; # Label of button.
|
|
|
|
#
|
|
# Get the column and row indices.
|
|
#
|
|
($col,$row) = ind2cr($ind);
|
|
|
|
#
|
|
# Get this button's label.
|
|
#
|
|
$btn = $rrnametab->get($row,$col);
|
|
$name = $btn->cget(-text);
|
|
$name =~ s/^\* //;
|
|
|
|
#
|
|
# Skip buttons that haven't been modified.
|
|
#
|
|
next if(!$modified{$name});
|
|
|
|
#
|
|
# Modify the the button's label.
|
|
#
|
|
$btn->configure(-text => $name);
|
|
}
|
|
|
|
#
|
|
# Reset the modified-keyrec flag.
|
|
#
|
|
$modified = 0;
|
|
%modified = ();
|
|
|
|
settitle($title);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: errval()
|
|
#
|
|
# Purpose: Take an error action.
|
|
#
|
|
sub errval
|
|
{
|
|
my $row = shift; # Errant rollrec's row.
|
|
my $rrn = shift; # Errant rollrec's name.
|
|
my $msg = shift; # Error message.
|
|
|
|
# print STDERR "errval: <$rrn>\t$msg\n";
|
|
|
|
fieldcolor($row,$rrn,$ERRCOLOR);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: warnval()
|
|
#
|
|
# Purpose: Take a warning action.
|
|
#
|
|
sub warnval
|
|
{
|
|
my $row = shift; # Errant rollrec's row.
|
|
my $rrn = shift; # Errant rollrec's name.
|
|
my $msg = shift; # Warning message.
|
|
|
|
# print STDERR "warnval: <$rrn>\t$msg\n";
|
|
|
|
fieldcolor($row,$rrn,$WARNCOLOR);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: fieldcolor()
|
|
#
|
|
# Purpose: Change the text color of a given edit window field.
|
|
#
|
|
sub fieldcolor
|
|
{
|
|
my $row = shift; # Rollrec's row.
|
|
my $rrn = shift; # Rollrec's name.
|
|
my $clr = shift; # New color.
|
|
|
|
my $tbl; # Table to modify.
|
|
my $wij; # Widget to modify.
|
|
|
|
#
|
|
# Get the label widget for the field.
|
|
#
|
|
$tbl = $edittabs{$rrn};
|
|
$wij = $tbl->get($row,$COL_FIELD);
|
|
|
|
#
|
|
# Turn the label widget's color.
|
|
#
|
|
$wij->configure(-foreground => $clr);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: addmsg()
|
|
#
|
|
# Purpose: Add a message to one of the edit window's message columns.
|
|
# If the count parameter is zero, then we'll zap the column.
|
|
#
|
|
sub addmsg
|
|
{
|
|
my $rrn = shift; # Rollrec name.
|
|
my $col = shift; # Column to modify.
|
|
my $cnt = shift; # Thing count.
|
|
my $thing = shift; # Thing.
|
|
|
|
my $tbl; # Table to modify.
|
|
my $lab; # New label.
|
|
my $str = ' '; # Error message.
|
|
|
|
if($cnt)
|
|
{
|
|
$str = "$cnt $thing";
|
|
$str = $str . 's' if($cnt != 1);
|
|
}
|
|
|
|
$tbl = $edittabs{$rrn};
|
|
$lab = $tbl->Label(-text => $str, -anchor => 'w');
|
|
$lab->pack(-fill => 'x', -side => 'top');
|
|
$tbl->put($ROW_MSG,$col,$lab);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: toggle_ignwarn()
|
|
#
|
|
# Purpose: Toggle on /off the "Ignore Edit Warnings" menu command.
|
|
#
|
|
# If we're turning off edit warnings, we'll also go through
|
|
# any open edit windows and turn off any "warned" lines.
|
|
# Error lines will remain marked.
|
|
#
|
|
sub toggle_ignwarn
|
|
{
|
|
if($givewarnings)
|
|
{
|
|
$givewarnings = 0;
|
|
$tog_ignwarn->configure(-label => $IGNORE_OFF);
|
|
|
|
#
|
|
# Turn off all the warning labels in all the edit windows.
|
|
#
|
|
foreach my $rrn (keys(%edittabs))
|
|
{
|
|
for(my $row = $ROW_FIRST; $row <= $ROW_LAST; $row++)
|
|
{
|
|
my $clr; # Current row color.
|
|
my $wij; # Row widget.
|
|
|
|
#
|
|
# Skip non-warning rows.
|
|
#
|
|
$wij = $edittabs{$rrn}->get($row,$COL_FIELD);
|
|
$clr = $wij->cget(-foreground);
|
|
next if($clr ne $WARNCOLOR);
|
|
|
|
#
|
|
# Change the label color.
|
|
#
|
|
fieldcolor($row,$rrn,$NORMALCOLOR);
|
|
}
|
|
|
|
addmsg($rrn,$COL_DATA,0,' ');
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$givewarnings = 1;
|
|
$tog_ignwarn->configure(-label => $IGNORE_ON);
|
|
}
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: toggle_namefilt()
|
|
#
|
|
# Purpose: Toggle on /off the "Use Name Filter" menu command.
|
|
#
|
|
sub toggle_namefilt
|
|
{
|
|
if($namefilter)
|
|
{
|
|
$namefilter = 0;
|
|
$tog_namefilt->configure(-label => $FILTER_OFF);
|
|
}
|
|
else
|
|
{
|
|
$namefilter = 1;
|
|
$tog_namefilt->configure(-label => $FILTER_ON);
|
|
}
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: set_btncols()
|
|
#
|
|
# Purpose:
|
|
#
|
|
sub set_btncols
|
|
{
|
|
my $err = shift; # Error flag.
|
|
|
|
my $dlg; # Dialog widget.
|
|
my $lab; # Label for dialog box.
|
|
my $ent; # Entry for dialog box.
|
|
|
|
my $col; # New column count.
|
|
my $ret; # Dialog box return.
|
|
|
|
#
|
|
# Create the new dialog box.
|
|
#
|
|
$dlg = $wm->DialogBox(-title => 'Set Columns for Button Window',
|
|
-buttons => ["Okay", "Cancel" ]);
|
|
|
|
#
|
|
# Add a label to the dialog.
|
|
#
|
|
$lab = $dlg->Label(-text => 'Enter New Column Count:');
|
|
$lab->pack(-side => 'left');
|
|
|
|
#
|
|
# Add a text entry slot and focus on the entry.
|
|
#
|
|
$ent = $dlg->add('Entry');
|
|
$ent->pack(-side => 'left');
|
|
$dlg->configure(-focus => $ent);
|
|
|
|
#
|
|
# Add a potential error location to the dialog.
|
|
#
|
|
$lab = $dlg->Label(-text => ' ');
|
|
$lab->pack(-side => 'bottom');
|
|
if($err)
|
|
{
|
|
$lab->configure(-text => "Count must be between 1 and $MAXCOLS",
|
|
-foreground => 'red')
|
|
}
|
|
|
|
#
|
|
# Show the dialog box and handle cancellations.
|
|
#
|
|
$ret = $dlg->Show();
|
|
return if($ret eq 'Cancel');
|
|
|
|
#
|
|
# Get the user's column size.
|
|
#
|
|
$col = $ent->get();
|
|
|
|
#
|
|
# If this is an invalid column count, give an error message and
|
|
# ask again.
|
|
#
|
|
set_btncols(1) if(($col < 1) || ($col > $MAXCOLS));
|
|
|
|
#
|
|
# Save the new column count and rebuild the table.
|
|
#
|
|
$columncount = $col;
|
|
buildtable(0);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: editbegone()
|
|
#
|
|
# Purpose: Destroy an edit window. In addition to deleting the window
|
|
# itself, the rollrec is removed from several tables. These
|
|
# tables are the list of edit windows (%editwinds), and the
|
|
# edit window radio buttons (%editrbs and %editdfs).
|
|
#
|
|
# In some cases, this routine will be passed the edit window
|
|
# widget instead of the rollrec name. If we couldn't find
|
|
# the argument in the edit-window hash, we'll look up the
|
|
# widget itself and recurse with the associated name.
|
|
#
|
|
sub editbegone
|
|
{
|
|
my $rrname = shift; # Name of rollrec whose editwin we'll destroy.
|
|
my $editwin; # Edit window to destroy.
|
|
|
|
# print STDERR "editbegone: destroying edit window for $rrname\n";
|
|
|
|
#
|
|
# Don't do anything for a null name.
|
|
#
|
|
return if($rrname eq '');
|
|
|
|
#
|
|
# Deselect the rollrec's button.
|
|
#
|
|
for(my $ind = 0; $ind < $numrrnames; $ind++)
|
|
{
|
|
#
|
|
# Destroy the window and remove it from our edit-window list.
|
|
#
|
|
if($rrnames[$ind] eq $rrname)
|
|
{
|
|
rrname_deselect($ind);
|
|
$editwinds{$rrname}->destroy();
|
|
delete($editwinds{$rrname});
|
|
delete($edittabs{$rrname});
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
#
|
|
# Didn't find the name in the list of rollrec names, so maybe it's
|
|
# a widget itself. If we find it in the list of edit windows,
|
|
# we'll delete it here.
|
|
#
|
|
foreach my $rrn (keys(%editwinds))
|
|
{
|
|
if($rrn == $rrname)
|
|
{
|
|
$editwinds{$rrname}->destroy();
|
|
delete($editwinds{$rrname});
|
|
delete($edittabs{$rrname});
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: renamebegone()
|
|
#
|
|
# Purpose: Destroy a rename window. In addition to deleting the window
|
|
# itself, the rollrec is removed from several tables. These
|
|
# tables are the list of rename windows (%renwinds).
|
|
#
|
|
# In some cases, this routine will be passed the rename window
|
|
# widget instead of the rollrec name. If we couldn't find
|
|
# the argument in the rename-window hash, we'll look up the
|
|
# widget itself and recurse with the associated name.
|
|
#
|
|
sub renamebegone
|
|
{
|
|
my $oldname = shift; # Old name of rollrec.
|
|
my $newname = shift; # New name of rollrec.
|
|
|
|
# print STDERR "renamebegone: destroying rename window for $oldname\n";
|
|
|
|
#
|
|
# Don't do anything for a null name.
|
|
#
|
|
return if($oldname eq '');
|
|
return if($newname eq '');
|
|
|
|
#
|
|
# Destroy the old name's rename window and remove it from our
|
|
# rename-window list.
|
|
#
|
|
if(exists($renwinds{$oldname}))
|
|
{
|
|
$renwinds{$oldname}->destroy();
|
|
delete($renwinds{$oldname});
|
|
delete($rentabs{$oldname});
|
|
}
|
|
|
|
#
|
|
# Remove the new name from our rename-window list.
|
|
#
|
|
delete($renwinds{$newname});
|
|
delete($rentabs{$newname});
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: helpbegone()
|
|
#
|
|
# Purpose: Destroy a help window.
|
|
#
|
|
sub helpbegone
|
|
{
|
|
$helpwin->destroy();
|
|
$inhelpwind = 0;
|
|
}
|
|
|
|
#############################################################################
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: errorbox()
|
|
#
|
|
# Purpose: Display an error dialog box.
|
|
#
|
|
sub errorbox
|
|
{
|
|
my $msg = shift; # Warning message.
|
|
my $dlg; # Warning dialog widget.
|
|
|
|
$dlg = $wm->Dialog(-title => "$NAME Error",
|
|
-text => $msg,
|
|
-default_button => "Okay",
|
|
-buttons => ["Okay"]);
|
|
$dlg->Show();
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: errorbox_multi()
|
|
#
|
|
# Purpose: Display a multiline error dialog box. Newlines in the message
|
|
# signal a new line (implemented with a new label) in the dialog
|
|
# box.
|
|
#
|
|
sub errorbox_multi
|
|
{
|
|
my $msgs = shift; # Messages to display.
|
|
|
|
my $dlg; # Warning dialog widget.
|
|
my $lab; # Label for table.
|
|
|
|
my @lines; # Lines in message.
|
|
my $line; # Individual message line.
|
|
|
|
$dlg = $wm->DialogBox(-title => "$NAME Error",
|
|
-buttons => ["Okay"]);
|
|
|
|
@lines = split /\n/, $msgs;
|
|
|
|
foreach $line (@lines)
|
|
{
|
|
$lab = $dlg->Label(-text => $line);
|
|
$lab->pack(-side => 'top');
|
|
}
|
|
|
|
$dlg->Show();
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: dbx_dups()
|
|
#
|
|
# Purpose: Puts up a dialog box with names of the duplicated rollrecs.
|
|
# This is used for the "Merge Rollrecs" command.
|
|
#
|
|
sub dbx_dups
|
|
{
|
|
my @dupnames = @_; # Duplicated rollrecs.
|
|
|
|
my $dbx; # Dialog box.
|
|
my $rrtab; # Dup'd rollrec table.
|
|
my $lab; # Label for table.
|
|
my $rowind = 1; # Table row index.
|
|
|
|
my $rows = @dupnames + 1; # Rows in table.
|
|
my $sbars = 'e'; # Scrollbars.
|
|
my $ret; # Dialog return.
|
|
|
|
#
|
|
# Build a dialog box to hold an error summary.
|
|
#
|
|
$dbx = $wm->DialogBox(-title => 'Duplicated Rollrecs',
|
|
-buttons => ["Merge", "Cancel" ]);
|
|
|
|
#
|
|
# If there's only a few rows, we'll dump the scrollbar.
|
|
#
|
|
$sbars = '' if($rows < 4);
|
|
|
|
#
|
|
# Build a table to hold the duplicated rollrec names.
|
|
#
|
|
$rrtab = $dbx->Table(-rows => $rows,
|
|
-columns => 1,
|
|
-relief => 'raised',
|
|
-scrollbars => $sbars,
|
|
-borderwidth => 1,
|
|
-fixedrows => 0,
|
|
-takefocus => 1,
|
|
);
|
|
|
|
#
|
|
# Add a column header.
|
|
#
|
|
$lab = $rrtab->Label(-text => 'Duplicated Rollrecs');
|
|
$rrtab->put(0,0,$lab);
|
|
|
|
#
|
|
# Add the selected rollrec names to the table.
|
|
#
|
|
foreach my $rrn (sort {$a <=> $b} @dupnames)
|
|
{
|
|
$lab = $rrtab->Label(-text => $rrn, -anchor => 'w');
|
|
$rrtab->put($rowind,0,$lab);
|
|
$rowind++;
|
|
}
|
|
|
|
#
|
|
# Pack the error table and display the dialog box.
|
|
#
|
|
$rrtab->pack(-side => 'top');
|
|
$ret = $dbx->Show();
|
|
|
|
return($ret);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: help_help()
|
|
#
|
|
# Purpose: Display a help window.
|
|
#
|
|
sub help_help
|
|
{
|
|
my $hframe; # Help frame.
|
|
my $wdgt; # General widget.
|
|
|
|
my $helpstr;
|
|
|
|
$helpstr = "
|
|
|
|
rollrec-editor - DNSSEC-Tools Rollrec GUI Editor
|
|
|
|
SYNOPSIS
|
|
|
|
rollrec-editor [options] <rollrec-file>
|
|
|
|
DESCRIPTION
|
|
|
|
rollrec-editor provides the capability for easy GUI-based management of
|
|
rollrec files. A rollrec file contains one or more rollrec records. These
|
|
records are used by the DNSSEC-Tools rollover utilities (rollerd, etc.) to
|
|
describe zones' rollover state. Each zone's rollrec record contains such
|
|
information as the zone file, the rollover phase, and logging level. rollrec
|
|
files are text files and may be edited by any text editor. rollrec-editor
|
|
allows editing of only those records a user should change and performs error
|
|
checking on the data.
|
|
|
|
When rollrec-editor starts, a window is created that has \"buttons\" for each
|
|
rollrec record in the given rollrec file. (In this documentation, this window
|
|
is called the Button Window.) Clicking on the buttons selects (or deselects)
|
|
that zone. After one or more zones are selected, one of several commands may
|
|
be executed. Commands allow modification and deletion of existing rollrec
|
|
records, creation of new rollrec records, merging of rollrec files, and
|
|
verification of file validity.
|
|
|
|
rollrec-editor's commands are available through the menus and most have a
|
|
keyboard accelerator. The commands are described in the manual page.
|
|
|
|
When a rollrec record is selected for modification, a new window is created to
|
|
hold the editable fields of the record. The fields may be modified in place.
|
|
When editing is complete, the record is \"saved\". This does not save the
|
|
modified rollrec into its on-disk file; the file must be saved explicitly from
|
|
the Button Window.
|
|
|
|
As stated above, verification checks are performed when saving an edited
|
|
rollrec record. One set of checks ensures that files and directories
|
|
associated with a zone actually exist. This check may be turned off at
|
|
command start-up with the -ignore-warns command line option. It may be
|
|
modified during execution with the \"Ignore Edit Warnings\" menu command.
|
|
|
|
More information may be found in rollrec-editor's man page.
|
|
|
|
";
|
|
|
|
#
|
|
# If we've already got another help window, we'll give an error and
|
|
# return. Otherwise, we'll turn on our in-helpwindow flag.
|
|
#
|
|
if($inhelpwind)
|
|
{
|
|
errorbox("Multiple help windows cannot be created\n");
|
|
return;
|
|
}
|
|
$inhelpwind = 1;
|
|
|
|
#
|
|
# Create a new window to hold our help info. Bind up some
|
|
# key accelerators, too.
|
|
#
|
|
$helpwin = MainWindow->new(-relief => 'raised',
|
|
-title => 'Help!',
|
|
-borderwidth => 1);
|
|
$helpwin->bind('<Control-Key-q>',\&file_quit);
|
|
$helpwin->bind('<Control-Key-w>',\&helpbegone);
|
|
|
|
#
|
|
# Now make the containers for the window.
|
|
#
|
|
$hframe = $helpwin->Frame(-relief => 'raised', -borderwidth => 1);
|
|
|
|
$hframe->pack(-fill => 'x');
|
|
|
|
#
|
|
# Add the help data to the frame.
|
|
#
|
|
$wdgt = $hframe->Label(-text => $helpstr,
|
|
-justify => 'left');
|
|
$wdgt->pack(-side => 'top');
|
|
|
|
#
|
|
# Add a button to dismiss the window.
|
|
#
|
|
$wdgt = $hframe->Button(-text => 'Done',
|
|
-command => \&helpbegone);
|
|
$wdgt->pack(-side => 'top');
|
|
}
|
|
|
|
#----------------------------------------------------------------------
|
|
#
|
|
# Routine: settitle()
|
|
#
|
|
# Purpose: Set the title for use in the "Editing File" line.
|
|
#
|
|
sub settitle
|
|
{
|
|
my $name = shift; # Name to use.
|
|
|
|
if($modified)
|
|
{
|
|
$name .= " (modified)" if(!$modset);
|
|
$modset = 1;
|
|
}
|
|
$title = $name;
|
|
}
|
|
|
|
#----------------------------------------------------------------------
|
|
#
|
|
# Routine: version()
|
|
#
|
|
# Purpose: Print the version number(s) and exit.
|
|
#
|
|
sub version
|
|
{
|
|
print STDERR "$VERS\n";
|
|
print STDERR "$DTVERS\n";
|
|
exit(0);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: usage()
|
|
#
|
|
# Purpose: Print a usage message and exit.
|
|
#
|
|
sub usage
|
|
{
|
|
print STDERR "usage: rollrec-editor [options] <rollrec-file>\n";
|
|
print STDERR "\toptions:\n";
|
|
print STDERR "\t\t-ignore-warns ignore edit warnings\n";
|
|
print STDERR "\t\t-no-filter turn off name filtering\n";
|
|
print STDERR "\t\t-columns columns columns in button window\n";
|
|
print STDERR "\t\t-V program version\n";
|
|
exit(0);
|
|
}
|
|
|
|
1;
|
|
|
|
#############################################################################
|
|
|
|
=pod
|
|
|
|
=head1 NAME
|
|
|
|
rollrec-editor - DNSSEC-Tools Rollrec GUI Editor
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
rollrec-editor [options] <rollrec-file>
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
B<rollrec-editor> provides the capability for easy GUI-based management of
|
|
I<rollrec> files. A B<rollrec> file contains one or more I<rollrec> records.
|
|
These records are used by the DNSSEC-Tools rollover utilities (B<rollerd>,
|
|
etc.) to describe zones' rollover state. Each zone's I<rollrec> record
|
|
contains such information as the zone file, the rollover phase, and logging
|
|
level. I<rollrec> files are text files and may be edited by any text editor.
|
|
B<rollrec-editor> allows editing of only those records a user should change
|
|
and performs error checking on the data.
|
|
|
|
When B<rollrec-editor> starts, a window is created that has "buttons" for each
|
|
I<rollrec> record in the given I<rollrec> file. (In this documentation, this
|
|
window is called the Button Window.) Clicking on the buttons selects (or
|
|
deselects) that zone. After one or more zones are selected, one of several
|
|
commands may be executed. Commands allow modification and deletion of
|
|
existing I<rollrec> records, creation of new I<rollrec> records, merging of
|
|
I<rollrec> files, and verification of file validity.
|
|
|
|
B<rollrec-editor>'s commands are available through the menus and most have a
|
|
keyboard accelerator. The commands are described below in the COMMANDS
|
|
section.
|
|
|
|
When a I<rollrec> record is selected for modification, a new window is created
|
|
to hold the editable fields of the record. The fields may be modified in
|
|
place. When editing is complete, the record is "saved". This does not save
|
|
the modified I<rollrec> into its on-disk file; the file must be saved
|
|
explicitly from the Button Window.
|
|
|
|
As stated above, verification checks are performed when saving an edited
|
|
I<rollrec> record. One set of checks ensures that files and directories
|
|
associated with a zone actually exist. This check may be turned off at
|
|
command start-up with the B<-ignore-warns> command line option. It may be
|
|
modified during execution with the "Ignore Edit Warnings" menu command.
|
|
|
|
=head2 Button Window Layout
|
|
|
|
The Button Window contains a button for each I<rollrec> record in the
|
|
selected file. The buttons are arranged in a table that with at least three
|
|
columns. The number of columns may be set at command start-up with the
|
|
B<-columns> command line option. It may be modified during execution with
|
|
the "Columns in Button Window" menu command.
|
|
|
|
When setting the number of columns, B<rollrec-editor> minimizes the space
|
|
required to display the selected file's I<rollrec> buttons. This will
|
|
sometimes cause the number of columns to differ from that requested.
|
|
|
|
For example, assume a I<rollrec> file has 12 I<rollrec> records. The
|
|
following table shows how many rows and columns are given for each of
|
|
the given column selections.
|
|
|
|
column count rows columns
|
|
1 12 1
|
|
2 6 2
|
|
3 4 3
|
|
4 3 4
|
|
5 3 4
|
|
6 2 6
|
|
7 2 6
|
|
8 2 6
|
|
9 2 6
|
|
10 2 6
|
|
11 2 6
|
|
12 1 12
|
|
|
|
The actual rows and columns for a requested column count will vary in order
|
|
to allow a "best-fit".
|
|
|
|
=head2 UNDOING MODIFICATIONS
|
|
|
|
B<The "undo" capability is not currently implemented.>
|
|
|
|
B<rollrec-editor> has the ability to reverse modifications it has made to a
|
|
I<rollrec> file. This historical restoration will only work for modifications
|
|
made during a particular execution of B<rollrec-editor>; modifications made
|
|
during a previous execution may not be undone.
|
|
|
|
After a "Save" operation, the data required for reversing modifications are
|
|
deleted. This is not the case for the "Save As" operation.
|
|
|
|
=head1 OPTIONS
|
|
|
|
B<rollrec-editor> supports the following options.
|
|
|
|
=over 4
|
|
|
|
=item B<-columns columns>
|
|
|
|
This option allows the user to specify the number of columns to be used in
|
|
the Button Window.
|
|
|
|
=item B<-ignore-warns>
|
|
|
|
This option causes B<rollrec-editor> to ignore edit warnings when performing
|
|
validation checks on the contents of I<rollrec> records.
|
|
|
|
=item B<-no-filter>
|
|
|
|
This option turns off name filtering when B<rollrec-editor> presents a
|
|
file-selection dialog for choosing a new I<rollrec> file. If this option
|
|
is not given, then the file-selection dialog will only list regular files
|
|
with a suffix of B<.rrf>.
|
|
|
|
=item B<-Version>
|
|
|
|
Displays the version information for B<rollrec-editor> and the DNSSEC-Tools
|
|
package.
|
|
|
|
=back
|
|
|
|
=head1 COMMANDS
|
|
|
|
B<rollrec-editor> provides the following commands, organized by menus:
|
|
File, Edit, Commands, Rollrecs, and Options.
|
|
|
|
=head2 File Menu
|
|
|
|
The File Menu contains commands for manipulating I<rollrec> files and
|
|
stopping execution.
|
|
|
|
=over 4
|
|
|
|
=item B<Open>
|
|
|
|
Open a new I<rollrec> file. If the specified file does not exist, the user
|
|
will be prompted for the action to take. If the user chooses the "Continue"
|
|
action, then B<rollrec-editor> will continue editing the current I<rollrec>
|
|
file. If the "Quit" action is selected, then B<rollrec-editor> will exit.
|
|
|
|
=item B<Save>
|
|
|
|
Save the current I<rollrec> file. The data for the "Undo Changes" command are
|
|
purged, so this file will appear to be unmodified.
|
|
|
|
Nothing will happen if no changes have been made.
|
|
|
|
=item B<Save As>
|
|
|
|
Save the current I<rollrec> file to a name selected by the user.
|
|
|
|
=item B<Quit>
|
|
|
|
Exit B<rollrec-editor>.
|
|
|
|
=back
|
|
|
|
=head2 Edit Menu
|
|
|
|
The Edit Menu contains commands for general editing operations.
|
|
|
|
=over 4
|
|
|
|
=item B<Undo Changes>
|
|
|
|
Reverse modifications made to the I<rollrec> records. This is B<only>
|
|
for the in-memory version of the I<rollrec> file.
|
|
|
|
B<Not currently implemented.>
|
|
|
|
=back
|
|
|
|
=head2 Commands Menu
|
|
|
|
The Commands Menu contains commands for modifying I<rollrec> records.
|
|
|
|
=over 4
|
|
|
|
=item B<New Rollrec>
|
|
|
|
Create a new I<rollrec> record. The user is given a new window in which to
|
|
edit the user-modifiable I<rollrec> fields. A button for the new I<rollrec>
|
|
record will be inserted into the Button Window.
|
|
|
|
After editing is completed, the "Save" button will add the new I<rollrec>
|
|
record to the in-memory I<rollrec> file. The file must be saved in order to
|
|
have the new I<rollrec> added to the file.
|
|
|
|
Potentially erroneous conditions will be reported to the user at save time.
|
|
If the I<ignore-warnings> flag has been turned on, then these warnings will
|
|
not be reported. Errors (e.g., invalid log conditions) will always be
|
|
reported.
|
|
|
|
=item B<Delete Selected Rollrecs>
|
|
|
|
Delete the selected I<rollrec> records. The buttons for each selected record
|
|
will be removed from the Button Window.
|
|
|
|
=item B<Edit Selected Rollrecs>
|
|
|
|
Modify the selected I<rollrec> records. For every record selected
|
|
for modification, the user is given a new window in which to edit the
|
|
user-modifiable I<rollrec> fields. When the edit window goes away (after a
|
|
"Save" or "Cancel"), the I<rollrec> record's button is deselected.
|
|
|
|
After editing is completed, the "Save" button will add the new I<rollrec>
|
|
record to the in-memory I<rollrec> file. The file must be saved in order to
|
|
have the new I<rollrec> added to the file.
|
|
|
|
Potentially erroneous conditions will be reported to the user at save time.
|
|
If the I<ignore-warnings> flag has been turned on, then these warnings will
|
|
not be reported. Errors (e.g., invalid log conditions) will always be
|
|
reported.
|
|
|
|
=item B<Rename Selected Rollrec>
|
|
|
|
Rename the selected I<rollrec> record. The name in the I<rollrec>'s "roll"
|
|
or "skip" line will be changed to the new name. Only one I<rollrec> may be
|
|
renamed at a time, and it may not be edited while the rename is taking place.
|
|
|
|
If the I<rollrec> has been modified, the new contents B<must> be written to
|
|
disk prior to the rename happening. The user will be prompted to ensure that
|
|
this the user wishes to continue.
|
|
|
|
=item B<Merge Rollrec Files>
|
|
|
|
Merge a I<rollrec> file with the currently open I<rollrec> file. After a
|
|
successful merge, the I<rollrec> records in the second file will be added
|
|
to the I<end> of the currently open I<rollrec> file.
|
|
|
|
If there are any I<rollrec> name collisions in the files, then the user will
|
|
be asked whether to continue with the merge or cancel it. If the merge
|
|
continues, then the conflicting I<rollrec> records from the "new" file will be
|
|
discarded in favor of the currently open I<rollrec> file.
|
|
|
|
=item B<Verify Rollrec File>
|
|
|
|
Verify the validity of the I<rollrec> file. The user-editable fields in the
|
|
open I<rollrec> file are checked for validity. An edit window is opened for
|
|
each I<rollrec> record that registers an error or warning.
|
|
|
|
If the I<ignore-warnings> flag has been turned on, then potentially erroneous
|
|
conditions will not be reported. Errors (e.g., invalid log conditions) will
|
|
always be reported.
|
|
|
|
=item B<Summarize Problems>
|
|
|
|
Summarize the warning and error counts of the I<rollrec> file. Each
|
|
I<rollrec> record in the open I<rollrec> file is checked for validity. If
|
|
any warnings or errors are found, a window is displayed that lists the name
|
|
of each I<rollrec> record and its warning and error counts.
|
|
|
|
If the I<ignore-warnings> flag has been turned on, then potentially erroneous
|
|
conditions will not be reported. Errors (e.g., invalid log conditions) will
|
|
always be reported.
|
|
|
|
=back
|
|
|
|
=head2 View Menu
|
|
|
|
The View Menu contains miscellaneous commands for viewing edit windows.
|
|
|
|
=over 4
|
|
|
|
=item B<Select All Rollrecs/Unselect All Rollrecs>
|
|
|
|
Select or unselect all I<rollrec> buttons. All the buttons in the Button
|
|
Window will be selected or unselected. If B<any> of the buttons are not
|
|
selected, this command will cause all the buttons to become selected. If
|
|
I<all> of the buttons are selected, this command will cause all the buttons
|
|
to be deselected.
|
|
|
|
This command is a toggle that switches between Select All Rollrecs and
|
|
Unselect All Rollrecs.
|
|
|
|
=item B<Reveal Rollrec Edit Windows>
|
|
|
|
Raise all I<rollrec> edit windows. This command brings all I<rollrec> edit
|
|
windows to the front so that any that are hidden behind other windows will
|
|
become visible.
|
|
|
|
=item B<Close Rollrec Edit Windows>
|
|
|
|
Close all I<rollrec> edit windows. This command closes and deselects all
|
|
I<rollrec> edit windows.
|
|
|
|
=back
|
|
|
|
=head2 Options Menu
|
|
|
|
The Options Menu allows the user to set several options that control
|
|
B<rollrec-editor> behavior.
|
|
|
|
=over 4
|
|
|
|
=item B<Ignore Edit Warnings/Don't Ignore Edit Warnings>
|
|
|
|
Certain operations perform validation checks on the contents of I<rollrec>
|
|
records. Warnings and errors may be reported by these checks. This option
|
|
controls whether or not warnings are flagged during validation. If they
|
|
are flagged, then the operation will not continue until the warning condition
|
|
is fixed or the operation canceled. If the warnings are ignored, then the
|
|
operation will complete without the condition being fixed.
|
|
|
|
This command is a toggle that switches between Ignore Edit Warnings mode and
|
|
Don't Ignore Edit Warnings mode.
|
|
|
|
=item B<Filter Name Selection/Don't Filter Name Selection>
|
|
|
|
When opening I<rollrec> files for editing or merging, a file-selection dialog
|
|
box is displayed to allow the user to select a I<rollrec> file. This option
|
|
controls whether a filename filter is used by the dialog box. If Filter Names
|
|
Selection mode is used, then only regular files with a suffix of B<.rrf> will
|
|
be displayed by the dialog box. If Don't Filter Name Selection mode is used,
|
|
then all regular files will be displayed by the dialog box.
|
|
|
|
This command is a toggle that switches between Filter Name Selection display
|
|
and Don't Filter Name Selection display.
|
|
|
|
=item B<Columns in Button Window>
|
|
|
|
Set the number of columns used in the Button Window. See the Button Window
|
|
Layout section for more information on columns in the Button Window.
|
|
|
|
=back
|
|
|
|
=head2 Help Menu
|
|
|
|
The Help Menu contains commands for getting assistance.
|
|
|
|
=over 4
|
|
|
|
=item B<Help>
|
|
|
|
Display a help window.
|
|
|
|
=back
|
|
|
|
=head1 KEYBOARD ACCELERATORS
|
|
|
|
Below are the keyboard accelerators for the B<rollrec-editor> commands:
|
|
|
|
Ctrl-A Select All Rollrecs
|
|
|
|
Ctrl-D Delete Selected Rollrecs
|
|
|
|
Ctrl-E Edit Selected Rollrecs
|
|
|
|
Ctrl-H Help
|
|
|
|
Ctrl-K Close Rollrec Edit Windows
|
|
|
|
Ctrl-M Merge Rollrec Files
|
|
|
|
Ctrl-N New Rollrec
|
|
|
|
Ctrl-O Open
|
|
|
|
Ctrl-Q Quit
|
|
|
|
Ctrl-R Reveal Rollrec Edit Windows
|
|
|
|
Ctrl-S Save
|
|
|
|
Ctrl-U Undo Changes (not currently implemented)
|
|
|
|
Ctrl-V Verify Rollrec File
|
|
|
|
These accelerators are all lowercase letters.
|
|
|
|
=head1 REQUIREMENTS
|
|
|
|
B<rollrec-editor> is implemented in Perl/Tk, so both Perl and Perl/Tk must be
|
|
installed on your system.
|
|
|
|
=head1 KNOWN ISSUES
|
|
|
|
The following are known issues. These will be resolved in the fullness of time.
|
|
|
|
=over 4
|
|
|
|
=item
|
|
|
|
There is an issue with the column count and adding new I<rollrecs>.
|
|
It doesn't always work properly, thus occasionally leaving some I<rollrec>
|
|
buttons undisplayed.
|
|
|
|
=item
|
|
|
|
There is no undo command.
|
|
|
|
=back
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright 2007-2014 SPARTA, Inc. All rights reserved.
|
|
See the COPYING file included with the DNSSEC-Tools package for details.
|
|
|
|
=head1 AUTHOR
|
|
|
|
Wayne Morrison, tewok@tislabs.com
|
|
|
|
=head1 SEE ALSO
|
|
|
|
B<lsroll(1)>,
|
|
B<rollchk(8)>,
|
|
B<rollerd(8)>
|
|
B<rollinit(8)>,
|
|
B<rollset(8)>,
|
|
B<zonesigner(8)>
|
|
|
|
B<Net::DNS::SEC::Tools::rollrec(3)>
|
|
|
|
B<file-rollrec(5)>
|
|
|
|
=cut
|