NAME

Apache::Logmonster::Utility - Common Perl scripting functions

DESCRIPTION

Just a big hodge podge of useful subs that I use in scripts all over the place. Peruse through the list of methods and surely you too can find something of use.

METHODS

new

To use any of the utility methods, you must create a utility object:

use Apache::Logmonster::Utility;
my $utility = Apache::Logmonster::Utility;

check_pidfile

check_pidfile is a process management method. It will check to make sure an existing pidfile does not exist and if not, it will create the pidfile.

my $pidfile = $utility->check_pidfile("/var/run/changeme.pid");
unless ($pidfile) {
	warn "WARNING: couldn't create a process id file!: $!\n";
	exit 0;
};

do_a_bunch_of_cool_stuff;
unlink $pidfile;

The above example is all you need to do to add process checking (avoiding multiple daemons running at the same time) to a program or script. This is used in toaster-watcher.pl and rrdutil. toaster-watcher normally completes a run in a few seconds and is run every 5 minutes.

However, toaster-watcher can be configured to do things like expire old messages from maildirs and feed spam through a processor like sa-learn. This can take a long time on a large mail system so we don't want multiple instances of toaster-watcher running.

returns the path to the pidfile (on success).

install_from_sources_php

$utility->install_from_sources_php();

Downloads a PHP program and installs it. Not completed.

file_check_writable

use Mail::Toaster::Utility;
$utility->file_check_writable("/tmp/boogers", $debug) ? print "yes" : print "no";

If the file exists, it checks to see if it's writable. If the file does not exist, then it checks to see if the enclosing directory is writable.

It will output verbose messages if you set the debug flag.

returns a 1 if writable, zero otherwise.

file_check_readable

$utility->file_check_readable($file);

input is a string consisting of a path name to a file. An optional second argument changes the default exit behaviour to warn and continue (rather than dying).

return is 1 for yes, 0 for no.

install_from_source

$vals = { package => 'simscan-1.07',
		site    => 'http://www.inter7.com',
		url     => '/simscan/',
		targets => ['./configure', 'make', 'make install'],
		patches => '',
		debug   => 1,
};

$utility->install_from_source($conf, $vals);

Downloads and installs a program from sources.

returns 1 on success, 0 on failure.

check_homedir_ownership

Checks the ownership on all home directories to see if they are owned by their respective users in /etc/password. Offers to repair the permissions on incorrectly owned directories. This is useful when someone that knows better does something like "chown -R user /home /user" and fouls things up.

$utility->check_homedir_ownership;

archive_expand

$utility->archive_expand("package.tar.bz2", $debug);

Takes an archive and decompresses and expands it's contents. Works with bz2, gz, and tgz files.

drives_get_mounted

$utility->drives_get_mounted($debug);

Uses mount to fetch a list of mounted drive/partitions.

returned is a hashref of mounted slices and their mount points.

is_process_running

Verify if a process is running or not.

$utility->is_process_running($process) ? print "yes" : print "no";

$process is the name as it would appear in the process table.

mailtoaster

$utility->mailtoaster();

Downloads and installs Mail::Toaster.

files_diff

$utility->files_diff($file1, $file2, $type, $debug);

if ( $utility->files_diff("foo", "bar") ) 
{ 
	print "different!\n"; 
};

Determine if the files are different. $type is assumed to be text unless you set it otherwise. For anthing but text files, we do a MD5 checksum on the files to determine if they're different or not.

return 0 if files are the same, 1 if they are different, and -1 on error.

yes_or_no

my $r = $utility->yes_or_no("Would you like fries with that?");

$r ? print "fries are in the bag\n" : print "no fries!\n";

There are two optional arguments that can be passed. The first is a string which is the question to ask. The second is an integer representing how long (in seconds) to wait before timing out.

returns 1 on yes, 0 on negative or null response.

file_write

$utility->file_write ($file, @lines)

my $file = "/tmp/foo";
my @lines = "1", "2", "3";

print "success" if ($utility->file_write($file, @lines));

$file is the file you want to write to @lines is a an array, each array element is a line in the file

1 is returned on success, 0 or undef on failure

file_read

my @lines = $utility->file_read($file)

Reads in a file, and returns an array with the files contents, one line per array element. All lines in array are chomped.

find_the_bin

$utility->find_the_bin($bin, $dir);

my $apachectl = $utility->find_the_bin("apachectl", "/usr/local/sbin")

Check all the "normal" locations for a binary that should be on the system and returns the full path to the binary. Return zero if we can't find it.

If the optional $dir is sent, then check that directory first.

syscmd

Just a little wrapper around system calls, that returns any failure codes and prints out the error(s) if present.

my $r = $utility->syscmd($cmd)

print "syscmd: error result: $r\n" if ($r);

return is the exit status of the program you called.

file_archive

$utility->file_archive ($file)

Make a backup copy of a file by copying the file to $file.timestamp.

get_dir_files

$utility->get_dir_files($dir, $debug)

$dir is a directory. The return will be an array of files names contained in that directory.

clean_tmp_dir

$utility->clean_tmp_dir($dir)

$dir is a directory. Running this will empty it. Be careful!

file_delete

Deletes a file. Uses unlink if we have appropriate permissions, otherwise uses a system rm call, using sudo if it's not being run as root. This sub will try very hard to delete the file!

$utility->file_delete($file, $warn);

Arguments are a file path and $warn is an optional boolean.

returns 1 for success, 0 for failure.

get_the_date

$utility->get_the_date ($bump, $debug)

$bump is the optional offset (in seconds) to subtract from the date.

returned is an array:

$dd = day
$mm = month
$yy = year
$lm = last month
$hh = hours
$mn = minutes
$ss = seconds

my ($dd, $mm, $yy, $lm, $hh, $mn, $ss) = $utility->get_the_date();

get_file

use Mail::Toaster::Utility;
my $utility = new Mail::Toaster::Utility;

$utility->get_file($url, $debug);

Use an appropriate URL fetching utility (fetch, curl, wget, etc) based on your OS to download a file from the $url handed to us.

Returns 1 for success, 0 for failure.

answer

use Mail::Toaster::Utility;
my $utility = Mail::Toaster::Utility->new();

my $answer = $utility->answer("question", $default, $timer)

arguments: $q is the question $default is an optional default answer. $timer is how long (in seconds) to wait for a response

returned is a string. If the user responded, their response is returned. If not, then the default response is returned. If no default was supplied, 0 is returned.

file_append

$utility->file_append($file, $lines)

Pass a filename and an array ref and it'll append the array contents to the file. It's that simple.

logfile_append

$utility->logfile_append($file, \@lines)

Pass a filename and an array ref and it'll append a timestamp and the array contents to the file. Here's a working example:

$utility->logfile_append($file, ["proggy", "Starting up", "Shutting down"] )

That will append a line like this to the log file:

2004-11-12 23:20:06 proggy Starting up
2004-11-12 23:20:06 proggy Shutting down

chdir_source_dir

$utility->chdir_source_dir("/usr/local/src");

changes your working directory to the supplied one. Creates it if it doesn't exist.

returns 1 on success

source_warning

if ( -d $package )
{
    unless ( $utility->source_warning($package, 1, $src) )
    { 
        carp "OK then, skipping install.\n";
        exit 0;
    };
};

Just check to see if the sources are present. If they are, offer to remove them.

returns 1 if removed.

parse_config

$conf = $utility->parse_config( { 
	file   => $file, 
	debug  => $debug, 
	etcdir => $etcdir,
} )

pass parse_config a hashref. $file is the file to be parsed. $etcdir is where the file should be found. It defaults to /usr/local/etc and will also check the current working directory.

A hashref is returned with the key/value pairs.

sudo

my $sudo = $utility->sudo();

$utility->syscmd("$sudo rm /etc/root-owned-file");

Often you want to run a script as an unprivileged user. However, the script may need elevated privileges for a plethora of reasons. Rather than running the script suid, or as root, configure sudo allowing the script to run system commands with appropriate permissions.

If sudo is not installed and you're running as root, it'll offer to install sudo for you. This is recommended, as is properly configuring sudo.

AUTHOR

Matt Simerson <matt@cadillac.net>

BUGS

None known. Report any to author.

TODO

SEE ALSO

http://www.tnpi.biz/internet/www/logmonster

COPYRIGHT

Copyright 2003-2004, The Network People, Inc. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the The Network People, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.