rslp 0.0.2 → 0.1.1
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGES.md +15 -0
- data/README.md +11 -0
- data/lib/rslp.rb +54 -15
- data/lib/slp/functions.rb +4 -1
- data/rslp.gemspec +3 -3
- data/spec/rslp_spec.rb +149 -5
- data.tar.gz.sig +0 -0
- metadata +5 -5
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c95a3256bfee540b035527983b2855d2ed8cfee989c766674259cc5649c928f
|
4
|
+
data.tar.gz: c78b46ee391b1dc210100c998a1e37ef1ab27e1dca89474aef4f48a2c0670612
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfbdfcea3945c0d0ee3625a0494e012b98ad85704089e254cafa2d9b9e3e85db19d93fb06ded3518e5c3d10073c43c1efcc1537b3ac4679867b3e035d881b0c3
|
7
|
+
data.tar.gz: 9e504c569a23cbfd41701beddf4670cf2441eea128ce9686c6ceb10bc7ebf61554a6641367ddebf490b8cd2c979ff45cb2d76b8f7d2961030f7d67c4e5564f5f
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 0.1.1 - 22-Oct-2022
|
2
|
+
* Added many more specs, along with instructions for how to install and
|
3
|
+
run an openslp container via Docker so that you can run the specs.
|
4
|
+
* The :url parameter to the register method now raises an error unless
|
5
|
+
it is present. It was always required in practice, but now it's enforced.
|
6
|
+
* Many documentation updates, notably that some methods may not actually
|
7
|
+
be implemented yet by the underlying OpenSLP library.
|
8
|
+
|
9
|
+
## 0.1.0 - 19-Oct-2022
|
10
|
+
* Updated the constructor, now uses keyword arguments.
|
11
|
+
* Constructor now accepts a hostname, or a comma separate lists of hosts.
|
12
|
+
* Added the set_app_property_file singleton method.
|
13
|
+
* Changed the deregister method to return the url.
|
14
|
+
* Minor refactoring of callback procs.
|
15
|
+
|
1
16
|
## 0.0.2 - 12-Oct-2022
|
2
17
|
* Fixed the parse_service_url singleton method. The underlying SLPSrvURL
|
3
18
|
struct is now a managed struct.
|
data/README.md
CHANGED
@@ -24,6 +24,17 @@ None that I'm aware of. Please report bugs on the project page at:
|
|
24
24
|
|
25
25
|
https://github.com/djberg96/rslp
|
26
26
|
|
27
|
+
## Running the Specs
|
28
|
+
You will need an OpenSLP server running on localhost to run all of the specs.
|
29
|
+
The easiest way to do that is to install docker and run:
|
30
|
+
|
31
|
+
`docker run -d -p 427:427/tcp -p 427:427/udp vcrhonek/openslp`
|
32
|
+
|
33
|
+
Once you're done just terminate the container.
|
34
|
+
|
35
|
+
## Notes
|
36
|
+
Also see Novell's SLP implementation.
|
37
|
+
|
27
38
|
## Future Plans
|
28
39
|
None at this time.
|
29
40
|
|
data/lib/rslp.rb
CHANGED
@@ -11,7 +11,7 @@ module OpenSLP
|
|
11
11
|
extend OpenSLP::Functions
|
12
12
|
|
13
13
|
# The version of the rslp library.
|
14
|
-
VERSION = '0.
|
14
|
+
VERSION = '0.1.1'.freeze
|
15
15
|
|
16
16
|
# Internal error raised whenever an openslp function fails.
|
17
17
|
class Error < StandardError; end
|
@@ -31,24 +31,32 @@ module OpenSLP
|
|
31
31
|
#
|
32
32
|
# The +async+ argument may be set to true or false and establishes whether
|
33
33
|
# the underlying handle is set to handle asynchronous operations or not. By
|
34
|
-
# default this value is false.
|
34
|
+
# default this value is false, and may not be supported by your implementation.
|
35
|
+
#
|
36
|
+
# The +host+ argument, if present, will associate the Host/IP with the OpenSLP
|
37
|
+
# handle. This is the Hostname/IP address of the Service Agent / Directory Agent
|
38
|
+
# from # which service is requested. For multicast, use a comma separated list of
|
39
|
+
# Hostnames/IP addresses.
|
35
40
|
#
|
36
41
|
# If a block is given, then the object itself is yielded to the block, and
|
37
42
|
# it is automatically closed at the end of the block.
|
38
43
|
#
|
39
44
|
# Examples:
|
40
45
|
#
|
41
|
-
#
|
46
|
+
# # Block form
|
47
|
+
# OpenSLP::SLP.new(lang: 'en-us', async: false, host: 'localhost') do |slp|
|
42
48
|
# # ... do stuff
|
43
49
|
# end
|
44
50
|
#
|
45
|
-
#
|
51
|
+
# # Non-block form
|
52
|
+
# slp = OpenSLP::SLP.new(lang: 'en-us')
|
46
53
|
# # Do stuff
|
47
54
|
# slp.close
|
48
55
|
#
|
49
|
-
def initialize(lang
|
56
|
+
def initialize(lang: '', async: false, host: nil)
|
50
57
|
@lang = lang
|
51
58
|
@async = async
|
59
|
+
@host = host
|
52
60
|
|
53
61
|
ptr = FFI::MemoryPointer.new(:ulong)
|
54
62
|
|
@@ -57,6 +65,16 @@ module OpenSLP
|
|
57
65
|
|
58
66
|
@handle = ptr.read_ulong
|
59
67
|
|
68
|
+
if @host
|
69
|
+
if @host.split(',').size > 1
|
70
|
+
result = SLPAssociateIFList(@handle, @host)
|
71
|
+
raise Error, "SLPAssociateIFList(): #{result}" if result != :SLP_OK
|
72
|
+
else
|
73
|
+
result = SLPAssociateIP(@handle, @host)
|
74
|
+
raise Error, "SLPAssociateIP(): #{result}" if result != :SLP_OK
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
60
78
|
if block_given?
|
61
79
|
begin
|
62
80
|
yield self
|
@@ -86,11 +104,13 @@ module OpenSLP
|
|
86
104
|
# Returns the url if successful.
|
87
105
|
#
|
88
106
|
def register(options = {})
|
107
|
+
url = options.fetch(:url){ raise ArgumentError, ":url must be provided" }
|
108
|
+
|
89
109
|
options[:lifetime] ||= SLP_LIFETIME_DEFAULT
|
90
110
|
options[:attributes] ||= ""
|
91
111
|
options[:fresh] ||= true
|
92
112
|
|
93
|
-
options[:callback] ||= Proc.new{ |
|
113
|
+
options[:callback] ||= Proc.new{ |_hslp, err, _cookie| }
|
94
114
|
|
95
115
|
if options[:attributes] && options[:attributes] != ""
|
96
116
|
attributes = options[:attributes].map{ |k,v| "(#{k}=#{v})" }.join(',')
|
@@ -103,7 +123,7 @@ module OpenSLP
|
|
103
123
|
|
104
124
|
result = SLPReg(
|
105
125
|
@handle,
|
106
|
-
|
126
|
+
url,
|
107
127
|
options[:lifetime],
|
108
128
|
nil,
|
109
129
|
attributes,
|
@@ -117,14 +137,14 @@ module OpenSLP
|
|
117
137
|
cookie.free unless cookie.null?
|
118
138
|
end
|
119
139
|
|
120
|
-
|
140
|
+
url
|
121
141
|
end
|
122
142
|
|
123
143
|
# Deregisters the advertisement for +url+ in all scopes where the service
|
124
144
|
# is registered and all language locales.
|
125
145
|
#
|
126
146
|
def deregister(url)
|
127
|
-
callback = Proc.new{ |
|
147
|
+
callback = Proc.new{ |_hslp, err, _cookie| }
|
128
148
|
|
129
149
|
begin
|
130
150
|
cookie = FFI::MemoryPointer.new(:void)
|
@@ -134,7 +154,7 @@ module OpenSLP
|
|
134
154
|
cookie.free unless cookie.null?
|
135
155
|
end
|
136
156
|
|
137
|
-
|
157
|
+
url
|
138
158
|
end
|
139
159
|
|
140
160
|
# Deletes specified attributes from a registered service. The attributes
|
@@ -143,6 +163,10 @@ module OpenSLP
|
|
143
163
|
#
|
144
164
|
# Returns the list of deleted attributes if successful.
|
145
165
|
#
|
166
|
+
# Note that this method may not be supported. In that case, the only way
|
167
|
+
# to alter a service's attributes is to deregister it then register it
|
168
|
+
# again without the undesired attributes.
|
169
|
+
#
|
146
170
|
def delete_service_attributes(url, attributes)
|
147
171
|
callback = Proc.new{ |hslp, err, cookie| }
|
148
172
|
|
@@ -188,12 +212,15 @@ module OpenSLP
|
|
188
212
|
# form of an LDAP search filter. The default is an empty string, which
|
189
213
|
# will gather all services of the requested type.
|
190
214
|
#
|
215
|
+
# The result is an array of hashes, with the URL as the key and its
|
216
|
+
# remaining lifetime as the value.
|
217
|
+
#
|
191
218
|
def find_services(type, scope = '', filter = '')
|
192
219
|
arr = []
|
193
220
|
|
194
|
-
callback = Proc.new{ |
|
221
|
+
callback = Proc.new{ |_hslp, url, lifetime, err, _cookie|
|
195
222
|
if err == SLP_OK
|
196
|
-
arr << {url =>
|
223
|
+
arr << {url => lifetime}
|
197
224
|
true
|
198
225
|
else
|
199
226
|
false
|
@@ -225,7 +252,7 @@ module OpenSLP
|
|
225
252
|
def find_service_types(auth = '*', scope = '')
|
226
253
|
arr = []
|
227
254
|
|
228
|
-
callback = Proc.new{ |
|
255
|
+
callback = Proc.new{ |_hslp, types, err, _cookie|
|
229
256
|
if err == SLP_OK
|
230
257
|
arr << types
|
231
258
|
true
|
@@ -237,7 +264,7 @@ module OpenSLP
|
|
237
264
|
begin
|
238
265
|
cookie = FFI::MemoryPointer.new(:void)
|
239
266
|
result = SLPFindSrvTypes(@handle, auth, scope, callback, cookie)
|
240
|
-
raise Error, "
|
267
|
+
raise Error, "SLPFindSrvTypes(): #{result}" if result != :SLP_OK
|
241
268
|
ensure
|
242
269
|
cookie.free unless cookie.null?
|
243
270
|
end
|
@@ -253,7 +280,7 @@ module OpenSLP
|
|
253
280
|
def find_service_attributes(url, attrs = '', scope = '')
|
254
281
|
arr = []
|
255
282
|
|
256
|
-
callback = Proc.new{ |
|
283
|
+
callback = Proc.new{ |_hslp, attrlist, err, _cookie|
|
257
284
|
if err == SLP_OK
|
258
285
|
arr << attrlist
|
259
286
|
true
|
@@ -350,5 +377,17 @@ module OpenSLP
|
|
350
377
|
|
351
378
|
str
|
352
379
|
end
|
380
|
+
|
381
|
+
# Set the application-specific configuration file full path name.
|
382
|
+
#
|
383
|
+
# The contents of this property file will override the contents of the
|
384
|
+
# default or global UA configuration file (usually /etc/slp.conf or
|
385
|
+
# C:\windows\slp.conf).
|
386
|
+
#
|
387
|
+
def self.set_app_property_file(path)
|
388
|
+
result = SLPSetAppPropertyFile(string)
|
389
|
+
raise Error, "SLPSetAppPropertyFile(): #{result}" if result != :SLP_OK
|
390
|
+
path
|
391
|
+
end
|
353
392
|
end
|
354
393
|
end
|
data/lib/slp/functions.rb
CHANGED
@@ -49,10 +49,12 @@ module OpenSLP
|
|
49
49
|
callback :SLPAttrCallback, [:handle, :string, :int, :pointer], :bool
|
50
50
|
callback :SLPRegReportCallback, [:handle, :int, :pointer], :void
|
51
51
|
|
52
|
+
attach_function :SLPAssociateIFList, [:handle, :string], SLPError
|
53
|
+
attach_function :SLPAssociateIP, [:handle, :string], SLPError
|
52
54
|
attach_function :SLPClose, [:handle], :void
|
53
|
-
attach_function :SLPEscape, [:string, :pointer, :bool], SLPError
|
54
55
|
attach_function :SLPDelAttrs, [:handle, :string, :string, :SLPRegReportCallback, :pointer], SLPError
|
55
56
|
attach_function :SLPDereg, [:handle, :string, :SLPRegReportCallback, :pointer], SLPError
|
57
|
+
attach_function :SLPEscape, [:string, :pointer, :bool], SLPError
|
56
58
|
|
57
59
|
attach_function :SLPFindAttrs,
|
58
60
|
[:handle, :string, :string, :string, :SLPAttrCallback, :pointer], SLPError
|
@@ -74,6 +76,7 @@ module OpenSLP
|
|
74
76
|
attach_function :SLPReg,
|
75
77
|
[:handle, :string, :ushort, :string, :string, :bool, :SLPRegReportCallback, :pointer], SLPError
|
76
78
|
|
79
|
+
attach_function :SLPSetAppPropertyFile, [:string], SLPError
|
77
80
|
attach_function :SLPSetProperty, [:string, :string], :void
|
78
81
|
attach_function :SLPUnescape, [:string, :pointer, :bool], SLPError
|
79
82
|
end
|
data/rslp.gemspec
CHANGED
@@ -3,7 +3,7 @@ require 'rbconfig'
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |spec|
|
5
5
|
spec.name = 'rslp'
|
6
|
-
spec.version = '0.
|
6
|
+
spec.version = '0.1.1'
|
7
7
|
spec.license = 'Apache-2.0'
|
8
8
|
spec.author = 'Daniel J. Berger'
|
9
9
|
spec.email = 'djberg96@gmail.com'
|
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
}
|
32
32
|
|
33
33
|
spec.description = <<-EOF
|
34
|
-
The rslp library is an FFI interface for the OpenSLP service
|
35
|
-
|
34
|
+
The rslp library is an FFI interface for the OpenSLP service location
|
35
|
+
protocol library. See http://www.openslp.org for more information.
|
36
36
|
EOF
|
37
37
|
end
|
data/spec/rslp_spec.rb
CHANGED
@@ -1,20 +1,26 @@
|
|
1
|
-
|
1
|
+
##############################################################################
|
2
2
|
# rslp_spec.rb
|
3
3
|
#
|
4
|
-
# Test suite for the rslp library.
|
5
|
-
|
4
|
+
# Test suite for the rslp library. Note that these specs assume that you
|
5
|
+
# have an OpenSLP server running on localhost. If not, install Docker and
|
6
|
+
# run the following command:
|
7
|
+
#
|
8
|
+
# docker run -d -p 427:427/tcp -p 427:427/udp vcrhonek/openslp
|
9
|
+
#
|
10
|
+
# Once complete, simply stop the docker container and delete the image.
|
11
|
+
##############################################################################
|
6
12
|
require 'rspec'
|
7
13
|
require 'rslp'
|
8
14
|
|
9
15
|
RSpec.describe OpenSLP::SLP do
|
10
16
|
before do
|
11
17
|
@lang = 'en-us'
|
12
|
-
@slp = described_class.new(@lang, false)
|
18
|
+
@slp = described_class.new(lang: @lang, async: false, host: 'localhost')
|
13
19
|
end
|
14
20
|
|
15
21
|
context "version" do
|
16
22
|
example "version is set to the expected value" do
|
17
|
-
expect(described_class::VERSION).to eq('0.
|
23
|
+
expect(described_class::VERSION).to eq('0.1.1')
|
18
24
|
end
|
19
25
|
end
|
20
26
|
|
@@ -109,6 +115,144 @@ RSpec.describe OpenSLP::SLP do
|
|
109
115
|
expect(described_class.unescape_reserved("\\2Ctag-example\\2C")).to eq(expected)
|
110
116
|
end
|
111
117
|
end
|
118
|
+
|
119
|
+
context "set_app_property_file" do
|
120
|
+
example "defines a set_app_property_file method" do
|
121
|
+
expect(described_class).to respond_to(:set_app_property_file)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "instance methods" do
|
127
|
+
let(:service){ "service:ntp" }
|
128
|
+
let(:url){ "#{service}://time.windows.com" }
|
129
|
+
let(:attributes){ {"foo" => "hello", "bar" => "world"} }
|
130
|
+
|
131
|
+
context "close" do
|
132
|
+
example "has a close method that returns the expected value" do
|
133
|
+
expect(@slp).to respond_to(:close)
|
134
|
+
expect(@slp.close).to be_nil
|
135
|
+
end
|
136
|
+
|
137
|
+
example "calling close multiple times has no effect" do
|
138
|
+
expect(@slp.close).to be_nil
|
139
|
+
expect(@slp.close).to be_nil
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context "find_scopes" do
|
144
|
+
example "has a find_scopes method" do
|
145
|
+
expect(@slp).to respond_to(:find_scopes)
|
146
|
+
end
|
147
|
+
|
148
|
+
example "the find_scopes method returns the expected value" do
|
149
|
+
expect(@slp.find_scopes).to eq(['DEFAULT'])
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context "find_services" do
|
154
|
+
before do
|
155
|
+
sleep 1
|
156
|
+
@slp.register(url: url, attributes: attributes)
|
157
|
+
end
|
158
|
+
|
159
|
+
example "has a find_services method" do
|
160
|
+
expect(@slp).to respond_to(:find_services)
|
161
|
+
end
|
162
|
+
|
163
|
+
example "the find_services method returns the expected types" do
|
164
|
+
results = @slp.find_services(service)
|
165
|
+
expect(results).to be_kind_of(Array)
|
166
|
+
expect(results.first).to be_kind_of(Hash)
|
167
|
+
end
|
168
|
+
|
169
|
+
example "the find_services method returns the expected values" do
|
170
|
+
results = @slp.find_services(service)
|
171
|
+
expect(results.first.keys).to include(url)
|
172
|
+
expect(results.first.values.first).to be_kind_of(Numeric)
|
173
|
+
end
|
174
|
+
|
175
|
+
example "the find_services method with valid scope returns the expected values" do
|
176
|
+
results = @slp.find_services(service, 'DEFAULT')
|
177
|
+
expect(results.first.keys).to include(url)
|
178
|
+
expect(results.first.values.first).to be_kind_of(Numeric)
|
179
|
+
end
|
180
|
+
|
181
|
+
=begin
|
182
|
+
# These specs appear to cause a segfault in the OpenSLP daemon.
|
183
|
+
example "the find_services method with invalid scope returns an empty value" do
|
184
|
+
results = @slp.find_services(service, 'bogus')
|
185
|
+
expect(results).to be_empty
|
186
|
+
end
|
187
|
+
|
188
|
+
example "the find_services method with filter on existing attribute returns the expected values" do
|
189
|
+
results = @slp.find_services(service, '', "(foo=hello)")
|
190
|
+
expect(results).to eq(1)
|
191
|
+
end
|
192
|
+
=end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "find_service_types" do
|
196
|
+
example "has a find_services method" do
|
197
|
+
expect(@slp).to respond_to(:find_service_types)
|
198
|
+
end
|
199
|
+
|
200
|
+
example "the find_service_types method returns the expected results" do
|
201
|
+
results = @slp.find_service_types
|
202
|
+
expect(results).to be_kind_of(Array)
|
203
|
+
expect(results.first).to eq(service)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context "registration" do
|
208
|
+
example "registers a service successfully if url is provided" do
|
209
|
+
expect(@slp.register(url: url)).to eq(url)
|
210
|
+
end
|
211
|
+
|
212
|
+
example "doesn't matter if service is already registered" do
|
213
|
+
expect(@slp.register(url: url)).to eq(url)
|
214
|
+
end
|
215
|
+
|
216
|
+
example "accepts hash attributes option and registers them as expected" do
|
217
|
+
expect(@slp.register(url: url, attributes: attributes)).to eq(url)
|
218
|
+
end
|
219
|
+
|
220
|
+
example "raises an error if the :url option is not provided" do
|
221
|
+
expect{ @slp.register }.to raise_error(ArgumentError, ":url must be provided")
|
222
|
+
end
|
223
|
+
|
224
|
+
example "registers a service successfully with a lifetime value" do
|
225
|
+
expect(@slp.register(url: url, lifetime: OpenSLP::SLP::SLP_LIFETIME_MAXIMUM)).to eq(url)
|
226
|
+
expect(@slp.find_services(service).first.values.first).to be_within(1).of(OpenSLP::SLP::SLP_LIFETIME_MAXIMUM)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
context "deregistration" do
|
231
|
+
example "deregisters a service successfully if it exists" do
|
232
|
+
expect(@slp.deregister(url)).to eq(url)
|
233
|
+
expect(@slp.find_services(url)).to be_empty
|
234
|
+
end
|
235
|
+
|
236
|
+
example "fails to deregister a service successfully if it does not exist" do
|
237
|
+
expect{ @slp.deregister('bogus') }.to raise_error(OpenSLP::SLP::Error)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
context "find service attributes" do
|
242
|
+
before do
|
243
|
+
@slp.register(url: url, attributes: attributes)
|
244
|
+
end
|
245
|
+
|
246
|
+
example "successfully finds service attribute when they exist" do
|
247
|
+
expect(@slp.find_service_attributes(url)).to eq(["(foo=hello),(bar=world)"])
|
248
|
+
expect(@slp.find_service_attributes(url, "foo")).to eq(["(foo=hello)"])
|
249
|
+
expect(@slp.find_service_attributes(url, "foo,bar")).to eq(["(foo=hello),(bar=world)"])
|
250
|
+
end
|
251
|
+
|
252
|
+
example "returns an empty array if the service attribute does not exist" do
|
253
|
+
expect(@slp.find_service_attributes(url, "bogus")).to eq([])
|
254
|
+
end
|
255
|
+
end
|
112
256
|
end
|
113
257
|
|
114
258
|
after do
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rslp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel J. Berger
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
|
36
36
|
WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2022-10-
|
38
|
+
date: 2022-10-22 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: ffi
|
@@ -80,8 +80,8 @@ dependencies:
|
|
80
80
|
- !ruby/object:Gem::Version
|
81
81
|
version: '3.9'
|
82
82
|
description: |2
|
83
|
-
The rslp library is an FFI interface for the OpenSLP service
|
84
|
-
|
83
|
+
The rslp library is an FFI interface for the OpenSLP service location
|
84
|
+
protocol library. See http://www.openslp.org for more information.
|
85
85
|
email: djberg96@gmail.com
|
86
86
|
executables: []
|
87
87
|
extensions: []
|
@@ -131,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
131
|
- !ruby/object:Gem::Version
|
132
132
|
version: '0'
|
133
133
|
requirements: []
|
134
|
-
rubygems_version: 3.3.
|
134
|
+
rubygems_version: 3.3.7
|
135
135
|
signing_key:
|
136
136
|
specification_version: 4
|
137
137
|
summary: Interface for the OpenSLP library
|
metadata.gz.sig
CHANGED
Binary file
|