MINI MINI MANI MO

Path : /opt/oracle/product/18c/dbhomeXE/lib/
File Upload :
Current File : //opt/oracle/product/18c/dbhomeXE/lib/asmcmdattr.pm

# 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