net-netrc 0.1.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/lib/net/netrc.rb +166 -0
- data/test/test_netrc.rb +96 -0
- metadata +52 -0
data/lib/net/netrc.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
# = net/netrc.rb - ftp(1) .netrc parsing
|
2
|
+
#
|
3
|
+
# Copyright (c) 2005 Robert J. Showalter
|
4
|
+
#
|
5
|
+
# This library is distributed under the terms of the Ruby license.
|
6
|
+
# You may freely distribute or modify this library.
|
7
|
+
#
|
8
|
+
# See Net::Netrc for usage.
|
9
|
+
#
|
10
|
+
# $Id: netrc.rb,v 1.1 2005/12/15 15:09:01 bshow Exp $
|
11
|
+
|
12
|
+
require 'etc'
|
13
|
+
|
14
|
+
module Net
|
15
|
+
|
16
|
+
class Netrc
|
17
|
+
|
18
|
+
VERSION_MAJOR = 0
|
19
|
+
VERSION_MINOR = 1
|
20
|
+
VERSION_PATCH = 0
|
21
|
+
VERSION = "#{VERSION_MAJOR}.#{VERSION_MINOR}.#{VERSION_PATCH}"
|
22
|
+
|
23
|
+
# detect whether running on MS Windows platform
|
24
|
+
# use Matt Mower's Platform module if available
|
25
|
+
# (//http://rubyforge.org/projects/platform/)
|
26
|
+
begin
|
27
|
+
require 'platform'
|
28
|
+
IS_WIN32 = Platform::OS == :win32
|
29
|
+
rescue LoadError
|
30
|
+
IS_WIN32 = RUBY_PLATFORM =~ /mswin|mingw|bccwin|wince/i
|
31
|
+
end
|
32
|
+
|
33
|
+
# machine name, or nil if default entry
|
34
|
+
attr_accessor :machine
|
35
|
+
|
36
|
+
# login name (nil if none)
|
37
|
+
attr_accessor :login
|
38
|
+
|
39
|
+
# password (nil if none)
|
40
|
+
attr_accessor :password
|
41
|
+
|
42
|
+
# account name (nil if none)
|
43
|
+
attr_accessor :account
|
44
|
+
|
45
|
+
# Returns name of .netrc file
|
46
|
+
#
|
47
|
+
# If the environment variable <tt>NETRC</tt> is set, it is used
|
48
|
+
# as the name of the .netrc file. Otherwise, a search
|
49
|
+
# is made for <tt>.netrc</tt> (and <tt>_netrc</tt> on Windows) in the
|
50
|
+
# following locations. The first existing file found
|
51
|
+
# will be returned.
|
52
|
+
#
|
53
|
+
# - User's home directory as returned by <tt>Etc.getpwuid</tt>
|
54
|
+
# - <tt>ENV['HOME']</tt> directory
|
55
|
+
#
|
56
|
+
# On Windows platforms, the following additional locations
|
57
|
+
# are checked:
|
58
|
+
# - <tt>ENV['USERPROFILE']</tt>
|
59
|
+
# - <tt>ENV['HOMEPATH']</tt>
|
60
|
+
# - <tt>ENV['HOMEDRIVE'] + ENV['HOMEDIR']</tt>
|
61
|
+
def Netrc.rcname
|
62
|
+
|
63
|
+
# use file indicated by NETRC environment variable if defined
|
64
|
+
return ENV['NETRC'] if ENV['NETRC']
|
65
|
+
|
66
|
+
dirs = []
|
67
|
+
files = ['.netrc']
|
68
|
+
|
69
|
+
# build candidate list of directories to check
|
70
|
+
pw = Etc.getpwuid
|
71
|
+
dirs << pw.dir if pw
|
72
|
+
dirs << ENV['HOME']
|
73
|
+
if IS_WIN32
|
74
|
+
dirs << ENV['USERPROFILE']
|
75
|
+
dirs << ENV['HOMESHARE']
|
76
|
+
dirs << ENV['HOMEDRIVE'] + ENV['HOMEPATH'] || '' if ENV['HOMEDRIVE']
|
77
|
+
files << '_netrc'
|
78
|
+
end
|
79
|
+
|
80
|
+
# return first found file
|
81
|
+
dirs.flatten.each do |dir|
|
82
|
+
files.each do |file|
|
83
|
+
name = File.join(dir, file)
|
84
|
+
return name if File.exist?(name)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# nothing found
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
|
92
|
+
# opens .netrc file, returning File object if successful.
|
93
|
+
# +name+ is the name of the .netrc file to open. If omitted,
|
94
|
+
# #rcname is used to locate the file.
|
95
|
+
#
|
96
|
+
# returns nil if the file does not exist.
|
97
|
+
#
|
98
|
+
# On non-Windows platforms, raises SecurityError if the file
|
99
|
+
# is not owned by the current user or if it is readable or
|
100
|
+
# writable by other than the current user.
|
101
|
+
def Netrc.rcopen(name = nil)
|
102
|
+
name ||= rcname or return nil
|
103
|
+
return nil unless File.exist?(name)
|
104
|
+
unless IS_WIN32
|
105
|
+
s = File.stat(name)
|
106
|
+
raise SecurityError, "Not owner: #{name}" unless s.owned?
|
107
|
+
raise SecurityError, "Bad permissions: #{name}" if s.mode & 077 != 0
|
108
|
+
end
|
109
|
+
File.open(name, 'r')
|
110
|
+
end
|
111
|
+
|
112
|
+
# given a machine name, returns a Net::Netrc object containing
|
113
|
+
# the matching entry for that name, or the default entry. If
|
114
|
+
# no match is found and no default entry exists, nil is returned.
|
115
|
+
#
|
116
|
+
# +io+ is a previously-opened IO object. If not supplied,
|
117
|
+
# #rcopen is called to locate and open the .netrc file. +io+
|
118
|
+
# will be closed when this method returns.
|
119
|
+
def Netrc.locate(mach, io = nil)
|
120
|
+
need_close = false
|
121
|
+
if io.nil?
|
122
|
+
io = rcopen or return nil
|
123
|
+
need_close = true
|
124
|
+
end
|
125
|
+
entry = nil
|
126
|
+
key = nil
|
127
|
+
inmacdef = false
|
128
|
+
begin
|
129
|
+
while line = io.gets
|
130
|
+
if inmacdef
|
131
|
+
inmacdef = false if line.strip.empty?
|
132
|
+
next
|
133
|
+
end
|
134
|
+
toks = line.scan(/"((?:\\.|[^"])*)"|((?:\\.|\S)+)/).flatten.compact
|
135
|
+
toks.each { |t| t.gsub!(/\\(.)/, '\1') }
|
136
|
+
while toks.length > 0
|
137
|
+
tok = toks.shift
|
138
|
+
if key
|
139
|
+
entry = new if key == 'machine' && tok == mach
|
140
|
+
entry.send "#{key}=", tok if entry
|
141
|
+
key = nil
|
142
|
+
end
|
143
|
+
case tok
|
144
|
+
when 'default'
|
145
|
+
return entry if entry
|
146
|
+
entry = new
|
147
|
+
when 'machine'
|
148
|
+
return entry if entry
|
149
|
+
key = 'machine'
|
150
|
+
when 'login', 'password', 'account'
|
151
|
+
key = tok
|
152
|
+
when 'macdef'
|
153
|
+
inmacdef = true
|
154
|
+
break
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
ensure
|
159
|
+
io.close if need_close
|
160
|
+
end
|
161
|
+
entry
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
data/test/test_netrc.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# $Id: test_netrc.rb,v 1.1 2005/12/15 15:09:01 bshow Exp $
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), "../lib")
|
4
|
+
|
5
|
+
require 'net/netrc'
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
class TestNetrc < Test::Unit::TestCase
|
9
|
+
|
10
|
+
SAMPLE_NETRC = 'dot.netrc.test'
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@path = File.join(File.dirname(__FILE__), SAMPLE_NETRC)
|
14
|
+
File.open(@path, 'w') do |f|
|
15
|
+
f << <<EOT
|
16
|
+
machine example.com
|
17
|
+
login example_login
|
18
|
+
password example_password
|
19
|
+
account example_account
|
20
|
+
|
21
|
+
machine twowords.com
|
22
|
+
login "twowords login"
|
23
|
+
password "twowords password"
|
24
|
+
account "twowords account"
|
25
|
+
|
26
|
+
macdef foo
|
27
|
+
this is a macro definition.
|
28
|
+
it starts with the line following 'macdef',
|
29
|
+
and ends with a null line (consecutive newline characters)
|
30
|
+
|
31
|
+
default
|
32
|
+
login default_login
|
33
|
+
password default_password
|
34
|
+
|
35
|
+
machine unreached.com
|
36
|
+
login unreached_login
|
37
|
+
password unreached_password
|
38
|
+
|
39
|
+
EOT
|
40
|
+
end
|
41
|
+
File.chmod(0600, @path)
|
42
|
+
ENV['NETRC'] = @path
|
43
|
+
end
|
44
|
+
|
45
|
+
def teardown
|
46
|
+
File.unlink @path
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_path
|
50
|
+
assert_not_nil(ENV['NETRC'])
|
51
|
+
assert(File.exists?(ENV['NETRC']), '#{SAMPLE_NETRC} not found')
|
52
|
+
assert_equal(Net::Netrc.rcname, @path)
|
53
|
+
end
|
54
|
+
|
55
|
+
unless Net::Netrc::IS_WIN32
|
56
|
+
def test_security
|
57
|
+
File.chmod(0666, @path)
|
58
|
+
assert_raise(SecurityError) { Net::Netrc.rcopen }
|
59
|
+
File.chmod(0600, @path)
|
60
|
+
assert_nothing_raised { Net::Netrc.rcopen }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_entries
|
65
|
+
|
66
|
+
entry = Net::Netrc.locate('example.com')
|
67
|
+
assert_not_nil(entry)
|
68
|
+
assert_equal('example.com', entry.machine)
|
69
|
+
assert_equal('example_login', entry.login)
|
70
|
+
assert_equal('example_password', entry.password)
|
71
|
+
assert_equal('example_account', entry.account)
|
72
|
+
|
73
|
+
entry = Net::Netrc.locate('twowords.com')
|
74
|
+
assert_not_nil(entry)
|
75
|
+
assert_equal('twowords.com', entry.machine)
|
76
|
+
assert_equal('twowords login', entry.login)
|
77
|
+
assert_equal('twowords password', entry.password)
|
78
|
+
assert_equal('twowords account', entry.account)
|
79
|
+
|
80
|
+
default = Net::Netrc.locate('')
|
81
|
+
assert_not_nil(default)
|
82
|
+
assert_nil(default.machine)
|
83
|
+
assert_equal('default_login', default.login)
|
84
|
+
assert_equal('default_password', default.password)
|
85
|
+
assert_nil(default.account)
|
86
|
+
|
87
|
+
entry = Net::Netrc.locate('unreached.com')
|
88
|
+
assert_not_nil(entry)
|
89
|
+
assert_equal(default.machine, entry.machine)
|
90
|
+
assert_equal(default.login, entry.login)
|
91
|
+
assert_equal(default.password, entry.password)
|
92
|
+
assert_equal(default.account, entry.account)
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: net-netrc
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2005-12-15 00:00:00 -05:00
|
8
|
+
summary: Net::Netrc provides ftp(1)-style .netrc parsing
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: bshow@rubyforge.org
|
12
|
+
homepage: http://net-netrc.rubyforge.org
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: net/netrc
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
signing_key:
|
28
|
+
cert_chain:
|
29
|
+
authors:
|
30
|
+
- Bob Showalter
|
31
|
+
files:
|
32
|
+
- lib/net
|
33
|
+
- lib/net/netrc.rb
|
34
|
+
- test/test_netrc.rb
|
35
|
+
test_files:
|
36
|
+
- test/test_netrc.rb
|
37
|
+
rdoc_options: []
|
38
|
+
extra_rdoc_files: []
|
39
|
+
executables: []
|
40
|
+
extensions: []
|
41
|
+
requirements: []
|
42
|
+
dependencies:
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: Platform
|
45
|
+
version_requirement:
|
46
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
47
|
+
requirements:
|
48
|
+
-
|
49
|
+
- ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: 0.3.0
|
52
|
+
version:
|