rye 0.9.7 → 0.9.8
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.tar.gz.sig +0 -0
- data/CHANGES.txt +44 -38
- data/README.rdoc +44 -30
- data/Rakefile +41 -82
- data/VERSION +1 -0
- data/gem-public_cert.pem +20 -0
- data/lib/rye.rb +74 -52
- data/lib/rye/box.rb +7 -4
- data/lib/rye/dsl.rb +100 -0
- data/rye.gemspec +95 -55
- data/try/10_basic_tryouts.rb +44 -0
- data/try/12_batch_tryouts.rb +26 -0
- data/try/13_set_tryouts.rb +42 -0
- data/try/14_auth_methods_tryouts.rb +28 -0
- data/try/15_file_tryouts.rb +12 -0
- data/try/20_file_transfer_tryouts.rb +46 -0
- data/try/25_template_upload.rb +37 -0
- data/try/30_safemode_tryouts.rb +85 -0
- data/try/35_basics_with_hop.rb +36 -0
- data/try/70_rye_cli_tryouts.rb +0 -0
- data/try/copying.rb +18 -0
- data/try/keys.rb +141 -0
- data/tst/10-key1 +27 -0
- data/tst/10-key1.pub +1 -0
- data/tst/10-key2 +30 -0
- data/tst/10-key2.pub +1 -0
- data/tst/10_keys_test.rb +88 -0
- data/tst/50_rset_test.rb +54 -0
- data/tst/60-file.mp3 +0 -0
- data/tst/60_rbox_transfer_test.rb +53 -0
- data/tst/65_rbox_file_append_test.rb +53 -0
- data/tst/70_rbox_env_test.rb +19 -0
- data/tst/dsl_example.rb +80 -0
- data/tst/rye.rb +13 -0
- data/tst/shell.rb +280 -0
- data/tst/shell2.rb +278 -0
- data/tst/shell3.rb +280 -0
- data/tst/test_hop.rb +25 -0
- metadata +86 -25
- metadata.gz.sig +0 -0
- data/bin/try +0 -246
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rye'
|
2
|
+
|
3
|
+
|
4
|
+
## a Rye::Box instance defaults to localhost
|
5
|
+
lbox = Rye::Box.new
|
6
|
+
lbox.host
|
7
|
+
#=> 'localhost'
|
8
|
+
|
9
|
+
## can add commands
|
10
|
+
lbox = Rye::Box.new
|
11
|
+
initially = lbox.can? :rm
|
12
|
+
Rye::Cmd.add_command :rm
|
13
|
+
ret = [initially, lbox.can?(:rm)]
|
14
|
+
#=> [false, true]
|
15
|
+
|
16
|
+
## can remove commands
|
17
|
+
lbox = Rye::Box.new
|
18
|
+
Rye::Cmd.remove_command :rm
|
19
|
+
lbox.can?(:rm)
|
20
|
+
#=> false
|
21
|
+
|
22
|
+
## returns a Rye::Rap object
|
23
|
+
box = Rye::Box.new
|
24
|
+
box.uptime.class
|
25
|
+
#=> Rye::Rap
|
26
|
+
|
27
|
+
## returns the same stuff as backticks
|
28
|
+
Rye::Box.new.echo("canadian").first
|
29
|
+
#=> `echo canadian`.chomp
|
30
|
+
|
31
|
+
## starts in the home directory
|
32
|
+
lbox = Rye::Box.new.pwd.first
|
33
|
+
#=> ENV['HOME']
|
34
|
+
|
35
|
+
## can get remote environment variables
|
36
|
+
lbox = Rye::Box.new
|
37
|
+
File.exists? lbox.getenv['HOME']
|
38
|
+
#=> true
|
39
|
+
|
40
|
+
## can set an environment variable
|
41
|
+
lbox = Rye::Box.new
|
42
|
+
lbox.setenv( 'TIPPLE', 'whiskey')
|
43
|
+
lbox.getenv[ 'TIPPLE' ]
|
44
|
+
#=> 'whiskey'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rye'
|
2
|
+
|
3
|
+
|
4
|
+
## can execute commands in a batch
|
5
|
+
r = Rye::Box.new
|
6
|
+
file = "/tmp/rye-#{rand.to_s}"
|
7
|
+
r.batch do
|
8
|
+
touch file
|
9
|
+
end
|
10
|
+
r.file_exists? file
|
11
|
+
#=> true
|
12
|
+
|
13
|
+
## a batch can take arguments
|
14
|
+
r = Rye::Box.new
|
15
|
+
file = r.batch("/tmp/rye-#{rand.to_s}") do |f|
|
16
|
+
touch f
|
17
|
+
f
|
18
|
+
end
|
19
|
+
r.file_exists? file
|
20
|
+
#=> true
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
r = Rye::Box.new
|
25
|
+
r.disable_safe_mode
|
26
|
+
r.rm '/tmp/rye-*'
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "rye"
|
2
|
+
|
3
|
+
@dev_null = File.open("/dev/null", "w")
|
4
|
+
|
5
|
+
@opt_test_set = Rye::Set.new(
|
6
|
+
"option passing test",
|
7
|
+
:safe => false,
|
8
|
+
:debug => @dev_null,
|
9
|
+
:error => @dev_null
|
10
|
+
)
|
11
|
+
@opt_test_set.add_boxes("11.22.33.44")
|
12
|
+
@opt_test_box = @opt_test_set.boxes.first
|
13
|
+
|
14
|
+
@para_set_test = Rye::Set.new(
|
15
|
+
"parallel test set",
|
16
|
+
:parallel => true
|
17
|
+
)
|
18
|
+
@para_set_test.add_boxes("localhost", "_")
|
19
|
+
|
20
|
+
## save any raised exceptions
|
21
|
+
@para_set_test.hostname.last.first.class
|
22
|
+
#=> SocketError
|
23
|
+
|
24
|
+
## save any raised exceptions alongside normal results
|
25
|
+
@para_set_test.hostname.first.first.class
|
26
|
+
#=> String
|
27
|
+
|
28
|
+
## Pass :safe option to boxes
|
29
|
+
#box = @opt_test_set.boxes.first
|
30
|
+
@opt_test_box.instance_variable_get(:@rye_safe)
|
31
|
+
#=> false
|
32
|
+
|
33
|
+
## Pass :debug option to boxes
|
34
|
+
@opt_test_box.instance_variable_get(:@rye_debug).path
|
35
|
+
#=> "/dev/null"
|
36
|
+
|
37
|
+
## Pass :error option to boxes
|
38
|
+
@opt_test_box.instance_variable_get(:@rye_error).path
|
39
|
+
#=> "/dev/null"
|
40
|
+
|
41
|
+
|
42
|
+
@dev_null.close
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "rye"
|
2
|
+
|
3
|
+
# May need to update this in the future with a
|
4
|
+
# different free SSH provider
|
5
|
+
@hostname = "shellmix.com"
|
6
|
+
|
7
|
+
## Don't prompt for password if "publickey" is the only :auth_method
|
8
|
+
box = Rye::Box.new(
|
9
|
+
@hostname,
|
10
|
+
:auth_methods => ["publickey"]
|
11
|
+
)
|
12
|
+
|
13
|
+
begin
|
14
|
+
box.connect
|
15
|
+
rescue Net::SSH::AuthenticationFailed => ex
|
16
|
+
ex.class
|
17
|
+
end
|
18
|
+
#=> Net::SSH::AuthenticationFailed
|
19
|
+
|
20
|
+
## Never prompt for password if :no_password_prompt option is true
|
21
|
+
box = Rye::Box.new(@hostname, :password_prompt => false)
|
22
|
+
|
23
|
+
begin
|
24
|
+
box.connect
|
25
|
+
rescue Net::SSH::AuthenticationFailed => ex
|
26
|
+
ex.class
|
27
|
+
end
|
28
|
+
#=> Net::SSH::AuthenticationFailed
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rye'
|
2
|
+
|
3
|
+
@local_sandbox = File.join(Rye.sysinfo.tmpdir, 'rye-tryouts')
|
4
|
+
@lbox = Rye::Box.new 'localhost'
|
5
|
+
Rye::Cmd.add_command :rm
|
6
|
+
|
7
|
+
|
8
|
+
## sandbox should not exist
|
9
|
+
@lbox.file_exists? @local_sandbox
|
10
|
+
#=> false
|
11
|
+
|
12
|
+
## create sandbox
|
13
|
+
@lbox.mkdir :p, @local_sandbox
|
14
|
+
@lbox.file_exists? @local_sandbox
|
15
|
+
#=> true
|
16
|
+
|
17
|
+
## upload file
|
18
|
+
@lbox.file_upload 'README.rdoc', @local_sandbox
|
19
|
+
@lbox.file_exists? File.join(@local_sandbox, 'README.rdoc')
|
20
|
+
#=> true
|
21
|
+
|
22
|
+
## download file
|
23
|
+
@downloaded_file = File.join(Rye.sysinfo.tmpdir, 'localfile')
|
24
|
+
@lbox.file_download File.join(@local_sandbox, 'README.rdoc'), @downloaded_file
|
25
|
+
@lbox.file_exists? @downloaded_file
|
26
|
+
#=> true
|
27
|
+
|
28
|
+
## download to StringIO
|
29
|
+
content = @lbox.file_download File.join(@local_sandbox, 'README.rdoc')
|
30
|
+
content.class
|
31
|
+
#=> StringIO
|
32
|
+
|
33
|
+
## downloaded StringIO matches file content
|
34
|
+
file = @lbox.file_download File.join(@local_sandbox, 'README.rdoc')
|
35
|
+
file.rewind
|
36
|
+
file.read == File.read(File.join(@local_sandbox, 'README.rdoc'))
|
37
|
+
#=> true
|
38
|
+
|
39
|
+
## destroy sandbox
|
40
|
+
@lbox.rm :r, :f, @local_sandbox
|
41
|
+
@lbox.file_exists? @local_sandbox
|
42
|
+
#=> false
|
43
|
+
|
44
|
+
|
45
|
+
@lbox.rm @downloaded_file
|
46
|
+
Rye::Cmd.remove_command :rm
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rye'
|
2
|
+
|
3
|
+
@local_sandbox = File.join(Rye.sysinfo.tmpdir, 'rye-tryouts')
|
4
|
+
@rendered = "#{@local_sandbox}/rendered.txt"
|
5
|
+
@lbox = Rye::Box.new 'localhost', :info => STDOUT
|
6
|
+
Rye::Cmd.add_command :rm
|
7
|
+
@lbox.rm :r, :f, @local_sandbox
|
8
|
+
|
9
|
+
## sandbox should not exist
|
10
|
+
File.exists? @local_sandbox
|
11
|
+
#=> false
|
12
|
+
|
13
|
+
## create sandbox
|
14
|
+
@lbox.mkdir :p, @local_sandbox
|
15
|
+
@lbox.file_exists? @local_sandbox
|
16
|
+
#=> true
|
17
|
+
|
18
|
+
## write template
|
19
|
+
@lbox.template_write @rendered, "<%= uname :a %>"
|
20
|
+
@lbox.file_exists? @rendered
|
21
|
+
#=> true
|
22
|
+
|
23
|
+
## upload multiple templates
|
24
|
+
@lbox.template_upload "Templ1", @local_sandbox
|
25
|
+
@lbox.file_exists? @rendered
|
26
|
+
#=> true
|
27
|
+
|
28
|
+
|
29
|
+
## destroy sandbox
|
30
|
+
#@lbox = Rye::Box.new
|
31
|
+
#Rye::Cmd.add_command :rm
|
32
|
+
#
|
33
|
+
#@lbox.file_exists? @local_sandbox
|
34
|
+
##=> false
|
35
|
+
|
36
|
+
|
37
|
+
Rye::Cmd.remove_command :rm
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'rye'
|
2
|
+
|
3
|
+
## enabled by default
|
4
|
+
Rye::Box.new.safe?
|
5
|
+
#=> true
|
6
|
+
|
7
|
+
## can be diabled when created
|
8
|
+
r = Rye::Box.new 'localhost', :safe => false
|
9
|
+
r.safe?
|
10
|
+
#=> false
|
11
|
+
|
12
|
+
## can be disabled on the fly
|
13
|
+
r = Rye::Box.new
|
14
|
+
r.disable_safe_mode
|
15
|
+
r.safe?
|
16
|
+
#=> false
|
17
|
+
|
18
|
+
## cannot execute arbitrary commands
|
19
|
+
begin
|
20
|
+
r = Rye::Box.new 'localhost'
|
21
|
+
r.execute '/bin/ls'
|
22
|
+
rescue Rye::CommandNotFound
|
23
|
+
:success
|
24
|
+
end
|
25
|
+
#=> :success
|
26
|
+
|
27
|
+
## cannot remove files
|
28
|
+
begin
|
29
|
+
r = Rye::Box.new 'localhost'
|
30
|
+
file = "/tmp/tryouts-#{rand.to_s}"
|
31
|
+
r.touch file
|
32
|
+
#p [:file_exists, r.file_exists?(file)]
|
33
|
+
r.rm file
|
34
|
+
rescue Rye::CommandNotFound
|
35
|
+
:success
|
36
|
+
end
|
37
|
+
#=> :success
|
38
|
+
|
39
|
+
## can use file globs
|
40
|
+
begin
|
41
|
+
r = Rye::Box.new 'localhost'
|
42
|
+
r.ls '/bin/**'
|
43
|
+
rescue Rye::Err
|
44
|
+
:success
|
45
|
+
end
|
46
|
+
#=> :success
|
47
|
+
|
48
|
+
## can use a tilda
|
49
|
+
begin
|
50
|
+
r = Rye::Box.new 'localhost'
|
51
|
+
r.ls '~'
|
52
|
+
rescue Rye::Err
|
53
|
+
:success
|
54
|
+
end
|
55
|
+
#=> :success
|
56
|
+
|
57
|
+
## can execute arbitrary commands
|
58
|
+
r = Rye::Box.new 'localhost', :safe => false
|
59
|
+
ret = r.execute '/bin/ls'
|
60
|
+
ret.empty?
|
61
|
+
#=> false
|
62
|
+
|
63
|
+
## can remove files
|
64
|
+
r = Rye::Box.new 'localhost', :safe => false
|
65
|
+
file = "/tmp/tryouts-#{rand.to_s}"
|
66
|
+
r.touch file
|
67
|
+
r.rm file
|
68
|
+
r.file_exists? file
|
69
|
+
#=> false
|
70
|
+
|
71
|
+
## can use file globs
|
72
|
+
r = Rye::Box.new 'localhost', :safe => false
|
73
|
+
ret = r.ls '/bin/**'
|
74
|
+
ret.empty?
|
75
|
+
#=> false
|
76
|
+
|
77
|
+
## can use a tilda
|
78
|
+
r = Rye::Box.new 'localhost', :safe => false
|
79
|
+
ret = r.ls '~'
|
80
|
+
ret.empty?
|
81
|
+
#=> false
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rye'
|
2
|
+
|
3
|
+
|
4
|
+
## a Rye::Hop instance defaults to localhost
|
5
|
+
lhop = Rye::Hop.new "localhost"
|
6
|
+
lhop.host
|
7
|
+
#=> 'localhost'
|
8
|
+
|
9
|
+
## can set up arbitray port forwards from the hop, a give you the localport
|
10
|
+
lhop = Rye::Hop.new "localhost"
|
11
|
+
lhop.host
|
12
|
+
lport = lhop.fetch_port("localhost", 22)
|
13
|
+
lport.is_a?(Fixnum)
|
14
|
+
#=> true
|
15
|
+
|
16
|
+
## Rye::Box can use Rye::Hop
|
17
|
+
lhop = Rye::Hop.new 'localhost'
|
18
|
+
lbox = Rye::Box.new 'localhost', :via => lhop
|
19
|
+
lbox.host
|
20
|
+
#=> 'localhost'
|
21
|
+
|
22
|
+
## Rye::Box still returns a Rye::Rap
|
23
|
+
lhop = Rye::Hop.new 'localhost'
|
24
|
+
lbox = Rye::Box.new 'localhost', :via => lhop
|
25
|
+
lbox.uptime.class
|
26
|
+
#=> Rye::Rap
|
27
|
+
|
28
|
+
## a Rye:Set of Rye::Box's can use a Rye::Hop
|
29
|
+
lset = Rye::Set.new 'hopset', :parallel => true
|
30
|
+
lhop = Rye::Hop.new 'localhost'
|
31
|
+
lbox0 = Rye::Box.new 'localhost', :via => lhop
|
32
|
+
lbox1 = Rye::Box.new 'localhost', :via => lhop
|
33
|
+
lbox2 = Rye::Box.new 'localhost', :via => lhop
|
34
|
+
lset.add_boxes lbox0, lbox1, lbox2
|
35
|
+
lset.host.count
|
36
|
+
#=> 3
|
File without changes
|
data/try/copying.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# THIS IS A SCRAP FILE.
|
4
|
+
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
6
|
+
|
7
|
+
require 'rye'
|
8
|
+
boxA = Rye::Box.new('localhost', :user => "delano")
|
9
|
+
boxB = Rye::Box.new('127.0.0.1', :user => 'delano', :safe => false, :debug => STDOUT)
|
10
|
+
set = Rye::Set.new
|
11
|
+
set.add_boxes(boxA, boxB)
|
12
|
+
|
13
|
+
#p boxA['/tmp/ssh-test'].cat.stderr
|
14
|
+
|
15
|
+
#boxB['/tmp/ssh-test'].copy_to boxA['/tmp'], boxA['/tmp']
|
16
|
+
|
17
|
+
|
18
|
+
p boxA.ls(:a)
|
data/try/keys.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# THIS IS A SCRAP FILE.
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
__END__
|
8
|
+
require 'openssl'
|
9
|
+
key = OpenSSL::PKey::RSA.generate(1024)
|
10
|
+
pub = key.public_key
|
11
|
+
ca = OpenSSL::X509::Name.parse("/C=US/ST=Florida/L=Miami/O=Waitingf/OU=Poopstat/CN=waitingf.org/emailAddress=bkerley@brycekerley.net")
|
12
|
+
cert = OpenSSL::X509::Certificate.new
|
13
|
+
cert.version = 2
|
14
|
+
cert.serial = 1
|
15
|
+
cert.subject = ca
|
16
|
+
cert.issuer = ca
|
17
|
+
cert.public_key = pub
|
18
|
+
cert.not_before = Time.now
|
19
|
+
cert.not_after = Time.now + 3600
|
20
|
+
File.open("private.pem", "w") { |f| f.write key.to_pem }
|
21
|
+
File.open("cert.pem", "w") { |f| f.write cert.to_pem }
|
22
|
+
|
23
|
+
require "openssl"
|
24
|
+
|
25
|
+
|
26
|
+
pkey = OpenSSL::PKey::RSA.new(512)
|
27
|
+
cert = OpenSSL::X509::Certificate.new
|
28
|
+
cert.version = 1
|
29
|
+
cert.subject = cert.issuer = OpenSSL::X509::Name.parse("/C=FOO")
|
30
|
+
cert.public_key = pkey.public_key
|
31
|
+
cert.not_before = Time.now
|
32
|
+
cert.not_after = Time.now+3600*24*365
|
33
|
+
cert.sign(pkey, OpenSSL::Digest::SHA1.new)
|
34
|
+
p12 = OpenSSL::PKCS12.create("passwd", "FriendlyName", pkey, cert)
|
35
|
+
#puts p12.to_der
|
36
|
+
|
37
|
+
__END__
|
38
|
+
# Tasks demonstrated:
|
39
|
+
# Creating a public-private key pair
|
40
|
+
# Saving individual keys to disk in PEM format
|
41
|
+
# Reading individual keys from disk
|
42
|
+
# Encyrpting with public key
|
43
|
+
# Decrypting with private key
|
44
|
+
# Checking whether a key has public | private key
|
45
|
+
|
46
|
+
require 'openssl'
|
47
|
+
|
48
|
+
# in a real rsa implementation, message would be the symmetric key
|
49
|
+
# used to encrypt the real message data
|
50
|
+
# which would be 'yourpass' in snippet http://www.bigbold.com/snippets/posts/show/576
|
51
|
+
message = "This is some cool text."
|
52
|
+
puts "\nOriginal Message: #{message}\n"
|
53
|
+
|
54
|
+
puts "Using ruby-openssl to generate the public and private keys\n"
|
55
|
+
|
56
|
+
# .generate creates an object containing both keys
|
57
|
+
new_key = OpenSSL::PKey::RSA.generate( 1024 )
|
58
|
+
puts "Does the generated key object have the public key? #{new_key.public?}\n"
|
59
|
+
puts "Does the generated key object have the private key? #{new_key.private?}\n\n"
|
60
|
+
|
61
|
+
# write the new keys as PEM's
|
62
|
+
new_public = new_key.public_key
|
63
|
+
puts "New public key pem:\n#{new_public}\n"
|
64
|
+
puts "The new public key in human readable form:\n"
|
65
|
+
puts new_public.to_text + "\n"
|
66
|
+
|
67
|
+
output_public = File.new("./new_public.pem", "w")
|
68
|
+
output_public.puts new_public
|
69
|
+
output_public.close
|
70
|
+
|
71
|
+
new_private = new_key.to_pem
|
72
|
+
puts "new private key pem:\n#{new_private}\n"
|
73
|
+
|
74
|
+
output_private = File.new("./new_private.pem", "w")
|
75
|
+
output_private.puts new_private
|
76
|
+
output_private.close
|
77
|
+
|
78
|
+
puts "\nEncrypt/decrypt using previously saved pem files on disk...\n"
|
79
|
+
# we encrypt with the public key
|
80
|
+
# note: of course the public key PEM contains only the public key
|
81
|
+
puts "Reading Public Key PEM...\n"
|
82
|
+
public_key = OpenSSL::PKey::RSA.new(File.read("./new_public.pem"))
|
83
|
+
puts "Does the public pem file have the public key? #{public_key.public?}\n"
|
84
|
+
puts "Does the public pem file have the private key? #{public_key.private?}\n"
|
85
|
+
puts "\nEncrypting with public key ...\n"
|
86
|
+
cipher_text = public_key.public_encrypt( message )
|
87
|
+
puts "cipher text:\n#{cipher_text}\n"
|
88
|
+
|
89
|
+
# get the private key from pem file and decrypt
|
90
|
+
# note the private key PEM contains both keys
|
91
|
+
puts "\nReading Private Key PEM...\n"
|
92
|
+
private_key = OpenSSL::PKey::RSA.new(File.read("./new_private.pem"))
|
93
|
+
puts "Does the private pem file have the public key? #{private_key.public?}\n"
|
94
|
+
puts "Does the private pem file have the private key? #{private_key.private?}\n"
|
95
|
+
puts "\nDecrypting with private key ...\n"
|
96
|
+
clear_text = private_key.private_decrypt( cipher_text )
|
97
|
+
puts "\ndecoded text:\n#{clear_text}\n\n"
|
98
|
+
|
99
|
+
|
100
|
+
__END__
|
101
|
+
|
102
|
+
# outputs: -rw-r--r--
|
103
|
+
def self.calc_mode pbit
|
104
|
+
# permission bit
|
105
|
+
mode = Array.new(10, '-')
|
106
|
+
mt = pbit & 0170000
|
107
|
+
# S_IFMT
|
108
|
+
case mt
|
109
|
+
# S_IFDIR
|
110
|
+
when 00040000
|
111
|
+
mode[0] = 'd'
|
112
|
+
# S_IFBLK
|
113
|
+
when 0060000
|
114
|
+
mode[0] = 'b'
|
115
|
+
# S_IFCHR
|
116
|
+
when 0020000
|
117
|
+
mode[0] = 'c'
|
118
|
+
# S_IFLNK
|
119
|
+
when 0120000
|
120
|
+
mode[0] = 'l'
|
121
|
+
# S_IFFIFO
|
122
|
+
when 0010000
|
123
|
+
mode[0] = 'p'
|
124
|
+
# S_IFSOCK
|
125
|
+
when 0140000
|
126
|
+
mode[0] = 's'
|
127
|
+
end
|
128
|
+
u = pbit & 00700
|
129
|
+
g = pbit & 00070
|
130
|
+
o = pbit & 00007
|
131
|
+
mode[1] = 'r' if u & 00400 != 0
|
132
|
+
mode[2] = 'w' if u & 00200 != 0
|
133
|
+
mode[3] = 'x' if u & 00100 != 0
|
134
|
+
mode[4] = 'r' if g & 00040 != 0
|
135
|
+
mode[5] = 'w' if g & 00020 != 0
|
136
|
+
mode[6] = 'x' if g & 00010 != 0
|
137
|
+
mode[7] = 'r' if o & 00004 != 0
|
138
|
+
mode[8] = 'w' if o & 00002 != 0
|
139
|
+
mode[9] = 'x' if o & 00001 != 0
|
140
|
+
mode.join('')
|
141
|
+
end
|