MINI MINI MANI MO
# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
#
# NAME
# asmcmdattr - ASM CoMmanD line interface ATTRIBUTE operations
#
# DESCRIPTION
# This module contains the code for ASMCMD/ASM attribute-related
# operations, such as listing the contents of v$asm_attribute.
#
# NOTES
# usage: asmcmdcore [-p] [command]
#
# MODIFIED (MM/DD/YY)
# diguzman 05/30/16 - 19654070: Little change at _no_instance_cmd routine
# ykatada 10/07/14 - #19617921: binds to asmcmdshare_do_construct_select
# pvenkatr 02/01/13 - using asmcmdshare_filter_invisible_cmds.
# pvenkatr 08/24/11 - Removed flags hash table - using from XML
# adileepk 06/20/11 - Connection Pooling.
# adileepk 11/08/10 - Adding changes to integrate the parser module with
# asmcmd.
# moreddy 05/06/10 - bug 8667038 NLS for error messages
# amitroy 04/20/10 - BUG 8933243 - USE DIFFERENT CHARACTER IN ASMCMD TO
# "HIDE COLUMN DETAILS" INSTEAD OF -H
# pvenkatr 03/31/10 - Syntax, description, example - all from XML
# moreddy 03/22/10 - Adding more tracing
# moreddy 01/08/10 - Adding trace messages
# pvenkatr 09/03/09 - Help message from xml file.
# sanselva 04/06/09 - ASMCMD long options and consistency
# heyuen 10/14/08 - use dynamic modules
# heyuen 09/10/08 - hide template attributes
# heyuen 08/02/08 - display dgname in lsattr
# heyuen 07/28/08 - use command properties array
# heyuen 05/12/08 - remove attribute number and incarnation from lsattr
# heyuen 04/22/08 - add order in lsattr
# heyuen 04/15/08 - reorder help messages
# heyuen 03/31/08 - add parameter check in lsattr
# heyuen 02/12/08 - change help messages
# heyuen 01/31/08 - fix unitialized variable untaint
# heyuen 07/23/07 - creation
#
#############################################################################
#
############################ Functions List #################################
# asmcmdattr_init
# asmcmdattr_process_cmd
# asmcmdattr_is_cmd
# asmcmdattr_process_lsattr
# asmcmdattr_process_setattr
# asmcmdattr_parse_int_args
# asmcmdattr_get_asmcmd_cmds
# asmcmdattr_is_no_instance_cmd
# asmcmdattr_syntax_error
# asmcmdattr_process_help
#############################################################################
package asmcmdattr;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(asmcmdattr_init
);
use strict;
use DBI qw(:sql_types);
use Getopt::Long qw(:config no_ignore_case bundling);
use asmcmdglobal;
use asmcmdshare;
use asmcmdparser;
use List::Util qw[min max];
####################### ASMCMDATTR Global Constants ######################
# ASMCMD Column Header Names:
# Below are the names of the column headers for lsattr.
our (%asmcmdattr_lsattr_header) = ('group_name' , 'Group_Name',
'group_number' , 'Group_Num',
'attr_name' , 'Name',
'value' , 'Value',
'read_only' , 'RO',
'system_created' , 'Sys'
);
####################### ASMCMDATTR Global Variables ######################
#
# The following list is primarily used for is_cmd callback.
# All other data comes from XML.
#
our (%asmcmdattr_cmds) = (lsattr => {},
setattr => {}
);
sub is_asmcmd
{
return 1;
}
########
# NAME
# asmcmdattr_init
#
# DESCRIPTION
# This function initializes the asmcmdattr module. For now it simply
# registers its callbacks with the asmcmdglobal 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, \&asmcmdattr_process_cmd);
push (@asmcmdglobal_help_callbacks, \&asmcmdattr_process_help);
push (@asmcmdglobal_command_list_callbacks, \&asmcmdattr_get_asmcmd_cmds);
push (@asmcmdglobal_is_command_callbacks, \&asmcmdattr_is_cmd);
push (@asmcmdglobal_is_wildcard_callbacks, \&asmcmdattr_is_wildcard_cmd);
push (@asmcmdglobal_syntax_error_callbacks, \&asmcmdattr_syntax_error);
push (@asmcmdglobal_no_instance_callbacks, \&asmcmdattr_is_no_instance_cmd);
%asmcmdglobal_cmds = (%asmcmdglobal_cmds, %asmcmdattr_cmds);
#Perform ASMCMD consistency check if enabled
if($asmcmdglobal_hash{'consistchk'} eq 'y')
{
if(!asmcmdshare_check_option_consistency(%asmcmdattr_cmds))
{
exit 1;
}
}
}
########
# NAME
# asmcmdattr_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 asmcmdattr module; 0 if not.
#
# NOTES
# Only asmcmdcore_shell() calls this routine.
########
sub asmcmdattr_process_cmd
{
my ($dbh) = @_;
my ($succ) = 0;
# Get current command from global value, which is set by
# asmcmdtemplate_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) = ( lsattr => \&asmcmdattr_process_lsattr ,
setattr => \&asmcmdattr_process_setattr );
if (defined ( $cmdhash{ $cmd } ))
{ # If user specifies a known command, then call routine to process it. #
$cmdhash{ $cmd }->($dbh);
$succ = 1;
}
return $succ;
}
########
# NAME
# asmcmdattr_is_cmd
#
# DESCRIPTION
# This routine checks if a user-entered command is one of the known
# ASMCMD internal commands that belong to the ASMCMDATTR module.
#
# PARAMETERS
# arg (IN) - user-entered command name string.
#
# RETURNS
# True if $arg is one of the known commands, false otherwise.
########
sub asmcmdattr_is_cmd
{
my ($arg) = shift;
return defined ( $asmcmdattr_cmds{ $arg } );
}
########
# NAME
# asmcmdattr_process_lsattr
#
# DESCRIPTION
# This function processes the asmcmd command lsattr.
#
# PARAMETERS
# dbh (IN) - initialized database handle, must be non-null.
#
# RETURNS
# Null.
#
# NOTES
# Only asmcmdattr_process_cmd() calls this function.
########
sub asmcmdattr_process_lsattr
{
my ($dbh) = shift;
my (%args);
my ($ret);
my ($header, $pattern);
my (@dgroups, %dgnmap);
my (@what , @from, $sth, $qry, @where, @order, @binds, @tmp_cols);
my ($k, $v, $row, $h);
my (@attr_list);
my (%x);
my ($dgname, $meta, $vals);
my (@cols);
my (@select);
my (%as);
my ($gnum);
my (%min_col_wid, $print_format, $print_string, @what_print);
# Get option parameters, if any.
$ret = asmcmdattr_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
return unless defined ($ret);
#Set the correct options if deprecated options were used and print WARNING.
asmcmdshare_handle_deprecation($asmcmdglobal_hash{'cmd'},\%args);
# get disk group names
@dgroups = asmcmdshare_get_dg($dbh);
foreach (@dgroups)
{
$dgnmap{$_->{'group_number'}} = $_->{'name'};
}
if (defined($args{'G'}))
{
$dgname = $args{'G'};
$dgname =~ tr/a-z/A-Z/;
$gnum = asmcmdshare_get_gnum_from_gname($dbh, $args{'G'});
if (!defined ($gnum))
{
my (@eargs) = ($args{'G'});
asmcmdshare_error_msg(8001, \@eargs);
return;
}
push (@where, "v\$asm_diskgroup_stat.name = ?");
push (@binds, [$dgname, SQL_VARCHAR]);
}
# check if -m is specified
$meta = defined($args{'m'});
# check if -l is specified
$vals = defined($args{'l'});
# check if pattern is specified
if (defined($args{'lsattr'}))
{
($pattern) = @{$args{'lsattr'}};
$pattern =~ s,$ASMCMDGLOBAL_WCARD_CHARS,\%,g;
}
@what = ('v$asm_attribute.name as attr_name');
if ($vals)
{
push (@what, 'v$asm_attribute.value');
}
if ($meta)
{
@what = ('v$asm_diskgroup_stat.name as group_name', @what);
push (@what, 'v$asm_attribute.read_only');
push (@what, 'v$asm_attribute.system_created');
}
push (@from, 'v$asm_attribute');
push (@from, 'v$asm_diskgroup_stat');
push (@where, 'v$asm_diskgroup_stat.group_number = v$asm_attribute.group_number');
if ($pattern)
{
my ($like_pattern);
$like_pattern = '%' . $pattern . '%';
push (@where, 'v$asm_attribute.name LIKE ? ');
push (@binds, [$like_pattern, SQL_VARCHAR]);
}
push (@where, 'v$asm_attribute.name not like \'template%\'');
push (@order, 'v$asm_diskgroup_stat.name');
push (@order, 'v$asm_attribute.name');
$sth = asmcmdshare_do_construct_select($dbh, \@what, \@from, \@where,
\@order, \@binds);
@tmp_cols = @{$sth->{NAME}};
@what = ();
foreach (@tmp_cols)
{
push (@what, "\L$_");
}
#initialize the min_col_wid array
foreach(@what)
{
$min_col_wid{$_} = 0;
}
#get the rows
while (defined($row = asmcmdshare_fetch($sth)))
{
my (%attr_info) = ();
while(($k,$v) = each(%{$row}))
{
$k =~ tr/[A-Z]/[a-z]/;
$attr_info{$k} = $v;
$min_col_wid{$k} = max($min_col_wid{$k}, length($v));
}
push (@attr_list, \%attr_info);
}
asmcmdshare_finish($sth);
#get the header length
foreach (@what)
{
$min_col_wid{$_} = max($min_col_wid{$_},
length($asmcmdattr_lsattr_header{$_}));
}
#create print format
$print_format = '';
foreach (@what)
{
$print_format .= "%-" . $min_col_wid{$_} . "s ";
}
$print_format .= "\n";
#print header
if (!defined ($args{'suppressheader'}) )
{
@what_print = ();
foreach (@what)
{
push (@what_print, $asmcmdattr_lsattr_header{$_});
}
$print_string = sprintf($print_format, @what_print);
asmcmdshare_print($print_string);
}
#print rows
foreach $h (@attr_list)
{
@what_print = ();
foreach (@what)
{
push (@what_print, $h->{$_});
}
$print_string = sprintf($print_format, @what_print);
asmcmdshare_print($print_string);
}
return;
}
########
# NAME
# asmcmdattr_process_setattr
#
# DESCRIPTION
# This function processes the asmcmd command setattr.
#
# PARAMETERS
# dbh (IN) - initialized database handle, must be non-null.
#
# RETURNS
# Null.
#
# NOTES
# Only asmcmdattr_process_cmd() calls this function.
########
sub asmcmdattr_process_setattr
{
my ($dbh) = @_;
my (%args);
my ($ret);
my ($sth, $qry, $dgname);
my ($attr_name, $attr_val);
# Get option parameters, if any.
$ret = asmcmdattr_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
return unless defined ($ret);
# get the diskgroup name
$dgname = $args{'G'};
$dgname =~ tr/[a-z]/[A-Z]/;
($attr_name, $attr_val) = @{$args{'setattr'}};
$qry = "ALTER DISKGROUP " . $dgname . " SET ATTRIBUTE ";
$qry .= '\''. $attr_name . "\' = \'" . $attr_val . '\'';
$ret = asmcmdshare_do_stmt($dbh, $qry);
}
########
# NAME
# asmcmdattr_parse_int_args
#
# DESCRIPTION
# This routine parses the arguments for flag options for ASMCMD internal
# commands.
#
# PARAMETERS
# cmd (IN) - user-entered command name string.
# args_ref (OUT) - hash of user-specified flag options for a command,
# populated by getopts().
#
# RETURNS
# Zero on success; undefined on error.
#
# NOTES
# $cmd must already be verified as a valid ASMCMD internal command.
########
sub asmcmdattr_parse_int_args
{
my ($cmd, $args_ref) = @_;
my ($key);
my (@string);
#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. #
asmcmdattr_syntax_error($cmd);
return undef;
}
return 0;
}
########
# NAME
# asmcmdattr_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.
########
sub asmcmdattr_get_asmcmd_cmds
{
return asmcmdshare_filter_invisible_cmds(%asmcmdattr_cmds);
}
########
# NAME
# asmcmdattr_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
#
########
sub asmcmdattr_is_no_instance_cmd
{
my ($arg) = shift;
my ($rc);
return 1 unless defined($asmcmdattr_cmds{$arg});
$rc = asmcmdshare_get_cmd_noinst($arg);
if ($rc eq "true")
{
return 1;
}
elsif ($rc eq "undef")
{
return -1;
}
return 0;
}
########
# NAME
# asmcmdattr_syntax_error
#
# DESCRIPTION
# This routine prints the correct syntax for a command to STDERR, used
# when there is a syntax error. If the command with bad syntax is asmcmd
# itself, then asmcmdbase_syntax_error also calls exit() to quit out.
#
# PARAMETERS
# cmd (IN) - user-entered command name string.
#
# RETURNS
# Exits if cmd is "asmcmd" or "asmcmd_no_conn_str"; 1 if another command
# that 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. Thus, even if exit() is called, the exit value is
# zero.
########
sub asmcmdattr_syntax_error
{
my ($cmd) = shift;
my ($cmd_syntax); # Correct syntax for $cmd. #
my ($succ) = 0;
# display syntax only for commands from this module.
if (asmcmdattr_is_cmd($cmd))
{
$cmd_syntax = asmcmdshare_get_help_syntax($cmd); # Get syntax for $cmd. #
$cmd_syntax = asmcmdshare_trim_str ($cmd_syntax);
if (defined ($cmd_syntax))
{
asmcmdshare_printstderr 'usage: ' . $cmd_syntax . "\n";
asmcmdshare_printstderr 'help: help ' . $cmd . "\n";
$succ = 1;
}
}
return $succ;
}
########
# NAME
# asmcmdattr_is_wildcard_cmd
#
# DESCRIPTION
# This routine determines if an ASMCMDATTR 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 asmcmdattr_is_wildcard_cmd
{
my ($arg) = shift;
return defined ($asmcmdattr_cmds{ $arg }) &&
(asmcmdshare_get_cmd_wildcard($arg) eq "true") ;
}
########
# NAME
# asmcmdattr_process_help
#
# DESCRIPTION
# This function is the help function for the asmcmdattr module.
#
# PARAMETERS
# command (IN) - display the help message for this command.
#
# RETURNS
# 1 if command found; 0 otherwise.
########
sub asmcmdattr_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 (asmcmdattr_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;
}
1;
OHA YOOOO