mirror of
https://github.com/zerotier/edge.git
synced 2026-05-22 16:25:05 -07:00
1486 lines
32 KiB
Perl
Executable File
1486 lines
32 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
#
|
|
# Copyright 2009-2014 SPARTA, Inc. All rights reserved. See the COPYING
|
|
# file distributed with this software for details.
|
|
#
|
|
# DNSSEC-Tools: bubbles
|
|
#
|
|
# bubbles provides a simple overview of the roll-state of a set
|
|
# of zones.
|
|
#
|
|
|
|
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::rollrec;
|
|
use Net::DNS::SEC::Tools::BootStrap;
|
|
|
|
use Getopt::Long qw(:config no_ignore_case_always);
|
|
|
|
#
|
|
# Version information.
|
|
#
|
|
my $NAME = "bubbles";
|
|
my $VERS = "$NAME version: 2.1.0";
|
|
my $DTVERS = "DNSSEC-Tools Version: 2.2.3";
|
|
|
|
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 =
|
|
(
|
|
"kskcolor=s", # Color for KSK rollers.
|
|
"zskcolor=s", # Color for ZSK rollers.
|
|
"noncolor=s", # Color for non-rollers.
|
|
|
|
"showksk", # Show KSK-rolling zones.
|
|
"showzsk", # Show ZSK-rolling zones.
|
|
"showrolls", # Show rolling zones.
|
|
"shownonrolls", # Show non-rolling zones.
|
|
|
|
"columns=i", # Columns in button window.
|
|
"interval=s", # Interval between file checks.
|
|
"no-filter", # No-name-filtering flag.
|
|
"ignore-display", # Ignore rollrec display flag.
|
|
|
|
"Version", # Display the version number.
|
|
"help", # Give a usage message and exit.
|
|
);
|
|
|
|
#
|
|
# Default colors for zone buttons.
|
|
#
|
|
my $RRTAB_KSKROLL = 'red';
|
|
my $RRTAB_ZSKROLL = 'yellow';
|
|
my $RRTAB_NONROLL = 'green';
|
|
|
|
#
|
|
# Values for options.
|
|
#
|
|
my $kskclr = $RRTAB_KSKROLL; # Color for KSK rollers.
|
|
my $zskclr = $RRTAB_ZSKROLL; # Color for ZSK rollers.
|
|
my $nonclr = $RRTAB_NONROLL; # Color for non-rollers.
|
|
my $showksk = 0; # Show KSK-rolling zones.
|
|
my $showzsk = 0; # Show ZSK-rolling zones.
|
|
my $shownon = 0; # Show non-rolling zones.
|
|
my $igndisp = 0; # Ignore rollrec display 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.
|
|
my $lastmod = 0; # Last mod. time for rrf.
|
|
|
|
#
|
|
# Lists of rollrecs.
|
|
#
|
|
my %rollrecs = (); # Rollrec hash.
|
|
my @rollrecs = (); # Rollrec array.
|
|
my @rrnames = (); # List of rollrec names.
|
|
my $numrrnames; # Number of rollrec names.
|
|
|
|
my $DEFAULT_INTERVAL = 60; # Default interval in seconds.
|
|
my $SMALL_INT = 10; # Smallest interval.
|
|
my $interval = $DEFAULT_INTERVAL; # Interval between file checks.
|
|
|
|
###########################################################################
|
|
#
|
|
# Tk GUI data
|
|
#
|
|
|
|
########################################################
|
|
#
|
|
# Main window data.
|
|
#
|
|
my $MAINTITLE = "DNSSEC-Tools Zone States";
|
|
|
|
my $title = "dummy"; # Node for 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 $bodylist; # Listbox for body.
|
|
my $null; # Empty frame.
|
|
|
|
########################################################
|
|
#
|
|
# Menubar and menu data.
|
|
#
|
|
|
|
#
|
|
# Menu item widgets.
|
|
#
|
|
|
|
my $tog_namefilt = 1; # Use-name-filter toggle.
|
|
|
|
########################################################
|
|
#
|
|
# Button window data.
|
|
#
|
|
|
|
#
|
|
# Column and row data for button windows.
|
|
#
|
|
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; # Column count.
|
|
|
|
#
|
|
# Font data for text in button window.
|
|
#
|
|
my $fontsize = 18;
|
|
my $font = "*-*-bold-r-*-*-$fontsize-*-*-*-*-*-*-*";
|
|
|
|
#
|
|
# Constants for message text colors.
|
|
#
|
|
|
|
my $rrnametab; # Rollrec name table widget.
|
|
|
|
###########################################################################
|
|
|
|
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.
|
|
my $tmprolls = 0; # Temporary argument variable.
|
|
my $tmpnons = 0; # Temporary argument variable.
|
|
my $tmpival = ''; # Temporary interval value.
|
|
|
|
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.
|
|
#
|
|
$tmpival = $options{'interval'} if(defined($options{'interval'}));
|
|
$namefilter = 0 if(defined($options{'no-filter'}));
|
|
$kskclr = $options{'kskcolor'} if(defined($options{'kskcolor'}));
|
|
$zskclr = $options{'zskcolor'} if(defined($options{'zskcolor'}));
|
|
$nonclr = $options{'noncolor'} if(defined($options{'noncolor'}));
|
|
$showksk = $options{'showksk'} if(defined($options{'showksk'}));
|
|
$showzsk = $options{'showzsk'} if(defined($options{'showzsk'}));
|
|
$shownon = $options{'shownonrolls'} if(defined($options{'shownonrolls'}));
|
|
$igndisp = $options{'ignore-display'} if(defined($options{'ignore-display'}));
|
|
$tmprolls = $options{'showrolls'} if(defined($options{'showrolls'}));
|
|
|
|
#
|
|
# Check for the column-count option.
|
|
#
|
|
if(defined($options{'columns'}))
|
|
{
|
|
$columncount = $options{'columns'};
|
|
if($columncount < $MINCOLS)
|
|
{
|
|
print STDERR "column count must be at least $MINCOLS\n";
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
#
|
|
# Parse the interval argument. If a time unit isn't given, we'll
|
|
# assume we're dealing in minutes.
|
|
#
|
|
if($tmpival ne '')
|
|
{
|
|
my $nums; # Number of time units.
|
|
my $unit; # Time unit.
|
|
my $mult; # Time-unit multiplier.
|
|
|
|
#
|
|
# Pull the number/units tuple out of the argument.
|
|
#
|
|
if(! ($tmpival =~ /^([0-9]+)([smh])$/))
|
|
{
|
|
if(! ($tmpival =~ /^([0-9]+)$/))
|
|
{
|
|
print STDERR "invalid interval\n";
|
|
usage();
|
|
}
|
|
|
|
$nums = $tmpival;
|
|
$unit = 'm';
|
|
}
|
|
else
|
|
{
|
|
$nums = $1;
|
|
$unit = $2;
|
|
}
|
|
|
|
#
|
|
# Get the unit multiplier.
|
|
#
|
|
if($unit eq 's')
|
|
{
|
|
$mult = 1;
|
|
}
|
|
elsif($unit eq 'm')
|
|
{
|
|
$mult = 60;
|
|
}
|
|
elsif($unit eq 'h')
|
|
{
|
|
$mult = 60 * 60;
|
|
}
|
|
|
|
#
|
|
# Calculate the number of seconds in our interval.
|
|
#
|
|
$interval = $nums * $mult;
|
|
}
|
|
|
|
#
|
|
# Ensure the file-check interval isn't too small, then bump it up
|
|
# into the realm of milliseconds.
|
|
#
|
|
if($interval < $SMALL_INT)
|
|
{
|
|
print STDERR "smallest interval is $SMALL_INT seconds\n";
|
|
exit(1);
|
|
}
|
|
$interval = $interval * 1000;
|
|
|
|
#
|
|
# Adjust the display flags.
|
|
#
|
|
if($tmprolls)
|
|
{
|
|
$showksk = 1;
|
|
$showzsk = 1;
|
|
}
|
|
if(!$showksk && !$showzsk && !$shownon)
|
|
{
|
|
$showksk = 1;
|
|
$showzsk = 1;
|
|
$shownon = 1;
|
|
}
|
|
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: reader()
|
|
#
|
|
# Purpose: Forces a re-read of the rollrec file if it has been
|
|
# modified since it was last read.
|
|
#
|
|
sub reader
|
|
{
|
|
my @stat; # Rollrec file's file info.
|
|
|
|
@stat = stat $rrfile;
|
|
|
|
if($stat[9] > $lastmod)
|
|
{
|
|
buildtable(1);
|
|
$lastmod = $stat[9];
|
|
}
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: buildmainwind()
|
|
#
|
|
# Purpose: Create and initialize the main window.
|
|
#
|
|
sub buildmainwind
|
|
{
|
|
my $cmd; # Command menu.
|
|
my $view; # View menu.
|
|
my $opts; # Options menu.
|
|
my $help; # Help menu.
|
|
|
|
my $curfile; # Current keyrec.
|
|
my $keyrecs; # Keyrec listbox.
|
|
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.
|
|
#
|
|
$cmd = $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.
|
|
#
|
|
$cmd->command(-label => 'Open...',
|
|
-command => \&cmd_open,
|
|
-accelerator => 'Ctrl+O',
|
|
-underline => 0);
|
|
$cmd->separator();
|
|
$cmd->command(-label => 'DS Published for All Zones',
|
|
-command => [\&cmd_dspuball]);
|
|
$cmd->separator();
|
|
$cmd->command(-label => 'Halt Rollerd After Current Operations',
|
|
-command => [\&cmd_halt, '']);
|
|
$cmd->command(-label => 'Halt Rollerd Now',
|
|
-command => [\&cmd_halt, 'now']);
|
|
$cmd->separator();
|
|
$cmd->command(-label => 'Quit',
|
|
-command => \&cmd_quit,
|
|
-accelerator => 'Ctrl+Q',
|
|
-underline => 0);
|
|
$cmd->pack(-side => 'left');
|
|
|
|
$wm->bind('<Control-Key-O>',\&cmd_open);
|
|
$wm->bind('<Control-Key-o>',\&cmd_open);
|
|
$wm->bind('<Control-Key-Q>',\&cmd_quit);
|
|
$wm->bind('<Control-Key-q>',\&cmd_quit);
|
|
|
|
##################################################
|
|
#
|
|
# Add the Options menu entries.
|
|
#
|
|
$opts->command(-label => 'Columns in Button Window',
|
|
-command => [\&set_btncols, 0],
|
|
-underline => 0);
|
|
$opts->pack(-side => 'left');
|
|
|
|
|
|
##################################################
|
|
#
|
|
# Add the Help menu entries.
|
|
#
|
|
$help->command( -label => 'Help',
|
|
-command => \&help_help,
|
|
-accelerator => 'Ctrl+H',
|
|
-underline => 0);
|
|
$help->command( -label => "About $NAME",
|
|
-command => \&help_about,
|
|
-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 => "Viewing Rollrec File: ");
|
|
$curfile->pack(-side => 'left');
|
|
$curfile = $rrfl->Label(-textvariable => \$title);
|
|
$curfile->pack(-side => 'left');
|
|
$rrfl->pack(-side => 'top', -fill => 'x');
|
|
|
|
##################################################
|
|
#
|
|
# Create a listbox 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');
|
|
|
|
#
|
|
# Arrange to have the table rebuilt in a bit.
|
|
#
|
|
$wm->repeat($interval, \&reader);
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# 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.
|
|
|
|
#
|
|
# Read the list of rollrec names.
|
|
#
|
|
readrrf($rrfile,1) if($readflag);
|
|
|
|
#
|
|
# Ask the user what to do if we don't have any rollrec names.
|
|
# Possible actions:
|
|
# - stop execution
|
|
# - continue as-is
|
|
# - ignore the values of display flags and display data
|
|
#
|
|
if($numrrnames == 0)
|
|
{
|
|
my $dlg; # Warning dialog widget.
|
|
my $ret; # Warning response.
|
|
|
|
#
|
|
# Ask the user what to do.
|
|
#
|
|
$dlg = $wm->Dialog(-title => 'Warning',
|
|
-text => "No rollrec entries have \"display zone\" flag turned on",
|
|
-buttons => ["Continue", "Ignore Display", "Quit" ]);
|
|
$ret = $dlg->Show();
|
|
|
|
#
|
|
# And now we'll take the requested action.
|
|
#
|
|
if($ret eq "Quit")
|
|
{
|
|
exit(0);
|
|
}
|
|
if($ret eq "Continue")
|
|
{
|
|
return;
|
|
}
|
|
elsif($ret eq "Ignore Display")
|
|
{
|
|
#
|
|
# Set the ignore-display-flag flag and
|
|
# re-read the list of rollrec names.
|
|
#
|
|
$igndisp = 1;
|
|
readrrf($rrfile,1) if($readflag);
|
|
}
|
|
}
|
|
|
|
#
|
|
# Ensure the rollrec name list is sorted.
|
|
#
|
|
@rrnames = sort(@rrnames);
|
|
|
|
#
|
|
# Figure out the number of columns we'll use.
|
|
#
|
|
$columncount = int(sqrt($numrrnames));
|
|
if($columncount < $MINCOLS)
|
|
{
|
|
$columncount = $MINCOLS;
|
|
}
|
|
|
|
#
|
|
# Create a brand new table.
|
|
#
|
|
maketable();
|
|
|
|
#
|
|
# 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.
|
|
my $clr; # Cell's background color.
|
|
my $rrn; # Name in rollrec.
|
|
|
|
#
|
|
# Get name for this rollrec.
|
|
#
|
|
$rrn = $rrnames[$ind];
|
|
|
|
#
|
|
# Get the column and row indices.
|
|
#
|
|
($col,$row) = ind2cr($ind);
|
|
|
|
#
|
|
# Set color according to roll status.
|
|
#
|
|
if($rollrecs{$rrn}{'kskphase'} > 0)
|
|
{
|
|
$clr = $kskclr;
|
|
$rrn .= "($rollrecs{$rrn}{'kskphase'})";
|
|
}
|
|
elsif($rollrecs{$rrn}{'zskphase'} > 0)
|
|
{
|
|
$clr = $zskclr;
|
|
$rrn .= "($rollrecs{$rrn}{'zskphase'})";
|
|
}
|
|
else
|
|
{
|
|
$clr = $nonclr;
|
|
}
|
|
|
|
#
|
|
# Create the new button.
|
|
#
|
|
$btn = $rrnametab->Button(-text => "$rrn",
|
|
-font => $font,
|
|
-anchor => 'w',
|
|
-state => 'normal',
|
|
-command => [\&rrname_toggle,
|
|
$ind],
|
|
-activebackground => $clr,
|
|
-background => $clr);
|
|
|
|
$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_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_ROLL) ? $RRTAB_NONROLL : $RRTAB_ROLL;
|
|
|
|
#
|
|
# ... 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: 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: cmd_open()
|
|
#
|
|
sub cmd_open
|
|
{
|
|
my $fowin; # File-open widget.
|
|
my %fsopts = (); # FileSelect() options.
|
|
my $newfile; # New file name.
|
|
|
|
#
|
|
# 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: cmd_halt()
|
|
#
|
|
sub cmd_halt
|
|
{
|
|
my $opt = shift; # Optional "now".
|
|
|
|
#
|
|
# Tell rollerd that it's time to go away.
|
|
#
|
|
system("rollctl -quiet -halt $opt");
|
|
|
|
#
|
|
# Pause for a moment and then shut ourself down.
|
|
#
|
|
sleep(2);
|
|
cmd_quit();
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: cmd_dspuball()
|
|
#
|
|
sub cmd_dspuball
|
|
{
|
|
#
|
|
# Tell rollerd that all the zones's new DS records have been
|
|
# published.
|
|
#
|
|
system("rollctl -quiet -dspuball");
|
|
}
|
|
|
|
#---------------------------------------------------------------------------
|
|
# Routine: cmd_quit()
|
|
#
|
|
sub cmd_quit
|
|
{
|
|
#
|
|
# Destroy the rollrec name table's widgets.
|
|
#
|
|
if($rrnametab)
|
|
{
|
|
$rrnametab->clear;
|
|
$rrnametab->destroy;
|
|
}
|
|
|
|
rollrec_discard();
|
|
|
|
#
|
|
# Destroy the main window. This will cause MainLoop() to return,
|
|
# leading to the program exiting.
|
|
#
|
|
$wm->destroy;
|
|
}
|
|
|
|
##############################################################################
|
|
#
|
|
# 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");
|
|
|
|
cmd_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 = ();
|
|
|
|
#
|
|
# 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 necessary data to the %rollrecs hash.
|
|
#
|
|
$rollrecs{$rrn}{'display'} = $rrec->{'display'};
|
|
$rollrecs{$rrn}{'kskphase'} = $rrec->{'kskphase'};
|
|
$rollrecs{$rrn}{'zskphase'} = $rrec->{'zskphase'};
|
|
|
|
#
|
|
# 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;
|
|
}
|
|
|
|
#
|
|
# Drop out the zones that aren't to be displayed.
|
|
#
|
|
for(my $ind=$numrrnames-1; $ind >= 0; $ind--)
|
|
{
|
|
my $rrec; # This rollrec's data.
|
|
my $rrn;
|
|
|
|
#
|
|
# Get the zone name and its rollrec.
|
|
#
|
|
$rrn = $rrnames[$ind];
|
|
$rrec = rollrec_fullrec($rrn);
|
|
|
|
#
|
|
# If the zone's display flag is off, lop it out of the list.
|
|
#
|
|
if(($igndisp == 0) && ($rollrecs{$rrn}{'display'} == 0))
|
|
{
|
|
splice @rrnames, $ind, 1;
|
|
next;
|
|
}
|
|
|
|
#
|
|
# If this zone is doing a KSK roll and we aren't displaying
|
|
# KSK-rolling zones, we'll remove it from the list.
|
|
#
|
|
if(($showksk == 0) && ($rollrecs{$rrn}{'kskphase'} > 0))
|
|
{
|
|
splice @rrnames, $ind, 1;
|
|
next;
|
|
}
|
|
|
|
#
|
|
# If this zone is doing a ZSK roll and we aren't displaying
|
|
# ZSK-rolling zones, we'll remove it from the list.
|
|
#
|
|
if(($showzsk == 0) && ($rollrecs{$rrn}{'zskphase'} > 0))
|
|
{
|
|
splice @rrnames, $ind, 1;
|
|
next;
|
|
}
|
|
|
|
#
|
|
# If we're displaying non-rolling zones and this zone isn't
|
|
# doing a roll, we'll remove it from the list.
|
|
#
|
|
if(($shownon == 0) &&
|
|
(($rollrecs{$rrn}{'kskphase'} == 0) &&
|
|
($rollrecs{$rrn}{'zskphase'} == 0)))
|
|
{
|
|
splice @rrnames, $ind, 1;
|
|
next;
|
|
}
|
|
|
|
}
|
|
|
|
#
|
|
# Recalculate the number of zones we'll track.
|
|
#
|
|
$numrrnames = @rrnames;
|
|
|
|
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: 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: 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: help_help()
|
|
#
|
|
# Purpose: Display a help window.
|
|
#
|
|
sub help_help
|
|
{
|
|
my $hframe; # Help frame.
|
|
my $wdgt; # General widget.
|
|
|
|
my $helpstr;
|
|
|
|
$helpstr = "
|
|
|
|
bubbles - DNSSEC-Tools Rollrec Simple GUI Display
|
|
|
|
SYNOPSIS
|
|
|
|
bubbles [options] <rollrec-file>
|
|
|
|
DESCRIPTION
|
|
|
|
bubbles gives a simple display of the roll status of a set of zones listed in
|
|
a rollrec file. In contrast, blinkenlights gives a detailed display of the
|
|
roll status of a set of zones.
|
|
|
|
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 states. Each zone's rollrec record contains such information as the
|
|
zone file, the rollover phase, and logging level. rollrec files are text
|
|
files.
|
|
|
|
When bubbles starts, a window is created that has 'bubbles' for each zone with
|
|
a rollrec record in the given rollrec file. (Clicking on a bubble doesn't do
|
|
anything.) By default, all zones with a display flag set on will be shown in
|
|
the bubbles window. Options may be given to modify this behavior.
|
|
|
|
More information may be found in bubbles' 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>',\&cmd_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: help_about()
|
|
#
|
|
# Purpose: Display an about window.
|
|
#
|
|
sub help_about
|
|
{
|
|
my $dlg; # About dialog widget.
|
|
|
|
$dlg = $wm->Dialog(-title => "About $NAME",
|
|
-text => "$VERS\n\n$DTVERS",
|
|
-buttons => ["Continue" ]);
|
|
$dlg->Show();
|
|
}
|
|
|
|
#----------------------------------------------------------------------
|
|
#
|
|
# Routine: settitle()
|
|
#
|
|
# Purpose: Set the title for use in the "Editing File" line.
|
|
#
|
|
sub settitle
|
|
{
|
|
my $name = shift; # Name to use.
|
|
|
|
$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: bubbles [options] <rollrec-file>\n";
|
|
print STDERR "\toptions:\n";
|
|
print STDERR "\t\t-kskcolor color for KSK rolling zones\n";
|
|
print STDERR "\t\t-zskcolor color for ZSK rolling zones\n";
|
|
print STDERR "\t\t-noncolor color for non-rolling zones\n";
|
|
print STDERR "\n";
|
|
print STDERR "\t\t-showksk show KSK-rolling zones\n";
|
|
print STDERR "\t\t-showzsk show ZSK-rolling zones\n";
|
|
print STDERR "\t\t-showrolls show rolling zones\n";
|
|
print STDERR "\t\t-shownonrolls show non-rolling zones\n";
|
|
print STDERR "\n";
|
|
print STDERR "\t\t-ignore-display ignore rollrec display flags\n";
|
|
print STDERR "\t\t-interval n interval between file checks\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-Version program version\n";
|
|
exit(0);
|
|
}
|
|
|
|
1;
|
|
|
|
#############################################################################
|
|
|
|
=pod
|
|
|
|
=head1 NAME
|
|
|
|
bubbles - DNSSEC-Tools Rollrec Simple GUI Display
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
bubbles [options] <rollrec-file>
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
B<bubbles> gives a simple display of the roll status of a set of zones
|
|
listed in a I<rollrec> file. In contrast, B<blinkenlights> gives a detailed
|
|
display of the roll status of a set of zones. B<bubbles> gives very little
|
|
control over B<rollerd>, the way B<blinkenlights> does. B<bubbles> can halt
|
|
B<rollerd>'s execution only.
|
|
|
|
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 states. 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.
|
|
|
|
When B<bubbles> starts, a window is created that has "bubbles" for each
|
|
zone with a I<rollrec> record in the given I<rollrec> file. (Clicking on a
|
|
bubble doesn't do anything.) By default, all zones with a I<display> flag
|
|
set on will be shown in the B<bubbles> window. Options may be given to
|
|
modify this behavior.
|
|
|
|
The zone bubbles are color-coded according to roll-over state. The default
|
|
colors are:
|
|
|
|
* green: not in roll-over
|
|
|
|
* yellow: in ZSK roll-over
|
|
|
|
* red: in KSK roll-over
|
|
|
|
These colors may be specified by the user via command-line options.
|
|
|
|
In building the bubble window, B<bubbles> window defaults to creating a square
|
|
window. This may be overridden by specifying the number of columns, using the
|
|
B<-columns> option.
|
|
|
|
=head1 OPTIONS
|
|
|
|
B<bubbles> 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<-kskcolor color>
|
|
|
|
Set the bubble color for zones that are performing KSK roll-overs.
|
|
|
|
=item B<-zskcolor color>
|
|
|
|
Set the bubble color for zones that are performing ZSK roll-overs.
|
|
|
|
=item B<-noncolor color>
|
|
|
|
Set the bubble color for zones that are not in roll-over.
|
|
|
|
=item B<-ignore-display>
|
|
|
|
Ignore the B<rollrec> display flag and display every zone in the B<rollrec>
|
|
file.
|
|
|
|
=item B<-interval wait-time>
|
|
|
|
Interval between checks of the B<rollrec> file. By default, I<wait-time> is
|
|
given in minutes. This can be adjusted by specifying one of the following
|
|
time-unit suffixes.
|
|
|
|
* s - seconds
|
|
|
|
* m - minutes
|
|
|
|
* h - hours
|
|
|
|
Examples:
|
|
|
|
* I<-interval 24> - 24 minutes
|
|
|
|
* I<-interval 24s> - 24 seconds
|
|
|
|
* I<-interval 24m> - 24 minutes
|
|
|
|
* I<-interval 24h> - 24 hours
|
|
|
|
=item B<-no-filter>
|
|
|
|
This option turns off name filtering when B<bubbles> 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<-showksk>
|
|
|
|
Show the zones that are performing KSK roll-overs.
|
|
|
|
=item B<-shownonrolls>
|
|
|
|
Show the zones that are not in roll-over.
|
|
|
|
=item B<-showrolls>
|
|
|
|
Show the zones that are performing either type of roll-over.
|
|
|
|
=item B<-showzsk>
|
|
|
|
Show the zones that are performing ZSK roll-overs.
|
|
|
|
=item B<-help>
|
|
|
|
Give a usage message and exit.
|
|
|
|
=item B<-Version>
|
|
|
|
Displays the version information for B<bubbles> and the DNSSEC-Tools
|
|
package.
|
|
|
|
=back
|
|
|
|
=head1 REQUIREMENTS
|
|
|
|
B<bubbles> is implemented in Perl/Tk, so both Perl and Perl/Tk must be
|
|
installed on your system.
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright 2009-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<blinkenlights(8)>,
|
|
B<rollchk(8)>,
|
|
B<rollerd(8)>
|
|
B<rollinit(8)>,
|
|
B<rollrec-editor(8)>
|
|
B<rollset(8)>,
|
|
|
|
B<Net::DNS::SEC::Tools::rollrec(3)>
|
|
|
|
B<file-rollrec(5)>
|
|
|
|
=cut
|
|
|