]> git.etc.gen.nz Git - spong.git/commitdiff
added file into CVS repository
authorStephen L Johnson <sjohnson@monsters.org>
Tue, 20 Jun 2000 04:11:58 +0000 (04:11 +0000)
committerStephen L Johnson <sjohnson@monsters.org>
Tue, 20 Jun 2000 04:11:58 +0000 (04:11 +0000)
pod/admin-guide.pod [new file with mode: 0755]
pod/developer-guide.pod [new file with mode: 0755]
pod/spong-hosts.pod [new file with mode: 0755]
pod/spong.message.pod [new file with mode: 0755]

diff --git a/pod/admin-guide.pod b/pod/admin-guide.pod
new file mode 100755 (executable)
index 0000000..8f208ad
--- /dev/null
@@ -0,0 +1,318 @@
+=head1 NAME
+
+admin-guide - Spong Administrator's Guide
+
+=head1 DESCRIPTION
+
+This document is for Spong Administrator. It details how to install and 
+configure the Spong Server and Spong Client programs.
+
+=head1 Installation
+
+=head2 Installation - Server
+
+To build and install the spong server do the following on the machine 
+that is to be the Spong Server. It is suggest that your have web server 
+running on the same machne for the spong web display program. It is not
+required, but it will simplify the installation.
+
+=over
+
+=item o
+
+Edit the "build" script, and set the variables at the top of that script
+according to where you want spong installed, and where certain programs
+that spong relies on are located.
+
+=item o
+
+Check to make sure there is a config/spong.conf.E<lt>osE<gt> file corresponding
+to your operating system, if not - create one. This file contains paths and
+command line arguments to helper programs that are used to determine things
+like disk usage, etc... If you have to create your own spong.conf.E<lt>osE<gt>
+file, then please email it to me so that I can add it to the distribution.
+
+=item o
+
+Make sure you are in the directory that you unpacked spong in and type: 
+C<./build E<lt>osE<gt>> where E<lt>osE<gt> is the name corresponding to your
+operating system. You can type C<./build help> to generate a list of
+valid operating system strings.
+
+When the build completes, you will be left with some new directories
+in the folder that you unpacked spong in. The build process takes the spong
+source (and documentation), and replaces some "tokens" with values that
+you have supplied at the top of the build script. The build process also
+creates a spong.conf file, and generates various types of documentation
+based on the POD files that come with spong.
+
+=item o
+
+Now, type C<./build install>. Note that the install process makes
+no assumptions about what user you want to run spong as (you B<don't>
+have to run it as root). This means that you have to be a little more careful
+when you install spong (making sure it has the correct permissions, and
+that you have permission to copy the www pages into your web server's document
+tree).
+
+=item o
+
+Now edit the spong.conf, spong.hosts, spong.group and spong.messages files
+that you just installed and season to taste. You should now be able to
+read the manual pages for each.
+
+=back
+
+
+Now you will have the executables and configuration files in place
+on the server. You need to start the spong-server and spong-network programs.
+The spong-server program will listen for reports from various agents, and
+the spong-network program will start testing the hosts you have defined
+for any problems. After starting those programs, you should start seeing
+files show up in the I<$SPONGDB> directory that you defined in the spong.conf
+file.
+
+B<NOTE - HOSTNAMES:> Part of spong-server's status message authentification has
+to do with host names. B<spong-server> checks the host name in a status message
+against the hosts defined in the spong.hosts file. The the status message host
+name is not found, spong-server will silently drop the messages.
+
+So it is important that your serves are able to resolve their fully qualified
+domain name. To do this check there is a little perl test program
+B<gethost-test> from in the F</utils> directory of the Spong distribution. Just
+run it from a command line by entering C<perl gethost-test.> It tests to see is
+the host can resolve it's fully qualified domain name.  If it can't then it
+will advise you on ways to fix the problem.
+
+
+=head2 Installation - Client
+
+For each client machine you will need to install the the package just like a 
+the server installation described above. After the C<./build install> step
+is done, you can remove a number of directories that are not needed by 
+spong-client. (Assuming a standard installation directory). 
+
+=over
+
+=item www/
+
+=item cgi-bin/
+
+=back
+
+The only configuration file that you have to edit is the F<etc/spong.conf> (and
+F<etc/spong.conf.E<gt>hostE<gt>> files(s).
+
+If you have a number of like clients with the same OS your can copy
+the entire installation directory tree from an installed client to other
+clients. You can use tar+ftp, rcp, rdist or whatever mechamism you would
+normally use. Just be sure the Spong installation directory into the same
+location as the original client.
+
+
+=head2 Debugging Problems
+
+The general way to debug Spong programs is to use the B<--debug #> parameter.
+The B<#> is a number from 1 to 9 that contols the amount of debugging that is
+printed. The higher the number the more detail that is output.  This force the
+program to run in the fore-ground, (if it daemonizes itself) and the program
+will print out a lot of debugging statements. Also each program updates it's
+command line buffer with the current status which can be viewed in the ps
+command.
+
+If I<$SPONG_LOG_FILE> or I<$SPONG_LOG_SYSLOG> are set in the F<spong.conf> file
+the programs will log errors to a log file and/or syslog , respectively. The
+file  are named F<program-name.log> in the I<$SPONGTMP> directory and the
+entries are logged to syslog under the USER facility with a priorty of ERR.
+
+
+=over 
+
+=item B<spong-server>
+
+
+When spong-server is run with B<--debug #> the primary process will run in the
+fore-ground and all of the child processes with write their debugging
+statements to the screen. The I<query> processing will print out all of the
+database queries with the type of data requested and in what format. The
+I<spong update</i> and I<Big Brother update> process will print out
+host/service/color of every status message that is received.
+
+The update processes will print out their actions concerning notifications. If
+a notification is indicated, <spong-server> will call B<spong-message> with the
+B<--debug> parameter if B<--debug> was specified in the command line.
+
+=item B<spong-client>
+
+B<spong-client> will print out the check that is being performed along with
+the status and the summary message.
+
+=item B<spong-network>
+
+B<spong-network> will print out the current host that is being checking and the
+name of the check as it performs them, along with the status and the summary
+message.
+
+=item B<spong-message>
+
+spong-message can be tested outside of spong-server to test your notification
+configurations. Your run spong-message with the following parameters:
+
+    spong-message --debug color host service time "Summary message"
+
+where:
+
+=over 
+
+=item time
+
+a number which is the date/time in epoch format (i.e.
+the number of seconds since 00:00 01/01/1970). Just pick a big number.
+
+=back 
+
+B<spong-message> will print out the current rule number (starting with 0).
+The the success or failure of all of the checks of the matching
+attributes.
+
+After the rules matching phase, spong-message will then print out all of the
+people being notified and how they are being notified. B<spong-message> can
+potentially print out a large quantity of debugging. You may want to redirect
+the output to a file while you are testing it.
+
+=head2 Customizing Web Pages
+
+Spong has a feature that allows users to customize some aspects of the Spong
+web pages. If a header and/or footer template file exist, the contents of the
+field will be display as a header or footer of every web page generated. The
+header or footer files should be placed in the F</html> directory where the
+Spong www/ directory was installed (the I<$IWWW> variable from the B<build>
+program) and named "header.html" or "footer.html", respectively.
+
+Place the HTML code that you want display into the template files.
+You can also specifiy other HTML files to be included when the file is
+display. Insert the string "B<!!WWWSHOW!!>/filename" into
+the place that your desire the file named "filename" to be display. The
+file to be include should placed into the same directory are the "header.html"
+or "footer.html" file resides.
+
+B<Note:> This customization feature is limited in the current release.
+More substiution variables (i.e. hostname, service, status, etc)
+will be added into future. As will the ability to select which type of
+pages the headers or footer will be placed (i.e. service status screen,
+server display screen, history screen, problem screen, etc.)
+
+
+=head2 Expanded Host Status Web Pages (Information Files)
+
+This feature is one of Spong's best kept secrets. You can create additional
+information files that will be displayed on all status displays for a
+particular host. To use this feature, you first have to create an info
+directory in a host's database directory (i.e.
+L<$SPONGDB|spong.conf/"$SPONGDB">/hostname/info/).  Then you place the
+documentation files that will displayed into that directory.  L<spong-server>
+looks for the the following files:
+
+=over 12
+
+=item I<$SPONGDB>/E<lt>hostnameE<gt>/info/info.txt
+
+=item I<$SPONGDB>/E<lt>hostnameE<gt>/info/info.html
+
+=item I<$SPONGDB>/E<lt>hostnameE<gt>/info/info.brief.txt
+
+=item I<$SPONGDB>/E<lt>hostnameE<gt>/info/info.standard.txt
+
+=item I<$SPONGDB>/E<lt>hostnameE<gt>/info/info.full.txt
+
+=item I<$SPONGDB>/E<lt>hostnameE<gt>/info/info.brief.html
+
+=item I<$SPONGDB>/E<lt>hostnameE<gt>/info/info.standard.html
+
+=item I<$SPONGDB>/E<lt>hostnameE<gt>/info/info.full.html
+
+=back 
+
+where E<lt>hostnameE<gt> is the name of a host as defined in spong.hosts. See
+L<spong.hosts> for most information.
+
+
+B<spong-server> first looks for a info.brief, info.standard or info.full file
+depending on the type of display (brief, standard or full; and html or txt). If
+the program finds one it will display that file. Otherwise, B<spong-server>
+will look for a F<info.txt> or F<info.html> file and then display that file as
+a default.
+
+The .txt files are used with text mode displays like those generated by the
+B<spong> display command (see L<spong>). The .html files are used by the html
+mode displays. The .html files can contain html code, URLs, embeded graphics,
+Javascript, or anything that you display on a web page.
+
+
+=head2 Custom Contacts
+
+The web pages generated by Spong have "smart" "Contact Staff" links. That is,
+the web page knows which host your are looking at when on your are looking at a
+detailed status page. The spong-server generated a customize "Contact Staff"
+link on a page's action bar that has the hostname and a message which contains
+all of the current problems that system currently has.
+
+The "Contact Staff" link's URL consists of two parts. The first part is the
+I<$WWWCONTACT> from the F<spong.conf> configuration file (see
+L<spong.conf/"$WWWCONTACT">). It contains the URL to your contact
+staff CGI program that you must supply (see below).  The second part of the are
+the host name and the problem message passed as two form variables: I<host>
+and I<message> respectively.
+
+The I<$WWWCONTACT> CGI program needs to handle two form variables (I<host> and
+I<message>) and a couple of fields on a form for the user to fill out. A TEXT
+field should be used to the I<host> variable with a size of 50 characters of so
+to handle big host names. The I<message> field should be placed in a TEXT AREA
+field. The size of the TEXT AREA field should be limited if the destinations
+are pager. Most alpha-pages have a message limit of 150-250 characters.  The
+rest of the form should be populated with whatever fields that you need into
+order to interface to your paging applications
+
+=head2 Customized Action Bar
+
+The Action Bar of the Host and Service Status Displays (see the L<User
+Guide|user-guide> for more details) can be customized with the
+I<$WWW_ACTIONBAR_CUSTOM> configuration parameter (see
+L<spong.conf/"$WWW_ACTIONBAR_CUSTOM">). Any HTML code
+defined in this parameter will be included at the end of the Action Bars.
+
+This parameter is preprocessed with the Perl C<eval> function before the
+contents are printed. This allows you to include complex perl variables or perl
+code. Because of the C<eval> processing you should use single quotes to enclose
+the contents of this parameter. This will prevent premature evaluation of perl
+variables before the output.
+
+If your do not need this customization, just leave B<$WWW_ACTIONBAR_CUSTOM>
+undefined. Nothing will be added to the Action Bars.
+
+=head2 B<$WWW_REFRESH> Logic
+
+The default of the spong-server is to not allow auto-refreshes if
+B<@WWW_REFRESH_ALLOW> and B<@WWW_REFRESH_DENY> variables are empty (see
+L<spong.conf>). The B<spong-server> the matches the I<REMOTE_ADDR>,
+I<REMOTE_HOST>, and I<REMOTE_USER> fields in the CGI environment against the
+list of REFRESH_ALLOW expressions.  If there is a match the session if ok'ed for
+auto-refreshes. The server then checks the I<REMOTE_xxx> fields against the
+list of REFRESH_DENY expressions.  A match here disallows auto-refresh even if
+there was a previous match of a REFRESH_ALLOW expression.
+
+For example, if I<@WWW_REFRESH_ALLOW> contains[ 'joe', '.*-support',
+'^192.168.12.*', 'noc-display' ] and I<@WWW_REFRESH_DENY> contains
+['bill','mary']. If a web brower on a machine at ip address 192.168.12.143
+queries the spong-server web pages, the auto-refresh would be allowed because
+it matches the '^192.168.12.*' expression of I<@WWW_REFRESH_ALLOW>. But if the
+user was 'fred' at the same machine (192.168.12.143), auto-refresh would not be
+enabled because 'fred' is in the I@<WWW_RERESH_DENY> list.
+
+=head1 SEE ALSO
+
+L<spong-server>, L<www-spong>, L<spong.conf>
+
+=head1 AUTHOR
+
+Stephen L Johnson <F<sjohnson@monsters.org>>
diff --git a/pod/developer-guide.pod b/pod/developer-guide.pod
new file mode 100755 (executable)
index 0000000..35918a3
--- /dev/null
@@ -0,0 +1,471 @@
+=head1 NAME
+
+B<developer-guide> - developer's guide to Spong
+
+=head1 DESCRIPTION
+
+This is the developer guild to Spong. It documents the inner workings of the
+client and server programs. It also describes the plugin mechanism of the
+B<spong-client> and B<spong-network> so that new check modules can be
+developed for these programs.
+
+=head1 PROTOCOLS
+
+This section deals with the low level communucation protocols that the clients
+use to talk with the B<spong-server>.  The Spong and Big Brothers protocols
+almost identical. They vary only in the data format.
+
+=head2 SPONG PROTOCOL
+
+The B<spong-server> listens in on port 1998 for status updates from clients.
+After a socket has been opened, the client program sends a message with the
+following format:
+
+    command host service color time[:ttl] summary (\n)
+    detailed status message line 1 (\n)
+    detailed status message line 2 (\n)
+    ...
+    detailed status message line n (\n)
+
+Where:
+
+=over
+
+=item command
+
+The command being sent to the spong server indicating
+a type of update message or a change in operating status of the client.
+
+=item host
+
+The fully qualified domain name of the host the message
+is for.
+
+=item service
+
+The name of the service that the update message is
+for.
+
+=item color
+
+The status color of the service (green - ok, yellow
+- warning, red - alert).
+
+=item time
+
+The date/time of the update message in epoch time format
+(i.e. the number of seconds since 01/01/70, 00:00 AM)
+
+=item ttl
+
+This optional field is the time to live, in seconds, for the status message. 
+Normally a will become stale (i.e. purple status) after 2 times $SPONGSLEEP
+seconds which is the default. See L<spong.conf/"$SPONGSLEEP". This field will
+override the defaiult and keep the status message valid for a longer period of
+time.
+
+=item summary
+
+The status summary message field. A short and to the point message that
+summarises the status being returned.
+
+=item detailed status message
+
+The remained lines of the message which will be the detailed information of the
+status. Typically it can be the output of the df command or the top processes
+by CPU utilization or the detailed reponses of network checks.
+
+=back
+
+=head2 BIG BROTHER PROTOCOL
+
+The B<spong-server> listens in on port 1984 for status Big Brother
+client updates. After a socket has been opens the client sends a message
+with the following format:
+
+    command host service color time summary (\n)
+    detailed status message line 1 (\n)
+    detailed status message line 2 (\n)
+    ...
+    detailed status message line n (\n)
+
+Where:
+
+=over 
+
+=item command
+
+The command being sent to the spong server indicating
+a type of update message or a change in operating status of the client.
+At present the only command defined is C<status> which indicates a
+service status update message.
+
+=item host
+
+The fully qualified domain name of the host the message
+is for.
+
+=item service
+
+The name of the service that the update message is
+for.
+
+=item color
+
+The status color of the service (green - ok, yellow
+- warning, red - alert).
+
+=item time
+
+The date/time of the update message in standard date
+format (i.e. Thu Jan 1 00:00:00 UTC 1970)
+
+=item summary
+
+The status summary message field.
+
+=item detailed status message
+
+The remained lines of the message
+which will be the detailed information of the status. Typically it can
+be the output of the df command or the top processes by CPU utilization
+or the detailed reponses of network checks.
+
+=back
+
+=head1 MODULES
+
+B<spong-client>, B<spong-network>, B<spong-message> and B<spong-server> use
+various routines which are coded as modules. When the programs are
+initializating, they determine which modules are going to be required. The
+programs then go out and load each of the modules from the library directory.
+When the modules are loaded they register themselves with the plugins
+registery.  The plugin registry is the mechanism that the client programs use
+to keep track of the modules into order to run them.
+
+=head2 SERVER MODULES
+
+B<spong-server> has a hook that allows external programs access to the incoming
+status updates coming from Spong client programs. The hook takes the form of
+Server Data modules which are called after spong-server stores the status 
+update in it's database.
+
+B<spong-server> passes all of the information of the update message in addition
+to the current event status duration to the Data Module. The modules should
+do any processing that they need to do in as short a time as possible. This is
+to minimize the resource overhead with lots of simultaneous status updates
+arrive at same time.
+
+Debugging messages and error messages can be printed by using the 
+&main::debug() and &main::error() functions respectively. If the module
+develops a fatal error, it should terminate using the die() or croak() 
+functions depending on ones preference. Modules should just return upon a 
+successful invocation.  
+
+See L<spong-server-mod-template> for an example of how to code a
+B<spong-server> Server Data Module.
+
+=head2 CLIENT MODULES
+
+Client modules define checks which are to be done on the host that the
+B<spong-client> program is running on. The module's check function is called
+without any parameters. Client modules are expected to issue any systems
+command and parse the output in order to determine the service status.
+
+Any threshold variables needed for warning and alert level trigger need to be
+defined and placed into the F<SPONG/etc/spong.conf> file. The threshold
+variable need to be uniquely named and should be named according to the type of
+check being done (i.e. $DISKWARN or $DFWARN for disk checks and $CPUWARN for
+CPU checks, etc.).
+
+Once the service status and messages have been determined the module
+can call the C<E<amp>main::status()> function in order to send the
+information back to the spong-server. See L<"Status Function"> for more 
+information.
+
+=head2 NETWORK MODULES
+
+Network modules defined checks that to be done on hosts over the network
+to ensure that a network service is running. The modules are called with
+the name of the host the check is to be done to. The modules is also expected
+to put an alarm wrapper around the code that performs the check. This is
+to prevent excessive delays dues to lost communications. It is suggested
+that 10 seconds be used for the alarm setting.
+
+The module should not call the E<amp>main::status() function directly.
+B<spong-network> has a mechanism for rechecking services that are reported down
+on an initial check. If the recheck mechanism is engauged, "red" statuses will
+be downgraded to "yellow" until a failure count threshold is reached. The the
+services will be reported as "red".
+
+After the status condition has been determined the check function should return
+three parameterers:
+
+=over
+
+=item STATUS
+
+The status color either "red", "yellow", or "green".
+
+=item SUMMARY
+
+A short line line summary of the status
+
+=item MESSAGE
+
+more detailed information (can be multi-lined)
+
+=back
+
+These parameters are the same that will be passed to the C<E<amp>main::status()>
+command. See L<"Status Function"> for more information on these parameters.
+
+The network modules have two support functions avaiable,
+C<E<amp>main::check_tcp()> and C<E<amp>main::check_simple()>, which can
+simplify simple TCP port checks.
+
+C<E<amp>main::check_tcp( host, port, data );>
+
+Where the arguments are:
+
+=over
+
+=item HOST
+
+The name or ip address of the host to be checked.
+
+=item PORT
+
+The name, or port number, of service to connect with.
+
+=item DATA
+
+The data to be send to the host after the port is opened.
+
+=back
+
+The function C<E<amp>main::check_tcp()> will make a connection to
+the given PORT on the HOST and send a message (DATA). It then returns what
+it gets back to the caller.
+
+C<E<amp>main::check_simple( host, port, send, check, service)>
+
+Where the arguments are
+
+=over 
+
+=item HOST
+
+The name or ip address of the host to be checked.
+
+=item PORT
+
+The name of the port to connect with.
+
+=item SEND
+
+The messge to sent to the host after the port is opened.
+
+=item CHECK
+
+A perl regular express to be used to validate the response return
+by the host.
+
+=item SERVICE
+
+The name of the sevive being check. It is used in the summary
+and detailed status messages.
+
+The function C<E<amp>main::check_simple()> is a generic TCP port checking
+routine. This will go out connect to a given port (using C<E<amp>main::check_tcp()>) and
+check to make sure you get back expected results. The function returned
+three parameters: STATUS, SUMMARY and MESSAGE as detailed above. The return
+values of this function can returned as the necessary returned values  of 
+the check module.
+
+=back
+
+=head2 MESSAGE MODULES
+
+Message modules are function called to send a notification message to
+a contact on a specific service or service. The messaging functions are called
+with an the contacts identifier for the messaging service (i.e. the page PIN
+code of a paging provider). The messaging module is expected to take care of
+all of the data formating and communications logic to send a notification
+message to the contact.
+
+The messaging functions has access to these global variable in order format
+a notification message:
+
+=over
+
+=item I<$color>
+
+The status color of the message
+
+=item I<$host>
+
+The fully qualified domain name of the host
+
+=item I<$time>
+
+The date and time of the message being sent. (format is
+epoch time or time())
+
+=item I<$message>
+
+A one line summary status line</li>
+
+=item I<$duration>
+
+The current duration of the current status in seconds.
+(a zero duration indicates a change in status)
+
+=back
+
+There are two support functions that be used to format a message and send the
+message via e-mail: C<E<amp>main::email_status()> and
+C<E<amp>main::email_mini_status()>.  Both functions format e-mail message to be
+send to RECIPIENTS, but C<email_mini_status()> sends out a shorter mail message
+which is more suitable for SMS and smaller alpha pagers.
+
+Both functions are called thusly:
+
+C<E<amp>main::email_status( recipient, flags )>
+
+C<E<amp>main::email_mini_status( recipient, flags )>
+
+Where the arguments to the functions are:
+
+=over
+
+=item RECIPIENT
+
+one or more e-mail recipients which placed in the to: line
+of the mail message.
+
+=item FLAGS
+
+flags to alter the formating of the message.
+
+=back
+
+The only flag current defined is 'shortsubject'. This prevents $color,
+$hostname, and $summary from being placed on the "subject:" line.
+
+=head1 CREATING MODULES
+
+Creating the actual modules is very trivia to do. Create your module by
+following the appropriate template from below.
+
+=over
+
+=item o
+
+L<spong-client module template|spong-client-mod-template>
+
+=item o
+
+L<spong-network module template|spong-network-mod-template>
+
+=item o
+
+L<spong-message module template|spong-message-mod-template>
+
+=item o
+
+L<spong-server data module template|spong-server-mod-template>
+
+=back
+
+Then place your template module file into the appropirate directory below.
+
+=over
+
+=item
+
+B<spong-client> - F<LIBDIR/Spong/Client/plugins>
+
+=item 
+
+B<spong-nework> - F<LIBDIR/Spong/Network/plugins>
+
+=item
+
+B<spong-message> - F<LIBDIR/Spong/Message/plugins>
+
+=item
+
+B<spong-server> - F<LIBDIR/Spong/plugins>
+
+=back
+
+Then test your modules by running the program with the --debug parameter to see
+if it is operating properly.
+
+=head1 Status Function
+
+E<amp>main::status( SERVERADDR, HOST, SERVICE, COLOR, SUMMARY, MESSAGE )
+
+The arguments to the C<E<amp>main::status()> function are:
+
+=over 8
+
+=item SERVERADDR 
+
+Should be I<$SPONGSERVER>.
+
+=item HOST
+
+The full hostname of the machine being reported.
+
+=item SERVICE
+
+The a short name that describes the service
+that you are reporting on.
+
+=item COLOR
+
+The color of the status being reported, either "green", "yellow", or "red".
+"green" denotes an OK status, there are no problems and everything is within
+normal parameters. "yellow" denotes a warning status, a abnormal situation that
+has which may be need to be looked at or a parameter has changed (up or down)
+towards a critical level. "red" denotes an alert status, a critical situation
+that has arised and needs immediate attenation or a parameter has changed (up
+or down) to a critical level.
+
+=item SUMMARY
+
+A short one line summary of the status. This should be a short and concise
+summary of the current situation of the service. The simplest form is to 
+say "Service is OK" or "Service is down". Another form is to display current
+information (like system uptime, number of job and users) and additional
+text for warning and alerts (i.e. "uptime - 123, jobs - 123, users - 123, cpu
+load level is at 3.2"). 
+
+If you are reporting on multiple sets of like items (like file partitions or
+processes), report the names of those items that are abnormal, (i.e.
+"filesystems: / at 99%, /tmp at 100%"). 
+
+=item MESSAGE
+
+This is the place to put detailed information about the status of the service.
+Typically this will be the output of the system commands or function calls. For example, it could be the 10 jobs by cpu usage in a ps command, or the output
+of a df command for disk checking. 
+
+There are no limitations on the contexts of the field. You can include URL's
+that link to another monitor package or take you to an administration web page
+for the service in question.
+
+=back
+
+=head1 SEE ALSO
+
+L<spong-server>, L<spong-client>, L<spong-network>, L<spong-messsage>,
+L<spong-server-mod-template>, L<spong-client-mod-template>,
+L<spong-network-mod-template>, L<spong-message-mod-template>, L<spong.conf>
+
+=head1 AUTHOR
+
+Stephen L Johnson, <F<sjohnson@monsters.org>>
+
diff --git a/pod/spong-hosts.pod b/pod/spong-hosts.pod
new file mode 100755 (executable)
index 0000000..906da06
--- /dev/null
@@ -0,0 +1,214 @@
+=head1 NAME
+
+B<spong.hosts> - define hosts and services to monitor
+
+
+=head1 DESCRIPTION
+
+The F<spong.hosts> file defines two things. 1) The hosts you want to monitor
+(and the attributes associated with each host), and 2) The humans that will 
+be contacted when a given host has problems (and the attributes associated
+with each human).
+
+=head2 %HOSTS
+
+Each host should have the following attributes associated with it:
+
+=over 
+
+=item * services
+
+=back
+
+the network services running on that host
+
+Optionally, the follow attributes can also be assigned to a host:
+
+=over 
+
+=item * down
+
+time period(s) the host is scheduled down, problems are not reported during
+this time.
+
+=item * ip_addr
+
+a list of one or more ip addresses corresponding to multiple interfaces the
+machine might have.
+
+=back
+
+The services is a string listing the network modules to run against the host
+seperated by spaces.  The list of network modules included with Spong is contactly growing, but they include ``dns'' (if you have the
+Net::DNS Perl module installed), ``ftp'', ``smtp'', ``http'', ``imap'',
+``pop3'', ``nntp'', ``nfs'',``ntp'' and ``ssh''.  The list can include any
+addition network checks that you have developed (see L<spong-network</b> and
+L<developer-guide> for more details) . Any host listed is automatically checked
+for network connectivity (via ping). The metaservice ``noping'' can be included
+in the list of modules to cause B<spong-network> to skip the 'ping' test.
+
+The I<down> attribute is a list of ``downtimes''. It is a list (well reference
+to one anyway) of one or more strings in the following format -
+``d:hh:mm-hh:mm''.  ``d'' is the day of the week (0-6, 0 = Sunday, 6 =
+Saturday), if ``d'' is ``*'', then every day of the week is matched. The string
+to the right of the day is the start and end time of the down time in 24 hour
+format
+
+The I<ip_addr> attribute is a list (well reference to one anyway) of IP
+address that the machine responds to.
+
+Additional attributes can be added into I<%HOSTS> entries. These attributes
+can be used for any external program of additional modudules that you have
+added to your Spong installation. All of the Spong programs will ignore any
+attributes that they don't recognize.
+
+=head2 %HUMANS
+
+Each human that is defined should have the following attributes associated
+with it:
+
+=over
+
+=item * name
+
+name of the person to contact
+
+=back
+
+And zero or more of the following attributes assigned to each human for
+messaging when there are problems:
+
+=over 
+
+=item * email
+
+email address
+
+=item * skytel
+
+skytel pager number
+
+=item * alltelsms
+
+phone number of a phone subscribered to Alltel Communications SMS service.
+
+=item * teletouch
+
+teletouch pager number
+
+=item * teletouch_short
+
+teletouch pages numer for small alpha pagers
+
+=back
+
+These attributes are messaging modules names for sending out notifictions to
+people. All of the messing modules are loaded by B<spong-message> as a plugin
+modules. The attributes listed above are the messaging modules that are part of
+the current Spong distribution.  New messaging modules can be easily be
+developed. See L<spong-message> and the L<developer-guide> for more details).
+
+=HEAD1 FORMAT
+
+The F<spong.conf> file is simply Perl code that gets imported by each spong
+program, so the only real format restrictions is just what is syntactically
+correct in Perl (which some would say is anything 8-).
+
+What is expected in this file are the definitions for two hashes of hashes (in
+Perl speak). The I<%HOSTS> hash, and the I<%HUMANS> hash. If you are
+not comfortable with Perl lingo, then just think of them as stanza definitions.
+
+First, the HUMANS. The following describes the <%HUMANS> hash.
+
+<pre>&nbsp;&nbsp;&nbsp; %HUMANS = ( [stanza], [stanza], [stanza] );</pre>
+where [stanza] is a second hash, that looks like the following:
+<pre>&nbsp;&nbsp; 'unix-staff' =>&nbsp;&nbsp;&nbsp; { name&nbsp; => 'Midrange On-call Staff',
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; email => 'its-unix@uiowa.edu',
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; skytel => '1234567' },</pre>
+What this says is that the 'unix-staff' human has the following attributes
+(name = Midrange On-call Staff, email = <a href="MAILTO:its-unix@uiowa.edu">its-unix@uiowa.edu</a>,
+skytel = 1234567).
+<p>Now, the HOSTS. The following describes the <b>%HOSTS</b> hash.
+<pre>&nbsp;&nbsp;&nbsp; %HOSTS = ( [stanza], [stanza], [stanza] );</pre>
+where [stanza] is a second hash, that looks like the following:
+<pre>&nbsp;&nbsp;&nbsp; 'www.uiowa.edu' =>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { services => 'ftp smtp http',
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ip_addr&nbsp; => ['192.168.15.2','10.2.124.200'],</pre>
+
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; down&nbsp;&nbsp;&nbsp;&nbsp; => [ '*:0015-0030','6:23:00-23:59'] }</pre>
+What this says is that the 'www.uiowa.edu' host has the following attributes
+(services = ftp smtp http; ip address=192.168.15.2 and 10.2.124.200;&nbsp;
+and down time of 12:15AM-12:30AM every day and from 11:00PM-12:00PM on
+Saturdays).
+<p>I know the format can be a little odd at first, but I chose it because
+of both its simplicity to work with in the code (I don't have to parse
+anything - Perl does all the work), and because it is easy to extend -
+adding additional attributes is quite straightforward.
+<p>
+<hr>
+<h1>
+<a NAME="spong.hosts_examples_0"></a>EXAMPLES</h1>
+Here are some lines from our spong.hosts file to show you possible configurations.
+<pre>&nbsp;%HUMANS = (
+
+&nbsp; 'unix-staff' =>&nbsp;&nbsp;&nbsp; { name&nbsp; => 'Midrange On-call Staff',
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; email => 'its-unix@school.edu',
+
+&nbsp;
+
+&nbsp; 'edhill' =>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { name&nbsp; => 'Ed Hill',
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; email => 'ed-hill@school.edu',
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; skytel => '1234567' },
+
+&nbsp;);
+
+&nbsp;%HOSTS = (
+
+&nbsp; 'strobe.weeg.school.edu' =>&nbsp;&nbsp; { services => 'dns ftp smtp http',
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ip_addr&nbsp; => [ '128.255.1.3',&nbsp;
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '128.255.64.3' ],
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; down&nbsp;&nbsp;&nbsp;&nbsp; => [ "*:05:30-06:30",
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "0:00:00-04:00 ] },
+
+&nbsp; 'www.school.edu' =>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { services => 'ftp smtp http' },
+
+&nbsp;);
+
+
+
+
+</pre>
+
+<h1>
+
+<hr WIDTH="100%">COMPATABILITY</h1>
+In a future release of spong the %HUMAN configuration information will
+be moved into the spong.message configuration file. It is currenly being
+retained in the spong.hosts file for compatability.
+<br>
+<hr>
+<h1>
+<a NAME="spong.hosts_see_0"></a>SEE ALSO</h1>
+the <i>spong-server</i> manpage , the <i>spong-network</i> manpage , the
+<i>spong-message</i> manpage
+<p>
+<hr>
+<h1>
+<a NAME="spong.hosts_author_0"></a>AUTHOR</h1>
+Ed Hill (<a href="MAILTO:ed-hill@uiowa.edu">ed-hill@uiowa.edu</a>), Unix
+System Administrator, The University of Iowa
+<br>Stephen L Johnson (<a href="MAILTO:stephen.johnson@mail.state.ar.us">stephen.johnson@mail.state.ar.us</a>)
+or (<a href="MAILTO:sjohnson@monsters.org">sjohnson@monsters.org</a>),
+Unix System Administator, DIS - State of Arkansas
+<p>Based on code/ideas from Sean MacGuire (BB), and Helen Harrison (Pong).
+</body>
+</html>
diff --git a/pod/spong.message.pod b/pod/spong.message.pod
new file mode 100755 (executable)
index 0000000..30f0a2b
--- /dev/null
@@ -0,0 +1,293 @@
+=head1 NAME
+
+B<spong.message> - define rules on how and when to send notifications
+
+=head1 DESCRIPTION
+
+The F<spong.message> file defines the rules that B<spong-message> program used
+for notifications. The rules consist of attributes which define crieria
+which events are matched against and a list of contacts to notify if all
+of the matching criteria are met.
+
+Each rule should have more of more of the following matching 
+terms:
+
+=over
+
+=item * hosts
+
+A list of one or more regular expressions that are matched against the host
+name of the status event. If the one of the expression matches the host name,
+the term is considered matched.
+
+=item * host_groups
+
+A list of one or more host group names from F<spong.groups> (see
+L<spong.groups>). The host name of the event check against all of the members
+of the specified groups. If it is found, this attribute is considered matched.
+
+=item * services
+
+A list of one or more regular expressions that are matched against the service
+name of the status event. If one of the expression matches the service name,
+the term is considered matched.
+
+=item * times
+
+A list of one or more day-of-week ranges and/or time ranges combinations which
+are checked against the time stamp of the status event. If one of the day/time
+combinations matched, the term is considered matched.
+
+=item * exclude_hosts
+
+A list of one or more regular expressions that are matched against the host
+name of the status event. If at least one of the expressions matches the host
+name, the term is considered an exclusion match.
+
+=item * exclude_services
+
+A list of one or more regular expressions that are matched against the host
+name of the status event. If at leat one of the expressions matched the service
+name, the term is considered an exclusion match..
+
+=item * exclude_host_groups
+
+A list of one or more host group names from the F<spong.groups>  (see L<spong.groups>). If the host name of the status event is a member of one of the host
+groups, the term is considered an exclusion match.
+
+=back
+
+And each rule must have the following attributes:
+
+=over 
+
+=item * contacts
+
+A list of contact stanzas that are to be notified if the rules is matched.
+
+=back
+
+Each of the elements of the I<hosts>, I<services>, I<exclude_hosts>, and
+I<exclude_services> are actually Perl regular expressions. You can use wide
+cards to specify which groups of hosts or services to match.
+
+The I<times> term is a list of stanzas that have days of the week
+(I<days>) and/or time ranges (I<times>) to match against the time parameter
+passed to spong-message. Each times stanza can have a days and/or a times
+attributes.  
+
+The I<days> attributes are a list of strings with the following format -
+'d' or 'd-d'. Where d is the day of the where (0-6, 0=Sunday, 6=Staurday).
+And 'd-d' represents a range of days (i.e. 1-5 = Monday - Friday).
+
+The I<times> attributes are a list of string with the following format -
+'hh:mm-hh:mm'. This is a starting and ending time of a time range in 24
+hour format.
+
+B<Note:> The I<down> attribute in a host's entry in the F<spong.hosts> file has the effect of an "I<exclude_times>" term for the host. If the timestamp of
+a status event matched on a I<down> downtime period, no notifications will
+be sent. See L<spong.hosts/"down"> for more details.
+
+The I<contacts> term is a list of stanzas representing the contacts to notify
+if the rule's matching criteria are met. Each stanza can be
+a string or a contact stanza. The strings can be one of the following
+formats - 'human', 'human:func' where human is a strings represent an
+entry from the %HUMANS defined in F<spong.hosts>
+and func is one of the message module attributes defined for that human.
+
+A contact entry can also be a stanza The stanza  must have a rcpt attribute
+which is a I<contact> strings as defined above (i.e. 'human' or 'human:func').
+It can also have an optional I<delay> and/or I<repeat> attribute.  The I<delay>
+attribute is the duration, in seconds, that an event be in an alert status
+before the I<rcpt> is notified. The I<repeat> attribute is the time interval,
+in seconds, in which notifications are resent once an initial notification is
+sent.
+
+=head1 FORMAT
+
+The spong.message file is simply Perl code that gets imported the
+B<spong-message> program, so the only real format restrictions is just what is
+syntactically correct in Perl (which some would say is anything 8-).
+
+
+What is expected in this file are the definition for the I<$MESSAGING_RULES>
+and I<$RULES_MATCH> which determines how the rules are processed.  If you are
+not comfortable with Perl lingo, then just think of them as stanza definitions.
+
+    $MESSAGING_RULES = [ [stanza], [stanza], [stanza] ]
+
+where [stanza] is a second hash, that looks like the following:
+
+  { hosts => [ 'unixweb', '.*-ops.cic.myschool.edu', 'steves-pc' ]
+    services => [ '.*' ],
+    exclude_hosts => [ 'backup-ops.cic.myschool.edu'],
+    exclude_services => [ 'dns', 'ssh'],
+    times => [
+               { days=> ['0','1-3','4-5'],
+                 times=> ['06:30-18:30','21:00-22:00'
+               },
+               { days => ['5','6','0-2'] },
+               { times => ['13:00-15:23','00:00-23:39'] },
+             ],
+    contacts => [ 'ops', 'sjohnson:email',
+                  { rcpt=>'sjohnson:teletouch', delay=>900, repeat=>600 },
+                  { rcpt=>'the_supervisor:teletouch', delay=3600,
+                    repeat=>1800 },
+                  # This contact should get be notified or else !!!!!
+                  { rcpt=>'the_boss', delay=>7200, repeat=>3600 },
+                ],
+  },
+
+The <b>$RULES_MATCH</b> variable has three possible values:
+=over 
+
+=item B<OLD>
+
+Use Spong ver 2.1 messaging. Send notification the human defined in the
+contact attibute for the host name of the message.
+
+=item B<FIRST-MATCH>
+
+Rules are checked in order until the first rules matches. Contacts are notified and B<spong-message> exits.
+
+=item B<ALL>
+
+Rules are checked into order. All matching rules are processed.
+
+=over
+
+I know the format can be a little odd at first and overwhelmng at first, but I
+chose it because of both its simplicity to work with in the code (I don't have
+to parse anything - Perl does all the work), and because it is easy to extend -
+adding additional attributes is quite straightforward.
+
+
+=head1 MATCHING LOGIC
+
+The primary factor of how spong.message rules are processed depends upon the
+vaule of I<$RULES_MATCH>. If set to 'OLD' then the rules are not used at all.
+B<spong-message> reverts back to it Spong version 2.1 behaviour. Notify the
+human defined in the contact attribute of the <b>%HOSTS</b> entry for the host.
+
+This functionality included for backwards compatibility and to aid in migrating old Spong vers 2.0 and Spong 2.1 installations to the current version. It will
+be removed some future version of Spong.
+
+If I<%RULES_MATCH> is set to 'FIRST-MATCH' then the rules are check in order
+until the first rule matching the event parameters. B<spong-message> will then
+begin notification processing. All of the contacts will be notified and then
+the program will exit.
+
+If I<$RULES_MATCH> is set to 'ALL' then all
+of the rules are scan in order. The contacts of all matching rules are adding
+to the list of recipients that will be notified. After rule matching is
+finished all of the contacts are be notified.
+
+All of the matching attributes except for I<exclude_hosts>,
+I<exclude_services> and I<exclude_host_groups> have an automatic "match if
+absent" property. For example, if the I<hosts> attribute is missing from a
+rule, that rule will match any host name.
+
+The I<exclude_hosts>, I<exclude_services>, and I<exclude_host_groups> terms
+have a slightly different matching behaviour man the others. If there is a
+match against any of them, the rule will not match even if all of the other
+terms match. For example, if a rules has B<hosts => [ '.*.cic.my-company',
+'.*.corp.my-company.com' ]> and B<exclude_hosts[ 'my-pc' ]>, a host name of
+'my-pc.corp.my-company.com' will not match against this rule because of the
+host name matches the I<exclude_hosts> attribute.
+
+The I<times> term's attributes, I<days> and I<times> , have the automatic
+"match if absent" property also. If one of the sub-attributes is missing from a
+stanza any check against that attribute will succeed.  That is, if I<days> is
+missing from the stanza, any day of the week will match against the stanza. If
+the I<times> attribute is missing, the stanza matches against any
+time. 
+
+
+=head1 EXAMPLES
+
+Here are some lines from our spong.hosts file to show you possible
+configurations.
+
+  $MESSAGING_RULES = [
+
+      # Franks Notifications
+      # Let him know about if it has been down for 30 minute or more.
+      {
+         hosts => [ '.*' ],
+         services => [ '.*' ],
+         contacts => [ {rcpt=>'fsipes', delay=>1800}, ],
+         exclude_hosts => ['tunixt'],
+         exclude_services => ['test'],
+      },
+
+      # Please note the previous stanza can also be written as follows
+      # Both stanzas are equivalent.
+      {
+         contacts => [ {rcpt=>'fsipes', delay=>1800}, ],
+         exclude_hosts => ['tunixt'],
+         exclude_services => ['test'],
+      },
+
+      # Let Dwayne in Engineering know when a system does down and dns problems
+      # except for the test box
+      {
+          hosts => ['.*'],
+          services => ['ping','ftp','smtp','dns'],
+          exclude_host => ['tunixt'],
+          contacts => [ 'dstucker' ],
+      },
+
+      # Let me know about everything except the test box except late at
+      # night
+      {
+         hosts => ['.*'],
+         services => ['.*'],
+         exclude_services => ['nntp','ntp'],
+         exclude_hosts => ['tunixt'],
+          contacts => ['sjohnson'],
+          times => [
+                    { times => ['06:00-21:00'] },
+                   ],
+      },
+
+      # Notify the unix oncall pager about the k12 systems after hours
+      # during week days and anytime on the weekend and repeat them
+      # every 15 minutes until acknowledged
+      {
+          host_groups => [ 'apscn' ],
+          exclude_services => ['nntp','ntp'],
+          exclude_hosts => ['tunixt'],
+          contacts => [ { rcpt=>'unix-oncall:teletouch', repeat=>900}, ],
+          times => [
+                { days => ['1-5'], times => ['17:00-23:59','00:00-08:00'] },
+                { days => ['0','6'] },
+                   ],
+          },
+
+    ];
+
+=head1 COMPATABILITY</h1>
+
+To use Spong version 2.1 iB<spong-message> and messaging configurations set
+I<$RULES_MATCH> to 'OLD'. If <b>$RULES_MATCH</b> is not defined it will default
+to 'OLD'.
+
+=head1 SEE ALSO
+
+L<spong-messsage>, L<spong.hosts>, L<spong.groups>
+
+=head1 AUTHOR
+
+Ed Hill <F<ed-hill@uiowa.edu>>, Unix System Administrator, The University of
+Iowa
+
+Stephen L Johnson <F<sjohnson@monsters.org>>
+
+=head1 HISTORY
+
+Based on code/ideas from Sean MacGuire (BB), and Helen Harrison (Pong). Ed Hill
+original converted Big Brother (http://www.bb4.com) into Perl which diverged
+from Big Brother to become Spong. Ed Hill continued Spong development until
+version 2.1. Stephen L Johnson took over development in October, 1999 with his
+changes which became Spong 2.5.
+