MINI MINI MANI MO
# Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
#
# NAME
# asmcmdpasswd - ASM CoMmanD line interface for shared password file
# operations
#
# DESCRIPTION
# This module handles the shared password file operations like create,
# move, copy, delete the password file, get and set the password
# file location.y
#
# MODIFIED (MM/DD/YY)
# apfwkr 03/28/18 - Backport moreddy_bug-27688692 from main
# moreddy 03/19/18 - 27688692: modify pwcreate
# prabbala 07/25/17 - 26485972: Fix value of dest_DG in _normalized_files
# anovelo 01/17/17 - 21159907: Disallow duplicate password files
# anovelo 10/27/16 - 19261460: Ensure CRS is updated in pwmove
# anovelo 10/24/16 - 24706236: Update calls to asmcmdshare_get_subdirs
# prabbala 09/15/16 - bug19777340: send dbuniquename to KFPKG in pwcopy
# yilhu 07/19/16 - 24309216: Add anchor for start of line when parsing
# diguzman 05/30/16 - 19654070: Little change at _no_instance_cmd routine
# moreddy 05/30/16 - 21168520: fix pwdelete --dbuniquename
# anovelo 03/08/16 - 21894027: Update format for orapwd
# dacavazo 01/18/16 - 22458930: fix undefined array value in pwdelete
# dacavazo 12/07/15 - 22223809: undef function before dl_find_symbol
# bhshanmu 07/26/15 - bhshanmu_perl_522_changes_for_rdbms
# prabbala 01/30/15 - 20101171: use asmcmdshare_runcmd to capture cmd o/p
# prabbala 11/25/14 - bug19512500: use asmcmdshare_runcmd to capture shell
# command output
# pvenkatr 07/05/13 - Bug 14014671: Reverse lookup API integration.
# pvenkatr 02/01/13 - using asmcmdshare_filter_invisible_cmds
# adileepk 05/08/12 - Fix for bug-14000743.
# adileepk 04/18/12 - Fix for bug-13964420.
# adileepk 03/15/12 - Fix for bug-13827285.
# ssonawan 03/08/12 - Bug 13050833: replace 'extended' by 'format'
# adileepk 01/31/12 - Fix for bug-13574607.
# adileepk 12/01/11 - Fix for bug-13450576. Adding pwget & pwset
# commands.
# adileepk 01/10/11 - Creation
#
#############################################################################
#
############################ Functions List #################################
#
# Top Level Command Processing Routines
# asmcmdpasswd_init
# asmcmdpasswd_process_cmd
# asmcmdpasswd_process_pwcreate
# asmcmdpasswd_process_pwcopy
# asmcmdpasswd_process_pwdelete
# asmcmdpasswd_process_pwmove
# asmcmdpasswd_process_pwset
# asmcmdpasswd_process_pwget
# asmcmdpasswd_process_help
#
# Error Routines
# asmcmdpasswd_syntax_error
#
# Help Routines
# asmcmdpasswd_get_asmcmd_cmds
#
# Misc Utility Routines
# asmcmdpasswd_get_res_list
#############################################################################
package asmcmdpasswd;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(asmcmdpasswd_init
);
use strict;
use Getopt::Std;
use asmcmdglobal;
use asmcmdshare;
use asmcmdparser;
use asmcmdbase;
####################### ASMCMDPASSWD Global Constants ######################
####################### ASMCMDPASSWD Global Variables ######################
my (%asmcmdpasswd_cmds) = (pwcreate => { },
pwcopy => { },
pwmove => { },
pwdelete => { },
pwset => { },
pwget => { },
);
my ($PLSQL_NUMBER) = 22;
my ($PLSQL_PWFILE) = 28;
sub is_asmcmd
{
return 1;
}
########
# NAME
# asmcmdpasswd_init
#
# DESCRIPTION
# This function initializes the asmcmdpasswd module.
#
# PARAMETERS
# None
#
# RETURNS
# Null
#
# NOTES
# Only asmcmdcore_main() calls this routine.
########
sub init
{
# All of the arrays defined in the asmcmdglobal module must be
# initialized here. Otherwise, an internal error will result.
push (@asmcmdglobal_command_callbacks, \&asmcmdpasswd_process_cmd);
push (@asmcmdglobal_help_callbacks, \&asmcmdpasswd_process_help);
push (@asmcmdglobal_command_list_callbacks, \&asmcmdpasswd_get_asmcmd_cmds);
push (@asmcmdglobal_is_command_callbacks, \&asmcmdpasswd_is_cmd);
push (@asmcmdglobal_is_wildcard_callbacks, \&asmcmdpasswd_is_wildcard_cmd);
push (@asmcmdglobal_syntax_error_callbacks, \&asmcmdpasswd_syntax_error);
push (@asmcmdglobal_no_instance_callbacks, \&asmcmdpasswd_is_no_instance_cmd);
%asmcmdglobal_cmds = (%asmcmdglobal_cmds, %asmcmdpasswd_cmds);
#Perform ASMCMD consistency check if enabled
if ($asmcmdglobal_hash{'consistchk'} eq 'y')
{
if (!asmcmdshare_check_option_consistency(%asmcmdpasswd_cmds))
{
exit 1;
}
}
}
########
# NAME
# asmcmdpasswd_process_cmd
#
# DESCRIPTION
# This routine calls the appropriate routine to process the command
# specified by $asmcmdglobal_hash{'cmd'}.
#
# PARAMETERS
# dbh (IN) - initialized database handle, must be non-null.
#
# RETURNS
# 1 if command is found in the asmcmdpasswd module; 0 if not.
#
# NOTES
# Only asmcmdcore_shell() calls this routine.
########
sub asmcmdpasswd_process_cmd
{
my ($dbh) = @_;
my ($succ) = 0;
my ($result);
# Get current command from global value, which is set by
# asmcmdpasswd_parse_asmcmd_args()and by asmcmdcore_shell().
my ($cmd) = $asmcmdglobal_hash{'cmd'};
# Declare and initialize hash of function pointers, each designating a
# routine that processes an ASMCMDTEMPLATE command.
my (%cmdhash) = ( pwcreate => \&asmcmdpasswd_process_pwcreate,
pwcopy => \&asmcmdpasswd_process_pwcopy,
pwmove => \&asmcmdpasswd_process_pwmove,
pwdelete => \&asmcmdpasswd_process_pwdelete,
pwset => \&asmcmdpasswd_process_pwset,
pwget => \&asmcmdpasswd_process_pwget,
);
if (defined ( $cmdhash{ $cmd } ))
{ # If user specifies a known command, then call routine to process it. #
$result = $cmdhash{ $cmd }->($dbh);
$succ = 1;
}
return $succ;
}
########
# NAME
# asmcmdpasswd_process_help
#
# DESCRIPTION
# This function is the help function for the ASMCMDPASSWD module.
#
# PARAMETERS
# command (IN) - display the help message for this command.
#
# RETURNS
# 1 if command found; 0 otherwise.
########
sub asmcmdpasswd_process_help
{
my ($command) = shift; # User-specified argument; show help on $cmd. #
my ($desc); # Command description for $cmd. #
my ($succ) = 0; # 1 if command found, 0 otherwise. #
if (asmcmdpasswd_is_cmd ($command))
{ # User specified a command name to look up. #
$desc = asmcmdshare_get_help_desc($command);
asmcmdshare_print "$desc\n";
$succ = 1;
}
return $succ;
}
########
# NAME
# asmcmdpasswd_is_cmd
#
# DESCRIPTION
# This routine checks if a user-entered command is one of the known
# ASMCMD internal commands that belong to the ASMCMDPASSWD module.
#
# PARAMETERS
# arg (IN) - user-entered command name string.
#
# RETURNS
# True if $arg is one of the known commands, false otherwise.
########
sub asmcmdpasswd_is_cmd
{
my ($arg) = shift;
return defined ( $asmcmdpasswd_cmds{ $arg } );
}
########
# NAME
# asmcmdpasswd_is_wildcard_cmd
#
# DESCRIPTION
# This routine determines if an ASMCMDPASSWD command allows the use
# of wild cards.
#
# PARAMETERS
# arg (IN) - user-entered command name string.
#
# RETURNS
# True if $arg is a command that can take wildcards as part of its argument,
# false otherwise.
########
sub asmcmdpasswd_is_wildcard_cmd
{
my ($arg) = shift;
return defined ($asmcmdpasswd_cmds{ $arg }) &&
(asmcmdshare_get_cmd_wildcard($arg) eq "true" ) ;
}
########
# NAME
# asmcmdpasswd_is_no_instance_cmd
#
# DESCRIPTION
# This routine determines if a command can run without an ASM instance.
#
# PARAMETERS
# arg (IN) - user-entered command name string.
#
# RETURNS
# 1 if $arg is a command that can run without an ASM instance or it does not
# belong to this module
# 0 if $arg is a command that needs to connect to an ASM instance
# -1 if $arg is a command that may use an ASM instance.
#
# NOTES
# The asmcmdpasswd module currently supports no command that can run
# without an ASM instance.
########
sub asmcmdpasswd_is_no_instance_cmd
{
my ($arg) = shift;
my ($rc);
return 1 unless defined($asmcmdpasswd_cmds{$arg});
$rc = asmcmdshare_get_cmd_noinst($arg);
if ($rc eq "true")
{
return 1;
}
elsif ($rc eq "undef")
{
return -1;
}
return 0;
}
########
# NAME
# asmcmdpasswd_parse_int_args
#
# DESCRIPTION
# This routine parses the arguments for flag options for ASMCMDPASSWD
# internal commands.
#
# PARAMETERS
# cmd (IN) - user-entered command name string.
# args_ref (OUT) - hash of user-specified flag options for a command,
# populated by asmcmdparser.
#
# RETURNS
# Zero on success; undefined on error.
#
# NOTES
# $cmd must already be verified as a valid ASMCMDPASSWD internal command.
########
sub asmcmdpasswd_parse_int_args
{
my ($cmd, $args_ref) = @_;
my (@string);
my ($key);
#include deprecated options if any
if ($asmcmdglobal_deprecated_options{ $cmd })
{
foreach my $key(keys %{$asmcmdglobal_deprecated_options{ $cmd }})
{
push(@string, $asmcmdglobal_deprecated_options{$cmd}{$key}[0]);
}
}
# Use asmcmdparser_parse_issued_command() from the asmcmdparser package to
# parse arguments for internal commands. These arguments are stored in @ARGV
if (!asmcmdparser_parse_issued_command($cmd, $args_ref,\@string))
{
# Print correct command format if syntax error. #
asmcmdpasswd_syntax_error($cmd);
return undef;
}
return 0;
}
########
# NAME
# asmcmdpasswd_syntax_error
#
# DESCRIPTION
# This function prints the correct syntax for a command to STDERR, used
# when there is a syntax error. This function is responsible for
# only ASMCMDPASSWD commands.
#
# PARAMETERS
# cmd (IN) - user-entered command name string.
#
# RETURNS
# 1 if the command belongs to this module; 0 if command not found.
#
# NOTES
# These errors are user-errors and not internal errors. They are of type
# record, not signal.
#
# Functions in this module can call this function directly, without
# calling the asmcmdshare::asmcmdshare_syntax_error equivalent. The
# latter is used only by the asmcmdcore module.
########
sub asmcmdpasswd_syntax_error
{
my ($cmd) = shift;
my ($cmd_syntax); # Correct syntax for $cmd. #
my ($succ) = 0;
#display syntax only for commands in this module.
if (asmcmdpasswd_is_cmd($cmd))
{
$cmd_syntax = asmcmdshare_get_help_syntax($cmd); # Get syntax for $cmd. #
$cmd_syntax = asmcmdshare_trim_str ($cmd_syntax); # Trim blank spaces #
if (defined ($cmd_syntax))
{
asmcmdshare_printstderr 'usage: ' . $cmd_syntax . "\n";
asmcmdshare_printstderr 'help: help ' . $cmd . "\n";
$succ = 1;
}
if ($asmcmdglobal_hash{'mode'} eq 'n')
{
$asmcmdglobal_hash{'e'} = -1;
}
}
return $succ;
}
########
# NAME
# asmcmdpasswd_get_asmcmd_cmds
#
# DESCRIPTION
# This routine constructs a string that contains a list of the names of all
# ASMCMD internal commands and returns this string.
#
# PARAMETERS
# None.
#
# RETURNS
# A string contain a list of the names of all ASMCMD internal commands.
#
# NOTES
# Used by the help command and by the error command when the user enters
# an invalid internal command.
#
# IMPORTANT: the commands names must be preceded by eight (8) spaces of
# indention! This formatting is mandatory.
########
sub asmcmdpasswd_get_asmcmd_cmds
{
return asmcmdshare_filter_invisible_cmds(%asmcmdpasswd_cmds);
}
########
# NAME
# asmcmdpasswd_get_res_list
#
# DESCRIPTION
# To find a list of resources associated with the given password file
#
# PARAMETERS
# $filepath - full path name of password file
#
# RETURNS
# @reslist - list of resource names associated with the given passwd file
#
########
sub asmcmdpasswd_get_res_list
{
my ($filepath) = shift ;
my (@reslist, $hasres, $ret);
my ($cdet);
my ($lib) = $asmcmdglobal_hash{'asmperl'};
undef &ASMCMDkgfPWFileGetRes;
$cdet = DynaLoader::dl_find_symbol($lib, "XS_ASMCMDCLNT_kgfPWFileGetRes");
DynaLoader::dl_install_xsub("ASMCMDkgfPWFileGetRes", $cdet);
($ret, $hasres, @reslist) = ASMCMDkgfPWFileGetRes( $filepath, '');
if ($ret != 0 )
{
asmcmdshare_trace (3,
"NOTE:Get CRS Resource List failed for $filepath err $ret\n",
'n', 'y');
die "Error: GetResource List failed for $filepath ret $ret\n";
}
# if no resources returned make sure the reslist is empty.
if ($hasres == 0 )
{
@reslist = (); # empty the resource list
}
return @reslist;
}
########
# NAME
# asmcmdpasswd_process_pwcreate
#
# DESCRIPTION
# This function processes the asmcmd command pwcreate.
# This function calls orapwd internally to create the pasword file, and uses
# srvctl to update the CRSD resource.
#
# PARAMETERS
# dbh (IN) - initialized database handle, must be non-null.
#
# RETURNS
# Null.
#
# NOTES
# Only asmcmdpasswd_process_cmd() calls this function.
#
########
sub asmcmdpasswd_process_pwcreate
{
my ($dbh) = shift;
my ($format) = undef;
my ($force) = 0;
my (%args);
my ($dbuniquename, $asm);
my ($filepath, $filename, $syspassword);
my (@eargs);
my ($alias, %norm);
my @buf; # Buffer to hold command output.
my $ret = asmcmdpasswd_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
return unless defined ($ret);
$dbuniquename = $args{'dbuniquename'} if defined $args{'dbuniquename'};
$asm = $args{'asm'} if defined $args{'asm'};
$format = $args{'format'} if defined $args{'format'};
$force = 1 if (defined($args{'f'}));
($filepath, $syspassword) = @{$args{'pwcreate'}};
%norm = asmcmdpasswd_normalized_files(\$dbh, undef, $filepath);
if (!$norm{'dest_success'})
{
asmcmdshare_error_msg(9455, undef);
return;
}
$filepath = $norm{'dest_filepath'};
if ($filepath !~ m/^\+/)
{
#Error, password file should be located on a diskgroup
# and the name of the disk group should be preceded by a '+' symbol.
asmcmdshare_error_msg(9455, undef);
return;
}
if (defined($format) && $format !~ m/^12(.2)?$/)
{
asmcmdshare_error_msg(9464, undef);
return;
}
#
# ORAPWD internally checks for resource name associated with given password
# file, and multiple resources using the given password file, or if given
# password file exists, and action based on "force" specified or not.
#
my (@patharr) = ("$ENV{'ORACLE_HOME'}/bin/",
"$ENV{'ORACLE_HOME'}/rdbms/bin/");
my ($opt);
# dbuniquename
$opt = "file=$filepath dbuniquename=$dbuniquename".
" password=$syspassword" if (defined($dbuniquename));
# asm
$opt = "file=$filepath asm=y".
" password=$syspassword" if (defined($asm));
# force option
$opt = $opt . " force=y" if ($force == 1);
# format option
$opt = $opt . " format=$format" if (defined($format));
my $errorflag = 'n';
# send parameter to asmcmdshare_execute_tool to skip tracing
@buf = asmcmdshare_execute_tool ("orapwd", ".exe", $opt, \@patharr, 0, 1);
$errorflag = 'y' if ($@ ne '');
foreach(@buf)
{
chomp $_;
$errorflag = 'y' if ($_ =~ /[A-Z]+-[0-9]+\s*:/); # If an error is detected
asmcmdshare_trace(3, "$_", 'y', 'y') if ($errorflag eq 'y');
}
if ($errorflag eq 'y')
{
asmcmdshare_error_msg(9454, undef);
}
else
{
asmcmdshare_trace(3, "The Password file was created successfuly by " .
"ASMCMD through an internal call to orapwd.",'y','n');
}
return;
}
########
# NAME
# asmcmdpasswd_process_pwcopy
#
# DESCRIPTION
# This top-level routine processes the pwcopy command.
# This function calls the core function of the ASMCMD cp command
# to copy the password file from the source to the destination.
# It then uses srvctl to update the CRSD resource with the new location of
# the password if and only if the user specifies either the '--asm' or
# '--dbuniquename' option.
#
# PARAMETERS
# dbh (IN) - initialize database handle, must be non-null.
#
# RETURNS
# Null.
#
# NOTES
# Only asmcmdpasswd_process_cmd() calls this routine.
########
sub asmcmdpasswd_process_pwcopy
{
my ($dbh) = shift; # local auto-variables #
my (%args); # cmd args #
my (@eargs);
my ($ret);
my ($copy_success_hash); # A reference to a hash of src and dest files #
# that were successfully copied #
my ($copy_success) = 0; # Flag to indicate whether the copy was #
# successful or not #
my (%norm); # See asmcmdshare_normalize_path() return value comments. #
my ($force) = 0;
my ($dbuniquename) = undef;
my ($asm) = undef;
my ($src_filepath, $dest_filepath);
my ($passwordfile_loc) = "";
$ret = asmcmdbase_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
return unless defined ($ret);
# check for the force option
$force = 1 if (defined($args{'f'}));
# check for the dbuniquename option.
if (defined($args{'asm'}))
{
$dbuniquename = "ASM";
$asm = 1;
}
elsif (defined($args{'dbuniquename'}))
{
$dbuniquename = $args{'dbuniquename'};
}
($src_filepath, $dest_filepath) = @{$args{'pwcopy'}};
%norm = asmcmdpasswd_normalized_files(\$dbh, $src_filepath, $dest_filepath);
if (!$norm{'src_success'} || !$norm{'dest_success'})
{
return;
}
$src_filepath = $norm{'src_filepath'};
$dest_filepath = $norm{'dest_filepath'};
###### -If OS -> OS- ######
if ($src_filepath !~ m/^\+/ && $dest_filepath !~ m/^\+/)
{
#Error out, OS -> OS not supported
asmcmdshare_error_msg(9458, undef);
return;
}
###### -If DG -> same DG- ######
if ($src_filepath =~ m/^\+/ && $dest_filepath =~ m/^\+/ &&
$norm{'src_DG'} == $norm{'dest_DG'})
{
#Error out, DG -> same DG not supported
asmcmdshare_error_msg(9459, undef);
return;
}
###### -If destination is OS CRS Resource cannot be updated ######
###### Only if $asm or $dbuniquename specified ######
if ((defined($asm) || defined($dbuniquename)) && ($dest_filepath !~ m/^\+/))
{
asmcmdshare_error_msg (9456, undef);
return;
}
if (defined($dbuniquename) || defined($asm))
{
$ret = asmcmdpasswd_get_pwfile ($asm, $dbuniquename, \$passwordfile_loc);
if ($ret && ($passwordfile_loc ne "" ))
{
# The resource has already a password file associated with it.
if ($force == 0)
{
push (@eargs, $passwordfile_loc);
push (@eargs, 'asm') if defined($asm);
push (@eargs, $dbuniquename) if defined($dbuniquename);
asmcmdshare_error_msg(8028, \@eargs);
return;
}
else
{
$ret = asmcmdpasswd_set_pwfile ($asm, $dbuniquename, "");
}
}
}
###### -Copy the password file- ######
${$args{'pwcopy'}}[0] = $src_filepath;
${$args{'pwcopy'}}[1] = $dest_filepath;
# copy the arguments for pwcopy so asmcmdbase_cp_core will process it
# correctly.
@{$args{'cp'}} = @{$args{'pwcopy'}};
# set the dbuniquename, if specified
if (defined($dbuniquename))
{
$asmcmdglobal_hash{'dbuniquename'} = $dbuniquename;
asmcmdshare_trace(3, "dbuniquename is $asmcmdglobal_hash{'dbuniquename'}",
'y', 'n');
}
# executes the core code of ASMCMD cp command to copy the password file to
# the destination
$copy_success_hash = asmcmdbase_cp_core($dbh, %args);
while ( my ($key, $value) = each(%$copy_success_hash) )
{
# get the absolute path of src file and dest file
$src_filepath = $key;
$dest_filepath = $value;
$copy_success++;
}
###### -Check that copy succeeded- ######
if (!$copy_success)
{
# Proceed no further. Error message would have been displayed at the cp
# level.
return;
}
asmcmdshare_trace(3, "The password file $src_filepath was copied " .
"successfully by ASMCMD to $dest_filepath", 'y', 'n');
###### -Update the CRS resource if necessary- ######
# Attempt to update the CRS resource with the new location of the password
# file if and only if the user specifies either the '--asm' or
# '--dbuniquename' option, and the destination file is on an ASM DG.
if ((defined $args{'asm'} || defined $args{'dbuniquename'}) &&
$copy_success == 1)
{
# The dest_filepath here will be on DG only.
asmcmdpasswd_set_pwfile ($asm, $dbuniquename, $dest_filepath);
}
return;
}
########
# NAME
# asmcmdpasswd_process_pwmove
#
# DESCRIPTION
# This top-level routine processes the pwmove command.
# This function calls the core function of the ASMCMD cp command
# to copy the password file from the source to the destination.
# Then deletes the original file from the source path.
# It then uses srvctl to update the CRSD resource with the new location of
# the password file.
#
# PARAMETERS
# dbh (IN) - initialize database handle, must be non-null.
#
# RETURNS
# Null.
#
# NOTES
# Only asmcmdpasswd_process_cmd() calls this routine.
########
sub asmcmdpasswd_process_pwmove
{
my ($dbh) = shift; # local auto-variables #
my (%args); # cmd args #
my (@eargs);
my ($ret);
my @buf = ();
my ($copy_success_hash); # A reference to a hash of src and dest files #
# that were successfully copied #
my ($copy_success) = 0; # Flag to indicate whether the copy was #
# successful or not #
my (%norm); # See asmcmdshare_normalize_path() return value comments. #
my ($alias_path); # User-entered raw path for deletion. #
my ($alias_name); # Alias name of a path. #
my ($is_dir); # Flag: 'Y' if alias is a directory; 'N' otherwise. #
my ($gnum); # Group number. #
my ($gname); # Group name. #
my ($par_id); # Parent ID of an alias. #
my ($spprserr) = 0; # Whether to suppress errors on normalization. #
my ($i); # Iteration variable for for() loops. #
my (@entries);
my ($dbuniquename) = undef;
my ($asm) = undef;
my ($force) = 0 ;
my ($src_filepath, $dest_filepath);
my ($passwordfile_loc);
my ($sqlstmt, $sth, $row);
my (@src_aliases) = ();
my (@reslist);
# get option parameters
$ret = asmcmdbase_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
return unless defined ($ret);
$dbuniquename = $args{'dbuniquename'} if defined $args{'dbuniquename'};
$asm = 1 if defined $args{'asm'};
$force = 1 if (defined ($args{'f'}));
($src_filepath, $dest_filepath) = @{$args{'pwmove'}};
if (defined($dbuniquename) || defined ($asm) )
{
$ret = asmcmdpasswd_get_pwfile ($asm, $dbuniquename, \$passwordfile_loc);
if ((defined ($ret) && ($ret == 1)) &&
(defined ($passwordfile_loc) && (length($passwordfile_loc) > 0 )) &&
($force == 0 ))
{
push (@eargs, $passwordfile_loc);
push (@eargs, 'asm') if defined($asm);
push (@eargs, $dbuniquename) if defined($dbuniquename);
asmcmdshare_error_msg (8028, \@eargs);
return;
}
elsif ($ret == 0)
{
return;
}
}
%norm = asmcmdpasswd_normalized_files(\$dbh, $src_filepath, $dest_filepath);
# If normalization failed, then return. Errors would have been printed by
# normalization routine.
if (!$norm{'src_success'} || !$norm{'dest_success'})
{
return;
}
$src_filepath = $norm{'src_filepath'};
$dest_filepath = $norm{'dest_filepath'};
######- Find all aliases for this src file -######
if ($norm{'src_onDG'})
{
$src_filepath =~ m/[\\\/]+([^\\\/]+)$/;
$alias_name = $1;
my @info = ();
my ($file_number);
#retreive the unique file number given the parent_id,reference_id,
#group_number and filename
asmcmdshare_get_subdirs($dbh, \@info, undef, $norm{'src_DG'},
$norm{'src_reference_index'},
$norm{'parent_index'}, $alias_name,
undef, 0, 0);
$file_number = $info[0]->{'file_number'};
# Find the SYS alias.
$alias_name = asmcmdbase_get_alias_path($dbh, $norm{'src_DG'},
$file_number, 'Y');
push(@src_aliases, $alias_name);
# Find the USER created alias.
$alias_name = asmcmdbase_get_alias_path($dbh, $norm{'src_DG'},
$file_number, 'N');
push(@src_aliases, $alias_name);
}
###### -If OS -> OS- ######
if ($src_filepath !~ m/^\+/ && $dest_filepath !~ m/^\+/)
{
#Error out, OS -> OS not supported
asmcmdshare_error_msg(9458, undef);
return;
}
###### -If DG -> same DG- ######
if ($src_filepath =~ m/^\+/ && $dest_filepath =~ m/^\+/ &&
$norm{'src_DG'} == $norm{'dest_DG'})
{
#Error out, DG -> same DG not supported
asmcmdshare_error_msg(9459, undef);
return;
}
###### If the destination file is on OS, res can not be updated #######
###### Only if $asm or $dbuniquename specified #######
if ((defined($asm) || defined($dbuniquename)) && ($dest_filepath !~ m/^\+/))
{
asmcmdshare_error_msg (9456, undef);
return;
}
# get the resource(s) associated with given source password file name
@reslist = asmcmdpasswd_get_res_list ($src_filepath);
# if shared by more than one resource - can't move, bail out.
if ($#reslist > 1)
{
@eargs = ($src_filepath);
asmcmdshare_error_msg (8026, \@eargs);
return;
}
# if only one resource and not matching given res - can't move, bail out
if (($#reslist == 1) &&
!((defined($asm) && ($reslist[0] eq "ora.asm")) ||
(defined($dbuniquename) && ($reslist[0] eq "db.$dbuniquename.db"))))
{
@eargs = ($src_filepath);
asmcmdshare_error_msg (8026, \@eargs);
return;
}
###### -Copy the password file- ######
${$args{'pwmove'}}[0] = $src_filepath;
${$args{'pwmove'}}[1] = $dest_filepath;
# copy the arguments for pwmove so asmcmdbase_cp_core will process it
# correctly.
@{$args{'cp'}} = @{$args{'pwmove'}};
# executes the core code of ASMCMD cp command to copy the password file to
# the destination.
$copy_success_hash = asmcmdbase_cp_core($dbh, %args);
while ( my ($key, $value) = each(%$copy_success_hash) )
{
# get the absolute path of src file and dest file
$src_filepath = $key;
$dest_filepath = $value;
$copy_success++;
}
###### -Check that copy succeeded- ######
if (!$copy_success)
{
# Proceed no further. Error message would have been displayed at the copy
# level.
return;
}
# Reconnect to instance since dbh handle would become useless after the copy
asmcmdbase_disconnect($dbh) if defined ($dbh);
$dbh = asmcmdbase_connect(undef);
###### -Delete the src file- ######
if ($src_filepath =~ m/^\+/) # If the src file was on a DG, use sql query to
# drop the file
{
$alias_path = $src_filepath;
%norm = asmcmdshare_normalize_path($dbh, $alias_path, $spprserr, \$ret);
# Error if normalization failed/ password file does not exist
if ($ret != 0)
{
@eargs = ($alias_path);
asmcmdshare_error_msg(9452, \@eargs);
return;
}
# Remove one entry at a time, if $alias_path contains '*' and has multiple
# password file matches.
for ($i = 0; $i < @{ $norm{'path'} }; $i++)
{
$alias_name = $alias_path = $norm{'path'}->[$i];
$alias_name =~ s,.*/([^/]+)$,$1,; # Get last level of path for name.#
$par_id = $norm{'par_id'}->[$i];
$gnum = $norm{'gnum'}->[$i];
# If parent index is -1, then the directory must be a diskgroup or '+';
# thus we cannot remove it.
if ($par_id != -1)
{
asmcmdshare_get_subdirs($dbh, \@entries, undef, $gnum, undef, $par_id,
$alias_name, undef, 0, 0);
$is_dir = $entries[$i]->{'alias_directory'};
$gname = asmcmdshare_get_gname_from_gnum ($dbh, $gnum);
# Run SQL to remove an entry.
asmcmdbase_rm_sql($dbh, $gname, $alias_path, $is_dir);
}
}
}
else # If the src file is on OS filesystem, use system command to remove it
{
$ret = 0;
eval
{
$ret = unlink("$src_filepath");
};
if ($@ || !defined($ret) || !$ret)
{
# Warn, no need to error out
asmcmdshare_print("Couldn't delete $src_filepath from OS filesystem\n");
}
}
asmcmdshare_trace(3, "The password file $src_filepath was moved " .
"successfuly by ASMCMD to $dest_filepath", 'y', 'n');
####### -Now update the CRS resource if necessary- ######
# Attempt to update the CRS resource with the new location of the password
# file if and only if the user specifies either the '--asm' or
# '--dbuniquename' option, and the destination file is on an ASM DG.
if ((defined $args{'asm'} || defined $args{'dbuniquename'}) &&
$copy_success == 1)
{
# Remove the original resource value.
asmcmdpasswd_set_pwfile ($asm, $dbuniquename, "");
# $dest_filepath will be on DG here.
asmcmdpasswd_set_pwfile ($asm, $dbuniquename, $dest_filepath);
}
return;
}
########
# NAME
# asmcmdpasswd_process_pwdelete
#
# DESCRIPTION
# This top-level routine processes the pwdelete command.
# This function removes the password file from the specified location
# and updates the CRSD resource.
#
# PARAMETERS
# dbh (IN) - initialize database handle, must be non-null.
#
# RETURNS
# Null.
#
# NOTES
# Only asmcmdpasswd_process_cmd() calls this routine.
########
sub asmcmdpasswd_process_pwdelete
{
my ($dbh) = shift;
my (%args); # Argument hash used by asmcmdparser. #
my (%norm); # See asmcmdshare_normalize_path() return value comments. #
my ($ret); # asmcmdbase_parse_int_args() return value. #
my ($dbuniquename);
my ($asm);
my ($force) = 0 ;
my ($alias_name, $filepath, $filetype);
my @buf; # Buffer to hold command output. #
my (@eargs);
my (@reslist);
$ret = asmcmdpasswd_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
return unless defined ($ret);
$dbuniquename = $args{'dbuniquename'} if defined $args{'dbuniquename'};
$asm = 1 if defined $args{'asm'};
$force = 1 if defined ($args{'f'});
($filepath) = @{$args{'pwdelete'}} if defined $args{'pwdelete'};
if (defined($args{'dbuniquename'}) || defined ($args{'asm'}))
{
$ret = asmcmdpasswd_get_pwfile ($asm, $dbuniquename, \$filepath);
}
elsif (defined $filepath)
{
%norm = asmcmdpasswd_normalized_files(\$dbh, $filepath, undef);
if (!$norm{'src_success'})
{
return;
}
$filepath = $norm{'src_filepath'};
}
#
# ORAPWD utility handles the clearing of resource name of given password
# and checking if more than one resources are using sceanrio.
#
######- Find all aliases for this src file -######
$filepath = $norm{'src_filepath'};
###### -Delete the file- ######
if (defined $args{'dbuniquename'} || defined $args{'asm'} ||
(@{$args{'pwdelete'}} && $filepath =~ /^\+/))
# If the src file was on a DG, use orapwd to drop the file
{
my (@patharr) = ("$ENV{'ORACLE_HOME'}/bin/",
"$ENV{'ORACLE_HOME'}/rdbms/bin/");
my $opt;
#dbuniquename
$opt = "delete=y dbuniquename=$dbuniquename" if (defined($dbuniquename));
#asm
$opt = "delete=y asm=y" if (defined($asm));
# if file name is provided
$opt = "delete=y file=$filepath" if defined($filepath);
# force
$opt = "$opt". " force=y" if ($force == 1);
my $errorflag = 'n';
@buf = asmcmdshare_execute_tool ("orapwd", ".exe", $opt, \@patharr);
$errorflag = 'y' if ($@ ne '');
foreach(@buf)
{
chomp $_;
$errorflag = 'y' if ($_ =~ /[A-Z]+-[0-9]+\s*:/); # If an error is found
asmcmdshare_trace(3, "$_", 'y', 'y') if ($errorflag eq 'y');
}
if ($errorflag eq 'y')
{
asmcmdshare_error_msg(9462, undef);
}
else
{
asmcmdshare_trace(3, "The Password file was deleted successfuly by " .
"ASMCMD through an internal call to orapwd.",
'y', 'n');
}
}
else # If the src file is on OS filesystem, use system command to remove it
{
$ret = 0;
eval
{
$ret = unlink("$filepath");
};
if ($@ || !defined($ret) || !$ret)
{
# Warn, no need to error out
asmcmdshare_print("Couldn't delete $filepath from OS filesystem\n");
return;
}
else
{
asmcmdshare_trace(3, "The password file $filepath was deleted " .
"successfuly by ASMCMD", 'y', 'n');
}
}
return;
}
########
# NAME
# asmcmdpasswd_process_pwset
#
# DESCRIPTION
# This top-level routine processes the pwset command.
# This function sets the location of the password file associated with and
# ASM or a DB instance on the CRS resource.
#
# PARAMETERS
# dbh (IN) - initialize database handle, must be non-null.
#
# RETURNS
# Null.
#
# NOTES
# Only asmcmdpasswd_process_cmd() calls this routine.
########
sub asmcmdpasswd_process_pwset
{
my $dbh = shift;
my %args; # Argument hash used by asmcmdparser. #
my $ret; # asmcmdbase_parse_int_args() return value. #
my @eargs;
my $dbuniquename;
my $asm;
my $force = 0 ;
my %norm;
my $srvctl;
my $srvctlcommand; # For executing the srvctl command. #
my @buf = (); # Buffer to hold command output. #
my @reslist;
my $filepath;
$ret = asmcmdpasswd_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
return unless defined ($ret);
$dbuniquename = "";
$dbuniquename = $args{'dbuniquename'} if defined $args{'dbuniquename'};
$asm = 1 if defined $args{'asm'};
$force = 1 if defined $args{'f'};
if (defined($dbuniquename) || defined ($asm))
{
$ret = asmcmdpasswd_get_pwfile ($asm, $dbuniquename, \$filepath);
if (defined($ret) && ($ret == 1) &&
($filepath ne "" && $filepath ne $args{'pwset'}))
{
if ($force == 0 )
{
push (@eargs, $filepath);
push (@eargs, 'asm') if defined ($asm);
push (@eargs, $dbuniquename) if defined ($dbuniquename);
# ASMCMD-8028 "Password file '%s' is associated with '%s' already. Use
# the force option."
asmcmdshare_error_msg (8028, \@eargs);
return ;
}
}
}
($filepath) = @{$args{'pwset'}};
if (!defined $filepath || $filepath eq '""' || $filepath eq "''")
{
$filepath = "";
}
if ($filepath ne "")
{
%norm = asmcmdpasswd_normalized_files(\$dbh, $filepath, undef);
if (!$norm{'src_success'})
{
return;
}
$filepath = $norm{'src_filepath'};
if (!($filepath =~ m/^\+/))
{
# ASMCMD-9456 "password file should be located on an ASM disk group"
asmcmdshare_error_msg(9456, undef);
return;
}
# Bug21159907: Check if the password file has been already set for another
# resource, but only if the force option is not set.
@reslist = asmcmdpasswd_get_res_list($filepath);
if (scalar @reslist > 0 && !$force)
{
@eargs = $filepath;
# ASMCMD-8026 Password file '%s' is in use. Use the force option.
asmcmdshare_error_msg(8026, \@eargs);
return;
}
}
asmcmdpasswd_set_pwfile($asm, $dbuniquename, $filepath);
return;
}
########
# NAME
# asmcmdpasswd_process_pwget
#
# DESCRIPTION
# This top-level routine processes the pwget command.
# This function retrieves the location of the password file associated with
# and ASM or a DB instance from the CRS resource.
#
# PARAMETERS
# dbh (IN) - initialize database handle, must be non-null.
#
# RETURNS
# Null.
#
# NOTES
# Only asmcmdpasswd_process_cmd() calls this routine.
########
sub asmcmdpasswd_process_pwget
{
my ($dbh) = shift;
my (%args); # Argument hash used by asmcmdparser. #
my ($ret); # asmcmdbase_parse_int_args() return value. #
my (@eargs);
my ($dbuniquename,$asm);
my ($passwordfile_loc) = "";
$ret = asmcmdpasswd_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
return unless defined ($ret);
$dbuniquename = $args{'dbuniquename'} if defined $args{'dbuniquename'};
$asm = 1 if defined $args{'asm'};
$ret = asmcmdpasswd_get_pwfile($asm, $dbuniquename, \$passwordfile_loc);
if ($ret)
{
if ($passwordfile_loc eq "")
{
if ($asm)
{
asmcmdshare_print("Password file location has not been set for " .
"ASM instance\n");
}
else
{
asmcmdshare_print("Password file location has not been set for " .
"DB instance\n");
}
}
else
{
asmcmdshare_print("$passwordfile_loc\n");
}
}
return;
}
########
# NAME
# asmcmdpasswd_set_pwfile
#
# DESCRIPTION
# This function sets the password file location on the corresponding CRS
# resource.
#
# PARAMETERS
# asm (IN) - Whether an ASM or a DB resource is to be updated
# dbuniquename (IN) - The dbuniquename, used only if asm is 0
# passwordfile_loc (IN) - The new location of the password file
# to be set on CRS.
#
# RETURNS
# 0 on failure
# 1 on success
#
# NOTES
# Assumes $passwordfile_loc is a valid path and the file is on DG
#
########
sub asmcmdpasswd_set_pwfile
{
my ($asm) = shift;
my ($dbuniquename) = shift;
my ($passwordfile_loc) = shift;
my ($ret) = 0;
my ($srvctl, $srvctlcommand);
my (@eargs) = ();
my ($errorflag) = 'n';
my (@buf) = ();
$srvctl = "$ENV{'ORACLE_HOME'}/bin/srvctl";
#Path in Win is ORACLE_HOME/bin/srvctl.bat
$srvctl .= ".bat" if ($^O =~ /win/i);
# Make sure the srvctl binary exists and can be executed.
if (! -x $srvctl)
{
#If not, try at a second locaction.
$srvctl = "$ENV{'ORACLE_HOME'}/srvm/bin/srvctl";
#path in Win is ORACLE_HOME/bin/srvctl.bat
$srvctl .= ".bat" if ($^O =~ /win/i);
if (! -x $srvctl)
{
@eargs = ($srvctl);
asmcmdshare_error_msg(8316, \@eargs);
return $ret;
}
}
#untaint srvctl
$srvctl =~ /([^\n^\r^\t]+)/;
$srvctl = $1;
if ($asm)
{
$srvctlcommand = "$srvctl modify asm -pwfile $passwordfile_loc";
}
else
{
$srvctlcommand = "$srvctl modify database " .
"-db $dbuniquename " .
"-pwfile $passwordfile_loc";
}
if (!asmcmdshare_runcmd("$srvctlcommand", \@buf, 1, 1))
{
# command succeeded
foreach(@buf)
{
chomp $_;
$errorflag = 'y' if ($_ =~ /[A-Z]+-[0-9]+\s*:/);# If an error is detected
asmcmdshare_trace(3, "$_", 'y', 'y') if ($errorflag eq 'y');
}
}
else
{
$errorflag = 'y';
}
if ($errorflag eq 'y')
{
asmcmdshare_error_msg(9453, undef);
return 0;
}
return 1;
}
########
# NAME
# asmcmdpasswd_get_pwfile
#
# DESCRIPTION
# This function retrieves the password file location from the corresponding
# CRS resource.
#
# PARAMETERS
# asm (IN) - Whether the instance is an ASM or a DB
# dbuniquename (IN) - The dbuniquename, used only if asm is 0
# pfile_loc_ref (IN) - Reference to the variable where the retrieved path
# is to be stored.
#
# RETURNS
# 0 on failure
# 1 on success
#
# NOTES
#
########
sub asmcmdpasswd_get_pwfile
{
my $asm = shift;
my $dbuniquename = shift;
my $pfile_loc_ref = shift;
my $srvctl;
my $srvctlcommand;
my $errorflag = 'n';
my @eargs = ();
my @buf = ();
my $ret = 0;
$srvctl = "$ENV{'ORACLE_HOME'}/bin/srvctl";
#Path in Win is ORACLE_HOME/bin/srvctl.bat
$srvctl .= ".bat" if ($^O =~ /win/i);
# Make sure the srvctl binary exists and can be executed.
if (! -x $srvctl)
{
#If not, try at a second locaction.
$srvctl = "$ENV{'ORACLE_HOME'}/srvm/bin/srvctl";
#path in Win is ORACLE_HOME/bin/srvctl.bat
$srvctl .= ".bat" if ($^O =~ /win/i);
if (! -x $srvctl)
{
@eargs = ($srvctl);
asmcmdshare_error_msg(8316, \@eargs);
return $ret;
}
}
#untaint srvctl
$srvctl =~ /([^\n^\r^\t]+)/;
$srvctl = $1;
if ($asm)
{
$srvctlcommand = "$srvctl config asm";
}
else
{
$srvctlcommand = "$srvctl config database -db $dbuniquename";
}
if (asmcmdshare_runcmd("$srvctlcommand", \@buf, 1, 1))
{
$errorflag = 'y';
}
foreach (@buf)
{
chomp $_;
$errorflag = 'y' if ($_ =~ /[A-Z]+-[0-9]+\s*:/ && # If an error is detected
$_ !~ /PRCA-1032 : ASM listener LISTENER does not exist/);
asmcmdshare_trace(3, "$_", 'y', 'y') if ($errorflag eq 'y');
# Bug 24308847: Add the anchor for start of line to differentiate the lines
# containing Password file and Backup of Password file when parsing output
if ($errorflag eq 'n' && $_ =~ /^Password file: (.*)$/)
{
if (defined $1)
{
$$pfile_loc_ref = $1;
}
else
{
$$pfile_loc_ref = "";
}
$ret = 1;
}
}
if ($errorflag eq 'y')
{
asmcmdshare_error_msg(9457, undef);
}
else
{
$ret = 1;
}
return $ret;
}
########
# NAME
# asmcmdpasswd_file_type
#
# DESCRIPTION
# This function retrieves the file type for a given file
#
# PARAMETERS
# dbh_ref (IN) - reference to the dbh handle
# fileName (IN) - The complete path to the file for which file type
# is to be found out
# fileType_ref (IN) - Reference to the variable where the retrived file
# type is to be stored.
#
# RETURNS
# 0 on failure
# 1 on success
#
# NOTES
# Assumes the path is a complete path and file exists.
#
########
sub asmcmdpasswd_file_type
{
my ($fileName, $fileType_ref, $fileSz, $blkSz);
my ($stmt, $dbh, $dbh_ref, $ret);
my ($return_status) = 0;
$dbh_ref = shift;
$dbh = $$dbh_ref;
$fileName = shift;
$fileType_ref = shift;
# get file information, block size, file size, file type
$stmt = $dbh->prepare(q{
begin
dbms_diskgroup.getfileattr(:fileName, :fileType, :fileSz, :blkSz);
end;
});
# Bind input parameters #
$stmt->bind_param( ":fileName", $fileName );
# Bind ouput params #
$stmt->bind_param_inout( ":fileType", $fileType_ref, $PLSQL_NUMBER);
$stmt->bind_param_inout( ":fileSz", \$fileSz, $PLSQL_NUMBER);
$stmt->bind_param_inout( ":blkSz", \$blkSz, $PLSQL_NUMBER);
$ret = $stmt->execute();
if (!defined ($ret) && ($asmcmdglobal_hash{'mode'} eq 'n'))
{
$asmcmdglobal_hash{'e'} = -1;
}
if (!defined $$fileType_ref || $$fileType_ref < 1 )
{
my (@eargs) = ($fileName);
asmcmdshare_error_msg(8012, \@eargs);
asmcmdshare_trace(1, $DBI::errstr, 'y', 'y') unless defined ($ret);
asmcmdshare_error_msg(9461, \@eargs);
}
else
{
# Call was a success;
$return_status = 1;
}
# reconnect
asmcmdbase_disconnect($dbh) if defined ($dbh);
#undef since we connect to local asm instance
$$dbh_ref = asmcmdbase_connect(undef);
return $return_status;
}
########
# NAME
# asmcmdpasswd_normalized_files
#
# DESCRIPTION
# This function returns the full expanded path for a given destination,
# OS or on on DG.
#
# PARAMETERS
# dbh_ref (IN/OUT) - Reference to initialized database handle, must be
# non-null.
# src_filepath (IN) - src file path to be normalized
# dest_filepath(IN) - the dest file path passed to the command by user.
# Can be a directory path or partial path or which
# may or may not contain the target filename.
#
# RETURNS
# %return_hash (OUT) - Hash of values
# $return_hash{'src_filepath'} = normalized $src_filepath
# $return_hash{'src_success'} = status of normalization for src file
# $return_hash{'src_exists'} = whether the src file exists
# $return_hash{'src_onDG'} = whether the src file is on DG or on OS
# $return_hash{'src_DG'} = if the src file is on DG, the DG num
# $return_hash{'dest_filepath'} = normalized $dest_filepath;
# $return_hash{'dest_success'} = status of normalization for dest file
# $return_hash{'dest_exists'} = whether the dest directorystructure exists
# $return_hash{'dest_onDG'} = whether the dest file is on DG or on OS
# $return_hash{'dest_DG'} = if the dest file is on DG, the DG num
#
# NOTES
# Assumes the reference to dbh handle is a valid and non-null
#
########
# Assumes the src_fileapth is a full path containing the filename at the end
sub asmcmdpasswd_normalized_files
{
my ($dbh_ref) = shift;
my ($src_filepath) = shift;
my ($dest_filepath) = shift;
my ($src_filename, $src_filetype, $ret);
my ($dir_path, $filename);
my (@eargs, @paths, @ref_ids, @par_ids, @entry_list, @dg_nums, $name);
my ($dbh) = $$dbh_ref;
my %norm;
my %return_hash;
$return_hash{'src_reference_index'} = -1;
$return_hash{'src_parent_index'} = -1;
$return_hash{'src_filepath'} = $src_filepath;
$return_hash{'src_success'} = 0;
$return_hash{'src_exists'} = 0;
$return_hash{'src_onDG'} = 0;
$return_hash{'src_DG'} = -1;
$return_hash{'dest_filepath'} = $dest_filepath;
$return_hash{'dest_success'} = 0;
$return_hash{'dest_exists'} = 0; # The directory structure exists
$return_hash{'dest_onDG'} = 0;
$return_hash{'dest_DG'} = -1;
if (defined $src_filepath && $src_filepath ne "")
{
###### -Normalize file- ######
# criteria: if it is an OS file, has to be full path,
# otherwise it will be treated as a relative path
# in the ASM context
# if path doesn't start with '/', then it is an ASM relative path
# every OS path must be absolute.
if ( ($src_filepath !~ /^[a-z]:/i) && ($src_filepath !~ m'^[/\\\\]'))
{
$return_hash{'src_onDG'} = 1;
# ASM file case
# if source file name is not an an absolute OS path, assume it is an ASM
# DG path and complete it
%norm = asmcmdshare_normalize_path($$dbh_ref, $src_filepath, 0, \$ret);
if ( $ret != 0 )
{
@eargs = ($src_filepath);
asmcmdshare_error_msg(9452, \@eargs);
}
else
{
$return_hash{'src_exists'} = 1;
$return_hash{'src_filepath'} = $norm{'path'}->[0];
$return_hash{'src_DG'} = $norm{'gnum'}->[0];
$return_hash{'src_parent_index'} = $norm{'par_id'}->[0];
$return_hash{'src_reference_index'} = $norm{'ref_id'}->[0];
###### -Check that the file is a password file- ######
if (asmcmdpasswd_file_type($dbh_ref, $norm{'path'}->[0],
\$src_filetype))
{
if ($src_filetype == $PLSQL_PWFILE)
{
@return_hash{keys %norm} = values %norm;
$return_hash{'src_success'} = 1;
}
else
{
# pw* commands can only be used to operate on password file
# commands
@eargs = ($asmcmdglobal_hash{'cmd'});
asmcmdshare_error_msg(9460, \@eargs);
}
}
}
}
else
{
# Assume the path is a full path to a file on the OS filesystem
$return_hash{'src_onDG'} = 0;
# If the path is simply a directory
if (-d $src_filepath)
{
@eargs = ($src_filepath);
asmcmdshare_error_msg(9452, \@eargs);
$return_hash{'src_exists'} = 1;
$return_hash{'src_success'}= 0;
}
# If the path is an existing filename
elsif (-e $src_filepath)
{
$return_hash{'src_exists'} = 1;
$return_hash{'src_success'}= 1;
}
# Else, the path is invalid
else
{
@eargs = ($src_filepath);
asmcmdshare_error_msg(9452, \@eargs);
$return_hash{'src_exists'} = 0;
$return_hash{'src_success'}= 0;
}
}
return %return_hash if (!$return_hash{'src_success'});
}
if (defined $dest_filepath && $dest_filepath ne "")
{
$src_filepath = $return_hash{'src_filepath'};
$src_filepath = "" if (!defined $src_filepath);
$src_filepath =~ m/[\\\/]+([^\\\/]+)$/;
$src_filename = $1;
###### -Normalize destination file- ######
if ( ($dest_filepath !~ /^[a-z]:/i) && ($dest_filepath !~ m'^[/\\\\]'))
{
$return_hash{'dest_onDG'} = 1;
$return_hash{'dest_DG'} = -1;
# Make the path absolute.
$dest_filepath = asmcmdshare_make_absolute($dest_filepath);
# Separate out the filename,if any, and the directory path
$filename = "";
$dir_path = $dest_filepath;
# If the $dest_filepath is of the form +diskgroup/path/to/filename
if ($dest_filepath =~ m/[\\\/]+([^\\\/]+)$/)
{
$filename = $1 if defined $1;
if ($filename ne "")
{
$dest_filepath =~ m/(.*)$filename$/;
$dir_path = $1;
}
}
# ASM file case
# if source file name is not an an absolute OS path nor ASM path,
# assume it is ASM and complete it
%norm = asmcmdshare_normalize_path($$dbh_ref, $dest_filepath, 1, \$ret);
if ( $ret == 0 )
{
$dest_filepath = $norm{'path'}->[0];
@paths = @{ $norm{'path'} };
@ref_ids = @{ $norm{'ref_id'} };
@par_ids = @{ $norm{'par_id'} };
@dg_nums = @{ $norm{'gnum'} };
$name = $paths[0];
$name =~ s,.*/(.*)$,$1,;
asmcmdshare_get_subdirs($$dbh_ref, \@entry_list, undef, $dg_nums[0],
$ref_ids[0], $par_ids[0], $name, undef, 0, 1);
if ( ($ref_ids[0] == $dg_nums[0] << 24 ) ||
$entry_list[0]->{'alias_directory'} eq 'Y')
{
if ($filename eq "")
{
if (defined $src_filename)
{
$norm{'path'}->[0] = $norm{'path'}->[0] . '/' . $src_filename;
}
else
{
$norm{'path'}->[0] = $norm{'path'}->[0] . '/';
}
}
else
{
$norm{'path'}->[0] = $norm{'path'}->[0] . '/' . $filename;
}
$return_hash{'dest_exists'} = 1;
$return_hash{'dest_filepath'} = $norm{'path'}->[0];
$return_hash{'dest_success'} = 1;
$return_hash{'dest_DG'} = $norm{'gnum'}->[0];
}
elsif ( $entry_list[0]->{'alias_directory'} eq 'N' )
{
$return_hash{'dest_exists'} = 1;
$return_hash{'dest_filepath'} = $norm{'path'}->[0];
$return_hash{'dest_success'} = 1;
$return_hash{'dest_DG'} = $norm{'gnum'}->[0];
}
else
{
$return_hash{'dest_exists'} = 0;
$return_hash{'dest_success'} = 0;
@eargs = ($norm{'path'}->[0]);
asmcmdshare_error_msg(8014, \@eargs);
}
}
else
{
$return_hash{'dest_exists'} = 0;
$return_hash{'dest_success'} = 1;
# given destination file does not exist, but is not an error
# in case of pwcreate command.
}
asmcmdbase_disconnect($$dbh_ref) if defined ($$dbh_ref);
$$dbh_ref = asmcmdbase_connect(undef);
}
# Path is an OS filesystem path
else
{
$return_hash{'dest_onDG'} = 0;
# If the path is a directory
if ( -d $dest_filepath )
{
# Remove trailing '/' or '\'
$dest_filepath =~ s/[\/\\]$//;
if (defined $src_filename)
{
$return_hash{'dest_filepath'} = $dest_filepath . '/'. $src_filename;
if ( -e $return_hash{'dest_filepath'})
{
$return_hash{'dest_exists'} = 1;
$return_hash{'dest_success'} = 1;
}
}
else
{
$return_hash{'dest_filepath'} = $dest_filepath . '/';
}
$return_hash{'dest_exists'} = 1;
$return_hash{'dest_success'} = 1;
}
# If the path is a file
elsif ( -e $dest_filepath )
{
$return_hash{'dest_filepath'} = $dest_filepath;
$return_hash{'dest_exists'} = 1;
$return_hash{'dest_success'} = 1;
}
else #$dest_filepath is NOT a dir and $dest_filepath does not exist
{
$filename = "";
# Extract the filename from the path - everything after the last
# '\' or '/'. Store it in $filename, if there is any filename.
$dest_filepath =~ m/[\\\/]+([^\\\/]+)$/;
$filename = $1 if defined $1;
if ($filename ne "")
{
# Extract the parent directory path
$dest_filepath =~ m/(.*)$filename$/;
$dir_path = $1;
# If the parent directory doesn't exist, then path is invalid
if (-d $dir_path)
{
$return_hash{'dest_success'} = 1;
$return_hash{'dest_exists'} = 1;
$return_hash{'dest_filepath'}= $dest_filepath
}
}
@eargs = ($dest_filepath);
asmcmdshare_error_msg(8005, \@eargs)
if $return_hash{'dest_success'} == 0;
}
}
}
return %return_hash;
}
1;
OHA YOOOO