net-proto 1.0.6 → 1.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/CHANGES +9 -0
- data/MANIFEST +6 -6
- data/README +22 -15
- data/Rakefile +7 -58
- data/doc/netproto.txt +14 -17
- data/examples/example_net_proto.rb +11 -11
- data/lib/generic/net/proto.rb +145 -0
- data/lib/linux/net/proto.rb +140 -0
- data/lib/net/proto.rb +10 -0
- data/lib/net/proto/common.rb +37 -0
- data/lib/sunos/net/proto.rb +134 -0
- data/net-proto.gemspec +3 -6
- data/test/test_net_proto.rb +52 -45
- metadata +40 -27
- data/ext/extconf.rb +0 -19
- data/ext/generic/generic.c +0 -168
- data/ext/linux/linux.c +0 -175
- data/ext/sunos/sunos.c +0 -160
- data/ext/version.h +0 -2
- data/ext/windows/windows.c +0 -86
data/CHANGES
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
== 1.1.0 - 18-Jan-2012
|
2
|
+
* Switched to FFI instead of C backend. Now works with JRuby, too.
|
3
|
+
* Added the generic get_protocol instance method that accepts either a
|
4
|
+
string or an integer and does the right thing. This method should be
|
5
|
+
preferred going forward.
|
6
|
+
* Documentation updates.
|
7
|
+
* Refactored the test suite to use features of test-unit 2.x.
|
8
|
+
* Added a default rake task.
|
9
|
+
|
1
10
|
== 1.0.6 - 22-Oct-2010
|
2
11
|
* Refactored the test suite and removed one test that was implementation
|
3
12
|
dependent and not useful.
|
data/MANIFEST
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
* MANIFEST
|
3
3
|
* README
|
4
4
|
* Rakefile
|
5
|
-
* net-proto.gemspec
|
6
5
|
* doc/netproto.txt
|
6
|
+
* net-proto.gemspec
|
7
|
+
* lib/net/proto.rb
|
8
|
+
* lib/net/proto/common.rb
|
9
|
+
* lib/generic/net/proto.rb
|
10
|
+
* lib/linux/net/proto.rb
|
11
|
+
* lib/sunos/net/proto.rb
|
7
12
|
* examples/example_net_proto.rb
|
8
|
-
* ext/version.h
|
9
|
-
* ext/generic/generic.c
|
10
|
-
* ext/linux/linux.c
|
11
|
-
* ext/sunos/sunos.c
|
12
|
-
* ext/windows/windows.c
|
13
13
|
* test/test_net_proto.rb
|
data/README
CHANGED
@@ -1,34 +1,41 @@
|
|
1
|
-
|
1
|
+
== Description
|
2
2
|
The net-proto package provides a way to get protocol information.
|
3
3
|
|
4
|
-
|
4
|
+
This is a wrapper for the getprotobyname(), getprotobynumber() and
|
5
|
+
the getprotoent() functions.
|
6
|
+
|
7
|
+
== Installation
|
5
8
|
gem install net-proto
|
6
9
|
|
7
|
-
|
8
|
-
|
10
|
+
== Prerequisites
|
11
|
+
ffi 1.0.0 or later.
|
9
12
|
|
10
|
-
|
11
|
-
|
13
|
+
== Synopsis
|
14
|
+
require 'net/proto'
|
12
15
|
|
13
|
-
|
16
|
+
# Using generic method
|
17
|
+
Net::Proto.get_protocol(1) # => 'icmp'
|
18
|
+
Net::Proto.get_protocol('icmp') # => 1
|
14
19
|
|
15
|
-
|
16
|
-
|
17
|
-
|
20
|
+
# Using type specific methods
|
21
|
+
Net::Proto.getprotobynumber(6) # => 'tcp'
|
22
|
+
Net::Proto.getprotobyname('tcp') # => 6
|
18
23
|
|
19
|
-
|
20
|
-
|
21
|
-
|
24
|
+
# Iterating over all protocols
|
25
|
+
Net::Proto.getprotoent do |ent|
|
26
|
+
p ent
|
27
|
+
end
|
22
28
|
|
29
|
+
== MS Windows
|
23
30
|
The Proto.getprotoent method is not supported on MS Windows because the
|
24
31
|
underlying function isn't supported by the MS Windows API.
|
25
32
|
|
26
|
-
|
33
|
+
== Why should I use this?
|
27
34
|
Ruby has a predefined set of constants in socket.c in the general form of
|
28
35
|
IPPROTO_XXX, Y. However, using constants in this fashion can be unreliable
|
29
36
|
because it's easy to define your own protocols (I set 'echo' to 7, for
|
30
37
|
example), or to modify/delete entries in /etc/protocols.
|
31
38
|
|
32
|
-
|
39
|
+
== Further Documentation
|
33
40
|
See the 'netproto.txt' file under the 'doc' directory for more details. There
|
34
41
|
is also an example under the 'examples' directory.
|
data/Rakefile
CHANGED
@@ -1,80 +1,29 @@
|
|
1
1
|
require 'rake'
|
2
|
-
require 'rake/clean'
|
3
2
|
require 'rake/testtask'
|
4
|
-
require '
|
5
|
-
include Config
|
6
|
-
|
7
|
-
desc 'Clean the build files for the net-proto source'
|
8
|
-
task :clean do
|
9
|
-
Dir['*.gem'].each{ |f| File.delete(f) }
|
10
|
-
Dir['**/*.rbc'].each{ |f| File.delete(f) }
|
11
|
-
|
12
|
-
make = RUBY_PLATFORM.match('mswin') ? 'nmake' : 'make'
|
13
|
-
|
14
|
-
Dir.chdir('ext') do
|
15
|
-
proto_file = 'proto.' + Config::CONFIG['DLEXT']
|
16
|
-
if File.exists?('proto.o') || File.exists?(proto_file)
|
17
|
-
sh "#{make} distclean"
|
18
|
-
end
|
19
|
-
rm_rf('proto.c') if File.exists?('proto.c')
|
20
|
-
rm_rf('net') if File.exists?('net')
|
21
|
-
end
|
22
|
-
|
23
|
-
rm_rf('net') if File.exists?('net')
|
24
|
-
rm_rf('lib') if File.exists?('lib')
|
25
|
-
end
|
3
|
+
require 'rake/clean'
|
26
4
|
|
27
|
-
|
28
|
-
task :build => [:clean] do
|
29
|
-
make = RUBY_PLATFORM.match('mswin') ? 'nmake' : 'make'
|
30
|
-
Dir.chdir('ext') do
|
31
|
-
ruby 'extconf.rb'
|
32
|
-
sh make
|
33
|
-
build_file = 'proto.' + Config::CONFIG['DLEXT']
|
34
|
-
Dir.mkdir('net') unless File.exists?('net')
|
35
|
-
FileUtils.cp(build_file, 'net')
|
36
|
-
end
|
37
|
-
end
|
5
|
+
CLEAN.include('**/*.gem', '**/*.rbx', '**/*.rbc')
|
38
6
|
|
39
|
-
namespace
|
40
|
-
desc '
|
7
|
+
namespace 'gem' do
|
8
|
+
desc 'Create the net-proto gem'
|
41
9
|
task :create => :clean do
|
42
|
-
rm_rf('lib') if File.exists?('lib')
|
43
|
-
spec = eval(IO.read('net-proto.gemspec'))
|
44
|
-
Gem::Builder.new(spec).build
|
45
|
-
end
|
46
|
-
|
47
|
-
desc 'Build a binary gem'
|
48
|
-
task :create_binary => [:build] do
|
49
|
-
file = 'ext/net/proto.' + CONFIG['DLEXT']
|
50
|
-
mkdir_p('lib/net')
|
51
|
-
mv(file, 'lib/net')
|
52
|
-
|
53
10
|
spec = eval(IO.read('net-proto.gemspec'))
|
54
|
-
spec.extensions = nil
|
55
|
-
spec.files = spec.files.reject{ |f| f.include?('ext/') }
|
56
|
-
spec.platform = Gem::Platform::CURRENT
|
57
|
-
|
58
11
|
Gem::Builder.new(spec).build
|
59
12
|
end
|
60
13
|
|
61
|
-
desc 'Install the net-proto
|
14
|
+
desc 'Install the net-proto gem'
|
62
15
|
task :install => [:create] do
|
63
|
-
ruby 'net-proto.gemspec'
|
64
16
|
file = Dir["net-proto*.gem"].last
|
65
17
|
sh "gem install #{file}"
|
66
18
|
end
|
67
19
|
end
|
68
20
|
|
69
21
|
desc 'Run the example net-proto program'
|
70
|
-
task :example
|
71
|
-
|
72
|
-
ruby '-Iext examples/example_net_proto.rb'
|
22
|
+
task :example do
|
23
|
+
ruby '-Ilib examples/example_net_proto.rb'
|
73
24
|
end
|
74
25
|
|
75
26
|
Rake::TestTask.new do |t|
|
76
|
-
task :test => :build
|
77
|
-
t.libs << 'ext'
|
78
27
|
t.warning = true
|
79
28
|
t.verbose = true
|
80
29
|
end
|
data/doc/netproto.txt
CHANGED
@@ -44,39 +44,36 @@ Proto.getprotoent{ |struct| ... }
|
|
44
44
|
|
45
45
|
== Notes
|
46
46
|
This module uses the reentrant (i.e. thread safe) functions on those
|
47
|
-
platforms that support them.
|
47
|
+
platforms that support them. In some cases, e.g. FreeBSD and HP-UX, the
|
48
48
|
standard function names are reentrant by default (i.e. there is no '_r'
|
49
|
-
version, or it's not needed)
|
50
|
-
all platforms.
|
49
|
+
version, or it's not needed).
|
51
50
|
|
52
51
|
The 'setprotoent()' and 'endprotoent()' functions are not implemented as
|
53
|
-
separate method calls.
|
52
|
+
separate method calls. Rather, these are called internally by the various
|
54
53
|
methods, except on Windows, which does not support them.
|
55
54
|
|
56
55
|
The 'getprotoent()' method is not supported on the MS Windows platform.
|
57
56
|
It's not part of the API as of Windows XP.
|
58
57
|
|
59
58
|
== Known Bugs
|
60
|
-
|
61
|
-
|
59
|
+
None that I'm aware of. Please log any bug reports on the project page
|
60
|
+
at https://github.com/djberg96/net-proto.
|
62
61
|
|
63
62
|
== Future Plans
|
64
|
-
|
65
|
-
|
63
|
+
Use the asynchronous calls (WSAAsyncGetProtoByName and
|
64
|
+
WSAAsyncGetProtoByNumber) on MS Windows systems.
|
66
65
|
|
67
66
|
== Copyright
|
68
|
-
|
69
|
-
|
67
|
+
(C) 2003-2012 Daniel J. Berger
|
68
|
+
All rights reserved.
|
70
69
|
|
71
70
|
== Warranty
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
This package is provided "as is" and without any express or
|
72
|
+
implied warranties, including, without limitation, the implied
|
73
|
+
warranties of merchantability and fitness for a particular purpose.
|
75
74
|
|
76
75
|
== License
|
77
|
-
|
76
|
+
Artistic 2.0
|
78
77
|
|
79
78
|
== Author
|
80
|
-
|
81
|
-
djberg96 at gmail dot com
|
82
|
-
imperator on IRC (Freenode)
|
79
|
+
Daniel J. Berger
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# A generic test program for general futzing. You cna run this example
|
5
5
|
# code via the 'rake example' task.
|
6
6
|
#########################################################################
|
7
|
-
require 'net/proto'
|
7
|
+
require 'net/proto'
|
8
8
|
include Net
|
9
9
|
|
10
10
|
puts "VERSION: " + Proto::VERSION
|
@@ -12,14 +12,14 @@ puts "VERSION: " + Proto::VERSION
|
|
12
12
|
puts "UDP port: " + Proto.getprotobyname("udp").to_s
|
13
13
|
|
14
14
|
unless File::ALT_SEPARATOR
|
15
|
-
|
16
|
-
|
15
|
+
puts "Name\t\tProto\tAliases"
|
16
|
+
puts "=========================="
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
}
|
25
|
-
end
|
18
|
+
Proto.getprotoent.each{ |s|
|
19
|
+
if s.name.length > 7
|
20
|
+
puts s.name + "\t" + s.proto.to_s + "\t" + s.aliases.join(", ")
|
21
|
+
else
|
22
|
+
puts s.name + "\t\t" + s.proto.to_s + "\t" + s.aliases.join(", ")
|
23
|
+
end
|
24
|
+
}
|
25
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'net/proto/common'
|
2
|
+
|
3
|
+
# The Net module serves as a namespace only.
|
4
|
+
module Net
|
5
|
+
# The Proto class serves as the base class for the various protocol methods.
|
6
|
+
class Proto
|
7
|
+
extend FFI::Library
|
8
|
+
|
9
|
+
ffi_lib FFI::Library::LIBC
|
10
|
+
|
11
|
+
if File::ALT_SEPARATOR
|
12
|
+
ffi_lib 'ws2_32'
|
13
|
+
ffi_convention :stdcall
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# These should exist on every platform.
|
19
|
+
attach_function :getprotobyname_c, :getprotobyname, [:string], :pointer
|
20
|
+
attach_function :getprotobynumber_c, :getprotobynumber, [:int], :pointer
|
21
|
+
|
22
|
+
# These are defined on most platforms, but not all.
|
23
|
+
begin
|
24
|
+
attach_function :setprotoent, [:int], :void
|
25
|
+
attach_function :endprotoent, [], :void
|
26
|
+
attach_function :getprotoent_c, :getprotoent, [], :pointer
|
27
|
+
rescue FFI::NotFoundError
|
28
|
+
# Ignore, not supported. Probably Windows.
|
29
|
+
else
|
30
|
+
private_class_method :setprotoent
|
31
|
+
private_class_method :endprotoent
|
32
|
+
private_class_method :getprotoent_c
|
33
|
+
end
|
34
|
+
|
35
|
+
private_class_method :getprotobyname_c
|
36
|
+
private_class_method :getprotobynumber_c
|
37
|
+
|
38
|
+
public
|
39
|
+
|
40
|
+
# If given a protocol string, returns the corresponding number. If
|
41
|
+
# given a protocol number, returns the corresponding string.
|
42
|
+
#
|
43
|
+
# Returns nil if not found in either case.
|
44
|
+
#
|
45
|
+
# Examples:
|
46
|
+
#
|
47
|
+
# Net::Proto.get_protocol('tcp') # => 6
|
48
|
+
# Net::Proto.get_protocol(1) # => 'icmp'
|
49
|
+
#
|
50
|
+
def self.get_protocol(arg)
|
51
|
+
if arg.is_a?(String)
|
52
|
+
getprotobyname(arg)
|
53
|
+
else
|
54
|
+
getprotobynumber(arg)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Given a protocol string, returns the corresponding number, or nil if
|
59
|
+
# not found.
|
60
|
+
#
|
61
|
+
# Examples:
|
62
|
+
#
|
63
|
+
# Net::Proto.getprotobyname('tcp') # => 6
|
64
|
+
# Net::Proto.getprotobyname('bogus') # => nil
|
65
|
+
#
|
66
|
+
def self.getprotobyname(protocol)
|
67
|
+
raise TypeError unless protocol.is_a?(String)
|
68
|
+
|
69
|
+
begin
|
70
|
+
setprotoent(0) if respond_to?(:setprotoent, true)
|
71
|
+
ptr = getprotobyname_c(protocol)
|
72
|
+
struct = ProtocolStruct.new(ptr) unless ptr.null?
|
73
|
+
ensure
|
74
|
+
endprotoent() if respond_to?(:endprotoent, true)
|
75
|
+
end
|
76
|
+
|
77
|
+
ptr.null? ? nil : struct[:p_proto]
|
78
|
+
end
|
79
|
+
|
80
|
+
# Given a protocol number, returns the corresponding string, or nil if
|
81
|
+
# not found.
|
82
|
+
#
|
83
|
+
# Examples:
|
84
|
+
#
|
85
|
+
# Net::Proto.getprotobynumber(6) # => 'tcp'
|
86
|
+
# Net::Proto.getprotobynumber(999) # => nil
|
87
|
+
#
|
88
|
+
def self.getprotobynumber(protocol)
|
89
|
+
raise TypeError unless protocol.is_a?(Integer)
|
90
|
+
|
91
|
+
begin
|
92
|
+
setprotoent(0) if respond_to?(:setprotoent, true)
|
93
|
+
ptr = getprotobynumber_c(protocol)
|
94
|
+
struct = ProtocolStruct.new(ptr) unless ptr.null?
|
95
|
+
ensure
|
96
|
+
endprotoent() if respond_to?(:endprotoent, true)
|
97
|
+
end
|
98
|
+
|
99
|
+
ptr.null? ? nil: struct[:p_name]
|
100
|
+
end
|
101
|
+
|
102
|
+
# In block form, yields each entry from /etc/protocols as a struct of type
|
103
|
+
# Proto::ProtoStruct. In non-block form, returns an array of structs.
|
104
|
+
#
|
105
|
+
# The fields are 'name' (a string), 'aliases' (an array of strings,
|
106
|
+
# though often only one element), and 'proto' (a number).
|
107
|
+
#
|
108
|
+
# Example:
|
109
|
+
#
|
110
|
+
# Net::Proto.getprotoent.each{ |prot|
|
111
|
+
# p prot.name
|
112
|
+
# p prot.aliases
|
113
|
+
# p prot.proto
|
114
|
+
# }
|
115
|
+
#
|
116
|
+
def self.getprotoent
|
117
|
+
raise NoMethodError unless respond_to?(:getprotoent, true)
|
118
|
+
|
119
|
+
structs = block_given? ? nil : []
|
120
|
+
|
121
|
+
begin
|
122
|
+
setprotoent(0)
|
123
|
+
until (ptr = getprotoent_c()).null?
|
124
|
+
ffi_struct = ProtocolStruct.new(ptr)
|
125
|
+
|
126
|
+
ruby_struct = ProtoStruct.new(
|
127
|
+
ffi_struct[:p_name],
|
128
|
+
ffi_struct[:p_aliases].read_array_of_string,
|
129
|
+
ffi_struct[:p_proto]
|
130
|
+
).freeze
|
131
|
+
|
132
|
+
if block_given?
|
133
|
+
yield ruby_struct
|
134
|
+
else
|
135
|
+
structs << ruby_struct
|
136
|
+
end
|
137
|
+
end
|
138
|
+
ensure
|
139
|
+
endprotoent()
|
140
|
+
end
|
141
|
+
|
142
|
+
structs
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'net/proto/common'
|
2
|
+
|
3
|
+
# The Net module serves as a namespace only.
|
4
|
+
module Net
|
5
|
+
|
6
|
+
# The Proto class serves as the base class for the various protocol methods.
|
7
|
+
class Proto
|
8
|
+
ffi_lib FFI::Library::LIBC
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
attach_function :setprotoent, [:int], :void
|
13
|
+
attach_function :endprotoent, [], :void
|
14
|
+
attach_function :getprotobyname_r, [:string, :pointer, :pointer, :long, :pointer], :int
|
15
|
+
attach_function :getprotobynumber_r, [:int, :pointer, :pointer, :long, :pointer], :int
|
16
|
+
attach_function :getprotoent_r, [:pointer, :pointer, :long, :pointer], :int
|
17
|
+
|
18
|
+
private_class_method :setprotoent, :endprotoent, :getprotobyname_r
|
19
|
+
private_class_method :getprotobynumber_r, :getprotoent_r
|
20
|
+
|
21
|
+
public
|
22
|
+
|
23
|
+
# If given a protocol string, returns the corresponding number. If
|
24
|
+
# given a protocol number, returns the corresponding string.
|
25
|
+
#
|
26
|
+
# Returns nil if not found in either case.
|
27
|
+
#
|
28
|
+
# Examples:
|
29
|
+
#
|
30
|
+
# Net::Proto.get_protocol('tcp') # => 6
|
31
|
+
# Net::Proto.get_protocol(1) # => 'icmp'
|
32
|
+
#
|
33
|
+
def self.get_protocol(argument)
|
34
|
+
if argument.is_a?(String)
|
35
|
+
getprotobyname(argument)
|
36
|
+
else
|
37
|
+
getprotobynumber(argument)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Given a protocol string, returns the corresponding number, or nil if
|
42
|
+
# not found.
|
43
|
+
#
|
44
|
+
# Examples:
|
45
|
+
#
|
46
|
+
# Net::Proto.getprotobyname('tcp') # => 6
|
47
|
+
# Net::Proto.getprotobyname('bogus') # => nil
|
48
|
+
#
|
49
|
+
def self.getprotobyname(protocol)
|
50
|
+
raise TypeError unless protocol.is_a?(String)
|
51
|
+
|
52
|
+
pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
53
|
+
qptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
54
|
+
buf = FFI::MemoryPointer.new(:char, 1024)
|
55
|
+
|
56
|
+
begin
|
57
|
+
setprotoent(0)
|
58
|
+
int = getprotobyname_r(protocol, pptr, buf, buf.size, qptr)
|
59
|
+
ensure
|
60
|
+
endprotoent()
|
61
|
+
end
|
62
|
+
|
63
|
+
int > 0 || qptr.get_pointer(0).null? ? nil : ProtocolStruct.new(pptr)[:p_proto]
|
64
|
+
end
|
65
|
+
|
66
|
+
# Given a protocol number, returns the corresponding string, or nil if
|
67
|
+
# not found.
|
68
|
+
#
|
69
|
+
# Examples:
|
70
|
+
#
|
71
|
+
# Net::Proto.getprotobynumber(6) # => 'tcp'
|
72
|
+
# Net::Proto.getprotobynumber(999) # => nil
|
73
|
+
#
|
74
|
+
def self.getprotobynumber(protocol)
|
75
|
+
raise TypeError unless protocol.is_a?(Integer)
|
76
|
+
|
77
|
+
pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
78
|
+
qptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
79
|
+
buf = FFI::MemoryPointer.new(:char, 1024)
|
80
|
+
|
81
|
+
begin
|
82
|
+
setprotoent(0)
|
83
|
+
int = getprotobynumber_r(protocol, pptr, buf, buf.size, qptr)
|
84
|
+
ensure
|
85
|
+
endprotoent()
|
86
|
+
end
|
87
|
+
|
88
|
+
int > 0 || qptr.get_pointer(0).null? ? nil : ProtocolStruct.new(pptr)[:p_name]
|
89
|
+
end
|
90
|
+
|
91
|
+
# In block form, yields each entry from /etc/protocols as a struct of type
|
92
|
+
# Proto::ProtoStruct. In non-block form, returns an array of structs.
|
93
|
+
#
|
94
|
+
# The fields are 'name' (a string), 'aliases' (an array of strings,
|
95
|
+
# though often only one element), and 'proto' (a number).
|
96
|
+
#
|
97
|
+
# Example:
|
98
|
+
#
|
99
|
+
# Net::Proto.getprotoent.each{ |prot|
|
100
|
+
# p prot.name
|
101
|
+
# p prot.aliases
|
102
|
+
# p prot.proto
|
103
|
+
# }
|
104
|
+
#
|
105
|
+
def self.getprotoent
|
106
|
+
structs = block_given? ? nil : []
|
107
|
+
|
108
|
+
pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
109
|
+
qptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
110
|
+
buf = FFI::MemoryPointer.new(1024)
|
111
|
+
|
112
|
+
begin
|
113
|
+
setprotoent(0)
|
114
|
+
|
115
|
+
while int = getprotoent_r(pptr, buf, buf.size, qptr)
|
116
|
+
break if int > 0 || qptr.null?
|
117
|
+
buf = FFI::MemoryPointer.new(1024)
|
118
|
+
|
119
|
+
ffi_struct = ProtocolStruct.new(pptr)
|
120
|
+
|
121
|
+
ruby_struct = ProtoStruct.new(
|
122
|
+
ffi_struct[:p_name],
|
123
|
+
ffi_struct[:p_aliases].read_array_of_string,
|
124
|
+
ffi_struct[:p_proto]
|
125
|
+
).freeze
|
126
|
+
|
127
|
+
if block_given?
|
128
|
+
yield ruby_struct
|
129
|
+
else
|
130
|
+
structs << ruby_struct
|
131
|
+
end
|
132
|
+
end
|
133
|
+
ensure
|
134
|
+
endprotoent
|
135
|
+
end
|
136
|
+
|
137
|
+
structs
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|