Dash:
[t2-trunk.git] / package / base / sam / sam.lua
blob07c0c26f40f60bd8f12e162a51f205735a2ec816
1 #!/usr/bin/lua
2 -- --- T2-COPYRIGHT-NOTE-BEGIN ---
3 -- This copyright note is auto-generated by ./scripts/Create-CopyPatch.
4 --
5 -- T2 SDE: package/.../sam/sam.lua
6 -- Copyright (C) 2006 The T2 SDE Project
7 --
8 -- More information can be found in the files COPYING and README.
9 --
10 -- This program is free software; you can redistribute it and/or modify
11 -- it under the terms of the GNU General Public License as published by
12 -- the Free Software Foundation; version 2 of the License. A copy of the
13 -- GNU General Public License can be found in the file COPYING.
14 -- --- T2-COPYRIGHT-NOTE-END ---
16 -- identification
17 local _NAME = "SAM"
18 local _VERSION = "0.0-devel"
19 local _COPYRIGHT = "Copyright (C) 2006 The T2 SDE Project"
20 local _DESCRIPTION = "System Administration Manager for systems based on T2"
22 -- SAM namespace
23 sam = sam or {
24 command = {}
27 require "sam.log"
29 -- default options
30 sam.opt = sam.opt or {
31 loglevel = sam.log.DEBUG, -- sam.log.WARN
34 --[[ DESCRIPTION ] ----------------------------------------------------------
36 Provided functions:
38 * sam.command["command-name"](args...)
39 * sam.command["command-name"].main(args...)
41 Execute a command (extended by modulues) with given arguments.
42 The only built-in command currently is "help".
44 --]] ------------------------------------------------------------------------
46 -- fprintf alike helper function
47 local function fprintf(stream, ...)
48 stream:write( string.format(unpack(arg)) )
49 end
51 -- MODULES ------------------------------------------------------------------
53 -- load_module(name)
54 -- Load the previously detected module.
55 local function load_module(name)
56 sam.info(_NAME, "Loading module %s (from %s)\n", name, sam.command[name]._module._FILE)
58 -- sanity check for module info
59 if not sam.command[name] or not sam.command[name]._module then
60 sam.error(_NAME, "No such command module '%s', giving up.\n", name)
61 return
62 end
64 -- load and execute the module
65 local module, emsg = loadfile(sam.command[name]._module._FILE)
67 if not module then
68 print(emsg)
69 os.exit(-1)
70 end
72 module = module()
74 -- module sanity check
75 if not module.main or not module._NAME then
76 sam.error(_NAME, "Command module '%s' is probably not a SAM module.\n", name)
77 return
78 end
80 -- copy module data
81 sam.command[name]._NAME = module._NAME
82 sam.command[name]._DESCRIPTION = module._DESCRIPTION
83 sam.command[name]._USAGE = module._USAGE
84 sam.command[name]._module.main = module.main
86 sam.command[name]._load = nil
88 -- set real methods
89 sam.command[name].main = function(self,...) return self._module.main(unpack(arg)) end
91 -- set correct metatable
92 setmetatable(sam.command[name], {
93 __call = function(self, ...) return self._module.main(unpack(arg)) end,
95 end
97 -- detect_modules()
98 -- Detect all SAM modules
99 local function detect_modules()
100 local lfs = require("lfs")
101 local moddir = os.getenv("SAM_MODULES") or "/usr/share/sam"
103 for file in lfs.dir( moddir ) do
104 local name
105 local path
107 _,_,name = string.find(file, "^sam_([%a][_%w%a]*).lua")
108 path = moddir .. "/" .. file
110 if name and lfs.attributes(path).mode == "file" and "sam_" .. name .. ".lua" == file then
111 sam.dbg(_NAME, "Found '%s' (%s)\n", name, path)
113 -- preset the module structure of the detected module
114 -- for auto-loading
115 sam.command[name] = {
116 _module = {
117 _NAME = name,
118 _FILE = path,
121 _load = function(self,...) load_module(self._module._NAME) end,
123 _NAME = name,
124 _DESCRIPTION = "",
125 _USAGE = "",
127 main = function(self,...)
128 load_module(self._module._NAME)
129 return self:main(unpack(arg))
130 end,
133 -- add a metatable so the commands can be used, however,
134 -- it is anly a intermediate metatable, as the module is not
135 -- loaded yet. The module gets loaded (dynamic linker alike)
136 -- once it is called
138 setmetatable(sam.command[name], {
139 __call = function(self, ...)
140 load_module(self._module._NAME)
141 return self:main(unpack(arg))
142 end,
149 -- COMMANDS -----------------------------------------------------------------
150 local function usage(cmd)
151 fprintf(io.stdout, "%s v%s %s\n\n", _NAME, _VERSION, _COPYRIGHT)
152 if cmd then
153 if sam.command[cmd]._load then sam.command[cmd]:_load() end
154 fprintf(io.stdout, "Usage: sam %s\n", sam.command[cmd]._USAGE)
155 else
156 fprintf(io.stdout, "Usage: sam <command> [command options]\n\n%s\n",
157 [[Commands:
158 help Show command overview (this)
159 help <command> Show command specific usage information]])
161 for k,_ in pairs(sam.command) do
162 if sam.command[k]._load then sam.command[k]:_load() end
163 fprintf(io.stdout, " %16s %s\n", k, sam.command[k]._DESCRIPTION)
168 -- --------------------------------------------------------------------------
169 -- INITIALIZE SAM
170 -- --------------------------------------------------------------------------
171 detect_modules()
173 -- --------------------------------------------------------------------------
174 -- MAIN
175 -- --------------------------------------------------------------------------
177 if arg[1] then
178 -- help
179 if arg[1] == "help" then
180 usage(arg[2])
181 elseif arg[2] == "help" then
182 usage(arg[1])
183 else
184 -- split command and command arguments
185 local cmd = arg[1]
186 local args = arg ; table.remove(args, 1)
188 sam.command[cmd](unpack(args or {}))