94 lines
1.8 KiB
Ruby
94 lines
1.8 KiB
Ruby
require 'singleton'
|
|
require 'rex'
|
|
require 'rex/service'
|
|
|
|
module Rex
|
|
|
|
###
|
|
#
|
|
# ServiceManager
|
|
# --------------
|
|
#
|
|
# This class manages service allocation and interaction. This class can be
|
|
# used to start HTTP servers and manage them and all that stuff. Yup.
|
|
#
|
|
###
|
|
class ServiceManager < Hash
|
|
|
|
#
|
|
# This class is a singleton.
|
|
#
|
|
include Singleton
|
|
|
|
#
|
|
# Calls the instance method to start a service.
|
|
#
|
|
def self.start(klass, *args)
|
|
self.instance.start(klass, *args)
|
|
end
|
|
|
|
#
|
|
# Calls the instance method to stop a service.
|
|
#
|
|
def self.stop(als)
|
|
self.instance.stop(als)
|
|
end
|
|
|
|
#
|
|
# Starts a service and assigns it a unique name in the service hash.
|
|
#
|
|
def start(klass, *args)
|
|
# Get the hardcore alias.
|
|
hals = "__#{klass.name}#{args.to_s}"
|
|
|
|
# Has a service already been constructed for this guy? If so, increment
|
|
# its reference count like it aint no thang.
|
|
if (inst = self[hals])
|
|
inst.ref
|
|
return inst
|
|
end
|
|
|
|
inst = klass.new(*args)
|
|
als = inst.alias
|
|
|
|
# Find an alias that isn't taken.
|
|
if (self[als])
|
|
cnt = 1
|
|
cnt += 1 while (self[als + " #{cnt}"])
|
|
als = inst.alias + " #{cnt}"
|
|
end
|
|
|
|
# Extend the instance as a service.
|
|
inst.extend(Rex::Service)
|
|
|
|
# Re-aliases the instance.
|
|
inst.alias = als
|
|
|
|
# Fire up the engines. If an error occurs an exception will be
|
|
# raised.
|
|
inst.start
|
|
|
|
# Alias associate and initialize reference counting
|
|
self[als] = self[hals] = inst.refinit
|
|
end
|
|
|
|
#
|
|
# Stops a service using the provided alias
|
|
#
|
|
def stop(als)
|
|
# Stop the service and be done wif it, but only if the number of
|
|
# references has dropped to zero
|
|
if ((inst = self[als]) and
|
|
(inst.deref))
|
|
# Since the instance may have multiple aliases, scan through
|
|
# all the pairs for matching stuff.
|
|
self.each_pair { |cals, cinst|
|
|
self.delete(cals) if (inst == cinst)
|
|
}
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
end
|