1329779Skevans--
2344220Skevans-- SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3344220Skevans--
4329779Skevans-- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org>
5329779Skevans-- All rights reserved.
6329779Skevans--
7329779Skevans-- Redistribution and use in source and binary forms, with or without
8329779Skevans-- modification, are permitted provided that the following conditions
9329779Skevans-- are met:
10329779Skevans-- 1. Redistributions of source code must retain the above copyright
11329779Skevans--    notice, this list of conditions and the following disclaimer.
12329779Skevans-- 2. Redistributions in binary form must reproduce the above copyright
13329779Skevans--    notice, this list of conditions and the following disclaimer in the
14329779Skevans--    documentation and/or other materials provided with the distribution.
15329779Skevans--
16329779Skevans-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17329779Skevans-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18329779Skevans-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19329779Skevans-- ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20329779Skevans-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21329779Skevans-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22329779Skevans-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23329779Skevans-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24329779Skevans-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25329779Skevans-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26329779Skevans-- SUCH DAMAGE.
27329779Skevans--
28329779Skevans-- $FreeBSD: stable/11/stand/lua/cli.lua 360596 2020-05-03 03:53:38Z kevans $
29329779Skevans--
30329779Skevans
31344220Skevanslocal config = require("config")
32344220Skevanslocal core = require("core")
33329779Skevans
34329779Skevanslocal cli = {}
35329779Skevans
36329779Skevans-- Internal function
37329779Skevans-- Parses arguments to boot and returns two values: kernel_name, argstr
38329779Skevans-- Defaults to nil and "" respectively.
39329779Skevans-- This will also parse arguments to autoboot, but the with_kernel argument
40329779Skevans-- will need to be explicitly overwritten to false
41344220Skevanslocal function parseBootArgs(argv, with_kernel)
42329779Skevans	if with_kernel == nil then
43329779Skevans		with_kernel = true
44329779Skevans	end
45329779Skevans	if #argv == 0 then
46329779Skevans		if with_kernel then
47329779Skevans			return nil, ""
48329779Skevans		else
49329779Skevans			return ""
50329779Skevans		end
51329779Skevans	end
52329779Skevans	local kernel_name
53329779Skevans	local argstr = ""
54329779Skevans
55344220Skevans	for _, v in ipairs(argv) do
56329779Skevans		if with_kernel and v:sub(1,1) ~= "-" then
57329779Skevans			kernel_name = v
58329779Skevans		else
59329779Skevans			argstr = argstr .. " " .. v
60329779Skevans		end
61329779Skevans	end
62329779Skevans	if with_kernel then
63329779Skevans		return kernel_name, argstr
64329779Skevans	else
65329779Skevans		return argstr
66329779Skevans	end
67329779Skevansend
68329779Skevans
69329779Skevans-- Declares a global function cli_execute that attempts to dispatch the
70329779Skevans-- arguments passed as a lua function. This gives lua a chance to intercept
71329779Skevans-- builtin CLI commands like "boot"
72344220Skevans-- This function intentionally does not follow our general naming guideline for
73344220Skevans-- functions. This is global pollution, but the clearly separated 'cli' looks
74344220Skevans-- more like a module indicator to serve as a hint of where to look for the
75344220Skevans-- corresponding definition.
76329779Skevansfunction cli_execute(...)
77329779Skevans	local argv = {...}
78329779Skevans	-- Just in case...
79329779Skevans	if #argv == 0 then
80344220Skevans		return loader.command(...)
81329779Skevans	end
82329779Skevans
83329779Skevans	local cmd_name = argv[1]
84344220Skevans	local cmd = cli[cmd_name]
85329779Skevans	if cmd ~= nil and type(cmd) == "function" then
86329779Skevans		-- Pass argv wholesale into cmd. We could omit argv[0] since the
87329779Skevans		-- traditional reasons for including it don't necessarily apply,
88329779Skevans		-- it may not be totally redundant if we want to have one global
89329779Skevans		-- handling multiple commands
90344220Skevans		return cmd(...)
91329779Skevans	else
92344220Skevans		return loader.command(...)
93329779Skevans	end
94329779Skevans
95329779Skevansend
96329779Skevans
97344220Skevansfunction cli_execute_unparsed(str)
98344220Skevans	return cli_execute(loader.parse(str))
99344220Skevansend
100344220Skevans
101344220Skevans-- Module exports
102344220Skevans
103344220Skevansfunction cli.boot(...)
104344220Skevans	local _, argv = cli.arguments(...)
105344220Skevans	local kernel, argstr = parseBootArgs(argv)
106344220Skevans	if kernel ~= nil then
107344220Skevans		loader.perform("unload")
108344220Skevans		config.selectKernel(kernel)
109344220Skevans	end
110344220Skevans	core.boot(argstr)
111344220Skevansend
112344220Skevans
113344220Skevansfunction cli.autoboot(...)
114344220Skevans	local _, argv = cli.arguments(...)
115344220Skevans	local argstr = parseBootArgs(argv, false)
116344220Skevans	core.autoboot(argstr)
117344220Skevansend
118344220Skevans
119344220Skevanscli['boot-conf'] = function(...)
120344220Skevans	local _, argv = cli.arguments(...)
121344220Skevans	local kernel, argstr = parseBootArgs(argv)
122344220Skevans	if kernel ~= nil then
123344220Skevans		loader.perform("unload")
124344220Skevans		config.selectKernel(kernel)
125344220Skevans	end
126344220Skevans	core.autoboot(argstr)
127344220Skevansend
128344220Skevans
129360596Skevanscli['read-conf'] = function(...)
130360596Skevans	local _, argv = cli.arguments(...)
131360596Skevans	config.readConf(assert(core.popFrontTable(argv)))
132360596Skevansend
133360596Skevans
134353136Skevanscli['reload-conf'] = function(...)
135353136Skevans	config.reload()
136353136Skevansend
137353136Skevans
138344220Skevans-- Used for splitting cli varargs into cmd_name and the rest of argv
139344220Skevansfunction cli.arguments(...)
140344220Skevans	local argv = {...}
141344220Skevans	local cmd_name
142344220Skevans	cmd_name, argv = core.popFrontTable(argv)
143344220Skevans	return cmd_name, argv
144344220Skevansend
145344220Skevans
146329779Skevansreturn cli
147