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 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