|
|
|
#!/usr/bin/lua
|
|
|
|
-- --- SDE-COPYRIGHT-NOTE-BEGIN ---
|
|
|
|
-- This copyright note is auto-generated by ./scripts/Create-CopyPatch.
|
|
|
|
--
|
|
|
|
-- Filename: package/.../sam/sam.lua
|
|
|
|
-- Copyright (C) 2006 The T2 SDE Project
|
|
|
|
--
|
|
|
|
-- More information can be found in the files COPYING and README.
|
|
|
|
--
|
|
|
|
-- This program is free software; you can redistribute it and/or modify
|
|
|
|
-- it under the terms of the GNU General Public License as published by
|
|
|
|
-- the Free Software Foundation; version 2 of the License. A copy of the
|
|
|
|
-- GNU General Public License can be found in the file COPYING.
|
|
|
|
-- --- SDE-COPYRIGHT-NOTE-END ---
|
|
|
|
|
|
|
|
-- identification
|
|
|
|
local _NAME = "SAM"
|
|
|
|
local _VERSION = "0.0-devel"
|
|
|
|
local _COPYRIGHT = "Copyright (C) 2006 The T2 SDE Project"
|
|
|
|
local _DESCRIPTION = "System Administration Manager for systems based on T2"
|
|
|
|
|
|
|
|
-- SAM namespace
|
|
|
|
sam = sam or {
|
|
|
|
command = {}
|
|
|
|
}
|
|
|
|
|
|
|
|
require "sam.log"
|
|
|
|
|
|
|
|
-- default options
|
|
|
|
sam.opt = sam.opt or {
|
|
|
|
loglevel = sam.log.DEBUG, -- sam.log.WARN
|
|
|
|
}
|
|
|
|
|
|
|
|
--[[ DESCRIPTION ] ----------------------------------------------------------
|
|
|
|
|
|
|
|
Provided functions:
|
|
|
|
|
|
|
|
* sam.command["command-name"](args...)
|
|
|
|
* sam.command["command-name"].main(args...)
|
|
|
|
|
|
|
|
Execute a command (extended by modulues) with given arguments.
|
|
|
|
The only built-in command currently is "help".
|
|
|
|
|
|
|
|
--]] ------------------------------------------------------------------------
|
|
|
|
|
|
|
|
-- fprintf alike helper function
|
|
|
|
local function fprintf(stream, ...)
|
|
|
|
stream:write( string.format(unpack(arg)) )
|
|
|
|
end
|
|
|
|
|
|
|
|
-- MODULES ------------------------------------------------------------------
|
|
|
|
|
|
|
|
-- load_module(name)
|
|
|
|
-- Load the previously detected module.
|
|
|
|
local function load_module(name)
|
|
|
|
sam.info(_NAME, "Loading module %s (from %s)\n", name, sam.command[name]._module._FILE)
|
|
|
|
|
|
|
|
-- sanity check for module info
|
|
|
|
if not sam.command[name] or not sam.command[name]._module then
|
|
|
|
sam.error(_NAME, "No such command module '%s', giving up.\n", name)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
-- load and execute the module
|
|
|
|
local module, emsg = loadfile(sam.command[name]._module._FILE)
|
|
|
|
|
|
|
|
if not module then
|
|
|
|
print(emsg)
|
|
|
|
os.exit(-1)
|
|
|
|
end
|
|
|
|
|
|
|
|
module = module()
|
|
|
|
|
|
|
|
-- module sanity check
|
|
|
|
if not module.main or not module._NAME then
|
|
|
|
sam.error(_NAME, "Command module '%s' is probably not a SAM module.\n", name)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
-- copy module data
|
|
|
|
sam.command[name]._NAME = module._NAME
|
|
|
|
sam.command[name]._DESCRIPTION = module._DESCRIPTION
|
|
|
|
sam.command[name]._USAGE = module._USAGE
|
|
|
|
sam.command[name]._module.main = module.main
|
|
|
|
|
|
|
|
sam.command[name]._load = nil
|
|
|
|
|
|
|
|
-- set real methods
|
|
|
|
sam.command[name].main = function(self,...) return self._module.main(unpack(arg)) end
|
|
|
|
|
|
|
|
-- set correct metatable
|
|
|
|
setmetatable(sam.command[name], {
|
|
|
|
__call = function(self, ...) return self._module.main(unpack(arg)) end,
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
-- detect_modules()
|
|
|
|
-- Detect all SAM modules
|
|
|
|
local function detect_modules()
|
|
|
|
local lfs = require("lfs")
|
|
|
|
local moddir = os.getenv("SAM_MODULES") or "/usr/share/sam"
|
|
|
|
|
|
|
|
for file in lfs.dir( moddir ) do
|
|
|
|
local name
|
|
|
|
local path
|
|
|
|
|
|
|
|
_,_,name = string.find(file, "^sam_([%a][_%w%a]*).lua")
|
|
|
|
path = moddir .. "/" .. file
|
|
|
|
|
|
|
|
if name and lfs.attributes(path).mode == "file" and "sam_" .. name .. ".lua" == file then
|
|
|
|
sam.dbg(_NAME, "Found '%s' (%s)\n", name, path)
|
|
|
|
|
|
|
|
-- preset the module structure of the detected module
|
|
|
|
-- for auto-loading
|
|
|
|
sam.command[name] = {
|
|
|
|
_module = {
|
|
|
|
_NAME = name,
|
|
|
|
_FILE = path,
|
|
|
|
},
|
|
|
|
|
|
|
|
_load = function(self,...) load_module(self._module._NAME) end,
|
|
|
|
|
|
|
|
_NAME = name,
|
|
|
|
_DESCRIPTION = "",
|
|
|
|
_USAGE = "",
|
|
|
|
|
|
|
|
main = function(self,...)
|
|
|
|
load_module(self._module._NAME)
|
|
|
|
return self:main(unpack(arg))
|
|
|
|
end,
|
|
|
|
}
|
|
|
|
|
|
|
|
-- add a metatable so the commands can be used, however,
|
|
|
|
-- it is anly a intermediate metatable, as the module is not
|
|
|
|
-- loaded yet. The module gets loaded (dynamic linker alike)
|
|
|
|
-- once it is called
|
|
|
|
|
|
|
|
setmetatable(sam.command[name], {
|
|
|
|
__call = function(self, ...)
|
|
|
|
load_module(self._module._NAME)
|
|
|
|
return self:main(unpack(arg))
|
|
|
|
end,
|
|
|
|
})
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- COMMANDS -----------------------------------------------------------------
|
|
|
|
local function usage(cmd)
|
|
|
|
fprintf(io.stdout, "%s v%s %s\n\n", _NAME, _VERSION, _COPYRIGHT)
|
|
|
|
if cmd then
|
|
|
|
if sam.command[cmd]._load then sam.command[cmd]:_load() end
|
|
|
|
fprintf(io.stdout, "Usage: sam %s\n", sam.command[cmd]._USAGE)
|
|
|
|
else
|
|
|
|
fprintf(io.stdout, "Usage: sam <command> [command options]\n\n%s\n",
|
|
|
|
[[Commands:
|
|
|
|
help Show command overview (this)
|
|
|
|
help <command> Show command specific usage information]])
|
|
|
|
|
|
|
|
for k,_ in pairs(sam.command) do
|
|
|
|
if sam.command[k]._load then sam.command[k]:_load() end
|
|
|
|
fprintf(io.stdout, " %16s %s\n", k, sam.command[k]._DESCRIPTION)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- --------------------------------------------------------------------------
|
|
|
|
-- INITIALIZE SAM
|
|
|
|
-- --------------------------------------------------------------------------
|
|
|
|
detect_modules()
|
|
|
|
|
|
|
|
-- --------------------------------------------------------------------------
|
|
|
|
-- MAIN
|
|
|
|
-- --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
if arg[1] then
|
|
|
|
-- help
|
|
|
|
if arg[1] == "help" then
|
|
|
|
usage(arg[2])
|
|
|
|
elseif arg[2] == "help" then
|
|
|
|
usage(arg[1])
|
|
|
|
else
|
|
|
|
-- split command and command arguments
|
|
|
|
local cmd = arg[1]
|
|
|
|
local args = arg ; table.remove(args, 1)
|
|
|
|
|
|
|
|
sam.command[cmd](unpack(args or {}))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|