The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Mail::Toaster::Utility

SYNOPSIS

a group of frequently used perl methods I've written for use with various scripts.

DESCRIPTION

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 Mail::Toaster::Utility;
  my $utility = Mail::Toaster::Utility->new;

answer

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

arguments: a string with the question to ask an optional default answer. 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.

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.

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

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;

clean_tmp_dir

  $utility->clean_tmp_dir($dir)

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

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.

install_from_sources_php

  $utility->install_from_sources_php();

Downloads a PHP program and installs it. Not completed.

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.

file_archive

  $utility->file_archive ($file)

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

returns 0 on failure, a file path on success.

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.

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_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.

file_get

   $utility->file_get($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.

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.

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

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.

find_the_bin

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

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.

Example:

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

fstab_list

Fetch a list of drives that are mountable from /etc/fstab.

   $utility->fstab_list;

returns an arrayref.

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.

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();

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, $debug);

Downloads and installs a program from sources.

targets and partches are array references.

An optional value to set is bintest. If set, it'll check the usual places for an executable binary. If found, it'll assume the software is already installed and require confirmation before re-installing.

returns 1 on success, 0 on failure.

is_arrayref

Checks whatever object is passed to it to see if it's an arrayref.

   $utility->is_arrayref($testme, $debug);

Enable debugging to see helpful error messages.

is_hashref

Most methods pass parameters around inside hashrefs. Unfortunately, if you try accessing a hashref method and the object isn't a hashref, it generates a fatal exception. This traps that exception and prints a useful error message.

   $utility->is_hashref($hashref, $debug);

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.

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

mailtoaster

   $utility->mailtoaster();

Downloads and installs Mail::Toaster.

path_parse

   my ($up1dir, $userdir) = $utility->path_parse($dir)

Takes a path like "/usr/home/matt" and returns "/usr/home" and "matt"

You (and I) should be using File::Basename instead as it's more portable.

parse_config

   $hashref = {
      file   => $file,    # file to be parsed
      debug  => $debug,   # 
      etcdir => $etcdir,  # where should I find $file?
   };

   $conf = $utility->parse_config( $hashref );

pass parse_config a hashref. $etcdir defaults to /usr/local/etc and will also checks the current working directory.

A hashref is returned with the key/value pairs.

pidfile_check

pidfile_check 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.

   $pidfile = $utility->pidfile_check("/var/run/program.pid");

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).

Example:

        my $pidfile = $utility->pidfile_check("/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;

source_warning

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

   $utility->source_warning("Mail-Toaster-4.01", 1, "/usr/local/etc");

returns 1 if removed.

Example:

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

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.

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);
   $r ? print "not ok!\n" : print "ok.\n";

return is the exit status of the program you called.

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.

AUTHOR

Matt Simerson <matt@cadillac.net>

BUGS

None known. Report any to author.

TODO

SEE ALSO

The following are all man/perldoc pages:

 Mail::Toaster 
 Mail::Toaster::Apache 
 Mail::Toaster::CGI  
 Mail::Toaster::DNS 
 Mail::Toaster::Darwin
 Mail::Toaster::Ezmlm
 Mail::Toaster::FreeBSD
 Mail::Toaster::Logs 
 Mail::Toaster::Mysql
 Mail::Toaster::Passwd
 Mail::Toaster::Perl
 Mail::Toaster::Provision
 Mail::Toaster::Qmail
 Mail::Toaster::Setup
 Mail::Toaster::Utility

 Mail::Toaster::Conf
 toaster.conf
 toaster-watcher.conf

 http://matt.simerson.net/computing/mail/toaster/
 http://matt.simerson.net/computing/mail/toaster/docs/

COPYRIGHT

Copyright 2003-2005, 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.