xref: /freebsd-12.1/stand/lua/cli.lua (revision 4532ac98)
1e37f4622SKyle Evans--
272e39d71SKyle Evans-- SPDX-License-Identifier: BSD-2-Clause-FreeBSD
372e39d71SKyle Evans--
4e37f4622SKyle Evans-- Copyright (c) 2018 Kyle Evans <[email protected]>
5e37f4622SKyle Evans--
6e37f4622SKyle Evans-- Redistribution and use in source and binary forms, with or without
7e37f4622SKyle Evans-- modification, are permitted provided that the following conditions
8e37f4622SKyle Evans-- are met:
9e37f4622SKyle Evans-- 1. Redistributions of source code must retain the above copyright
10e37f4622SKyle Evans--    notice, this list of conditions and the following disclaimer.
11e37f4622SKyle Evans-- 2. Redistributions in binary form must reproduce the above copyright
12e37f4622SKyle Evans--    notice, this list of conditions and the following disclaimer in the
13e37f4622SKyle Evans--    documentation and/or other materials provided with the distribution.
14e37f4622SKyle Evans--
15e37f4622SKyle Evans-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16e37f4622SKyle Evans-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17e37f4622SKyle Evans-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18e37f4622SKyle Evans-- ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19e37f4622SKyle Evans-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20e37f4622SKyle Evans-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21e37f4622SKyle Evans-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22e37f4622SKyle Evans-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23e37f4622SKyle Evans-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24e37f4622SKyle Evans-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25e37f4622SKyle Evans-- SUCH DAMAGE.
26e37f4622SKyle Evans--
27e37f4622SKyle Evans-- $FreeBSD$
28e37f4622SKyle Evans--
29e37f4622SKyle Evans
303e6c7d54SKyle Evanslocal config = require("config")
313e6c7d54SKyle Evanslocal core = require("core")
32e37f4622SKyle Evans
33e37f4622SKyle Evanslocal cli = {}
34e37f4622SKyle Evans
35e37f4622SKyle Evans-- Internal function
36e37f4622SKyle Evans-- Parses arguments to boot and returns two values: kernel_name, argstr
37e37f4622SKyle Evans-- Defaults to nil and "" respectively.
38e37f4622SKyle Evans-- This will also parse arguments to autoboot, but the with_kernel argument
39e37f4622SKyle Evans-- will need to be explicitly overwritten to false
40322a2dddSKyle Evanslocal function parseBootArgs(argv, with_kernel)
41e37f4622SKyle Evans	if with_kernel == nil then
42e37f4622SKyle Evans		with_kernel = true
43e37f4622SKyle Evans	end
44e37f4622SKyle Evans	if #argv == 0 then
45e37f4622SKyle Evans		if with_kernel then
46e37f4622SKyle Evans			return nil, ""
47e37f4622SKyle Evans		else
48e37f4622SKyle Evans			return ""
49e37f4622SKyle Evans		end
50e37f4622SKyle Evans	end
51e37f4622SKyle Evans	local kernel_name
52e37f4622SKyle Evans	local argstr = ""
53e37f4622SKyle Evans
54e2df27e3SKyle Evans	for _, v in ipairs(argv) do
55e37f4622SKyle Evans		if with_kernel and v:sub(1,1) ~= "-" then
56e37f4622SKyle Evans			kernel_name = v
57e37f4622SKyle Evans		else
58e37f4622SKyle Evans			argstr = argstr .. " " .. v
59e37f4622SKyle Evans		end
60e37f4622SKyle Evans	end
61e37f4622SKyle Evans	if with_kernel then
62e37f4622SKyle Evans		return kernel_name, argstr
63e37f4622SKyle Evans	else
64e37f4622SKyle Evans		return argstr
65e37f4622SKyle Evans	end
66e37f4622SKyle Evansend
67e37f4622SKyle Evans
68e37f4622SKyle Evans-- Declares a global function cli_execute that attempts to dispatch the
69e37f4622SKyle Evans-- arguments passed as a lua function. This gives lua a chance to intercept
70e37f4622SKyle Evans-- builtin CLI commands like "boot"
7122ae8ae1SKyle Evans-- This function intentionally does not follow our general naming guideline for
7222ae8ae1SKyle Evans-- functions. This is global pollution, but the clearly separated 'cli' looks
7322ae8ae1SKyle Evans-- more like a module indicator to serve as a hint of where to look for the
7422ae8ae1SKyle Evans-- corresponding definition.
75e37f4622SKyle Evansfunction cli_execute(...)
76e37f4622SKyle Evans	local argv = {...}
77e37f4622SKyle Evans	-- Just in case...
78e37f4622SKyle Evans	if #argv == 0 then
79c6d9f133SKyle Evans		return loader.command(...)
80e37f4622SKyle Evans	end
81e37f4622SKyle Evans
82e37f4622SKyle Evans	local cmd_name = argv[1]
832e4dad82SKyle Evans	local cmd = cli[cmd_name]
84e37f4622SKyle Evans	if cmd ~= nil and type(cmd) == "function" then
85e37f4622SKyle Evans		-- Pass argv wholesale into cmd. We could omit argv[0] since the
86e37f4622SKyle Evans		-- traditional reasons for including it don't necessarily apply,
87e37f4622SKyle Evans		-- it may not be totally redundant if we want to have one global
88e37f4622SKyle Evans		-- handling multiple commands
89c6d9f133SKyle Evans		return cmd(...)
90e37f4622SKyle Evans	else
91c6d9f133SKyle Evans		return loader.command(...)
92e37f4622SKyle Evans	end
93e37f4622SKyle Evans
94e37f4622SKyle Evansend
95e37f4622SKyle Evans
96ca3b8c9fSKyle Evansfunction cli_execute_unparsed(str)
97f6e00525SKyle Evans	return cli_execute(loader.parse(str))
98697f127dSKyle Evansend
99697f127dSKyle Evans
100eca5ca66SKyle Evans-- Module exports
101eca5ca66SKyle Evans
1022e4dad82SKyle Evansfunction cli.boot(...)
103e2df27e3SKyle Evans	local _, argv = cli.arguments(...)
104322a2dddSKyle Evans	local kernel, argstr = parseBootArgs(argv)
1052e4dad82SKyle Evans	if kernel ~= nil then
1062e4dad82SKyle Evans		loader.perform("unload")
107322a2dddSKyle Evans		config.selectKernel(kernel)
1082e4dad82SKyle Evans	end
1092e4dad82SKyle Evans	core.boot(argstr)
1102e4dad82SKyle Evansend
1112e4dad82SKyle Evans
1122e4dad82SKyle Evansfunction cli.autoboot(...)
113e2df27e3SKyle Evans	local _, argv = cli.arguments(...)
114322a2dddSKyle Evans	local argstr = parseBootArgs(argv, false)
1152e4dad82SKyle Evans	core.autoboot(argstr)
1162e4dad82SKyle Evansend
1172e4dad82SKyle Evans
118*4532ac98SKyle Evanscli['boot-conf'] = function(...)
119*4532ac98SKyle Evans	local _, argv = cli.arguments(...)
120*4532ac98SKyle Evans	local kernel, argstr = parseBootArgs(argv)
121*4532ac98SKyle Evans	if kernel ~= nil then
122*4532ac98SKyle Evans		loader.perform("unload")
123*4532ac98SKyle Evans		config.selectKernel(kernel)
124*4532ac98SKyle Evans	end
125*4532ac98SKyle Evans	core.autoboot(argstr)
126*4532ac98SKyle Evansend
127*4532ac98SKyle Evans
1282e4dad82SKyle Evans-- Used for splitting cli varargs into cmd_name and the rest of argv
129eca5ca66SKyle Evansfunction cli.arguments(...)
130eca5ca66SKyle Evans	local argv = {...}
131e2df27e3SKyle Evans	local cmd_name
132eca5ca66SKyle Evans	cmd_name, argv = core.popFrontTable(argv)
133eca5ca66SKyle Evans	return cmd_name, argv
134eca5ca66SKyle Evansend
135eca5ca66SKyle Evans
136e37f4622SKyle Evansreturn cli
137