187 lines
3.1 KiB
Ruby
187 lines
3.1 KiB
Ruby
# -*- coding: binary -*-
|
|
module Rex
|
|
module Parser
|
|
|
|
###
|
|
#
|
|
# This class parses the contents of an INI file.
|
|
#
|
|
###
|
|
class Ini < Hash
|
|
|
|
##
|
|
#
|
|
# Factories
|
|
#
|
|
##
|
|
|
|
#
|
|
# Creates a new class instance and reads in the contents of the supplied
|
|
# file path.
|
|
#
|
|
def self.from_file(path)
|
|
ini = Ini.new(path)
|
|
ini.from_file
|
|
return ini
|
|
end
|
|
|
|
#
|
|
# Creates a new class instance from the supplied string.
|
|
#
|
|
def self.from_s(str)
|
|
ini = Ini.new
|
|
ini.from_s(str)
|
|
return ini
|
|
end
|
|
|
|
#
|
|
# Initializes an ini instance and tries to read in the groups from the
|
|
# file if it exists.
|
|
#
|
|
def initialize(path = nil)
|
|
self.path = path
|
|
|
|
# Try to synchronize ourself with the file if we
|
|
# have one
|
|
begin
|
|
self.from_file if (self.path)
|
|
rescue
|
|
end
|
|
end
|
|
|
|
#
|
|
# Enumerates the groups hash keys.
|
|
#
|
|
def each_group(&block)
|
|
self.keys.each { |k|
|
|
yield
|
|
}
|
|
end
|
|
|
|
#
|
|
# Adds a group of the supplied name if it doesn't already exist.
|
|
#
|
|
def add_group(name = 'global', reset = true)
|
|
self[name] = {} if (reset == true)
|
|
self[name] = {} if (!self[name])
|
|
|
|
return self[name]
|
|
end
|
|
|
|
#
|
|
# Checks to see if name is a valid group.
|
|
#
|
|
def group?(name)
|
|
return (self[name] != nil)
|
|
end
|
|
|
|
##
|
|
#
|
|
# Serializers
|
|
#
|
|
##
|
|
|
|
#
|
|
# Reads in the groups from the supplied file path or the instance's file
|
|
# path.
|
|
#
|
|
def from_file(fpath = nil)
|
|
fpath = path if (!fpath)
|
|
|
|
read_groups(fpath)
|
|
end
|
|
|
|
#
|
|
# Reads in the groups from the supplied string.
|
|
#
|
|
def from_s(str)
|
|
read_groups_string(str.split("\n"))
|
|
end
|
|
|
|
#
|
|
# Writes the group settings to a file.
|
|
#
|
|
def to_file(tpath = nil)
|
|
tpath = path if (!tpath)
|
|
|
|
f = File.new(tpath, "w")
|
|
f.write(to_s)
|
|
f.close
|
|
end
|
|
|
|
#
|
|
# Converts the groups to a string.
|
|
#
|
|
def to_s
|
|
str = ''
|
|
keys.sort.each { |k|
|
|
str << "[#{k}]\n"
|
|
|
|
self[k].each_pair { |var, val|
|
|
str << "#{var}=#{val}\n"
|
|
}
|
|
|
|
str << "\n";
|
|
}
|
|
|
|
return str
|
|
end
|
|
|
|
attr_reader :path
|
|
|
|
protected
|
|
|
|
#
|
|
# Reads in the groups and their attributes from the supplied file
|
|
# path or from the instance's file path if one was set.
|
|
#
|
|
def read_groups(fpath) # :nodoc:
|
|
if (!fpath)
|
|
raise ArgumentError, "No file path specified.",
|
|
caller
|
|
end
|
|
|
|
# Read in the contents of the file
|
|
lines = ::IO.readlines(fpath)
|
|
|
|
# Now read the contents from the supplied string
|
|
read_groups_string(lines)
|
|
end
|
|
|
|
#
|
|
# Reads groups from the supplied string
|
|
#
|
|
def read_groups_string(str) # :nodoc:
|
|
# Reset the groups hash
|
|
self.clear
|
|
|
|
# The active group
|
|
active_group = nil
|
|
|
|
# Walk each line initializing the groups
|
|
str.each { |line|
|
|
next if (line.match(/^;/))
|
|
|
|
# Eliminate cr/lf
|
|
line.gsub!(/(\n|\r)/, '')
|
|
|
|
# Is it a group [bob]?
|
|
if (md = line.match(/^\[(.+?)\]/))
|
|
active_group = md[1]
|
|
self[md[1]] = {}
|
|
# Is it a VAR=VAL?
|
|
elsif (md = line.match(/^(.+?)=(.*)$/))
|
|
if (active_group)
|
|
self[active_group][md[1]] = md[2]
|
|
end
|
|
end
|
|
}
|
|
end
|
|
|
|
attr_writer :path # :nodoc:
|
|
|
|
end
|
|
|
|
end
|
|
end
|