#!/usr/bin/perl
#
# Script to read /etc/mrtg.conf and create a linked collection of
# index files. Expects Target names to be $HOST-$SERVICE-$OTHER
# with only $HOST-$SERVICE being mandatory. Creates to file groups
#  - group of hostfiles (all services on one host)
#  - group of servicefiles (all hosts with this service)
# 
# Examples for target name: mordor-disk-usr, frodo-dns
# The hostfiles are named overview-host-$HOSTNAME.html, the servicefiles
# are named overview-service-$SERVICE.html.
# One indexfile linking to those files is created.
#
# This software is distributed under the Artistic license, for more
# information about this license see the file Artistic
# For more documentation, see the file README
#
# Author           : Alexander Schreiber <als@thangorodrim.de>
# Distribution-Site:  http://www-user.tu-chemnitz.de/~als/software/mrtgindex/
#
# Version: $Id: mrtgindex,v 1.7 2001/06/11 05:38:56 als Exp $
#
#
# constants

########### begin configuration section #############

# user configuration

# path to mrtg config file
$MRTG_CONF = '/etc/mrtg.cfg';

# path to mrtg wwwroot, relative URI-path to the mrtg-files
# #NOTE# maybe replace with relative links?
$MRTG_WEBROOT = '.';

# path to mrtg fileroot, where should we store the generated HTML
$MRTG_FILEROOT = '/var/www/mrtg';

# style of generated HTML
#  - 1 = hierarchical without navigation
#  - 2 = with navigation bar
$HTML_STYLE = 2;

###### defaults, you shouldn't need to change them

# name of index file, you shouldn't need to change this
$GLOBAL_INDEX = 'index.html';

# first part of servicefile name,  you shouldn't need to change this
$SERVICEFILE_NAMEBASE = 'overview-service-';

# first part of hostfile name,  you shouldn't need to change this
$HOSTFILE_NAMEBASE = 'overview-host-';

# default background color for generated pages
$BG_COLOR = '#FDF6E6';

# number of columns, default 2 - set to one for low resolution displays
# with two columns, you need a (roughly) 1280 pixel wide display ...
# supported values: 1, 2  
$COL_NUM = 2;
########### end configuration section ###############

# you shouldn't need to touch anything below

$VERSION = 'version 0.3';

# globals

my @TargetList;
my %Title;

# code 

sub error_exit {
# called when fatal errors happen, writes message to STDERR and exits
# with returncode 1

    my $message = shift;

    print STDERR "fatal error: $message\n";
    exit(1);
}


sub load_targets {
# reads the mrtg config file and loads the name of all Target[.*] entries
# resulting list is stored in the global @TargetList
# also load the titles into the global %Title

    my $line;
    my $target_name;

    open(MRTGCONF, "<$MRTG_CONF") or &error_exit("cannot open config file");
    while ( $line = <MRTGCONF> ) {
        if ( $line =~ /^\s*Target\[(\w+)-(\w+)(-\w+)?\]:/ ) {
            $target_name = "$1-$2$3";
            push(@TargetList, $target_name);
        }
        if ( $line =~ /^\s*Title\[(\w+)-(\w+)(-\w+)?\]:(.*)$/ ) {
            $target_name = "$1-$2$3";
            $Title{$target_name} = $4;
        }
    }
    close(MRTGCONF);
}


sub create_servicefile {
# creates the servicefile for the service_name given as argument
# arguments: service_name

    my $service_name = shift;

    my $file_name;
    my $target_name;
    my @target_list;
    my $work;
    my $odd;
    my ($host_name, $sub_name);

    $file_name = "$MRTG_FILEROOT/$SERVICEFILE_NAMEBASE$service_name.html";
    open(OUTFILE, ">$file_name") or &error_exit("cannot open output");
    

    print OUTFILE &create_html_head("service stats for service $service_name");

    foreach $target_name ( @TargetList ) {
        if ( $target_name =~ /^(\w+)-$service_name/ ) {
            push(@target_list, $target_name);
        }
    }
    
    @target_list = sort(@target_list);

    print OUTFILE "<table cellpadding=20>\n";
    while ( $target_name = shift(@target_list) ) {
        print OUTFILE "  <tr>\n";
        print OUTFILE "    <td>\n";
        $target_name =~ /^(\w+)-(\w+)(-\w+)?/;
        $host_name = $1;
        $sub_name = $3;
        $sub_name =~ s/^-//;
        print OUTFILE "      <P><A HREF=\"$MRTG_WEBROOT/$target_name.html\"><STRONG>$Title{$target_name}</STRONG></A></P>\n";
        print OUTFILE "      <A HREF=\"$MRTG_WEBROOT/$target_name.html\"><IMG ALT=\"$target_name Graph\" BORDER=0 WIDTH=500 HEIGHT=135 SRC=\"$MRTG_WEBROOT/$target_name-day.png\"></A>\n";
        print OUTFILE "    </td>\n";
        unless ( $COL_NUM == 1 ) {
            $target_name = shift(@target_list);
            unless ( $target_name eq '' ) {
                print OUTFILE "    <td>\n";
                $target_name =~ /^(\w+)-(\w+)(-\w+)?/;
                $host_name = $1;
                $sub_name = $3;
                $sub_name =~ s/^-//;
                print OUTFILE "      <P><A HREF=\"$MRTG_WEBROOT/$target_name.html\"><STRONG>$Title{$target_name}</STRONG></A></P>\n";
                print OUTFILE "      <A HREF=\"$MRTG_WEBROOT/$target_name.html\"><IMG ALT=\"$target_name Graph\" BORDER=0 WIDTH=500 HEIGHT=135 SRC=\"$MRTG_WEBROOT/$target_name-day.png\"></A>\n";
                print OUTFILE "    </td>\n";
            } 
            print OUTFILE "  </tr>\n";
        }
    }
    print OUTFILE "</table>\n";


    print OUTFILE "<br>\n";
    print OUTFILE "<a href=\"$MRTG_WEBROOT/$GLOBAL_INDEX\">Back to index</a>\n";
    print OUTFILE "<hr>\n";
    print OUTFILE "generated by mrtgindex $VERSION\n";
    print OUTFILE '</BODY>', "\n";
    print OUTFILE '</HTML>', "\n";
    
    close(OUTFILE);

}

sub create_hostfile {
# creates the hostfile for the host_name given as argument
# arguments: host_name

    my $host_name = shift;

    my $file_name;
    my $target_name;
    my @target_list;
    my $work;
    my $odd;
    my ($service_name, $sub_name);

    $file_name = "$MRTG_FILEROOT/$HOSTFILE_NAMEBASE$host_name.html";
    open(OUTFILE, ">$file_name") or &error_exit("cannot open output");


    print OUTFILE &create_html_head("hosts stats for host $host_name");

    foreach $target_name ( @TargetList ) {
        if ( $target_name =~ /^$host_name-(\w+)/ ) {
            push(@target_list, $target_name);
        }
    }

    @target_list = sort(@target_list);

    print OUTFILE "<table cellpadding=20>\n";
    while ( $target_name = shift(@target_list) ) {
        print OUTFILE "  <tr>\n";
        print OUTFILE "    <td>\n";
        $target_name =~ /^(\w+)-(\w+)(-\w+)?/;
        $service_name = $2;
        $sub_name = $3;
        $sub_name =~ s/^-//;
        print OUTFILE "      <P><A HREF=\"$MRTG_WEBROOT/$target_name.html\"><STRONG>$Title{$target_name}</STRONG></A></P>\n";
        print OUTFILE "      <A HREF=\"$MRTG_WEBROOT/$target_name.html\"><IMG ALT=\"$target_name Graph\" BORDER=0 WIDTH=500 HEIGHT=135 SRC=\"$MRTG_WEBROOT/$target_name-day.png\"></A>\n";
        print OUTFILE "    </td>\n";
        unless ( $COL_NUM == 1 ) {
            $target_name = shift(@target_list);
            unless ( $target_name eq '' ) {
                print OUTFILE "    <td>\n";
                $target_name =~ /^(\w+)-(\w+)(-\w+)?/;
                $host_name = $1;
                $sub_name = $3;
                $sub_name =~ s/^-//;
                print OUTFILE "      <P><A HREF=\"$MRTG_WEBROOT/$target_name.html\"><STRONG>$Title{$target_name}</STRONG></A></P>\n";
                print OUTFILE "      <A HREF=\"$MRTG_WEBROOT/$target_name.html\"><IMG ALT=\"$target_name Graph\" BORDER=0 WIDTH=500 HEIGHT=135 SRC=\"$MRTG_WEBROOT/$target_name-day.png\"></A>\n";
                print OUTFILE "    </td>\n";
            }
            print OUTFILE "  </tr>\n";
        }
    }
    print OUTFILE "</table>\n";


    print OUTFILE "<br>\n";
    print OUTFILE "<a href=\"$MRTG_WEBROOT/$GLOBAL_INDEX\">Back to index</a>\n";
    print OUTFILE "<hr>\n";
    print OUTFILE "generated by mrtgindex $VERSION\n";
    print OUTFILE '</BODY>', "\n";
    print OUTFILE '</HTML>', "\n";

    close(OUTFILE);

}


sub create_global_index {
# creates the global index file

    my $file_name;
    my $target_name;
    my @target_list;
    my @service_list;
    my @host_list;
    my %host_sorter;
    my %service_sorter;
    my $work;


    @target_list = sort(@TargetList);
    foreach $target_name ( @target_list ) {
        $target_name =~ /^(\w+)-(\w+)/;
        $host_sorter{$1} = $1;
        $service_sorter{$2} = $2;
    }

    @host_list = sort(keys(%host_sorter));
    @service_list = sort(keys(%service_sorter));



    $file_name = "$MRTG_FILEROOT/$GLOBAL_INDEX";
    open(OUTFILE, ">$file_name") or &error_exit("unable to open output");

    print OUTFILE &create_html_head("mrtg overview");

    print OUTFILE "<h2>service based overview</h2>\n";
    print OUTFILE "<ul>\n";

    foreach $work ( @service_list ) {
        print OUTFILE "  <li><A HREF=\"$MRTG_WEBROOT/$SERVICEFILE_NAMEBASE$work.html\">service $work</a></li>\n";
    }

    print OUTFILE "</ul>\n";

    print OUTFILE "<h2>host based overview</h2>\n";
    print OUTFILE "<ul>\n";

    foreach $work ( @host_list ) {
        print OUTFILE "  <li><A HREF=\"$MRTG_WEBROOT/$HOSTFILE_NAMEBASE$work.html\">host $work</a></li>\n";
    }

    print OUTFILE "</ul>\n";

    print OUTFILE &create_html_tail();
}


sub create_files {
# builds and iterates through lists of services and hosts and calls
# the respective functions to create the files

    my $target_name;
    my @target_list;
    my @service_list;
    my @host_list;
    my %host_sorter;
    my %service_sorter;
    my $work;


    @target_list = sort(@TargetList);
    foreach $target_name ( @target_list ) {
        $target_name =~ /^(\w+)-(\w+)/;
        $host_sorter{$1} = $1;
        $service_sorter{$2} = $2;
    }

    @host_list = sort(keys(%host_sorter));
    @service_list = sort(keys(%service_sorter));

    foreach $work ( @host_list ) {
        if ( $HTML_STYLE == 1 ) {
            &create_hostfile($work);
        } elsif ( $HTML_STYLE == 2 ) {
            &create_displayfile('host', $work);
        }
    }

    foreach $work ( @service_list ) {
        if ( $HTML_STYLE == 1 ) {
            &create_servicefile($work);
        } elsif ( $HTML_STYLE == 2 ) {
          &create_displayfile('service', $work);
        }
    }
}

sub create_html_head {
# returns the standard html header for each file
# parameter: title of page

    my $page_title = shift;

    my $header;

    $header = '';

    $header .=  "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n";
    $header .=  "<HTML>\n";
    $header .=  "<HEAD>\n";
    $header .=  "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=iso-8859-1\">\n";
    $header .=  "<TITLE>$page_title</TITLE>\n";
    $header .=  "</HEAD>\n";
    $header .=  "<BODY  bgcolor=\"$BG_COLOR\">\n";
    $header .=  "<H1>$page_title</H1>\n";

    return $header;
}

sub create_html_tail {
# returns a standard HTMl tail (closing tags for body and html, link to
# index page)
# parameters: set_link, values "indexlink"/"" (set index links yes/no)


    my $set_link = shift;
    my $tail;

    $tail = '';

    $tail .= "<br>\n";
    if ( $set_link eq "indexlink" ) {
        $tail .= "<a href=\"$MRTG_WEBROOT/$GLOBAL_INDEX\">back to overview</a>\n";
    }
    $tail .= "<hr>\n";
    $tail .= "Generated by <a href=";
    $tail .= "\"http://www-user.tu-chemnitz.de/~als/software/mrtgindex/\"";
    $tail .= ">mrtgindex</a> $VERSION\n";
    $tail .= "</body>\n";
    $tail .= "</html>\n";

    return $tail;
}

sub create_index_nav {
# build the master index
# parameters: none

    my @target_names;
    my @service_targets;
    my @host_targets;

    my $target_count;
    my $host_count;
    my $service_count;

    my $work;
    my $target_name;

    my %service_sorter;
    my %target_sorter;
    
    

    open(HTML, ">$MRTG_FILEROOT/$GLOBAL_INDEX") or 
        &error_exit("cannot open indexfile");
    
    print HTML &create_html_head("mrtg overview");

    print HTML "<table border=\"0\" cellpadding=\"10\">\n";
    print HTML "  <tr>\n";
    print HTML "    <td>\n";
    print HTML &create_selector_list();
    print HTML "    </td>\n";
    print HTML "    <td>\n";
    print HTML "      <h1>mrtg overview</h1>\n";
    print HTML "    </td>\n";
    print HTML "  </tr>\n";
    print HTML "</table>\n";


    print HTML &create_html_tail();
    close(HTML);
}


sub create_displayfile {
# creates the display file for the named service/host
# parameters: target (service/host), target_name

    my $target = shift;
    my $target_class = shift;
    my $target_name;
    my @target_list;
    my $file_name;
    my $target_count;


    if ( $target eq 'service' ) {
        $file_name = "$MRTG_FILEROOT/$SERVICEFILE_NAMEBASE$target_class.html";
    } elsif ( $target = 'host' ) {
        $file_name = "$MRTG_FILEROOT/$HOSTFILE_NAMEBASE$target_class.html";
    } else {
        &error_exit("invalid target for display");
    }
    open(HTML, ">$file_name") or &error_exit("cannot open output file");
    print HTML &create_html_head("detail overview for $target $target_class");

    foreach $target_name ( @TargetList ) {
        $target_name =~ /^(\w+)-(\w+).*/;
        if ( $target eq 'host' ) {
            if ( $1 eq $target_class ) {
                push(@target_list, $target_name);
            }
        } elsif  ( $target eq 'service' ) {
            if ( $2 eq $target_class ) {
                push(@target_list, $target_name);
            }   
        }
    }

    $target_count = @target_list;
    $work = $target_count + 1;

    print HTML "<table>\n";
    print HTML "  <tr>\n";
    print HTML "    <td valign=\"top\">\n";
    print HTML &create_selector_list();
    print HTML "    </td>\n";
    print HTML "    <td>\n";
    print HTML "      <table>\n";
 
    while ( $target_name = shift(@target_list) ) {
        print HTML "        <tr>\n";
        print HTML "          <td>\n";
        print HTML "            <P><A HREF=\"$MRTG_WEBROOT/$target_name.html\"><STRONG>$Title{$target_name}</STRONG></A></P>\n";
        print HTML "            <A HREF=\"$MRTG_WEBROOT/$target_name.html\"><IMG ALT=\"$target_name Graph\" BORDER=0 WIDTH=500 HEIGHT=135 SRC=\"$MRTG_WEBROOT/$target_name-day.png\"></A>\n";

        print HTML "          </td>\n";
        if ( $COL_NUM == 2 ) {
            $target_name = shift(@target_list);
            if ( $target_name ne '' ) {
                print HTML "          <td>\n";
                print HTML "            <P><A HREF=\"$MRTG_WEBROOT/$target_name.html\"><STRONG>$Title{$target_name}</STRONG></A></P>\n";
                print HTML "            <A HREF=\"$MRTG_WEBROOT/$target_name.html\"><IMG ALT=\"$target_name Graph\" BORDER=0 WIDTH=500 HEIGHT=135 SRC=\"$MRTG_WEBROOT/$target_name-day.png\"></A>\n";
                print HTML "          </td>\n";
            }
        }
        print HTML "        </tr>\n";


    }

    print HTML "      </table>\n";

    print HTML "    </td>\n";
    print HTML "  </tr>\n";

    print HTML "</table>\n";


    print HTML &create_html_tail('indexlink');
    close(HTML);

}


sub create_selector_list {
# creates the selector list, returns the HTML for the list

    my $target_name;
    my %service_sorter;
    my %host_sorter;
    my @service_targets;
    my @host_targets;

    my $selector_list;

    foreach $target_name (@TargetList) {
        $target_name =~ /^(\w+)-(\w+).*/;
        $service_sorter{$2} = 1;
        $host_sorter{$1} = 1;
    }
    @service_targets = sort(keys(%service_sorter));
    @host_targets = sort(keys(%host_sorter));

    $selector_list = '';

    $selector_list .= "<h2>mrtg overview</h2>\n";
    $selector_list .= "<h3>host overview</h3>\n";
    $selector_list .= "<ul>\n";
    foreach $target_name ( @host_targets ) {
        $selector_list .= "  <li><a href=\"$MRTG_WEBROOT/";
        $selector_list .= "$HOSTFILE_NAMEBASE$target_name.html\">";
        $selector_list .= "host $target_name</a></li>\n";
    }
    $selector_list .= "</ul>\n";
    $selector_list .= "<h3>service overview</h3>\n";
    $selector_list .= "<ul>\n";
    foreach $target_name ( @service_targets ) {
        $selector_list .= "  <li><a href=\"$MRTG_WEBROOT/";
        $selector_list .= "$SERVICEFILE_NAMEBASE$target_name.html\">";
        $selector_list .= "service $target_name</a></li>\n";
    }
    $selector_list .= "</ul>\n";

    return $selector_list;
}


# ##MAIN##

&load_targets();
&create_files();

if ( $HMTL_STYLE == 1 ) {
    &create_global_index();
} elsif ( $HTML_STYLE == 2 ) {
    &create_index_nav();
}


