#!/usr/bin/perl -w 
#
# First we explicitly switch off the Nagios embbeded Perl Interpreter
# nagios: -epn
# ############################ nagios_send_host_mail.pl ############### #
# Date    : Dec 31 2010                                                 #
# Purpose : Script to send out Nagios e-mails.\n";                      #
# Author  : Frank Migge (support at frank4dd dot com)                   #
# Help    : http://nagios.frank4dd.com/howto                            #
# Licence : GPL - http://www.fsf.org/licenses/gpl.txt                   #
#           Written for and verified with Nagios version 3.2.3          #
# Help    : ./nagios_send_host_mail.pl -h                               #
#                                                                       #
# Version : 1.0 initial release                                         #
# Version : 1.1 add multipart MIME and logo                             #
# Version : 1.2 cleanup mail body generation code                       #
# Version : 1.3 use environment variables for Nagios data handoff       #
# Version : 1.4 add the performance graph image if available            #
#                                                                       #
# Depends : perl-Mail-Sendmail                                          #
#           perl-MIME-tools                                             #
#           rrdtool-devel                                               #
#           libnetpbm (if image conversion from PNG to JPG is required) #
#           netpbm (if image conversion from PNG to JPG is required)    #
# ##################################################################### #
#									#
# Modified by Robert Becht that to use $CONTACTGROUPMEMBERS$		#
# ##################################################################### #
#!/usr/bin/perl -w
use Getopt::Long;
use Mail::Sendmail;
use Digest::MD5 qw(md5_hex);
use MIME::Base64;
use RRDs;
use File::Temp;
use strict;
use warnings;

# The version of this script
my $Version            ='1.4';
# the sender e-mail address to be seen by recipients
my $mail_sender        = "Nagios Monitoring <nagiosadmin\@yourdomaine>";
# The nagios CGI URL
my $nagios_cgiurl      = "http://192.168.1.100/nagios/cgi-bin";
# Modified by Robert Becht that to use PNP4Nagios links
# The PNP4Nagios URL : il not use, simply make to equal '';
my $nagios_pnpurl      = "http://192.168.1.100/pnp4nagios";
# Here we define a simple HTML stylesheet to be used in the HTML header.
my $html_style         = "body {text-align: center; font-family: Verdana, sans-serif; font-size: 10pt;}\n"
                       . "img.logo {float: left; margin: 10px 10px 10px; vertical-align: middle}\n"
                       . "img.graph {border: 1px solid #000000; }\n"
                       . "span {font-family: Verdana, sans-serif; font-size: 12pt;}\n"
                       . "table {text-align:center; margin-left: auto; margin-right: auto;}\n"
                       . "th {white-space: nowrap;}\n"
                       . "th.even {background-color: #D9D9D9;}\n"
                       . "td.even {background-color: #F2F2F2;}\n"
                       . "th.odd {background-color: #F2F2F2;}\n"
                       . "td.odd {background-color: #FFFFFF;}\n"
                       . "th,td {font-family: Verdana, sans-serif; font-size: 10pt; text-align:left;}\n"
                       . "th.customer {width: 600px; background-color: #004488; color: #ffffff;}";
my $table_size         = "600px";
my $header_size        = "180px";
my $data_size          = "420px";

# the commandline argument -H/--smtphost
my $o_smtphost         = "192.168.1.1";
# your domaine
my $domaine	= "\@yourdomaine";
my @listaddress = ();


# ########################################################################
# This is the logo, a base64 encoded image file. The content below is the Nagios logo
# nagios-logo.gif. It can be replaced with any picture, such as your company's logo.
# A base64 conversion example: # uuencode --base64 logo.gif < images/nagios-logo.gif
# or by using the perl script convert_img_base64.pl.
# ########################################################################
my $logo = "R0lGODlhQABAAPYAAAAAAAcHCwcJCggGBQoGCAsLCxINDRQTFBYVGRsWGBgYFhsbGyAeHCMjIyUl\n"
       . "KikkJCwrLCQxKDAxLjM0MzQ1ODg3NTg4Nzo6Oz8+QUA+QEBBP0NDQ0hHRktLS09QTFBPTlFQT1RU\n"
       . "VFdZV1daXVhYV11cXVphX2NfX2FhX2NjYmVlaWtra215c3R0c3l5dnx8e4ODg4WEiYWLiYyMjI2N\n"
       . "kJOTk5aWmJeZlZmal5ycnJ6eoKKfoKOjo6inp6ysrK+usa6zr7Gvr7Gzr7S0tLW6tby3ubq5tbu7\n"
       . "u729wMG/v8TExMjFw8nJx8zMzMrSztDQz9PT09fX29ra2t/f5d/k4eLi3uPk4+fn6Ojo5+zs7PT0\n"
       . "9Pb2+P399/7+/szMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
       . "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5\n"
       . "BAEAAF4ALAAAAABAAEAAAAf+gF6Cg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnp+goaKjpKWm\n"
       . "p6ipqqusra6vsLGys7S1rF24hLmYuF2ZWVBNSlG+XVJQUFe+lVdMQ01Zk8ZHVl5NKxsTNVpeXT4b\n"
       . "HDnRlUwiDS1Zy5BQPjw5XUwQAAAXP1pdMAIAHVCCvf+6enXr9cQcCyvqBAYEeCQHDRjw5AEIgOFI\n"
       . "lxcDAGzo18UKEyVMPhITpAXKECJPrDSBQsVLsyFPtnQDhkyKlXszoxzxMYRJlYY5fHQp4mDePBVW\n"
       . "YGTUAKXLkRYXJFSQYOHFk249SDiAEAJGhww0tCgZUVVKtyEnPnAIkaKGWSv+PDo4aNCgKhMoJXAh\n"
       . "kTgPQY0Y+phaWUEAwAMSKBQgmLFFSop5BRYgmFcC7gIAFpZk+fFhgIEHhRvQ2NIDQgAHJSoUsGBx\n"
       . "EN4ABS4UAAABxFIoWHCsSHGkihF5KawMsQBAwYseFwAUeOFU3gUmRTQQMABjyYrZG6rcEBAgBJIk\n"
       . "PIb0G6SFRgG/IyDPY2qMSZIZJCpkXLFlyAQAHJhweUGgwIwuTSTXQRU7GABABU0M9QAACwwxRFEF\n"
       . "NLBBCTokOEgSHTAYFHEZ7YPMClR1AAIIBwCgQhZKSIBfTPwN4MIWTWS4kQ8LbiBFFw8y2EMWOaxw\n"
       . "AgSFLdCCWd0A0QCDNHT+gYMCRnFgkooTAEHFERgEMAIVUqwwgHEz3AdACVcoQQEAExwBRQYANODD\n"
       . "FDSUSIESVSTxzBIwMLkBE/4cURQEPVhTglEXRBGEPA288AIGs5lw4xEqCoBAiV9ewcNlEgxhRQuz\n"
       . "SRBCUQK0cEUPFSTAAQ4zXJbCeAB2MEAFQ3RDRAcLFBACFE+gYMAAC0wAggQRsNAPjxtY4MJ1+0jR\n"
       . "RAgFdKAEgDBAsMABEnTQQhI4ksCAo7mmMIQ6WQzBgw83blFSDz0kkQ4TOcBQQ09EAOHEFlDgcMQT\n"
       . "T2QBGAAgSKHFETpY2s0VR/QQVBNWcOGFFk/wMAMNOTAhhUyCwJvDDkOICDzDxTwQwUQ1XXCB0z9d\n"
       . "KDFBA9LCMGYBMESj0EAC7QLyLoJcUYMFEEAggQQTVDCBzUMuAkULCAxwAAQIIKBCU5yIhUMOPOgQ\n"
       . "Q3g81BDeFYt0AUUOMcywQw42IM1JLgAVA7MivWzxj8G2pK322my37fbbcMct99x012333Xjnrffe\n"
       . "fPftdyGBAAA7";

# ########################################################################
# Here I define the HTML color values for each Nagios notification type.
# There is one extra called TEST for sending a test e-mail from the cmdline
# outside of Nagios. The color values are used for highlighting the
# background of the notification type cell.
# ########################################################################
my %NOTIFICATIONCOLOR=('PROBLEM'=>'#FF8080','RECOVERY'=>'#80FF80','ACKNOWLEDGEMENT'=>'FFFF80',
                       'DOWNTIMESTART'=>'80FFFF','DOWNTIMEEND'=>'80FF80','DOWNTIMECANCELLED'=>'FFFF80',
                       'FLAPPINGSTART'=>'#FF8080','FLAPPINGSTOP'=>'#80FF80',' FLAPPINGDISABLED'=>'FFFF80',
                       'TEST'=>'80FFFF');

# ########################################################################
# Here we set the information where to pick up the RRD data files for the
# optional graph image generation, plus the graph size width x height px
# ########################################################################
#my $rrd_basedir        = "/srv/app/nagiosgraph/rrd";
my $rrd_basedir        = "/var/nagios/perfdata";
my $graph_img_size     = "521x60";
my $graph_bgcolor      = "#F2F2F2";
my $graph_border       = "#999999";

# ##### Global Variables - No changes necessary below this line ##########
# Nagios notification type, i.e. PROBLEM
my $o_notificationtype = $ENV{NAGIOS_NOTIFICATIONTYPE};
# Nagios notification author (if avail.)
my $o_notificationauth = $ENV{NAGIOS_NOTIFICATIONAUTHOR};
# Nagios notification comment (if avail.)
my $o_notificationcmt  = $ENV{NAGIOS_NOTIFICATIONCOMMENT};
# Nagios monitored host name
my $o_hostname         = $ENV{NAGIOS_HOSTNAME};
# Nagios monitored host alias
my $o_hostalias        = $ENV{NAGIOS_HOSTALIAS};
# Nagios host group the host belongs to
my $o_hostgroup        = $ENV{NAGIOS_HOSTGROUPNAME};
# Nagios monitored host IP address
my $o_hostaddress      = $ENV{NAGIOS_HOSTADDRESS};
# Nagios monitored host state, i.e. DOWN
my $o_hoststate        = $ENV{NAGIOS_HOSTSTATE};
# Nagios monitored host check output data
my $o_hostoutput       = $ENV{NAGIOS_HOSTOUTPUT};
# Nagios date when the event was recorded
my $o_datetime         = $ENV{NAGIOS_LONGDATETIME};
# The recipients defined in $CONTACTEMAIL$
my $o_to_recipients    = $ENV{NAGIOS_CONTACTEMAIL};
# Modified by Robert Becht that for use $CONTACTGROUPEMEMBERS$ with Nconf
my $o_to_group         = $ENV{NAGIOS_CONTACTGROUPMEMBERS};

# The next variables are provided through args
my $o_cc_recipients    = undef; # The recipients defined in $CONTACTADDRESS1$
my $o_bcc_recipients   = undef; # The recipients defined in $CONTACTADDRESS2$
my $o_format           = "html";# The e-mail output format (default: text)
my $o_addurl           = undef; # flag to add Nagios GUI URLs to HTML e-mails
my $o_language         = "en";  # The e-mail output language (default: English)
my $o_customer         = undef; # Company name and contract number for service providers
my $o_help             = undef; # We want help
my $o_verb             = undef; # verbose mode
my $o_version          = undef; # print version
my $o_test             = undef; # generate test message
my $text_msg_en        = undef;
my $html_msg_en        = undef;
my $text_msg_jp        = undef;
my $html_msg_jp        = undef;
my $logo_id            = undef;
my $graph_id           = undef;
my $graph_img          = undef;
my $boundary           = undef;
my $mail_content       = undef;
my %mail;

# ########################################################################
# subroutine defintions below
# ########################################################################

# ########################################################################
# p_version returns the program version
# ########################################################################
sub p_version { print "nagios_send_host_mail.pl version : $Version\n"; }

# ########################################################################
# print_usage returns the program usage
# ########################################################################
sub print_usage {
    print "Usage: $0 [-v] [-V] [-h] [-t] [-H <SMTP host>] [-p <customername>] [-r <to_recipients> or -g <to_group>] [-c <cc_recipients>] [-b <bcc_recipients>] [-f <text|html|multi|graph>] [-u] [-l <en|jp>]\n";
}

# ########################################################################
# help returns the program help message
# ########################################################################
sub help {
   print "\nNagios e-mail notification script for host events, version ".$Version."\n";
   print "GPL licence, (c)2010 Frank Migge\n\n";
   &print_usage();
   print <<EOT;

This script takes over the Nagios e-mail notifications by receiving the Nagios state information, 
formatting the e-mail and sending it out through an SMTP gateway.

-v, --verbose
   print extra debugging information 
-V, --version
   prints version number
-h, --help
   print this help message
-t, --test
   generates a test message together with -r, --to-recipients
-H, --smtphost=HOST
   name or IP address of SMTP gateway
-p, --customer="customer name and contract #"
  optionally, add the customer name and contract for service providers
-r, --to-recipients 
   this option overrides the Nagios-provided \$CONTACTEMAIL\$ list of to: recipients
-g, --to-group-recipients \$CONTACTGROUPMEMBERS\$(group_name) ->comma delimited list of groupmembers by name
    this option use the list of contactgroup and reconstitue the mail address with the below defined \$domaine.
    this is only possible when the contact name "abcd" provides the address "abcd\@domaine".
-c, --cc-recipients (separated by comma ",")
   the Nagios-provided \$CONTACTADDRESS1\$ list of cc: recipients
-b, --bcc-recipients (separated by comma ",")
   the Nagios-provided \$CONTACTADDRESS2\$ list of bcc: recipients
-f, --format='text|html|multi|graph'
   the email format to generate: either plain text, HTML, multipart S/MIME ouput or multipart with the Nagiosgraph added
-u, --addurl
   this adds URL's to the Nagios web GUI for check status, host and hostgroup views into the html mail, requires -f html, multi or graph
-l, --language='en|jp'
   the prefered e-mail language. The content-type header is currently is hard-coded to UTF-8. This might need to be changed if recipients require a different characterset encoding.  

EOT
}

# ########################################################################
# verb creates verbose output
# ########################################################################
sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; }

# ########################################################################
# unique content ID are needed for mulitpart messages with inline logos
# ########################################################################
sub create_content_id {
  my $unique_string  = rand(100);
  $unique_string  = $unique_string . substr(md5_hex(time()),0,23);
  $unique_string  =~ s/(.{5})/$1\./g;
  my $content_id  = qq(part.${unique_string}\@) . "MAIL";
  $unique_string  = undef;
  return $content_id;
}

# ########################################################################
# create_boundary creates the S/MIME multipart boundary strings
# ########################################################################
sub create_boundary {
  my $unique_string  = substr(md5_hex(time()),0,24);
  $boundary       = '======' . $unique_string ;
  $unique_string  = undef;
}

sub unknown_arg {
  print_usage();
  exit -1;
}

# ########################################################################
# create_address from the groupmembers list (Add by Robert Becht)
# ########################################################################
sub create_address {
chomp($o_to_group);
my @mlist = split(",",$o_to_group);
foreach (@mlist) {
    my $maddress = "$_"."$domaine";
    # Debugging
    #print "$maddress\n";
    push(@listaddress,$maddress);
    }
$o_to_group = join(";",@listaddress);
#$o_to_group = "\"$o_to_group\""; #only if it necesserary !
#Debugging
#print "$o_to_group\n";
return ($o_to_group);

}

# ########################################################################
# check_options checks and processes the commandline options given
# ########################################################################
sub check_options {
  Getopt::Long::Configure ("bundling");
  GetOptions(
      'v'     => \$o_verb,            'verbose'           => \$o_verb,
      'V'     => \$o_version,         'version'           => \$o_version,
      'h'     => \$o_help,            'help'              => \$o_help,
      't'     => \$o_test,            'test'              => \$o_test,
      'H:s'   => \$o_smtphost,        'smtphost:s'        => \$o_smtphost,
      'p:s'   => \$o_customer,        'customer:s'        => \$o_customer,
      'r:s'   => \$o_to_recipients,   'to-recipients:s'   => \$o_to_recipients,
      'g:s'   => \$o_to_group,	      'to-group-recipients' => \$o_to_group,
      'c:s'   => \$o_cc_recipients,   'cc-recipients:s'   => \$o_cc_recipients,
      'b:i'   => \$o_bcc_recipients,  'bcc-recipients:s'  => \$o_bcc_recipients,
      'f:s'   => \$o_format,          'format:s'          => \$o_format,
      'u'     => \$o_addurl,          'addurl'            => \$o_addurl,
      'l:s'   => \$o_language,        'language:s'        => \$o_language,
  ) or unknown_arg();

  # Basic checks
  if (defined ($o_help) ) { help(); exit 0};
  if (defined($o_version)) { p_version(); exit 0};
  if ( (! defined($o_to_recipients)) && (! defined($o_to_group))) # no recipients provided
    { print "Error: no recipients have been provided\n"; print_usage(); exit -1}
  else {
	if ( ! defined($o_to_group) ){
	    %mail = (
	    To      => $o_to_recipients,
	    From    => $mail_sender,
	    Sender  => $mail_sender
	    ); } else {
		&create_address;
		%mail = (
		To      => $o_to_group,
		From    => $mail_sender,
		Sender  => $mail_sender
		); 
		}
	 }

  if ( $o_format ne "text" && $o_format ne "html" 
    && $o_format ne "multi" && $o_format ne "graph") # wrong mail format
    { print "Error: wrong e-mail format.\n"; print_usage(); exit -1}
  if ( $o_language ne "en" && $o_language ne "jp" ) # wrong language
    { print "Error: wrong language id.\n"; print_usage(); exit -1}
  if (defined($o_addurl) && $o_format eq "text")
    { print "Error: cannot add URL's to text.\n"; print_usage(); exit -1}
  if (defined($o_test)) { create_test_data(); };
  # we try to create a graph image based on the hostname
  if ($o_format eq "graph") { $graph_img = create_graph_image(); }
}

#Debugging
# my @temp = %mail;
# my $refile = "/tmp/mail_debug.txt";
# open(DEBUG, ">$refile") or die "$refile:$!";
# print "@temp\n";
# close(DEBUG) or die $!;
#exit;

# ########################################################################
# if -x or --test, we need to create sample test data to send out
# In order to successfully test a e-mail with performance graph generation
# set a valid hostname to be able to pick up a RRD file.
# ########################################################################
sub create_test_data {
  if (! defined($o_customer)){         $o_customer         = "ACME Corporation";}
  if (! defined($o_notificationtype)){ $o_notificationtype = "TEST";}
  if (! defined($o_hoststate)){        $o_hoststate        = "UNKNOWN";}
  if (! defined($o_hostname)){         $o_hostname         = "susie114";}
  if (! defined($o_hostalias)){        $o_hostalias        = "testhost1.domain.com (LINUX)";}
  if (! defined($o_hostaddress)){      $o_hostaddress      = "192.168.1.1";}
  if (! defined($o_hostgroup)){        $o_hostgroup        = "Linux Servers";}
# if (! defined($o_datetime)){         $o_datetime         = "Thu Jan 6 12:08:04 JST 2011";}
  if (! defined($o_datetime)){         $o_datetime         = `date`;}
# if (! defined($o_datetime))         {$o_datetime         = localtime time;}
  if (! defined($o_hostoutput)){       $o_hostoutput       = "Test output for this host";}
  if (! defined($o_notificationauth)){ $o_notificationauth = "John Doe";}
  if (! defined($o_notificationcmt)){  $o_notificationcmt  = "Test message for the host";}
}


# ########################################################################
# Create a plaintext message in English -> $text_msg_en
# ########################################################################
sub create_message_en_text {
  $text_msg_en = "Nagios Monitoring System Notification\n"
               . "=====================================\n\n";

  # if customer name was given for service providers, display it here
  if ( defined($o_customer)) {
    $text_msg_en = $text_msg_en . "Customer: $o_customer\n";
  }

  $text_msg_en = $text_msg_en
               . "Notification Type: $o_notificationtype\n"
               . "Host Status: $o_hoststate\n"
               . "Hostname: $o_hostname\n"
               . "Hostalias: $o_hostalias\n"
               . "IP Address: $o_hostaddress\n"
               . "Hostgroup: $o_hostgroup\n"
               . "Event Time: $o_datetime\n"
               . "Event Data: $o_hostoutput\n\n";

  # if author and comment data has been passed from nagios
  # and these variables have content, then we add two more columns
  if ( ( defined($o_notificationauth) && defined($o_notificationcmt) ) &&
       ( ($o_notificationauth ne "") && ($o_notificationcmt ne "") ) ) {
    $text_msg_en =   $text_msg_en . "Author: $o_notificationauth\n"
                 . "Comment: $o_notificationcmt\n\n";
  }

  $text_msg_en = $text_msg_en . "-------------------------------------\n"
               . "Generated by Nagios, the OpenSource monitoring solution.\n";
}

# ########################################################################
# Create a simple HTML message in English -> $html_msg_en
# ########################################################################
sub create_message_en_html {
  # Start HTML message definition in English
  $html_msg_en = "<html><head><style type=\"text/css\">$html_style</style></head><body>\n"
               . "<table width=$table_size><tr>\n";

  if ($o_format eq "multi" || $o_format eq "graph") {
    $logo_id = create_content_id();
    $html_msg_en = $html_msg_en . "<td><img class=\"logo\" src=\"cid:$logo_id\"></td>"
                 . "<td><span>Nagios Monitoring System Notification</span></td></tr><tr>\n";
  } else {
    $html_msg_en = $html_msg_en . "<th colspan=2><span>Nagios Monitoring System Notification</span></th></tr><tr>\n";
  }

  if ( defined($o_customer)) {
    $html_msg_en = $html_msg_en . "<th colspan=2 class=customer>$o_customer</th></tr><tr>\n";
  }

  $html_msg_en = $html_msg_en
               . "<th width=$header_size class=odd>Notification Type:</th>\n"
               . "<td bgcolor=$NOTIFICATIONCOLOR{$o_notificationtype}>\n"
               . "$o_notificationtype</td></tr>\n"
               . "<tr><th class=even>Host Status:</th><td class=even>$o_hoststate</td></tr>\n"
               . "<tr><th class=odd>Host Name:</th><td>\n";
  
  if (defined($o_addurl)) {
    $html_msg_en = $html_msg_en
                 . "<a href=\"$nagios_cgiurl/status.cgi?host=$o_hostname&style=detail\">$o_hostname</a>";
  } else { $html_msg_en  = $html_msg_en . $o_hostname; }
  
  $html_msg_en = $html_msg_en . "</td></tr>\n"
               . "<tr><th class=even>Hostalias:</th><td class=even>$o_hostalias</td></tr>\n"
               . "<tr><th class=odd>IP Address:</th><td>$o_hostaddress</td></tr>\n"
               . "<tr><th class=even>Hostgroup:</th><td class=even>\n";
  
  if (defined($o_addurl)) {
    $html_msg_en = $html_msg_en
                 . "<a href=\"$nagios_cgiurl/status.cgi?hostgroup=$o_hostgroup&style=overview\">$o_hostgroup</a>";
  } else { $html_msg_en = $html_msg_en . $o_hostgroup; }
  
  $html_msg_en = $html_msg_en . "</td></tr>\n"
               . "<tr><th class=odd>Event Time:</th><td>$o_datetime</td></tr>\n"
               . "<tr><th class=even>Event Data:</th><td class=even>\n";
  
  if (defined($o_addurl)) {
      $html_msg_en = $html_msg_en ;
	  if ( $nagios_pnpurl eq '') {
	      $html_msg_en .= "<a href=\"$nagios_cgiurl/status.cgi?extinfo.cgi?type=1&host=$o_hostname\">$o_hostoutput</a>\n";
	      } else {
	      # Modified by Robert Becht for link to PNP4Nagios graph 
	      $html_msg_en .= "<a href=\"$nagios_pnpurl/index.php/graph?host=$o_hostname&serv=_HOST_\">$o_hostoutput</a>\n";
	      }
	  } else { $html_msg_en = $html_msg_en . $o_hostoutput; }
  
  $html_msg_en = $html_msg_en . "</td></tr>\n";

  # if author and comment data has been passed from nagios
  # and these variables have content, then we add two more columns
  if ( ( defined($o_notificationauth) && defined($o_notificationcmt) ) &&
       ( ($o_notificationauth ne "") && ($o_notificationcmt ne "") ) ) {
    $html_msg_en = $html_msg_en . "<tr><th align=left class=odd>Author:</th>\n"
                 . "<td>$o_notificationauth</td></tr>\n"
                 . "<tr><th class=even>Comment:</th>\n"
                 . "<td class=even>$o_notificationcmt</td></tr>";
  }

  $html_msg_en = $html_msg_en . "</table><p>\n";

  # if we got the graph format and a image has been generated, we add it here
  if (defined($graph_img) && $o_format eq "graph") {
    $graph_id = create_content_id();
    $html_msg_en = $html_msg_en . "<img class=\"graph\" src=\"cid:$graph_id\">\n";
  }

  $html_msg_en = $html_msg_en . "</p><hr>\n"
               . "Generated by Nagios, the OpenSource monitoring solution.\n"
               . "<hr>\n"
               . "</center></body></html>\n";
  # End HTML message definition in English
}

# ########################################################################
# Create a plain text message in Japanese -> $text_msg_jp
# ########################################################################
sub create_message_jp_text {
  $text_msg_jp = "Nagios 監視システムの通知\n"
               . "=====================================\n\n";

  # if customer name was given, display it here
  if ( defined($o_customer)) {
    $text_msg_jp = $text_msg_jp . "顧客名: $o_customer\n";
  }

  $text_msg_jp = $text_msg_jp
               . "通知の種類: $o_notificationtype\n"
               . "ホストの状態: $o_hoststate\n"
               . "ホスト名: $o_hostname\n"
               . "ホストの別名: $o_hostalias\n"
               . "IPアドレス: $o_hostaddress\n"
               . "ホストグループ: $o_hostgroup\n"
               . "イベントの日付と時刻: $o_datetime\n"
               . "イベントデータ出力: $o_hostoutput\n\n";

  # if author and comment data has been passed from nagios
  # and these variables have content, then we add two more columns
  if ( ( defined($o_notificationauth) && defined($o_notificationcmt) ) &&
       ( ($o_notificationauth ne "") && ($o_notificationcmt ne "") ) ) {
    $text_msg_jp = $text_msg_jp . "投稿者: $o_notificationauth\n"
                 . "コメント: $o_notificationcmt\n\n";
  }

  $text_msg_jp = $text_msg_jp . "-------------------------------------\n"
               . "このメーセジはオープンソースの監視システムNagiosで生成されています。\n";
}

# ########################################################################
# Create a simple HTML message in Japanese -> $html_msg_jp
# ########################################################################
sub create_message_jp_html {
  # Start HTML message definition in Japanese
  $html_msg_jp = "<html><head><style type=\"text/css\">$html_style</style></head><body>\n"
               . "<table width=$table_size><tr>\n";

  if ($o_format eq "multi") {
    $logo_id = create_content_id();
    $html_msg_jp = $html_msg_jp . "<td><img class=\"logo\" src=\"cid:$logo_id\"></td>"
                 . "<td><span>Nagios 監視システムの通知</span></td></tr><tr>\n";
  } else {
    $html_msg_jp = $html_msg_jp . "<th colspan=2><span>Nagios 監視システムの通知</span></th></tr><tr>\n";
  }

  if ( defined($o_customer)) {
    $html_msg_jp = $html_msg_jp . "<th colspan=2 class=customer>$o_customer</th></tr><tr>\n";
  }

  $html_msg_jp = $html_msg_jp
               . "<th width=$header_size class=odd>通知の種類:</th>\n"
               . "<td width=$data_size bgcolor=$NOTIFICATIONCOLOR{$o_notificationtype}>\n"
               . "$o_notificationtype</td></tr>\n"
               . "<tr><th class=even>ホストの状態:</th><td class=even>$o_hoststate</td></tr>\n"
               . "<tr><th class=odd>ホスト名:</th><td>\n";
  
  if (defined($o_addurl)) {
     $html_msg_jp  = $html_msg_jp 
                   . "<a href=\"$nagios_cgiurl/status.cgi?host=$o_hostname&style=detail\">$o_hostname</a>";
  } else { $html_msg_jp  = $html_msg_jp . $o_hostname; }
  
  $html_msg_jp  = $html_msg_jp . "</td></tr>\n"
                . "<tr><th class=even>ホストの別名:</th><td class=even>$o_hostalias</td></tr>\n"
                . "<tr><th class=odd>IPアドレス:</th><td>$o_hostaddress</td></tr>\n"
                . "<tr><th class=even>ホストグループ:</th><td class=even>\n";
  
  if (defined($o_addurl)) {
    $html_msg_jp = $html_msg_jp 
                 . "<a href=\"$nagios_cgiurl/status.cgi?hostgroup=$o_hostgroup&style=overview\">$o_hostgroup</a>";
  } else { $html_msg_jp = $html_msg_jp . $o_hostgroup; }
  
  $html_msg_jp = $html_msg_jp . "</td></tr>\n"
               . "<tr><th class=odd>イベントの日付と時刻:</th><td>$o_datetime</td></tr>\n"
               . "<tr><th class=even>イベントデータ出力:</th><td class=even>\n";
  
  if (defined($o_addurl)) {
    $html_msg_jp = $html_msg_jp . "<a href=\"$nagios_cgiurl/status.cgi?extinfo.cgi?type=1&host=$o_hostname\">$o_hostoutput</a>\n";
  } else { $html_msg_jp = $html_msg_jp . $o_hostoutput; }
  
  $html_msg_jp = $html_msg_jp . "</td></tr>\n";

  # if author and comment data has been passed from nagios
  # and these variables have content, then we add two more columns
  if ( ( defined($o_notificationauth) && defined($o_notificationcmt) ) &&
       ( ($o_notificationauth ne "") && ($o_notificationcmt ne "") ) ) {
    $html_msg_jp = $html_msg_jp . "<tr><th class=odd>投稿者:</th>\n"
                 . "<td>$o_notificationauth</td></tr>\n"
                 . "<tr><th class=even>コメント:</th>\n"
                 . "<td class=even>$o_notificationcmt</td></tr>";
  }

  $html_msg_jp = $html_msg_jp . "</table><p>\n";

  # if we got the graph format and a image has been generated, we add it here
  if (defined($graph_img) && $o_format eq "graph") {
    $graph_id = create_content_id();
    $html_msg_jp = $html_msg_jp . "<img class=\"graph\" src=\"cid:$graph_id\">\n";
  }

  $html_msg_jp = $html_msg_jp . "</p><hr>\n"
               . "このメーセジはオープンソースの監視システムNagiosで生成されています。\n"
               . "<hr>\n"
               . "</center></body></html>\n";
  # End HTML message definition in Japanese
}

# #######################################################################
# urlencode() URL encode a string
# #######################################################################
sub urlencode {
  $_[0] =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg;
  return $_[0];
}
# #######################################################################
# hashcolor() Choose a color for service
# #######################################################################
sub hashcolor {
  my $c=0;
  map{$c=(51*$c+ord)%(216)}split//,"$_[0]x";
  my $i = 0;
  my $n = 0;
  my $m = 0;
  my @h=(51*int $c/36,51*int $c/6%6,51*($c%6));
  for$i(0..2){$m=$i if$h[$i]<$h[$m];$n=$i if$h[$i]>$h[$n]}
  $h[$m]=102if$h[$m]>102;$h[$n]=153if$h[$n]<153;
  $c=sprintf"%06X",$h[2]+$h[1]*256+$h[0]*16**4;
  return $c;
}
# #######################################################################
# dbfilelist() Get list of matching rrd files
# #######################################################################
sub dbfilelist {
  my($host,$service, $rrddir) = @_;
  my $hs;

  # New style, files inside a <hostname> directory
  $rrddir .=  "/" . $host;
  $hs = urlencode "$service" . "___";
  verb("sub dbfilelist: Checking files inside directory: ".$rrddir);

  my @rrd;
  opendir DH, $rrddir;
    @rrd = grep s/^${hs}(.+)\.rrd$/$1/, readdir DH;
  closedir DH;
  verb("sub dbfilelist: We found number of files: ".@rrd);
  return @rrd;
}
# #######################################################################
# graphinfo() Find graphs and values
# #######################################################################
sub graphinfo {
  my($host,$service,$rrddir) = @_;
  my(@rrd,$ds,$f,$dsout,@values,$hs,%H,%R);

  $hs = $host . "/";
  $hs .= urlencode "$service" . "___";

  # Determine which files to read lines from
  @rrd = map {{ file=>$_ }}
           map { "${hs}${_}.rrd" }
           dbfilelist($host,$service, $rrddir);
  # we stop processing here if we could not find a file
  if (@rrd < 1) {
    verb("sub graphinfo: Could not find any graph file.");
    return undef;
  } else {
    verb("sub graphinfo: Listing $hs db files in $rrddir: "
           . join ', ', map { $_->{file} } @rrd);
  }

  for $f ( @rrd ) {
    unless ( $f->{line} ) {
      $ds = RRDs::info "$rrddir/$f->{file}";
      verb("sub graphinfo: RRDs::info ERR " . RRDs::error) if RRDs::error;
      map { $f->{line}{$_} = 1}
      grep {!$H{$_}++}
      map { /ds\[(.*)\]/; $1 }
      grep /ds\[(.*)\]/,
      keys %$ds;
    }
    verb("DS $f->{file} lines: " . join ', ', keys %{ $f->{line} } );
  }
  return \@rrd;
}
# #######################################################################
# rrdline() Generate the rrd parameters to produce a graph
# #######################################################################
sub rrdline {
  my($host,$service,$geom,$G,$rrddir,$tmpfile) = @_;
  my($g,$f,$v,$c,@ds);
  my $directory = $rrddir;

  @ds = ($tmpfile, '-a', 'PNG', '-t', $service);
  push @ds,  "--color=BACK$graph_bgcolor",
             "--color=SHADEA$graph_border",
             "--color=SHADEB$graph_border";

  # Identify where to pull data from and what to call it
  for $g ( @$G ) {
    $f = $g->{file};
    verb("file=$f");

    # Compute the longest label length
    my $longest = (sort map(length,keys(%{ $g->{line} })))[-1];

    for $v ( sort keys %{ $g->{line} } ) {
      $c = hashcolor($v);
      verb("sub rrdline: file=$f line=$v color=$c");
      my $sv = "$v";
      my $label = sprintf("%-${longest}s", $sv);
      push @ds , "DEF:$sv=$directory/$f:$v:AVERAGE"
               , "LINE2:${sv}#$c:$label";
      my $format = '%6.2lf%s';

      # Graph labels
      push @ds, "GPRINT:$sv:MAX:Max\\: $format"
              , "GPRINT:$sv:AVERAGE:Avg\\: $format"
              , "GPRINT:$sv:MIN:Min\\: $format"
              , "GPRINT:$sv:LAST:Cur\\: ${format}\\n";
    }
  }

  # Dimensions of graph if geom is specified
  if ( $geom ) {
    my($w,$h) = split 'x', $geom;
    push @ds, '-w', $w, '-h', $h;
  }
  return @ds;
}
# ########################################################################
# uuencode_image() takes the image file and returns a base64-image string
# ########################################################################
sub uuencode_image {
  my($tmpfile) = @_;
  open (IMG, $tmpfile) or die "Cannot read temporary image: $tmpfile - $!";
    binmode IMG; undef $/;
    my $uuencoded_img = encode_base64(<IMG>);
  close IMG;
  return $uuencoded_img;
}
# #######################################################################
# create_graph_img() tries to create a base64-encoded performance graph
# image. It takes the hostname and servicename and tries to find a
# matching RRD file according to the Nagiosgraphs layout. If there is one,
# queries the RRD information and graphs the last 24 hours similar to
# Nagiosgraph.
# #######################################################################
sub create_graph_image {
  my $img = undef;
  my $G = undef;

  # Figure out db files and line labels
  #$G = graphinfo($o_hostname,$o_servicedesc,$rrd_basedir);
  $G = graphinfo($o_hostname,"check-host-alive",$rrd_basedir);

  # if we could not find RRD data, we return $img as undef
  if(! defined($G)) {
    verb("sub create_graph_image: adding the graph was requested, but no graph data was found.");
    return $img;
  }

  # generate temporary graph files for todays RRD data
  my $fh_raw = File::Temp->new();
  my $bin_tmp_img = $fh_raw->filename;

  #my @ds = rrdline($o_hostname,$o_servicedesc,$graph_img_size,$G,$rrd_basedir,$bin_tmp_img);
  my @ds = rrdline($o_hostname,"check-host-alive",$graph_img_size,$G,$rrd_basedir,$bin_tmp_img);
  verb("sub create_graph_image: RRDs::graph ". join ' ', @ds);


  RRDs::graph(@ds);
  verb("sub create_graph_image: RRDs::graph ERR " . RRDs::error) if RRDs::error;

  # because our mail system being Notes, which does not support PNG
  # images, we must convert them to JPG before we can continue.
  # comment out the next 3 lines of PNG is OK
  my $jpg_tmp_img = $bin_tmp_img.".jpg";
  `pngtopnm $bin_tmp_img | pnmtojpeg >$jpg_tmp_img`;
  `mv $jpg_tmp_img $bin_tmp_img`;

  # Since the graph images are raw png files, we need to uuencode them
  $img = uuencode_image($bin_tmp_img);
  return $img;
}
# #######################################################################
# main
# #######################################################################
check_options();

$mail{Cc}   = $o_cc_recipients if $o_cc_recipients;
$mail{Bcc}  = $o_bcc_recipients if $o_bcc_recipients;
$mail{smtp} = $o_smtphost;

# Debugging
&create_test_data;

my $mail_subject_en = "Nagios: $o_notificationtype Host $o_hostname ($o_hostgroup) is $o_hoststate";

my $mail_subject_jp = "Nagios 通知: $o_notificationtype ホスト $o_hostname ($o_hostgroup)は $o_hoststate";
   $mail_subject_jp = "Nagios: $o_notificationtype Host $o_hostname ($o_hostgroup) is $o_hoststate";

# Check lang and if we have been asked to format it in fancy HTML.
# With the current setup, it will only be displayed correctly by
# HTML-capable Mail clients since it has no "text/plain" alternative part.
if ($o_language eq "en") {
  $mail{subject} = $mail_subject_en;
  if ($o_format eq "multi" || $o_format eq "graph") {
    verb("Sending HTML email (English) with inline logo.");
    create_message_en_html();
    create_boundary();
    $mail{'content-type'} = qq(multipart/related; boundary="$boundary");
    $boundary = '--' . $boundary;
    # Here we define the mail content to be send
    $mail_content = "This is a multi-part message in MIME format.\n"
    # create the first boundary start marker for the main message
            . "$boundary\n"
            . "Content-Type: text/html; charset=utf-8\n"
            . "Content-Transfer-Encoding: 8bit\n\n"
            . "$html_msg_en\n";

    # create the second boundary marker for the logo
    $mail_content = $mail_content . "$boundary\n"
            . "Content-Type: image/gif; name=\"logo.gif\"\n"
            . "Content-Transfer-Encoding: base64\n"
            . "Content-ID: <$logo_id>\n"
            . "Content-Disposition: inline; filename=\"logo.gif\"\n\n"
            . "$logo\n";

    # if we got graph format and a image has been generated, we add it here
    # create the third boundary marker for the graph
    if (defined($graph_img) && $o_format eq "graph") {
    $mail_content = $mail_content . "$boundary\n"
            . "Content-Type: image/gif; name=\"graph.jpg\"\n"
            . "Content-Transfer-Encoding: base64\n"
            . "Content-ID: <$graph_id>\n"
            . "Content-Disposition: inline; filename=\"graph.jpg\"\n\n"
            . "$graph_img\n";
    }

    # create the final end boundary marker
    $mail_content = $mail_content . "$boundary--\n";
    # put the completed message body into the mail
    $mail{body} = $mail_content;
  }
  elsif ($o_format eq "html") {
    create_message_en_html();
    $mail{'content-type'} = qq(text/html; charset="utf-8");
    $mail{body} = $html_msg_en;
  } else {
    create_message_en_text();
    $mail{'content-type'} = qq(text/plain; charset="utf-8");
    $mail{body} = $text_msg_en;
  } 
} elsif ($o_language eq "jp") {
  $mail{subject} = $mail_subject_jp;
  if ($o_format eq "multi" || $o_format eq "graph") {
    verb("Sending HTML email (Japanese) with inline logo.");
    create_message_jp_html();
    create_boundary();
    $mail{'content-type'} = qq(multipart/related; boundary="$boundary");
    $boundary = '--' . $boundary;
    # Here we define the mail content to be send
    $mail_content = "This is a multi-part message in MIME format.\n"
    # create the first boundary start marker for the main message
            . "$boundary\n"
            . "Content-Type: text/html; charset=utf-8\n"
            . "Content-Transfer-Encoding: 8bit\n\n"
            . "$html_msg_jp\n";

    # create the second boundary marker for the logo
    $mail_content = $mail_content . "$boundary\n"
            . "Content-Type: image/gif; name=\"logo.gif\"\n"
            . "Content-Transfer-Encoding: base64\n"
            . "Content-ID: <$logo_id>\n"
            . "Content-Disposition: inline; filename=\"logo.gif\"\n\n"
            . "$logo\n";

    # if we got the graph format and a image has been generated, we add it here
    if (defined($graph_img) && $o_format eq "graph") {
    # create the third boundary marker for the graph
    $mail_content = $mail_content . "$boundary\n"
            . "Content-Type: image/gif; name=\"graph.jpg\"\n"
            . "Content-Transfer-Encoding: base64\n"
            . "Content-ID: <$graph_id>\n"
            . "Content-Disposition: inline; filename=\"graph.jpg\"\n\n"
            . "$graph_img\n";
    }

    # create the final end boundary marker
    $mail_content = $mail_content . "$boundary--\n";
    # put the completed message body into the mail
    $mail{body} = $mail_content;
  }
  elsif ($o_format eq "html") {
    create_message_jp_html();
    $mail{'content-type'} = qq(text/html; charset="utf-8");
    $mail{body} = $html_msg_jp;
  } else {
    create_message_jp_text();
    $mail{'content-type'} = qq(text/plain; charset="utf-8");
    $mail{body} = $text_msg_jp;
  } 
}

sendmail(%mail) or die $Mail::Sendmail::error;
verb("Sendmail Log says:\n$Mail::Sendmail::log\n");
exit 0;
