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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f495c04e7aa0fa38ebead86d3100b360d13de94d02ee3fc2f54bc41eb5b087c
4
- data.tar.gz: 88a33d40ab0aa9e71048c73c765a250c60d559eda2619f483c1800bec48d4ba7
3
+ metadata.gz: 1c95a3256bfee540b035527983b2855d2ed8cfee989c766674259cc5649c928f
4
+ data.tar.gz: c78b46ee391b1dc210100c998a1e37ef1ab27e1dca89474aef4f48a2c0670612
5
5
  SHA512:
6
- metadata.gz: bf1356f4e184640cf4b8f13198dca65469cf653228b1a9679dfce3da82ab0de9f236f81d85e01d3b11d3fd27e8dd472345a09aebf9111df207dc233c27acecb4
7
- data.tar.gz: f67b5df2e8b5c6849b9fe826bee87b594bd4dcc351da1c640b0f3a637c106875e6160097f4e3a783abdfa9896df18b4813294dba6e94a81c914daebeb3d36f24
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.0.2'.freeze
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
- # OpenSLP::SLP.new('en-us') do |slp|
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
- # slp = OpenSLP::SLP.new('en-us')
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 = '', async = false)
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{ |hslp, err, cookie| }
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
- options[:url],
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
- options[:url]
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{ |hslp, err, cookie| }
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
- true
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{ |hslp, url, life, err, cook|
221
+ callback = Proc.new{ |_hslp, url, lifetime, err, _cookie|
195
222
  if err == SLP_OK
196
- arr << {url => life}
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{ |hslp, types, err, cookie|
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, "SLPFindSrvs(): #{result}" if result != :SLP_OK
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{ |hslp, attrlist, err, cookie|
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.0.2'
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
- location protocol library.
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.0.2')
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.0.2
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-13 00:00:00.000000000 Z
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
- location protocol library.
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.16
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