rslp 0.0.2 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|