ADSM-L

Ruby TSM dsmadmc interface

2004-08-06 02:23:26
Subject: Ruby TSM dsmadmc interface
From: Steve Harris <Steve_Harris AT HEALTH.QLD.GOV DOT AU>
To: ADSM-L AT VM.MARIST DOT EDU
Date: Fri, 6 Aug 2004 16:22:17 +1000
Hi all

I've been switching from perl to the ruby programming language for my scripting 
as ruby is nicer in many ways.  In order to use this with TSM I have ported 
Owen Crow's Adsm.pm perl module.  Some of you might find it useful.  
Steve.


=======================================================================
class Tsm

=begin
=Tsm
  
A ruby class to interface with the dsmadmc command
based on the perl Adsm package by Owen Crow
  
==Methods

Tsm.new("username","password")

The new method creates a TSM object.  Username and password are optional, and
are the TSM username and password to be usd for this session.  If these are
not supplied, the user's HOME environment variable is used to locate a file 
named .dsmrc.   See the Files section below.

Dsmadmc("c1","c2","c3"...)

When the Dsmadmc method is invoked on the Tsm object the string parameters 
passed are joined with a space and the resulting string is passed as a command 
to the dsmadmc command.  The output of the command is stripped of TSM header 
and footer information, continuation lines and blank lines, and returned as a 
single string to the caller.  The TSM return code is placed into the rc 
instance variable

rc  

This method returns the TSM return code from the last executed command 

Dsmconsole {|line| ...}

This method opens a TSM console session and passes returned lines to the block.
No processing is done on the returned lines. Interrupt is trapped.  

==Files

tsm.rb  - source

.dsmrc optionally contains lines of the form 

ID username
PA password

The first line of each type found is used to supply the TSM Id and Password
that is used when invoking the dsmadmc command. 

== Examples

require "tsm"
x = Tsm.new("someadmin","somepassword")
puts "#{x.Dsmadmc("-commad","q sess")} rc=#{x.rc}"
puts "#{x.Dsmadmc("q mount")} rc=#{x.rc}"
x.Dsmconsole { |l| puts l}

=end


  attr_accessor(:rc)
  
  def initialize(*args)
    @id=args.shift
    @pa=args.shift
    @rc=0
    if (@id.nil? or @pa.nil?) and not(ENV['HOME'].nil?)
      dsmrcfile=ENV['HOME'] + "/.dsmrc"

      begin
        mode = File.stat(dsmrcfile).mode%32678
        uid  = File.stat(dsmrcfile).uid
        #mode must be 600 or 400
        raise "Permissions of #{dsmrcfile} are #{sprintf("%o",mode)} and should 
be octal 600 or 400" unless ("477".oct & mode) != "400".oct
        raise "#{dsmrcfile} must be owned by you" unless uid == Process.uid
        File.open(ENV['HOME'] + "/.dsmrc").each_line do |l|
        
          if @id.nil? && l =~ /^ID\s+(.*)$/
            @id = $1
          end
          if @pa.nil? && l =~ /^PA\s+(.*)$/
            @pa = $1
          end 

        end
      rescue Errno::ENOENT  # ./dsmrc file does not exist
        prompt_user
      end

      if @id.nil? || @pa.nil? 
        prompt_user
      end
    end
  end

  def prompt_user

    if $stdin.isatty
      # an interactive terminal 
      stty = `stty`
      if @id.nil?
        print "Enter your user id:  " 
        @id = $stdin.gets.chomp
      end
      if @pa.nil?
        # Turn off echoing of characters for the password entry (only in UNIX
        `stty -echo`
        print "Enter password for #{@id}: "
        @pa=$stdin.gets.chomp
        `stty echo` if stty =~ /[^-]echo\b/
         print "\n"
      end
    else 
      # Last effort is to read the ID and password from stdin
      @id=$stdin.gets.chomp
      @pa=$stdin.gets.chomp
    end
  end

  def Dsmadmc(*args)
    # dsmadmc accepts a list as its argument. The list is joined with spaces
    # to form the command submitted to tsm
    command = args.join(" ")
    output = String.new("") # output of dsmadmc command
    @rc = 0
    flag = false
    IO.popen("dsmadmc -ID=#{@id} -PA=#{@pa} #{command} </dev/null").each_line 
do |$_|  
      next if $_ =~ /^\s*$/ # drop empty lines
      # Capture return code from output of dsmadmc. Did I miss any other
      # messages which contain the return code?
      if $_ =~ /^(ANS5103I|ANS5102I|ANS8002I).*?(\d+)\.$/ 
        @rc = $2
        break
      end
      # Wait for the flag and skip empty lines
      # Skip any lines starting with "more..."
      if flag  
        more = ($_ =~/^more\.\.\./ ) ? true : false
        output += $_ unless more
      end
      # Set the flag on the message which contains the command issued
      flag = true if $_ =~ /^(ANS5101I|ANS8000I)/
    end
    output   # return the output as a string with multiple lines
  end

  def Dsmconsole
     p=IO.popen("dsmadmc -ID=#{@id} -PA=#{@pa} -console </dev/null")
     begin
       p.each_line {|l| yield l}
     rescue Interrupt
       p.close_read 
     end    
  end
end
 


***********************************************************************************
This email, including any attachments sent with it, is confidential and for the 
sole use of the intended recipient(s).  This confidentiality is not waived or 
lost, if you receive it and you are not the intended recipient(s), or if it is 
transmitted/received in error.

Any unauthorised use, alteration, disclosure, distribution or review of this 
email is prohibited.  It may be subject to a statutory duty of confidentiality 
if it relates to health service matters.

If you are not the intended recipient(s), or if you have received this email in 
error, you are asked to immediately notify the sender by telephone or by return 
email.  You should also delete this email and destroy any hard copies produced.
***********************************************************************************

<Prev in Thread] Current Thread [Next in Thread>