Class: TSM::Command

Inherits:
Object
  • Object
show all
Includes:
Observable
Defined in:
lib/tsm.rb,
lib/tsm.rb

Overview

:nodoc:

Direct Known Subclasses

Dsmadmc, Dsmc

Defined Under Namespace

Classes: Response

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opt = {}, &block) ⇒ Command

Returns a new instance of Command.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/tsm.rb', line 47

def initialize(opt = {},&block)
	args = [find(self.class.to_s.split(":").last.downcase)]

	opt.merge(FORCE_OPT).each{|k,v| args.push("-#{k.to_s}#{'=' << v.to_s if v.class != TrueClass}") }
	opt.each_key do |k|
		opt.each_key {|k2| opt.delete(k2) if k.to_s.casecmp(k2.to_s) == -1}
	end

	@cmd = args.join(" ")

	yield self if block_given?

	self
ensure
	close if block_given? and not closed?
end

Instance Attribute Details

#appObject

Returns the value of attribute app.



45
46
47
# File 'lib/tsm.rb', line 45

def app
  @app
end

#cmdObject (readonly)

Returns the value of attribute cmd.



44
45
46
# File 'lib/tsm.rb', line 44

def cmd
  @cmd
end

#headerObject (readonly)

Returns the value of attribute header.



43
44
45
# File 'lib/tsm.rb', line 43

def header
  @header
end

#hostObject (readonly)

Returns the value of attribute host.



43
44
45
# File 'lib/tsm.rb', line 43

def host
  @host
end

#pathObject

Returns the value of attribute path.



45
46
47
# File 'lib/tsm.rb', line 45

def path
  @path
end

#promptObject (readonly)

Returns the value of attribute prompt.



43
44
45
# File 'lib/tsm.rb', line 43

def prompt
  @prompt
end

#ptyObject (readonly)

Returns the value of attribute pty.



44
45
46
# File 'lib/tsm.rb', line 44

def pty
  @pty
end

#timeoutObject

Returns the value of attribute timeout.



42
43
44
# File 'lib/tsm.rb', line 42

def timeout
  @timeout
end

Instance Method Details

#closeObject



84
85
86
87
88
89
90
91
# File 'lib/tsm.rb', line 84

def close
	notify('close',{'closed' => closed?})
	if @pty
		@pty[:r].close unless @pty[:r].closed?
		@pty[:w].close unless @pty[:w].closed?
	end
	@pty = nil
end

#closed?Boolean

Returns:

  • (Boolean)


93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/tsm.rb', line 93

def closed?
	return true unless @pty
	return true if @pty[:r].closed? and @pty[:w].closed?

	begin
		Process.kill(0,@pty[:pid])
	rescue Errno::ESRCH
		return true
	end

	false
end

#command(cmd, &block) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/tsm.rb', line 106

def command(cmd,&block)
	cmd.to_s.strip!

	notify('execute',{'command' => cmd,'closed'=>closed?})

	begin
		return self
	ensure
		close unless closed?
	end if cmd =~ /quit*/i

	raise Error::PTYError, 'No PTY' if closed?

	@pty[:w].puts(cmd.to_s)

	start = Time.now()
	res = Response.new
	@pty[:r].response(@prompt) do |line|
		res.parse(line,&block)
	end
	duration = Time.now() - start

	notify('complete',{'duration' => "%.2f" % duration,'rows' => res[:count] || 0})

	res
rescue Error::PTYError
	open
	retry
end

#open(&block) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/tsm.rb', line 64

def open(&block)
	return self unless closed?

	r,w,pid = PTY.spawn(@cmd)
	@header,@prompt,@host = r.prompt([/tsm: ([A-Z0-9]*)>/i,/Enter your password: /i],@timeout || 60)
	Response.new(@header.to_s).validate(Error::CommandError) if @host.to_s.empty?

	@established = Time.now()
	@pty = {:r => r,:w => w,:pid => pid}

	notify('open',{'host'=>@host})

	yield self if block_given?

	self
rescue PTY::ChildExited => details
ensure
	close if block_given? and not closed?
end

#serverObject

Raises:



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/tsm.rb', line 136

def server
	raise Error::PTYError, "No connection was established" unless @header

	svr = {}
	@header.each {|l|
		l = l.chomp
		l.strip!
		next if l.empty?

		if (m=/Command Line ([\S^-]+)([\s\S]+) - Version (\d+), Release (\d+), Level (\d(.\d))/i.match(l))
			svr[:interface] = {:version => m[3],:release => m[4],:level =>m[5],:type => m[1].downcase}
		elsif (m=/Session established with server (\w+): (\S+)/i.match(l))
			svr[:host] = {:hostname => m[1],:arch => m[2]}
		elsif (m=/Server Version (\d+), Release (\d+), Level (\d(.\d))/i.match(l))
			svr[:version] = {:version => m[1],:release => m[2],:level => m[3]}
		elsif (m=/Server date.time: ([0-9\/]+) ([0-9:]+)(\s+)Last access: ([0-9\/]+) ([0-9:]+)/i.match(l))
			svr[:established] = Time.local(*(ParseDate.parsedate("#{m[1]} #{m[2]}")))
			svr[:access] = Time.local(*(ParseDate.parsedate("#{m[4]} #{m[5]}")))
		end
	}
	svr[:time] = @established if @established

	svr
end