rsh 0.2.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.document CHANGED
@@ -1,6 +1,4 @@
1
- README.rdoc
1
+ *.rdoc
2
2
  lib/**/*.rb
3
3
  bin/*
4
4
  features/**/*.feature
5
- LICENSE
6
- CHANGELOG
data/.gitignore CHANGED
@@ -13,9 +13,13 @@ tmtags
13
13
  ## VIM
14
14
  *.swp
15
15
 
16
+ ## NETBEANS
17
+ nbproject
18
+
16
19
  ## PROJECT::GENERAL
17
20
  coverage
18
21
  rdoc
22
+ doc
19
23
  pkg
20
24
 
21
25
  ## PROJECT::SPECIFIC
@@ -1,3 +1,96 @@
1
+ [f5ac480 | Sun Oct 31 09:12:03 UTC 2010] Pavel Argentov <argentoff@gmail.com>
2
+
3
+ * Version 1.0.0 feature freeze
4
+
5
+ Version 1.0.0 features pure ruby rsh client. See Rsh class documentation for
6
+ details.
7
+
8
+ [0b8dd96 | Sun Oct 31 09:08:02 UTC 2010] Pavel Argentov <argentoff@gmail.com>
9
+
10
+ * Version bump to 1.0.0
11
+
12
+ [4062f8e | Sun Oct 31 09:04:02 UTC 2010] Pavel Argentov <argentoff@gmail.com>
13
+
14
+ * ruby_impl= optimization
15
+
16
+ [7c3f811 | Sun Oct 31 08:44:43 UTC 2010] Pavel Argentov <argentoff@gmail.com>
17
+
18
+ * ./doc -> .gitignore
19
+
20
+ [97c7732 | Sun Oct 31 08:43:27 UTC 2010] Pavel Argentov <argentoff@gmail.com>
21
+
22
+ * Kinda ready for test
23
+
24
+ [e3feeca | Sun Oct 31 07:44:06 UTC 2010] Pavel Argentov <argentoff@gmail.com>
25
+
26
+ * First byte experiment
27
+
28
+ Looks like successful. Leave it in place.
29
+
30
+ [0cb9667 | Sun Oct 31 07:26:45 UTC 2010] Pavel Argentov <argentoff@gmail.com>
31
+
32
+ * First byte experiment
33
+
34
+ Try to throw away first byte of server's output (it seems to be kinda
35
+ signalling char [ref?]); also made the lookup of rsh binary mandatory
36
+ again since :ruby_impl can change during the Rsh instance's lifetime.
37
+
38
+ [1ff74ab | Sun Oct 31 06:43:19 UTC 2010] Pavel Argentov <argentoff@gmail.com>
39
+
40
+ * Fixed .document
41
+
42
+ [eb3f789 | Sun Oct 31 06:35:14 UTC 2010] Pavel Argentov <argentoff@gmail.com>
43
+
44
+ * Docs cleanup
45
+
46
+ [13171cc | Sun Oct 31 06:24:30 UTC 2010] Pavel Argentov <argentoff@gmail.com>
47
+
48
+ * Yet another documentation reorganization
49
+
50
+ Renamed LICENSE and CHANGELOG to *.rdoc
51
+
52
+ [0e841ee | Sat Oct 30 19:38:52 UTC 2010] Pavel Argentov <argentoff@gmail.com>
53
+
54
+ * Added luser example to constructor's rdoc
55
+
56
+ [7a60372 | Sat Oct 30 19:35:41 UTC 2010] Pavel Argentov <argentoff@gmail.com>
57
+
58
+ * Fixed :luser bug in constructor
59
+
60
+ [27f985a | Sat Oct 30 19:28:13 UTC 2010] Pavel Argentov <argentoff@gmail.com>
61
+
62
+ * Merge all changes to rsh.rb
63
+
64
+ Merged all experimental code into rsh.rb, removed rsh_p_r.rb.
65
+
66
+ [94de036 | Sat Oct 30 18:52:42 UTC 2010] Pavel Argentov <argentoff@gmail.com>
67
+
68
+ * Continuing work on RshPR
69
+
70
+ Added flag :ruby_impl to force ruby implementation if needed.
71
+
72
+ [6e9cdb8 | Sat Oct 30 17:47:32 UTC 2010] Pavel Argentov <argentoff@gmail.com>
73
+
74
+ * More practical module
75
+
76
+ Made RshPR module more suitable to be used in Rsh class.
77
+
78
+ [6ef45bd | Sat Oct 30 16:59:40 UTC 2010] Pavel Argentov <argentoff@gmail.com>
79
+
80
+ * Pure ruby RSH
81
+
82
+ Added rsh_p_r.rb: pure ruby rsh implementation. As a module to start with.
83
+
84
+ [ef37141 | Thu Oct 28 03:39:10 UTC 2010] Pavel Argentov <argentoff@gmail.com>
85
+
86
+ * Netbeans adaptation
87
+
88
+ Added "nbproject" directory to git ignore list.
89
+
90
+ [3abbddc | Wed Oct 27 15:01:04 UTC 2010] Pavel Argentov <argentoff@gmail.com>
91
+
92
+ * Finished working on v0.2.2
93
+
1
94
  [63b17fa | Wed Oct 27 14:50:57 UTC 2010] Pavel Argentov <argentoff@gmail.com>
2
95
 
3
96
  * Finished project documentation rework
File without changes
data/Rakefile CHANGED
@@ -14,8 +14,8 @@ begin
14
14
  gem.authors = ["Pavel Argentov"]
15
15
  gem.add_development_dependency "rspec", ">= 1.2.9"
16
16
  gem.extra_rdoc_files = [
17
- "LICENSE",
18
- "CHANGELOG",
17
+ "LICENSE.rdoc",
18
+ "CHANGELOG.rdoc",
19
19
  "README.rdoc"
20
20
  ]
21
21
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
@@ -55,7 +55,7 @@ end
55
55
 
56
56
  desc 'update changelog'
57
57
  task :changelog do
58
- File.open('CHANGELOG', 'w+') do |changelog|
58
+ File.open('CHANGELOG.rdoc', 'w+') do |changelog|
59
59
  `git log -z --abbrev-commit`.split("\0").each do |commit|
60
60
  next if commit =~ /^Merge: \d*/
61
61
  ref, author, time, _, title, _, message = commit.split("\n", 7)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 1.0.0
data/lib/rsh.rb CHANGED
@@ -1,9 +1,19 @@
1
- # = UNIX rsh(1) wrapper class
1
+ # -*- Ruby -*-
2
+ # Ruby remote shell protocol (RFC 1282) client.
3
+
4
+ require 'socket' # we'll need it in pure ruby implementation
5
+
6
+ # = Ruby remote shell protocol (RFC 1282) client
2
7
  #
3
- # Creates and operates an 'rsh' command call instance. Parameters to rsh may
8
+ # Creates and operates an rsh client instance. Parameters may
4
9
  # be specified through either constructor or attribute accessors. Result of
5
- # rsh execution (_String_) is either returned in functional style (<tt>execute!</tt> method call)
6
- # or in special attribute, _result_.
10
+ # remote command execution (_String_) is either returned in functional style
11
+ # (<tt>execute!</tt> method call) or in special attribute, _:result_.
12
+ #
13
+ # == New: pure ruby rsh client
14
+ # As of ver. 1.0.0, pure ruby rsh client is implemented. It is used whether if
15
+ # you set :ruby_impl to true or if 'rsh' program wasn't found in the system while
16
+ # setting :ruby_impl to false.
7
17
  #
8
18
  # == Synopsis
9
19
  #
@@ -40,69 +50,88 @@
40
50
  # % man 1 rsh
41
51
  #
42
52
  class Rsh
53
+ # flags whether to force pure ruby rsh client
54
+ attr_accessor :ruby_impl
43
55
  # path to rsh program, +String+
44
56
  attr_reader :executable
45
-
46
57
  # result +String+
47
58
  attr_reader :result
48
-
49
59
  # remote server hostname or IP, +String+
50
60
  attr_accessor :host
51
-
52
61
  # remote command, +String+
53
62
  attr_accessor :command
54
-
55
63
  # remote username, +String+
56
64
  attr_accessor :ruser
57
-
65
+ # Local user name, used in pure ruby implementation.
66
+ attr_accessor :luser
58
67
  # rsh timeout, +Integer+ (see man 1 rsh)
59
68
  attr_accessor :to
60
-
61
69
  # boolean knob for <tt>/dev/null</tt> redirection; see man rsh for further
62
70
  # information
63
71
  attr_accessor :nullr
64
72
 
65
- # The Constructor. Checks the presence of rsh in the system (running,
73
+ # The Constructor. If :ruby_impl is false checks the presence of rsh in the system (running,
66
74
  # naturally, 'which rsh') and prepares the command to be run with <tt>execute!</tt>.
67
75
  # rsh CLI arguments are either having default values, being collected from constructor
68
76
  # call or specified via accessors.
69
77
  #
70
78
  # Call sequence:
71
- # Rsh.new -> Rsh instance
72
- # Rsh.new(:host => "hostname", :command => "example.sh", :ruser => "jack", :to => 5, :nullr => true) -> Rsh instance
79
+ # Rsh.new #=> Rsh instance
80
+ # Rsh.new(:host => "hostname",
81
+ # :command => "example.sh",
82
+ # :ruser => "jack",
83
+ # :to => 5,
84
+ # :nullr => true
85
+ # :ruby_impl => true) #=> Rsh instance
73
86
  #
74
87
  # If called without arguments, the following default values are being used:
75
88
  #
76
- # :host => "localhost"
77
- # :command => ""
78
- # :ruser => "nobody"
79
- # :to => 3
80
- # :nullr => false
89
+ # :host => "localhost"
90
+ # :command => ""
91
+ # :ruser => "nobody"
92
+ # :to => 3
93
+ # :nullr => false
94
+ # :ruby_impl => false
95
+ # :luser => ENV["USER"] || "nobody"
81
96
  #
82
97
  def initialize(args={})
83
- args = {:host => "localhost",
84
- :command => "",
85
- :ruser => "nobody",
86
- :to => 3,
87
- :nullr => false}.merge!(args)
98
+ args = {
99
+ :host => "localhost",
100
+ :command => "",
101
+ :ruser => "nobody",
102
+ :luser => ENV["USER"] || "nobody",
103
+ :to => 3,
104
+ :nullr => false,
105
+ :ruby_impl => false
106
+ }.merge!(args)
107
+
108
+ @result = ""
109
+ @ruby_impl = args[:ruby_impl]
110
+ @host = args[:host]
111
+ @command = args[:command]
112
+ @ruser = args[:ruser]
113
+ @luser = args[:luser]
114
+ @to = args[:to]
115
+ @nullr = args[:nullr]
116
+
88
117
  begin
89
118
  open("| which rsh") do |io|
90
119
  @executable = io.gets.chomp
91
120
  end
92
121
  rescue => detail
93
- raise "FATAL: Could not find rsh executable!"
122
+ @ruby_impl = true
94
123
  end
95
-
96
- @host = args[:host]
97
- @command = args[:command]
98
- @ruser = args[:ruser]
99
- @to = args[:to]
100
- @nullr = args[:nullr]
101
- @result = ""
124
+ end
125
+
126
+ # :ruby_impl writer ensuring that we can set/reset :ruby_impl only
127
+ # if @executable is not nil.
128
+ def ruby_impl=(bool)
129
+ @executable ? @ruby_impl = bool : @ruby_impl
102
130
  end
103
131
 
104
-
105
- # Executes rsh command using previously collected arguments.
132
+ # Executes rsh command using previously collected arguments. If :ruby_impl is
133
+ # true or system rsh binary was not found during initialize runs pure ruby rsh
134
+ # client.
106
135
  #
107
136
  # If given a block, calls it for each line received from rsh output
108
137
  # (parameter _line_).
@@ -125,15 +154,45 @@ class Rsh
125
154
  def execute!(command=nil)
126
155
  @command = command if command
127
156
  @result = ""
128
- open "|#{@executable} #{"-n" if @nullr} -l#{@ruser} -t#{@to} #{@host} #{@command}" do |io|
129
- io.each do |line|
157
+ if @ruby_impl
158
+ # pure ruby implementation call
159
+ rsh_ruby do |line|
130
160
  yield(line) if block_given?
131
161
  @result << line
132
162
  end
163
+ else
164
+ # OS'es rsh(1) call
165
+ open "|#{@executable} #{"-n" if @nullr} -l#{@ruser} -t#{@to} #{@host} #{@command}" do |io|
166
+ io.each do |line|
167
+ yield(line) if block_given?
168
+ @result << line
169
+ end
170
+ end
133
171
  end
134
172
  @result
135
173
  end
136
174
 
175
+ private
176
+ # pure ruby rsh client
177
+ def rsh_ruby
178
+ r = ""
179
+ s = TCPSocket.new(@host, 514)
180
+ s.write "0\0"
181
+ s.write "#{@luser}\0"
182
+ s.write "#{@ruser}\0"
183
+ s.write "#{@command}\0"
184
+ s.getc # cutting off the first byte, signalling?
185
+ while line = s.gets
186
+ if block_given?
187
+ yield line
188
+ else
189
+ r << line
190
+ end
191
+ end
192
+ s.close
193
+ r == "" ? nil : r
194
+ end
195
+
137
196
  alias :execute :execute!
138
197
 
139
198
  end
@@ -5,24 +5,24 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rsh}
8
- s.version = "0.2.2"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Pavel Argentov"]
12
- s.date = %q{2010-10-27}
12
+ s.date = %q{2010-10-31}
13
13
  s.description = %q{All freenixes (e.g. Linux, *BSD, etc.) have 'rsh' command.
14
14
  Here's the gem wrapping call to this command and handling the command's result/output.}
15
15
  s.email = %q{argentoff@gmail.com}
16
16
  s.extra_rdoc_files = [
17
- "CHANGELOG",
18
- "LICENSE",
17
+ "CHANGELOG.rdoc",
18
+ "LICENSE.rdoc",
19
19
  "README.rdoc"
20
20
  ]
21
21
  s.files = [
22
22
  ".document",
23
23
  ".gitignore",
24
- "CHANGELOG",
25
- "LICENSE",
24
+ "CHANGELOG.rdoc",
25
+ "LICENSE.rdoc",
26
26
  "README.rdoc",
27
27
  "Rakefile",
28
28
  "VERSION",
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rsh
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
+ - 1
7
8
  - 0
8
- - 2
9
- - 2
10
- version: 0.2.2
9
+ - 0
10
+ version: 1.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Pavel Argentov
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-27 00:00:00 +04:00
18
+ date: 2010-10-31 00:00:00 +04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -43,14 +43,14 @@ executables: []
43
43
  extensions: []
44
44
 
45
45
  extra_rdoc_files:
46
- - CHANGELOG
47
- - LICENSE
46
+ - CHANGELOG.rdoc
47
+ - LICENSE.rdoc
48
48
  - README.rdoc
49
49
  files:
50
50
  - .document
51
51
  - .gitignore
52
- - CHANGELOG
53
- - LICENSE
52
+ - CHANGELOG.rdoc
53
+ - LICENSE.rdoc
54
54
  - README.rdoc
55
55
  - Rakefile
56
56
  - VERSION