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 | 
						|
-- --- 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 | 
						|
 | 
						|
 |