You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
5.2 KiB
191 lines
5.2 KiB
#!/usr/bin/lua |
|
-- --- T2-COPYRIGHT-NOTE-BEGIN --- |
|
-- This copyright note is auto-generated by ./scripts/Create-CopyPatch. |
|
-- |
|
-- T2 SDE: 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. |
|
-- --- T2-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 |
|
|
|
|