jpayne@69: package TIGR::Foundation; jpayne@69: { jpayne@69: jpayne@69: =head1 NAME jpayne@69: jpayne@69: TIGR::Foundation - TIGR Foundation object jpayne@69: jpayne@69: =head1 SYNOPSIS jpayne@69: jpayne@69: use TIGR::Foundation; jpayne@69: my $obj_instance = new TIGR::Foundation; jpayne@69: jpayne@69: =head1 DESCRIPTION jpayne@69: jpayne@69: This module defines a structure for Perl programs to utilize jpayne@69: logging, version reporting, and dependency checking in a simple way. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: BEGIN { jpayne@69: require 5.006_00; # error if using Perl < v5.6.0 jpayne@69: } jpayne@69: jpayne@69: use strict; jpayne@69: use Cwd; jpayne@69: use Cwd 'chdir'; jpayne@69: use Cwd 'abs_path'; jpayne@69: use File::Basename; jpayne@69: use Getopt::Long; jpayne@69: use IO::Handle; jpayne@69: use POSIX qw(strftime); jpayne@69: use Sys::Hostname; jpayne@69: use English; jpayne@69: jpayne@69: require Exporter; jpayne@69: jpayne@69: our @ISA; jpayne@69: our @EXPORT; jpayne@69: @ISA = ('Exporter'); jpayne@69: @EXPORT = qw( jpayne@69: isReadableFile jpayne@69: isWritableFile jpayne@69: isExecutableFile jpayne@69: isCreatableFile jpayne@69: isReadableDir jpayne@69: isWritableDir jpayne@69: isCreatableDir jpayne@69: isCreatablePath jpayne@69: jpayne@69: getISODate jpayne@69: getSybaseDate jpayne@69: getMySQLDate jpayne@69: getFilelabelDate jpayne@69: getLogfileDate jpayne@69: ); jpayne@69: jpayne@69: ## internal variables and identifiers jpayne@69: our $REVISION = (qw$Revision: 1.1.1.1 $)[-1]; jpayne@69: our $VERSION = '1.1'; jpayne@69: our $VERSION_STRING = "$VERSION (Build $REVISION)"; jpayne@69: our @DEPEND = (); # there are no dependencies jpayne@69: jpayne@69: jpayne@69: ## prototypes jpayne@69: jpayne@69: # Functional Class : general jpayne@69: sub new(); jpayne@69: sub getProgramInfo($); jpayne@69: sub runCommand($); jpayne@69: jpayne@69: # Functional Class : depend jpayne@69: sub printDependInfo(); jpayne@69: sub printDependInfoAndExit(); jpayne@69: sub addDependInfo(@); jpayne@69: jpayne@69: # Functional Class : version jpayne@69: sub getVersionInfo(); jpayne@69: sub printVersionInfo(); jpayne@69: sub printVersionInfoAndExit(); jpayne@69: sub setVersionInfo($); jpayne@69: jpayne@69: # Functional Class : help jpayne@69: sub printHelpInfo(); jpayne@69: sub printHelpInfoAndExit(); jpayne@69: sub setHelpInfo($); jpayne@69: jpayne@69: # Functional Class : usage jpayne@69: sub printUsageInfo(); jpayne@69: sub printUsageInfoAndExit(); jpayne@69: sub setUsageInfo($); jpayne@69: jpayne@69: # Functional Class : files jpayne@69: sub isReadableFile($); jpayne@69: sub isExecutableFile($); jpayne@69: sub isWritableFile($); jpayne@69: sub isCreatableFile($); jpayne@69: sub isReadableDir($); jpayne@69: sub isWritableDir($); jpayne@69: sub isCreatableDir($); jpayne@69: sub isCreatablePath($); jpayne@69: jpayne@69: # Functional Class : date jpayne@69: sub getISODate(;@); jpayne@69: sub getSybaseDate(;@); jpayne@69: sub getMySQLDate(;@); jpayne@69: sub getFilelabelDate(;@); jpayne@69: sub getLogfileDate(;@); jpayne@69: jpayne@69: # Functional Class : logging jpayne@69: sub setDebugLevel($;$); jpayne@69: sub getDebugLevel(); jpayne@69: sub setLogFile($;$); jpayne@69: sub getLogFile(); jpayne@69: sub getErrorFile(); jpayne@69: sub printDependInfo(); jpayne@69: sub invalidateLogFILES(); jpayne@69: sub cleanLogFILES(); jpayne@69: sub closeLogERROR(); jpayne@69: sub closeLogMSG(); jpayne@69: sub openLogERROR(); jpayne@69: sub openLogMSG(); jpayne@69: sub logAppend($;$); jpayne@69: sub debugPush(); jpayne@69: sub debugPop(); jpayne@69: sub logLocal($$); jpayne@69: sub logError($;$); jpayne@69: sub bail($;$); jpayne@69: jpayne@69: # Functional Class : modified methods jpayne@69: sub TIGR_GetOptions(@); jpayne@69: jpayne@69: ## Implementation jpayne@69: jpayne@69: jpayne@69: # Functional Class : general jpayne@69: jpayne@69: =over jpayne@69: jpayne@69: =item $obj_instance = new TIGR::Foundation; jpayne@69: jpayne@69: This function creates a new instance of the TIGR::Foundation jpayne@69: object. A reference pointing to the object is returned on success. Otherwise, jpayne@69: this method returns undefined. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub new() { jpayne@69: jpayne@69: my $self = {}; jpayne@69: my $pkg = shift; jpayne@69: my $user_name = getpwuid($<); jpayne@69: my $host_name = hostname(); jpayne@69: jpayne@69: # create the object jpayne@69: bless $self, $pkg; jpayne@69: jpayne@69: ## Instance variables and identifiers, by functional class jpayne@69: jpayne@69: # Functional Class : general jpayne@69: my $pname = basename($0, ()); # extract the script name jpayne@69: jpayne@69: if((defined ($pname)) && ($pname =~ /^(.*)$/)) { jpayne@69: $pname = $1; jpayne@69: $self->{program_name} = $pname ; jpayne@69: } jpayne@69: jpayne@69: if ($self->{program_name} =~ /^-$/) { # check if '-' is the input jpayne@69: $self->{program_name} = "STDIN"; jpayne@69: } jpayne@69: jpayne@69: my $pcommand = join (' ', @ARGV); jpayne@69: jpayne@69: if((defined ($pcommand)) && ($pcommand =~ /^(.*)$/)) { jpayne@69: $pcommand = $1; jpayne@69: $self->{invocation} = $pcommand ; jpayne@69: } jpayne@69: jpayne@69: # The following four variables are to contain information specified by jpayne@69: # the 'host' program; there are methods of setting and retrieving each jpayne@69: jpayne@69: # Functional Class : depend jpayne@69: @{$self->{depend_info}} = (); jpayne@69: jpayne@69: # Functional Class : version jpayne@69: $self->{version_info} = undef; jpayne@69: jpayne@69: # Functional Class : help jpayne@69: $self->{help_info} = undef; jpayne@69: jpayne@69: # Functional Class : usage jpayne@69: $self->{usage_info} = undef; jpayne@69: jpayne@69: # Functional Class : logging jpayne@69: $self->{debug_level} = undef; # default debug is not defined jpayne@69: @{$self->{debug_store}} = (); # the backup debug level stack jpayne@69: @{$self->{debug_queue}} = (); # queue used by MSG routine jpayne@69: @{$self->{error_queue}} = (); # queue used by ERROR routine jpayne@69: $self->{max_debug_queue_size} = 100; # maximum size for queue before jpayne@69: # log entries are expired jpayne@69: @{$self->{log_files}} = # these log files are consulted jpayne@69: ("$self->{program_name}.log", # on file write error and are jpayne@69: "/tmp/$self->{program_name}.$$.log"); # modified by setLogFile jpayne@69: $self->{msg_file_open_flag} = 0; # flag to check logLocal file jpayne@69: $self->{error_file_open_flag} = 0; # flag to check logError file jpayne@69: $self->{msg_file_used} = 0; # flag to indicate if log file jpayne@69: $self->{error_file_used} = 0; # has been written to jpayne@69: $self->{msg_append_flag} = 0; # by default logs are truncated jpayne@69: $self->{error_append_flag} = 0; # by default logs are truncated jpayne@69: $self->{log_append_setting} = 0; # (truncate == 0) jpayne@69: $self->{static_log_file} = undef; # user defined log file jpayne@69: $self->{start_time} = undef; # program start time jpayne@69: $self->{finish_time} = undef; # program stop time jpayne@69: jpayne@69: # Log program invocation jpayne@69: $self->logLocal("START: " . "Username:$user_name, ". jpayne@69: "Hostname: $host_name ". $self->getProgramInfo('name') . jpayne@69: " " . $self->getProgramInfo('invocation'), 0); jpayne@69: $self->{start_time} = time; jpayne@69: jpayne@69: return $self; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: jpayne@69: =item $value = $obj_instance->getProgramInfo($field_type); jpayne@69: jpayne@69: This function returns field values for specified field types describing jpayne@69: attributes of the program. The C<$field_type> parameter must be a listed jpayne@69: attribute: C, C, C, C. jpayne@69: The C field specifies the bare name of the executable. The jpayne@69: C field specifies the command line arguments passed to the jpayne@69: executable. The C value returns the environment path to the jpayne@69: working directory. The C value specifies the absolute path to the jpayne@69: working directory. If C is found to be inconsistent, then that jpayne@69: value will return the C value. If an invalid C<$field_type> is jpayne@69: passed, the function returns undefined. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub getProgramInfo($) { jpayne@69: my $self = shift; jpayne@69: my $field_type = shift; jpayne@69: my $return_value = undef; jpayne@69: if (defined $field_type) { jpayne@69: $field_type =~ /^name$/ && do { jpayne@69: $return_value = $self->{program_name}; jpayne@69: }; jpayne@69: $field_type =~ /^invocation$/ && do { jpayne@69: $return_value = $self->{invocation}; jpayne@69: }; jpayne@69: $field_type =~ /^env_path$/ && do { jpayne@69: my $return_value = ""; jpayne@69: if ( jpayne@69: (defined $ENV{'PWD'}) && jpayne@69: (abs_path($ENV{'PWD'}) eq abs_path(".")) && jpayne@69: ($ENV{'PWD'} =~ /^(.*)$/) jpayne@69: ) { jpayne@69: $ENV{'PWD'} = $1; jpayne@69: $return_value = $ENV{'PWD'}; jpayne@69: } jpayne@69: else { jpayne@69: my $tmp_val = abs_path("."); jpayne@69: jpayne@69: if((defined ($tmp_val)) && ($tmp_val =~ /^(.*)$/)) { jpayne@69: $tmp_val = $1; jpayne@69: $return_value = $tmp_val; jpayne@69: } jpayne@69: } jpayne@69: return $return_value; jpayne@69: }; jpayne@69: jpayne@69: $field_type =~ /^abs_path$/ && do { jpayne@69: my $tmp_val = abs_path("."); jpayne@69: jpayne@69: if((defined ($tmp_val)) && ($tmp_val =~ /^(.*)$/)) { jpayne@69: $tmp_val = $1; jpayne@69: $return_value = $tmp_val; jpayne@69: } jpayne@69: }; jpayne@69: } jpayne@69: return $return_value; jpayne@69: } jpayne@69: jpayne@69: =item $exit_code = $obj_instance->runCommand($command_str); jpayne@69: jpayne@69: This function passes the argument C<$command_str> to /bin/sh jpayne@69: for processing. The return value is the exit code of the jpayne@69: C<$command_str>. If the exit code is not defined, then either the signal or jpayne@69: core dump value of the execution is returned, whichever is applicable. Perl jpayne@69: variables C<$?> and C<$!> are set accordingly. If C<$command_str> is not jpayne@69: defined, this function returns undefined. Log messages are recorded at log jpayne@69: level 4 to indicate the type of exit status and the corresponding code. jpayne@69: Invalid commands return -1. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub runCommand($) { jpayne@69: my $self = shift; jpayne@69: my $command_str = shift; jpayne@69: my $exit_code = undef; jpayne@69: my $signal_num = undef; jpayne@69: my $dumped_core = undef; jpayne@69: my $invalid_command = undef; jpayne@69: my $return_value = undef; jpayne@69: my @info_arr = getpwuid($<); jpayne@69: my $len = @info_arr; jpayne@69: my $home_dir = $info_arr[7]; jpayne@69: my $current_dir = $self->getProgramInfo("abs_path"); jpayne@69: jpayne@69: if((defined ($ENV{PATH})) && ($ENV{PATH} =~ /^(.*)$/)) {#taint checking jpayne@69: $ENV{PATH} = $1; jpayne@69: my $path_var = $ENV{PATH}; jpayne@69: my @paths = split /:/, $path_var; jpayne@69: my $pathval = undef; jpayne@69: my $i = 0; jpayne@69: my $paths_len = @paths; jpayne@69: jpayne@69: for ($i = 0; $i < $paths_len ; $i++) { jpayne@69: #substituting ~ with the home pathname. jpayne@69: $pathval = $paths[$i]; jpayne@69: $pathval =~ s/^~$/$home_dir/g; jpayne@69: my $home_root = $home_dir."\/"; jpayne@69: $pathval =~ s/^~\//$home_root/g; jpayne@69: jpayne@69: #substituting . with the current pathname. jpayne@69: $pathval =~ s/^\.$/$current_dir/g; jpayne@69: my $current_root = $current_dir."\/"; jpayne@69: $pathval =~ s/^\.\//$current_root/g; jpayne@69: $paths[$i] = $pathval; jpayne@69: } jpayne@69: jpayne@69: $ENV{PATH} = join(":", @paths); jpayne@69: } jpayne@69: jpayne@69: if((defined ($command_str)) && ($command_str =~ /^(.*)$/)) {#taint jpayne@69: #checking jpayne@69: $command_str = $1; jpayne@69: system($command_str); jpayne@69: $exit_code = $? >> 8; jpayne@69: $signal_num = $? & 127; jpayne@69: $dumped_core = $? & 128; jpayne@69: jpayne@69: if ($? == -1) { jpayne@69: $invalid_command = -1; jpayne@69: } jpayne@69: jpayne@69: if ( jpayne@69: (!defined $invalid_command) && jpayne@69: ($exit_code == 0) && jpayne@69: ($signal_num == 0) && jpayne@69: ($dumped_core != 0) jpayne@69: ) { jpayne@69: jpayne@69: $self->logLocal("Command '" . $command_str . "' core dumped", 4); jpayne@69: $return_value = $dumped_core; jpayne@69: } jpayne@69: elsif ( jpayne@69: (!defined $invalid_command) && jpayne@69: ($exit_code == 0) && jpayne@69: ($signal_num != 0) jpayne@69: ) { jpayne@69: jpayne@69: $self->logLocal("Command '" . $command_str . jpayne@69: "' exited on signal " . $signal_num, 4); jpayne@69: $return_value = $signal_num; jpayne@69: } jpayne@69: elsif ((!defined $invalid_command)) { jpayne@69: jpayne@69: $self->logLocal("Command '" . $command_str . jpayne@69: "' exited with exit code " . $exit_code, 4); jpayne@69: $return_value = $exit_code; jpayne@69: } jpayne@69: else { jpayne@69: jpayne@69: $self->logLocal("Command '" . $command_str . jpayne@69: "' exited with invalid code " . $?, 4); jpayne@69: $return_value = $?; jpayne@69: } jpayne@69: } jpayne@69: return $return_value; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: # Functional Class : depend jpayne@69: jpayne@69: =item $obj_instance->printDependInfo(); jpayne@69: jpayne@69: The C function prints the dependency list created by jpayne@69: C. One item is printed per line. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub printDependInfo() { jpayne@69: my $self = shift; jpayne@69: foreach my $dependent (@{$self->{depend_info}}) { jpayne@69: print STDERR $dependent, "\n"; jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $obj_instance->printDependInfoAndExit(); jpayne@69: jpayne@69: The C function prints the dependency list created by jpayne@69: C. One item is printed per line. The function exits with jpayne@69: exit code 0. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub printDependInfoAndExit() { jpayne@69: my $self = shift; jpayne@69: $self->printDependInfo(); jpayne@69: exit 0; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $obj_instance->addDependInfo(@depend_list); jpayne@69: jpayne@69: The C function adds C<@depend_list> information jpayne@69: to the dependency list. If C<@depend_list> is empty, the internal jpayne@69: dependency list is emptied. Contents of C<@depend_list> are not checked jpayne@69: for validity (eg. they can be composed entirely of white space or jpayne@69: multiple files per record). The first undefined record in C<@depend_list> jpayne@69: halts reading in of dependency information. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub addDependInfo(@) { jpayne@69: my $self = shift; jpayne@69: my $num_elts = 0; jpayne@69: while (my $data_elt = shift @_) { jpayne@69: push (@{$self->{depend_info}}, $data_elt); jpayne@69: $num_elts++; jpayne@69: } jpayne@69: if ($num_elts == 0) { jpayne@69: @{$self->{depend_info}} = (); jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: # Functional Class : version jpayne@69: jpayne@69: =item $version_string = $obj_instance->getVersionInfo(); jpayne@69: jpayne@69: The C function returns the version information set by the jpayne@69: C function. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub getVersionInfo() { jpayne@69: my $self = shift; jpayne@69: return $self->{version_info}; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $obj_instance->printVersionInfo(); jpayne@69: jpayne@69: The C function prints the version information set by the jpayne@69: C function. If there is no defined version information, jpayne@69: a message is returned notifying the user. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub printVersionInfo() { jpayne@69: my $self = shift; jpayne@69: if (defined $self->getVersionInfo()) { jpayne@69: print STDERR $self->getProgramInfo('name'), jpayne@69: " ", $self->getVersionInfo(), "\n"; jpayne@69: } jpayne@69: else { jpayne@69: print STDERR $self->getProgramInfo('name'), jpayne@69: " has no defined version information\n"; jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $obj_instance->printVersionInfoAndExit(); jpayne@69: jpayne@69: The C function prints version info set by the jpayne@69: C function. If there is no defined version information, jpayne@69: a message is printed notifying the user. This function calls exit with jpayne@69: exit code 0. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub printVersionInfoAndExit() { jpayne@69: my $self = shift; jpayne@69: $self->printVersionInfo(); jpayne@69: exit 0; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $obj_instance->setVersionInfo($version_string); jpayne@69: jpayne@69: The C function sets the version information to be reported jpayne@69: by C. If C<$version_string> is empty, invalid, or jpayne@69: undefined, the stored version information will be undefined. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub setVersionInfo($) { jpayne@69: my $self = shift; jpayne@69: my $v_info = shift; jpayne@69: if ( jpayne@69: (defined $v_info) && jpayne@69: ($v_info =~ /\S/) && jpayne@69: ((ref $v_info) eq "") jpayne@69: ) { jpayne@69: $self->{version_info} = $v_info; jpayne@69: } jpayne@69: else { jpayne@69: $self->{version_info} = undef; jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: # Functional Class : help jpayne@69: jpayne@69: =item $obj_instance->printHelpInfo(); jpayne@69: jpayne@69: The C function prints the help information passed by the jpayne@69: C function. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub printHelpInfo() { jpayne@69: my $self = shift; jpayne@69: if (defined $self->{help_info}) { jpayne@69: print STDERR $self->{help_info}; jpayne@69: } jpayne@69: else { jpayne@69: print STDERR "No help information defined.\n"; jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $obj_instance->printHelpInfoAndExit(); jpayne@69: jpayne@69: The C function prints the help info passed by the jpayne@69: C function. This function exits with exit code 0. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub printHelpInfoAndExit() { jpayne@69: my $self = shift; jpayne@69: $self->printHelpInfo(); jpayne@69: exit 0; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $obj_instance->setHelpInfo($help_string); jpayne@69: jpayne@69: The C function sets the help information via C<$help_string>. jpayne@69: If C<$help_string> is undefined, invalid, or empty, the help information jpayne@69: is undefined. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub setHelpInfo($) { jpayne@69: my $self = shift; jpayne@69: my $help_string = shift; jpayne@69: if ( jpayne@69: (defined $help_string) && jpayne@69: ($help_string =~ /\S/) && jpayne@69: ((ref $help_string) eq "") jpayne@69: ) { jpayne@69: chomp($help_string);#removing a new line if it is there. jpayne@69: $self->{help_info} = $help_string."\n";#adding a new line to help. jpayne@69: } jpayne@69: else { jpayne@69: $self->{help_info} = undef; jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: # Functional Class : usage jpayne@69: jpayne@69: =item $obj_instance->printUsageInfo(); jpayne@69: jpayne@69: The C function prints the usage information reported by the jpayne@69: C function. If no usage information is defined, but help jpayne@69: information is defined, help information will be printed. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub printUsageInfo() { jpayne@69: jpayne@69: my $self = shift; jpayne@69: if (defined $self->{usage_info}) { jpayne@69: print STDERR $self->{usage_info}; jpayne@69: } jpayne@69: elsif (defined $self->{help_info}) { jpayne@69: print STDERR $self->{help_info}; jpayne@69: } jpayne@69: else { jpayne@69: print STDERR "No usage information defined.\n"; jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $obj_instance->printUsageInfoAndExit(); jpayne@69: jpayne@69: The C function prints the usage information the jpayne@69: reported by the C function and exits with status 1. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub printUsageInfoAndExit() { jpayne@69: my $self = shift; jpayne@69: $self->printUsageInfo(); jpayne@69: $self->bail("Incorrect command line"); jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $obj_instance->setUsageInfo($usage_string); jpayne@69: jpayne@69: The C function sets the usage information via C<$usage_string>. jpayne@69: If C<$usage_string> is undefined, invalid, or empty, the usage information jpayne@69: is undefined. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub setUsageInfo($) { jpayne@69: my $self = shift; jpayne@69: my $usage_string = shift; jpayne@69: if ( jpayne@69: (defined $usage_string) && jpayne@69: ($usage_string =~ /\S/) && jpayne@69: ((ref $usage_string) eq "") jpayne@69: ) { jpayne@69: chomp($usage_string); #removing a new line if it is there. jpayne@69: $self->{usage_info} = $usage_string."\n";#adding a new line to usage jpayne@69: } jpayne@69: else { jpayne@69: $self->{usage_info} = undef; jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: # Functional Class : files jpayne@69: jpayne@69: =item $valid = isReadableFile($file_name); jpayne@69: jpayne@69: This function accepts a single scalar parameter containing a file name. jpayne@69: If the file corresponding to the file name is a readable plain file or symbolic jpayne@69: link, this function returns 1. Otherwise, the function returns 0. If the file jpayne@69: name passed is undefined, this function returns 0 as well. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub isReadableFile($) { jpayne@69: my $file = shift; jpayne@69: if (scalar(@_) != 0) { #incase the method was invoked as an instance jpayne@69: #method jpayne@69: $file = shift; jpayne@69: } jpayne@69: jpayne@69: if (defined ($file) && # was a file name passed? jpayne@69: ((-f $file) || (-l $file)) && # is the file a file or sym. link? jpayne@69: (-r $file) # is the file readable? jpayne@69: ) { jpayne@69: return 1; jpayne@69: } jpayne@69: else { jpayne@69: return 0; jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $valid = isExecutableFile($file_name); jpayne@69: jpayne@69: This function accepts a single scalar parameter containing a file name. jpayne@69: If the file corresponding to the file name is an executable plain file jpayne@69: or symbolic link, this function returns 1. Otherwise, the function returns 0. jpayne@69: If the file name passed is undefined, this function returns 0 as well. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub isExecutableFile($) { jpayne@69: my $file = shift; jpayne@69: if (scalar(@_) != 0) { # incase the method was invoked as a instance jpayne@69: # method jpayne@69: $file = shift; jpayne@69: } jpayne@69: jpayne@69: if (defined ($file) && # was a file name passed? jpayne@69: ((-f $file) || (-l $file)) && # is the file a file or sym. link? jpayne@69: (-x $file) # is the file executable? jpayne@69: ) { jpayne@69: return 1; jpayne@69: } jpayne@69: else { jpayne@69: return 0; jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $valid = isWritableFile($file_name); jpayne@69: jpayne@69: This function accepts a single scalar parameter containing a file name. jpayne@69: If the file corresponding to the file name is a writable plain file jpayne@69: or symbolic link, this function returns 1. Otherwise, the function returns 0. jpayne@69: If the file name passed is undefined, this function returns 0 as well. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub isWritableFile($) { jpayne@69: my $file = shift; jpayne@69: if (scalar(@_) != 0) { # incase the method was invoked as a instance jpayne@69: # method jpayne@69: $file = shift; jpayne@69: } jpayne@69: jpayne@69: if (defined ($file) && # was a file name passed? jpayne@69: ((-f $file) || (-l $file)) && # is the file a file or sym. link? jpayne@69: (-w $file) # is the file writable? jpayne@69: ) { jpayne@69: return 1; jpayne@69: } jpayne@69: else { jpayne@69: return 0; jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $valid = isCreatableFile($file_name); jpayne@69: jpayne@69: This function accepts a single scalar parameter containing a file name. If jpayne@69: the file corresponding to the file name is creatable this function returns 1. jpayne@69: The function checks if the location of the file is writable by the effective jpayne@69: user id (EUID). If the file location does not exist or the location is not jpayne@69: writable, the function returns 0. If the file name passed is undefined, jpayne@69: this function returns 0 as well. Note that files with suffix F are not jpayne@69: supported under UNIX platforms, and will return 0. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub isCreatableFile($) { jpayne@69: my $file = shift; jpayne@69: if (scalar(@_) != 0) { # incase the method was invoked as an instance jpayne@69: # method jpayne@69: $file = shift; jpayne@69: } jpayne@69: jpayne@69: my $return_code = 0; jpayne@69: jpayne@69: if ( jpayne@69: (defined ($file)) && jpayne@69: (! -e $file) && jpayne@69: ($file !~ /\/$/) jpayne@69: ) { jpayne@69: my $dirname = dirname($file); jpayne@69: # check the writability of the directory jpayne@69: $return_code = isWritableDir($dirname); jpayne@69: } jpayne@69: else { jpayne@69: # the file exists, it's not creatable jpayne@69: $return_code = 0; jpayne@69: } jpayne@69: return $return_code; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $valid = isReadableDir($directory_name); jpayne@69: jpayne@69: This function accepts a single scalar parameter containing a directory name. jpayne@69: If the name corresponding to the directory is a readable, searchable directory jpayne@69: entry, this function returns 1. Otherwise, the function returns 0. If the jpayne@69: name passed is undefined, this function returns 0 as well. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub isReadableDir($) { jpayne@69: my $file = shift; jpayne@69: if (scalar(@_) != 0) { # incase the method was invoked as an instance jpayne@69: # method jpayne@69: $file = shift; jpayne@69: } jpayne@69: jpayne@69: if (defined ($file) && # was a name passed? jpayne@69: (-d $file) && # is the name a directory? jpayne@69: (-r $file) && # is the directory readable? jpayne@69: (-x $file) # is the directory searchable? jpayne@69: ) { jpayne@69: return 1; jpayne@69: } jpayne@69: else { jpayne@69: return 0; jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $valid = isWritableDir($directory_name); jpayne@69: jpayne@69: This function accepts a single scalar parameter containing a directory name. jpayne@69: If the name corresponding to the directory is a writable, searchable directory jpayne@69: entry, this function returns 1. Otherwise, the function returns 0. If the jpayne@69: name passed is undefined, this function returns 0 as well. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub isWritableDir($) { jpayne@69: my $file = shift; jpayne@69: if (scalar(@_) != 0) { # incase the method was invoked as an instance jpayne@69: # method jpayne@69: $file = shift; jpayne@69: } jpayne@69: jpayne@69: if (defined ($file) && # was a name passed? jpayne@69: (-d $file) && # is the name a directory? jpayne@69: (-w $file) && # is the directory writable? jpayne@69: (-x $file) # is the directory searchable? jpayne@69: ) { jpayne@69: return 1; jpayne@69: } jpayne@69: else { jpayne@69: return 0; jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $valid = isCreatableDir($directory_name); jpayne@69: jpayne@69: This function accepts a single scalar parameter containing a directory name. jpayne@69: If the name corresponding to the directory is creatable this function returns jpayne@69: 1. The function checks if the immediate parent of the directory is writable by jpayne@69: the effective user id (EUID). If the parent directory does not exist or the jpayne@69: tree is not writable, the function returns 0. If the directory name passed is jpayne@69: undefined, this function returns 0 as well. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub isCreatableDir($) { jpayne@69: my $dir = shift; jpayne@69: if (scalar(@_) != 0) { # incase the method was invoked as an instance jpayne@69: # method jpayne@69: $dir = shift; jpayne@69: } jpayne@69: my $return_code = 0; jpayne@69: jpayne@69: if (defined ($dir)) { jpayne@69: $dir =~ s/\/$//g; jpayne@69: $return_code = isCreatableFile($dir); jpayne@69: } jpayne@69: return $return_code; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: =item $valid = isCreatablePath($path_name); jpayne@69: jpayne@69: This function accepts a single scalar parameter containing a path name. If jpayne@69: the C<$path_name> is creatable this function returns 1. The function checks jpayne@69: if the directory hierarchy of the path is creatable or writable by the jpayne@69: effective user id (EUID). This function calls itself recursively until jpayne@69: an existing directory node is found. If that node is writable, ie. the path jpayne@69: can be created in it, then this function returns 1. Otherwise, the function jpayne@69: returns 0. This function also returns zero if the C<$path_name> supplied jpayne@69: is disconnected from a reachable directory tree on the file system. jpayne@69: If the path already exists, this function returns 0. The C<$path_name> may jpayne@69: imply either a path to a file or a directory. Path names may be relative or jpayne@69: absolute paths. Any unresolvable relative paths will return 0 as well. This jpayne@69: includes paths with F<..> back references to nonexistent directories. jpayne@69: This function is recursive whereas C and jpayne@69: C are not. jpayne@69: jpayne@69: =cut jpayne@69: jpayne@69: jpayne@69: sub isCreatablePath($) { jpayne@69: my $pathname = shift; jpayne@69: if (scalar(@_) != 0) { # incase the method was invoked as an instance jpayne@69: # method jpayne@69: $pathname = shift; jpayne@69: } jpayne@69: my $return_code = 0; jpayne@69: jpayne@69: if (defined $pathname) { jpayne@69: # strip trailing '/' jpayne@69: $pathname =~ s/(.+)\/$/$1/g; jpayne@69: my $filename = basename($pathname); jpayne@69: my $dirname = dirname($pathname); jpayne@69: if ( jpayne@69: (! -e $pathname) && jpayne@69: ($dirname ne $pathname) && jpayne@69: ($filename ne "..") jpayne@69: ) { jpayne@69: if (-e $dirname) { jpayne@69: $return_code = isWritableDir($dirname); jpayne@69: } jpayne@69: else { jpayne@69: $return_code = isCreatablePath($dirname); jpayne@69: } jpayne@69: } jpayne@69: else { jpayne@69: $return_code = 0; jpayne@69: } jpayne@69: } jpayne@69: return $return_code; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: # Functional Class : date jpayne@69: jpayne@69: =item $date_string = getISODate($tm); jpayne@69: jpayne@69: This function returns the ISO 8601 datetime as a string given a time jpayne@69: structure as returned by the C