Page MenuHomeFreeBSD

D14295.id39135.diff
No OneTemporary

D14295.id39135.diff

Index: UPDATING
===================================================================
--- UPDATING
+++ UPDATING
@@ -51,6 +51,10 @@
****************************** SPECIAL WARNING: ******************************
+20180212:
+ FreeBSD loot loader enhanced with Lua scripting. It's purely opt-in
+ for now by building WITH_LOADER_LUA and WITHOUT_FORTH in /etc/src.conf.
+
20180114:
Clang, llvm, lld, lldb, compiler-rt and libc++ have been upgraded to
6.0.0. Please see the 20141231 entry below for information about
Index: share/mk/src.opts.mk
===================================================================
--- share/mk/src.opts.mk
+++ share/mk/src.opts.mk
@@ -183,6 +183,7 @@
LIBSOFT \
LOADER_FIREWIRE \
LOADER_FORCE_LE \
+ LOADER_LUA \
NAND \
OFED \
OPENLDAP \
Index: stand/Makefile
===================================================================
--- stand/Makefile
+++ stand/Makefile
@@ -8,6 +8,10 @@
SUBDIR+= ficl
SUBDIR+= forth
.endif
+.if ${MK_LOADER_LUA} != "no"
+SUBDIR+= liblua
+SUBDIR+= lua
+.endif
SUBDIR+= man
Index: stand/Makefile.amd64
===================================================================
--- stand/Makefile.amd64
+++ stand/Makefile.amd64
@@ -7,6 +7,9 @@
.if ${MK_FORTH} != "no"
SUBDIR+= ficl32
.endif
+.if ${MK_LOADER_LUA} != "no"
+SUBDIR+= liblua32
+.endif
SUBDIR+= efi
SUBDIR+= userboot
Index: stand/common/interp_lua.c
===================================================================
--- /dev/null
+++ stand/common/interp_lua.c
@@ -0,0 +1,159 @@
+/*-
+ * Copyright (c) 2011 Wojciech A. Koszek <wkoszek@FreeBSD.org>
+ * Copyright (c) 2014 Pedro Souza <pedrosouza@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "bootstrap.h"
+
+#define lua_c
+
+#include "lstd.h"
+
+#include <lua.h>
+#include <ldebug.h>
+#include <lauxlib.h>
+#include <lualib.h>
+#include <lutils.h>
+
+struct interp_lua_softc {
+ lua_State *luap;
+};
+
+static struct interp_lua_softc lua_softc;
+
+#ifdef LUA_DEBUG
+#define LDBG(...) do { \
+ printf("%s(%d): ", __func__, __LINE__); \
+ printf(__VA_ARGS__); \
+ printf("\n"); \
+} while (0)
+#else
+#define LDBG(...)
+#endif
+
+
+static void *
+interp_lua_realloc(void *ud __unused, void *ptr, size_t osize __unused, size_t nsize)
+{
+
+ if (nsize == 0) {
+ free(ptr);
+ return NULL;
+ }
+ return realloc(ptr, nsize);
+}
+
+static const luaL_Reg loadedlibs[] = {
+ {"_G", luaopen_base},
+ {LUA_LOADLIBNAME, luaopen_package},
+// {LUA_COLIBNAME, luaopen_coroutine},
+// {LUA_TABLIBNAME, luaopen_table},
+ {LUA_STRLIBNAME, luaopen_string},
+// {LUA_IOLIBNAME, luaopen_io},
+// {LUA_OSLIBNAME, luaopen_os},
+// {LUA_MATHLIBNAME, luaopen_math},
+// {LUA_UTF8LIBNAME, luaopen_utf8},
+// {LUA_DBLIBNAME, luaopen_debug},
+ {NULL, NULL}
+};
+
+void
+interp_init(void)
+{
+ lua_State *luap;
+ struct interp_lua_softc *softc = &lua_softc;
+ const char *filename;
+ const luaL_Reg *lib;
+
+ setenv("script.lang", "lua", 1);
+ LDBG("creating context");
+
+ luap = lua_newstate(interp_lua_realloc, NULL);
+ if (luap == NULL) {
+ printf("problem initializing the Lua interpreter\n");
+ abort();
+ }
+ softc->luap = luap;
+ register_utils(luap);
+
+ /* "require" functions from 'loadedlibs' and set results to global table */
+ for (lib = loadedlibs; lib->func; lib++) {
+ luaL_requiref(luap, lib->name, lib->func, 1);
+ lua_pop(luap, 1); /* remove lib */
+ }
+
+ filename = "/boot/loader.lua";
+ if (interp_include(filename) != 0) {
+ const char *errstr = lua_tostring(luap, -1);
+ errstr = errstr == NULL ? "unknown" : errstr;
+ printf("Startup errorr in %s:\nLUA ERROR: %s.\n", filename, errstr);
+ lua_pop(luap, 1);
+ }
+}
+
+int
+interp_run(const char *line)
+{
+ int argc;
+ char **argv;
+ lua_State *luap;
+ struct interp_lua_softc *softc = &lua_softc;
+ int status;
+
+ luap = softc->luap;
+ LDBG("executing line...");
+ if ((status = luaL_dostring(luap, line)) != 0) {
+ /*
+ * If we could not parse the line as Lua syntax,
+ * try parsing it as a loader command.
+ */
+ lua_pop(luap, 1);
+ if (parse(&argc, &argv, line) == 0) {
+ status = interp_builtin_cmd(argc, argv);
+ if (status != CMD_OK)
+ printf("Command failed\n");
+ free(argv);
+ } else {
+ printf("Failed to parse \'%s\'\n", line);
+ status = -1;
+ }
+ }
+
+ return (status == 0 ? CMD_OK : CMD_ERROR);
+}
+
+int
+interp_include(const char *filename)
+{
+ struct interp_lua_softc *softc = &lua_softc;
+
+ LDBG("loading file %s", filename);
+
+ return (luaL_dofile(softc->luap, filename));
+}
Index: stand/defs.mk
===================================================================
--- stand/defs.mk
+++ stand/defs.mk
@@ -23,6 +23,8 @@
FDTSRC= ${BOOTSRC}/fdt
FICLSRC= ${BOOTSRC}/ficl
LDRSRC= ${BOOTSRC}/common
+LIBLUASRC= ${BOOTSRC}/liblua
+LUASRC= ${SRCTOP}/contrib/lua/src
SASRC= ${BOOTSRC}/libsa
SYSDIR= ${SRCTOP}/sys
UBOOTSRC= ${BOOTSRC}/uboot
Index: stand/liblua/Makefile
===================================================================
--- /dev/null
+++ stand/liblua/Makefile
@@ -0,0 +1,38 @@
+# $FreeBSD$
+
+.include <bsd.init.mk>
+
+.PATH: ${LUASRC}
+.PATH: ${LIBLUASRC}
+
+LIB= lua
+INTERNALLIB=
+
+# Core Lua.
+SRCS= lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c \
+ lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c \
+ ltm.c lundump.c lvm.c lzio.c
+SRCS+= lauxlib.c lbaselib.c lstrlib.c loadlib.c
+
+# These aren't yet included, but link now, omitting them saves 15k
+#SRCS+= lcorolib.c ldblib.c lutf8lib.c
+
+# These aren't yet compatible with the boot environment, and some may never be
+#SRCS+= lbitlib.c liolib.c lmathlib.c loslib.c ltablib.c
+
+# Our utilities.
+SRCS+= lstd.c lutils.c
+
+WARNS= 3
+
+CFLAGS+= -DLUA_FLOAT_TYPE=LUA_FLOAT_INT64
+CFLAGS+= -DLUA_PATH_DEFAULT=\"/boot/\?.lua\"
+CFLAGS+= -ffreestanding -nostdlib -DBOOT_LUA -DLUA_USE_POSIX
+CFLAGS+= -fno-stack-protector -D__BSD_VISIBLE
+CFLAGS+= -I${BOOTSRC}/include -I${LIBLUASRC} -I${LUASRC} -I${LDRSRC}
+
+.if ${MACHINE_CPUARCH} == "amd64" && ${DO32:U0} == 0
+CFLAGS+= -fPIC
+.endif
+
+.include <bsd.lib.mk>
Index: stand/liblua/float.h
===================================================================
--- /dev/null
+++ stand/liblua/float.h
@@ -0,0 +1,32 @@
+/*-
+ * Copyright (c) 2018 M Warner Losh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Empty file to keep lua build happy. Lua expects to have to include float.h
+ * but the int64_t number implementation doesn't need it.
+ */
Index: stand/liblua/locale.h
===================================================================
--- /dev/null
+++ stand/liblua/locale.h
@@ -0,0 +1,27 @@
+/*-
+ * Copyright (c) 2018 M Warner Losh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
Index: stand/liblua/lstd.h
===================================================================
--- /dev/null
+++ stand/liblua/lstd.h
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2014 Pedro Souza <pedrosouza@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef LSTD_H
+#define LSTD_H
+
+#include <stand.h>
+#include <sys/types.h>
+#include <sys/stdint.h>
+#include <limits.h>
+#include <string.h>
+#include <machine/stdarg.h>
+
+typedef struct FILE
+{
+ int fd;
+ size_t offset;
+ size_t size;
+} FILE;
+
+FILE *fopen(const char *filename, const char *mode);
+FILE *freopen( const char *filename, const char *mode, FILE *stream);
+size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
+int fclose(FILE *stream);
+int ferror(FILE *stream);
+int feof(FILE *stream);
+int getc(FILE * stream);
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+
+#define stdin ((FILE*)NULL)
+#define stdout 1
+
+#ifndef BUFSIZ
+#define BUFSIZ 512
+#endif
+
+#define lua_writestringerror(s, p) do { printf((s), (p)); } while (0)
+
+void luai_writestring(const char *, int);
+
+#define lua_writestring(s,l) luai_writestring(s,l)
+
+#define fflush /* */
+#define fgets(b, l, s) fgetstr((b), (l), 0)
+
+#endif /* LSTD_H */
Index: stand/liblua/lstd.c
===================================================================
--- /dev/null
+++ stand/liblua/lstd.c
@@ -0,0 +1,175 @@
+/*-
+ * Copyright (c) 2014 Pedro Souza <pedrosouza@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "lstd.h"
+#include "math.h"
+
+FILE *
+fopen(const char *filename, const char *mode)
+{
+ struct stat st;
+ int fd;
+ FILE *f;
+
+ if (mode == NULL || mode[0] != 'r')
+ return NULL;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return NULL;
+
+ f = malloc(sizeof(FILE));
+ if (f == NULL) {
+ close(fd);
+ return NULL;
+ }
+
+ if (fstat(fd, &st) != 0) {
+ free(f);
+ close(fd);
+ return (NULL);
+ }
+
+ f->fd = fd;
+ f->offset = 0;
+ f->size = st.st_size;
+
+ return (f);
+}
+
+
+FILE *
+freopen(const char *filename, const char *mode, FILE *stream)
+{
+ fclose(stream);
+ return (fopen(filename, mode));
+}
+
+size_t
+fread(void *ptr, size_t size, size_t count, FILE *stream)
+{
+ size_t r;
+
+ if (stream == NULL)
+ return 0;
+ r = (size_t)read(stream->fd, ptr, size * count);
+ stream->offset += r;
+
+ return (r);
+}
+
+int
+fclose(FILE *stream)
+{
+ if (stream == NULL)
+ return EOF;
+ close(stream->fd);
+ free(stream);
+
+ return (0);
+}
+
+int
+ferror(FILE *stream)
+{
+
+ return (stream == NULL || stream->fd < 0);
+}
+
+int
+feof(FILE *stream)
+{
+
+ if (stream == NULL)
+ return 1;
+
+ return (stream->offset >= stream->size);
+}
+
+int
+getc(FILE *stream)
+{
+ char ch;
+ size_t r;
+
+ if (stream == NULL)
+ return EOF;
+ r = read(stream->fd, &ch, 1);
+ if (r == 1)
+ return ch;
+ return EOF;
+}
+
+void
+luai_writestring(const char *s, int i)
+{
+
+ while (i-- > 0)
+ putchar(*s++);
+}
+
+int64_t
+lstd_pow(int64_t x, int64_t y)
+{
+ int64_t rv = 1;
+
+ if (y < 0)
+ return 0;
+ rv = x;
+ while (--y)
+ rv *= x;
+
+ return rv;
+}
+
+int64_t
+lstd_floor(int64_t x)
+{
+
+ return (x);
+}
+
+int64_t
+lstd_fmod(int64_t a, int64_t b)
+{
+
+ return (a % b);
+}
+
+/*
+ * This can't be implemented, so maybe it should just abort.
+ */
+int64_t
+lstd_frexp(int64_t a, int *y)
+{
+ *y = 0;
+
+ return 0;
+}
Index: stand/liblua/luaconf.h
===================================================================
--- /dev/null
+++ stand/liblua/luaconf.h
@@ -0,0 +1,810 @@
+/*
+** $Id: luaconf.h,v 1.259 2016/12/22 13:08:50 roberto Exp $
+** Configuration file for Lua
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef luaconf_h
+#define luaconf_h
+
+#include <limits.h>
+#include <stddef.h>
+
+
+/*
+** ===================================================================
+** Search for "@@" to find all configurable definitions.
+** ===================================================================
+*/
+
+
+/*
+** {====================================================================
+** System Configuration: macros to adapt (if needed) Lua to some
+** particular platform, for instance compiling it with 32-bit numbers or
+** restricting it to C89.
+** =====================================================================
+*/
+
+/*
+@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. You
+** can also define LUA_32BITS in the make file, but changing here you
+** ensure that all software connected to Lua will be compiled with the
+** same configuration.
+*/
+/* #define LUA_32BITS */
+
+
+/*
+@@ LUA_USE_C89 controls the use of non-ISO-C89 features.
+** Define it if you want Lua to avoid the use of a few C99 features
+** or Windows-specific features on Windows.
+*/
+/* #define LUA_USE_C89 */
+
+
+/*
+** By default, Lua on Windows use (some) specific Windows features
+*/
+#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE)
+#define LUA_USE_WINDOWS /* enable goodies for regular Windows */
+#endif
+
+
+#if defined(LUA_USE_WINDOWS)
+#define LUA_DL_DLL /* enable support for DLL */
+#define LUA_USE_C89 /* broadly, Windows is C89 */
+#endif
+
+
+#if defined(LUA_USE_LINUX)
+#define LUA_USE_POSIX
+#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
+#define LUA_USE_READLINE /* needs some extra libraries */
+#endif
+
+
+#if defined(LUA_USE_MACOSX)
+#define LUA_USE_POSIX
+#define LUA_USE_DLOPEN /* MacOS does not need -ldl */
+#define LUA_USE_READLINE /* needs an extra library: -lreadline */
+#endif
+
+
+/*
+@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for
+** C89 ('long' and 'double'); Windows always has '__int64', so it does
+** not need to use this case.
+*/
+#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS)
+#define LUA_C89_NUMBERS
+#endif
+
+
+
+/*
+@@ LUAI_BITSINT defines the (minimum) number of bits in an 'int'.
+*/
+/* avoid undefined shifts */
+#if ((INT_MAX >> 15) >> 15) >= 1
+#define LUAI_BITSINT 32
+#else
+/* 'int' always must have at least 16 bits */
+#define LUAI_BITSINT 16
+#endif
+
+
+/*
+@@ LUA_INT_TYPE defines the type for Lua integers.
+@@ LUA_FLOAT_TYPE defines the type for Lua floats.
+** Lua should work fine with any mix of these options (if supported
+** by your C compiler). The usual configurations are 64-bit integers
+** and 'double' (the default), 32-bit integers and 'float' (for
+** restricted platforms), and 'long'/'double' (for C compilers not
+** compliant with C99, which may not have support for 'long long').
+*/
+
+/* predefined options for LUA_INT_TYPE */
+#define LUA_INT_INT 1
+#define LUA_INT_LONG 2
+#define LUA_INT_LONGLONG 3
+
+/* predefined options for LUA_FLOAT_TYPE */
+#define LUA_FLOAT_FLOAT 1
+#define LUA_FLOAT_DOUBLE 2
+#define LUA_FLOAT_LONGDOUBLE 3
+#define LUA_FLOAT_INT64 4
+
+#if defined(LUA_32BITS) /* { */
+/*
+** 32-bit integers and 'float'
+*/
+#if LUAI_BITSINT >= 32 /* use 'int' if big enough */
+#define LUA_INT_TYPE LUA_INT_INT
+#else /* otherwise use 'long' */
+#define LUA_INT_TYPE LUA_INT_LONG
+#endif
+#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT
+
+#elif defined(LUA_C89_NUMBERS) /* }{ */
+/*
+** largest types available for C89 ('long' and 'double')
+*/
+#define LUA_INT_TYPE LUA_INT_LONG
+#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
+
+#endif /* } */
+
+
+/*
+** default configuration for 64-bit Lua ('long long' and 'double')
+*/
+#if !defined(LUA_INT_TYPE)
+#define LUA_INT_TYPE LUA_INT_LONGLONG
+#endif
+
+#if !defined(LUA_FLOAT_TYPE)
+#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
+#endif
+
+/* }================================================================== */
+
+
+
+
+/*
+** {==================================================================
+** Configuration for Paths.
+** ===================================================================
+*/
+
+/*
+** LUA_PATH_SEP is the character that separates templates in a path.
+** LUA_PATH_MARK is the string that marks the substitution points in a
+** template.
+** LUA_EXEC_DIR in a Windows path is replaced by the executable's
+** directory.
+*/
+#define LUA_PATH_SEP ";"
+#define LUA_PATH_MARK "?"
+#define LUA_EXEC_DIR "!"
+
+
+/*
+@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
+** Lua libraries.
+@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
+** C libraries.
+** CHANGE them if your machine has a non-conventional directory
+** hierarchy or if you want to install your libraries in
+** non-conventional directories.
+*/
+#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
+#if defined(_WIN32) /* { */
+/*
+** In Windows, any exclamation mark ('!') in the path is replaced by the
+** path of the directory of the executable file of the current process.
+*/
+#define LUA_LDIR "!\\lua\\"
+#define LUA_CDIR "!\\"
+#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\"
+#define LUA_PATH_DEFAULT \
+ LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \
+ LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \
+ ".\\?.lua;" ".\\?\\init.lua"
+#define LUA_CPATH_DEFAULT \
+ LUA_CDIR"?.dll;" \
+ LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \
+ LUA_CDIR"loadall.dll;" ".\\?.dll"
+
+#else /* }{ */
+
+#define LUA_ROOT "/usr/local/"
+#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/"
+#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/"
+#ifndef LUA_PATH_DEFAULT
+#define LUA_PATH_DEFAULT \
+ LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \
+ "./?.lua;" "./?/init.lua"
+#endif
+#define LUA_CPATH_DEFAULT \
+ LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
+#endif /* } */
+
+
+/*
+@@ LUA_DIRSEP is the directory separator (for submodules).
+** CHANGE it if your machine does not use "/" as the directory separator
+** and is not Windows. (On Windows Lua automatically uses "\".)
+*/
+#if defined(_WIN32)
+#define LUA_DIRSEP "\\"
+#else
+#define LUA_DIRSEP "/"
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Marks for exported symbols in the C code
+** ===================================================================
+*/
+
+/*
+@@ LUA_API is a mark for all core API functions.
+@@ LUALIB_API is a mark for all auxiliary library functions.
+@@ LUAMOD_API is a mark for all standard library opening functions.
+** CHANGE them if you need to define those functions in some special way.
+** For instance, if you want to create one Windows DLL with the core and
+** the libraries, you may want to use the following definition (define
+** LUA_BUILD_AS_DLL to get it).
+*/
+#if defined(LUA_BUILD_AS_DLL) /* { */
+
+#if defined(LUA_CORE) || defined(LUA_LIB) /* { */
+#define LUA_API __declspec(dllexport)
+#else /* }{ */
+#define LUA_API __declspec(dllimport)
+#endif /* } */
+
+#else /* }{ */
+
+#define LUA_API extern
+
+#endif /* } */
+
+
+/* more often than not the libs go together with the core */
+#define LUALIB_API LUA_API
+#define LUAMOD_API LUALIB_API
+
+
+/*
+@@ LUAI_FUNC is a mark for all extern functions that are not to be
+** exported to outside modules.
+@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables
+** that are not to be exported to outside modules (LUAI_DDEF for
+** definitions and LUAI_DDEC for declarations).
+** CHANGE them if you need to mark them in some special way. Elf/gcc
+** (versions 3.2 and later) mark them as "hidden" to optimize access
+** when Lua is compiled as a shared library. Not all elf targets support
+** this attribute. Unfortunately, gcc does not offer a way to check
+** whether the target offers that support, and those without support
+** give a warning about it. To avoid these warnings, change to the
+** default definition.
+*/
+#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
+ defined(__ELF__) /* { */
+#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
+#else /* }{ */
+#define LUAI_FUNC extern
+#endif /* } */
+
+#define LUAI_DDEC LUAI_FUNC
+#define LUAI_DDEF /* empty */
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Compatibility with previous versions
+** ===================================================================
+*/
+
+/*
+@@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2.
+@@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1.
+** You can define it to get all options, or change specific options
+** to fit your specific needs.
+*/
+#if defined(LUA_COMPAT_5_2) /* { */
+
+/*
+@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated
+** functions in the mathematical library.
+*/
+#define LUA_COMPAT_MATHLIB
+
+/*
+@@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'.
+*/
+#define LUA_COMPAT_BITLIB
+
+/*
+@@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod.
+*/
+#define LUA_COMPAT_IPAIRS
+
+/*
+@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for
+** manipulating other integer types (lua_pushunsigned, lua_tounsigned,
+** luaL_checkint, luaL_checklong, etc.)
+*/
+#define LUA_COMPAT_APIINTCASTS
+
+#endif /* } */
+
+
+#if defined(LUA_COMPAT_5_1) /* { */
+
+/* Incompatibilities from 5.2 -> 5.3 */
+#define LUA_COMPAT_MATHLIB
+#define LUA_COMPAT_APIINTCASTS
+
+/*
+@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
+** You can replace it with 'table.unpack'.
+*/
+#define LUA_COMPAT_UNPACK
+
+/*
+@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'.
+** You can replace it with 'package.searchers'.
+*/
+#define LUA_COMPAT_LOADERS
+
+/*
+@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall.
+** You can call your C function directly (with light C functions).
+*/
+#define lua_cpcall(L,f,u) \
+ (lua_pushcfunction(L, (f)), \
+ lua_pushlightuserdata(L,(u)), \
+ lua_pcall(L,1,0,0))
+
+
+/*
+@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library.
+** You can rewrite 'log10(x)' as 'log(x, 10)'.
+*/
+#define LUA_COMPAT_LOG10
+
+/*
+@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base
+** library. You can rewrite 'loadstring(s)' as 'load(s)'.
+*/
+#define LUA_COMPAT_LOADSTRING
+
+/*
+@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library.
+*/
+#define LUA_COMPAT_MAXN
+
+/*
+@@ The following macros supply trivial compatibility for some
+** changes in the API. The macros themselves document how to
+** change your code to avoid using them.
+*/
+#define lua_strlen(L,i) lua_rawlen(L, (i))
+
+#define lua_objlen(L,i) lua_rawlen(L, (i))
+
+#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
+#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT)
+
+/*
+@@ LUA_COMPAT_MODULE controls compatibility with previous
+** module functions 'module' (Lua) and 'luaL_register' (C).
+*/
+#define LUA_COMPAT_MODULE
+
+#endif /* } */
+
+
+/*
+@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
+@@ a float mark ('.0').
+** This macro is not on by default even in compatibility mode,
+** because this is not really an incompatibility.
+*/
+/* #define LUA_COMPAT_FLOATSTRING */
+
+/* }================================================================== */
+
+
+
+/*
+** {==================================================================
+** Configuration for Numbers.
+** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
+** satisfy your needs.
+** ===================================================================
+*/
+
+/*
+@@ LUA_NUMBER is the floating-point type used by Lua.
+@@ LUAI_UACNUMBER is the result of a 'default argument promotion'
+@@ over a floating number.
+@@ l_mathlim(x) corrects limit name 'x' to the proper float type
+** by prefixing it with one of FLT/DBL/LDBL.
+@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
+@@ LUA_NUMBER_FMT is the format for writing floats.
+@@ lua_number2str converts a float to a string.
+@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
+@@ l_floor takes the floor of a float.
+@@ lua_str2number converts a decimal numeric string to a number.
+*/
+
+
+/* The following definitions are good for most cases here */
+
+#define l_floor(x) (l_mathop(floor)(x))
+
+#define lua_number2str(s,sz,n) \
+ l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n))
+
+/*
+@@ lua_numbertointeger converts a float number to an integer, or
+** returns 0 if float is not within the range of a lua_Integer.
+** (The range comparisons are tricky because of rounding. The tests
+** here assume a two-complement representation, where MININTEGER always
+** has an exact representation as a float; MAXINTEGER may not have one,
+** and therefore its conversion to float may have an ill-defined value.)
+*/
+#define lua_numbertointeger(n,p) \
+ ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \
+ (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \
+ (*(p) = (LUA_INTEGER)(n), 1))
+
+
+/* now the variable definitions */
+
+#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */
+
+#define LUA_NUMBER float
+
+#define l_mathlim(n) (FLT_##n)
+
+#define LUAI_UACNUMBER double
+
+#define LUA_NUMBER_FRMLEN ""
+#define LUA_NUMBER_FMT "%.7g"
+
+#define l_mathop(op) op##f
+
+#define lua_str2number(s,p) strtof((s), (p))
+
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */
+
+#define LUA_NUMBER long double
+
+#define l_mathlim(n) (LDBL_##n)
+
+#define LUAI_UACNUMBER long double
+
+#define LUA_NUMBER_FRMLEN "L"
+#define LUA_NUMBER_FMT "%.19Lg"
+
+#define l_mathop(op) op##l
+
+#define lua_str2number(s,p) strtold((s), (p))
+
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */
+
+#define LUA_NUMBER double
+
+#define l_mathlim(n) (DBL_##n)
+
+#define LUAI_UACNUMBER double
+
+#define LUA_NUMBER_FRMLEN ""
+#define LUA_NUMBER_FMT "%.14g"
+
+#define l_mathop(op) op
+
+#define lua_str2number(s,p) strtod((s), (p))
+
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_INT64 /* }{ int64 */
+
+#include "lstd.h"
+
+#include <machine/_inttypes.h>
+
+#define panic lua_panic
+/* Hack to use int64 as the LUA_NUMBER from ZFS code, kinda */
+
+#define LUA_NUMBER int64_t
+
+#define l_mathlim(n) (LUA_FLOAT_INT_HACK_##n)
+#define LUA_FLOAT_INT_HACK_MANT_DIG 32
+#define LUA_FLOAT_INT_HACK_MAX_10_EXP 32
+
+#define LUAI_UACNUMBER int64_t
+
+#define LUA_NUMBER_FRMLEN ""
+#define LUA_NUMBER_FMT "%" PRId64
+
+#define l_mathop(x) (lstd_ ## x)
+
+#define lua_str2number(s,p) strtoll((s), (p), 0)
+
+#define lua_getlocaledecpoint() '.'
+
+#else /* }{ */
+
+#error "numeric float type not defined"
+
+#endif /* } */
+
+
+
+/*
+@@ LUA_INTEGER is the integer type used by Lua.
+**
+@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
+**
+@@ LUAI_UACINT is the result of a 'default argument promotion'
+@@ over a lUA_INTEGER.
+@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
+@@ LUA_INTEGER_FMT is the format for writing integers.
+@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
+@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
+@@ lua_integer2str converts an integer to a string.
+*/
+
+
+/* The following definitions are good for most cases here */
+
+#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d"
+
+#define LUAI_UACINT LUA_INTEGER
+
+#define lua_integer2str(s,sz,n) \
+ l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n))
+
+/*
+** use LUAI_UACINT here to avoid problems with promotions (which
+** can turn a comparison between unsigneds into a signed comparison)
+*/
+#define LUA_UNSIGNED unsigned LUAI_UACINT
+
+
+/* now the variable definitions */
+
+#if LUA_INT_TYPE == LUA_INT_INT /* { int */
+
+#define LUA_INTEGER int
+#define LUA_INTEGER_FRMLEN ""
+
+#define LUA_MAXINTEGER INT_MAX
+#define LUA_MININTEGER INT_MIN
+
+#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */
+
+#define LUA_INTEGER long
+#define LUA_INTEGER_FRMLEN "l"
+
+#define LUA_MAXINTEGER LONG_MAX
+#define LUA_MININTEGER LONG_MIN
+
+#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */
+
+/* use presence of macro LLONG_MAX as proxy for C99 compliance */
+#if defined(LLONG_MAX) /* { */
+/* use ISO C99 stuff */
+
+#define LUA_INTEGER long long
+#define LUA_INTEGER_FRMLEN "ll"
+
+#define LUA_MAXINTEGER LLONG_MAX
+#define LUA_MININTEGER LLONG_MIN
+
+#elif defined(LUA_USE_WINDOWS) /* }{ */
+/* in Windows, can use specific Windows types */
+
+#define LUA_INTEGER __int64
+#define LUA_INTEGER_FRMLEN "I64"
+
+#define LUA_MAXINTEGER _I64_MAX
+#define LUA_MININTEGER _I64_MIN
+
+#else /* }{ */
+
+#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \
+ or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)"
+
+#endif /* } */
+
+#else /* }{ */
+
+#error "numeric integer type not defined"
+
+#endif /* } */
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Dependencies with C99 and other C details
+** ===================================================================
+*/
+
+/*
+@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89.
+** (All uses in Lua have only one format item.)
+*/
+#if !defined(LUA_USE_C89)
+#define l_sprintf(s,sz,f,i) snprintf(s,sz,f,i)
+#else
+#define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i))
+#endif
+
+
+/*
+@@ lua_strx2number converts an hexadecimal numeric string to a number.
+** In C99, 'strtod' does that conversion. Otherwise, you can
+** leave 'lua_strx2number' undefined and Lua will provide its own
+** implementation.
+*/
+#if !defined(LUA_USE_C89)
+#define lua_strx2number(s,p) lua_str2number(s,p)
+#endif
+
+
+/*
+@@ lua_number2strx converts a float to an hexadecimal numeric string.
+** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
+** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
+** provide its own implementation.
+*/
+#if !defined(LUA_USE_C89)
+#define lua_number2strx(L,b,sz,f,n) \
+ ((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n)))
+#endif
+
+
+/*
+** 'strtof' and 'opf' variants for math functions are not valid in
+** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the
+** availability of these variants. ('math.h' is already included in
+** all files that use these macros.)
+*/
+#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF))
+#undef l_mathop /* variants not available */
+#undef lua_str2number
+#define l_mathop(op) (lua_Number)op /* no variant */
+#define lua_str2number(s,p) ((lua_Number)strtod((s), (p)))
+#endif
+
+
+/*
+@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation
+** functions. It must be a numerical type; Lua will use 'intptr_t' if
+** available, otherwise it will use 'ptrdiff_t' (the nearest thing to
+** 'intptr_t' in C89)
+*/
+#define LUA_KCONTEXT ptrdiff_t
+
+#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
+ __STDC_VERSION__ >= 199901L
+#include <stdint.h>
+#if defined(INTPTR_MAX) /* even in C99 this type is optional */
+#undef LUA_KCONTEXT
+#define LUA_KCONTEXT intptr_t
+#endif
+#endif
+
+
+/*
+@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
+** Change that if you do not want to use C locales. (Code using this
+** macro must include header 'locale.h'.)
+*/
+#if !defined(lua_getlocaledecpoint)
+#define lua_getlocaledecpoint() (localeconv()->decimal_point[0])
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Language Variations
+** =====================================================================
+*/
+
+/*
+@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some
+** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from
+** numbers to strings. Define LUA_NOCVTS2N to turn off automatic
+** coercion from strings to numbers.
+*/
+/* #define LUA_NOCVTN2S */
+/* #define LUA_NOCVTS2N */
+
+
+/*
+@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
+** Define it as a help when debugging C code.
+*/
+#if defined(LUA_USE_APICHECK)
+#include <assert.h>
+#define luai_apicheck(l,e) assert(e)
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Macros that affect the API and must be stable (that is, must be the
+** same when you compile Lua and when you compile code that links to
+** Lua). You probably do not want/need to change them.
+** =====================================================================
+*/
+
+/*
+@@ LUAI_MAXSTACK limits the size of the Lua stack.
+** CHANGE it if you need a different limit. This limit is arbitrary;
+** its only purpose is to stop Lua from consuming unlimited stack
+** space (and to reserve some numbers for pseudo-indices).
+*/
+#if LUAI_BITSINT >= 32
+#define LUAI_MAXSTACK 1000000
+#else
+#define LUAI_MAXSTACK 15000
+#endif
+
+
+/*
+@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
+** a Lua state with very fast access.
+** CHANGE it if you need a different size.
+*/
+#define LUA_EXTRASPACE (sizeof(void *))
+
+
+/*
+@@ LUA_IDSIZE gives the maximum size for the description of the source
+@@ of a function in debug information.
+** CHANGE it if you want a different size.
+*/
+#define LUA_IDSIZE 60
+
+
+/*
+@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
+** CHANGE it if it uses too much C-stack space. (For long double,
+** 'string.format("%.99f", -1e4932)' needs 5034 bytes, so a
+** smaller buffer would force a memory allocation for each call to
+** 'string.format'.)
+*/
+#if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE
+#define LUAL_BUFFERSIZE 8192
+#else
+#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
+#endif
+
+/* }================================================================== */
+
+
+/*
+@@ LUA_QL describes how error messages quote program elements.
+** Lua does not use these macros anymore; they are here for
+** compatibility only.
+*/
+#define LUA_QL(x) "'" x "'"
+#define LUA_QS LUA_QL("%s")
+
+
+
+
+/* =================================================================== */
+
+/*
+** Local configuration. You can use this space to add your redefinitions
+** without modifying the main part of the file.
+*/
+
+
+
+
+
+#endif
Index: stand/liblua/lutils.h
===================================================================
--- /dev/null
+++ stand/liblua/lutils.h
@@ -0,0 +1,32 @@
+/*-
+ * Copyright (c) 2014 Pedro Souza <pedrosouza@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <lua.h>
+
+void lregister(lua_State *, const char *, const char *, int (*fptr)(lua_State *));
+void register_utils(lua_State *);
Index: stand/liblua/lutils.c
===================================================================
--- /dev/null
+++ stand/liblua/lutils.c
@@ -0,0 +1,268 @@
+/*-
+ * Copyright (c) 2014 Pedro Souza <pedrosouza@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lstd.h"
+#include "lutils.h"
+#include "bootstrap.h"
+
+static int
+lua_perform(lua_State *L)
+{
+ int argc;
+ char **argv;
+ int res = 1;
+
+ if (parse(&argc, &argv, luaL_checkstring(L, 1)) == 0) {
+ res = interp_builtin_cmd(argc, argv);
+ free(argv);
+ }
+ lua_pushinteger(L, res);
+
+ return 1;
+}
+
+static int
+lua_getchar(lua_State *L)
+{
+
+ lua_pushinteger(L, getchar());
+ return 1;
+}
+
+static int
+lua_ischar(lua_State *L)
+{
+
+ lua_pushboolean(L, ischar());
+ return 1;
+}
+
+static int
+lua_gets(lua_State *L)
+{
+ char buf[129];
+
+ ngets(buf, 128);
+ lua_pushstring(L, buf);
+ return 1;
+}
+
+static int
+lua_time(lua_State *L)
+{
+
+ lua_pushinteger(L, time(NULL));
+ return 1;
+}
+
+static int
+lua_delay(lua_State *L)
+{
+
+ delay((int)luaL_checknumber(L, 1));
+ return 0;
+}
+
+static int
+lua_getenv(lua_State *L)
+{
+ lua_pushstring(L, getenv(luaL_checkstring(L, 1)));
+
+ return 1;
+}
+
+static int
+lua_setenv(lua_State *L)
+{
+ const char *key, *val;
+
+ key = luaL_checkstring(L, 1);
+ val = luaL_checkstring(L, 2);
+ lua_pushinteger(L, setenv(key, val, 1));
+
+ return 1;
+}
+
+static int
+lua_unsetenv(lua_State *L)
+{
+ const char *ev;
+
+ ev = luaL_checkstring(L, 1);
+ lua_pushinteger(L, unsetenv(ev));
+
+ return 1;
+}
+
+static int
+lua_printc(lua_State *L)
+{
+ int status;
+ ssize_t l;
+ const char *s = luaL_checklstring(L, 1, &l);
+
+ status = (printf("%s", s) == l);
+
+ return status;
+}
+
+static int
+lua_openfile(lua_State *L)
+{
+ const char *str;
+
+ if (lua_gettop(L) != 1) {
+ lua_pushnil(L);
+ return 1;
+ }
+ str = lua_tostring(L, 1);
+
+ FILE * f = fopen(str, "r");
+ if (f != NULL) {
+ FILE ** ptr = (FILE**)lua_newuserdata(L, sizeof(FILE**));
+ *ptr = f;
+ } else
+ lua_pushnil(L);
+ return 1;
+}
+
+static int
+lua_closefile(lua_State *L)
+{
+ FILE ** f;
+ if (lua_gettop(L) != 1) {
+ lua_pushboolean(L, 0);
+ return 1;
+ }
+
+ f = (FILE**)lua_touserdata(L, 1);
+ if (f != NULL && *f != NULL) {
+ lua_pushboolean(L, fclose(*f) == 0 ? 1 : 0);
+ *f = NULL;
+ } else
+ lua_pushboolean(L, 0);
+
+ return 1;
+}
+
+static int
+lua_readfile(lua_State *L)
+{
+ FILE **f;
+ size_t size, r;
+ char * buf;
+
+ if (lua_gettop(L) < 1 || lua_gettop(L) > 2) {
+ lua_pushnil(L);
+ lua_pushinteger(L, 0);
+ return 2;
+ }
+
+ f = (FILE**)lua_touserdata(L, 1);
+
+ if (f == NULL || *f == NULL) {
+ lua_pushnil(L);
+ lua_pushinteger(L, 0);
+ return 2;
+ }
+
+ if (lua_gettop(L) == 2)
+ size = (size_t)lua_tonumber(L, 2);
+ else
+ size = (*f)->size;
+
+
+ buf = (char*)malloc(size);
+ r = fread(buf, 1, size, *f);
+ lua_pushlstring(L, buf, r);
+ free(buf);
+ lua_pushinteger(L, r);
+
+ return 2;
+}
+
+void
+lregister(lua_State *L, const char *tableName, const char *funcName, int (*funcPointer)(lua_State *))
+{
+ lua_getglobal(L, tableName);
+ if (!lua_istable(L, -1)) {
+ lua_pop(L, 1);
+ lua_newtable(L);
+ lua_setglobal(L, tableName);
+ lua_getglobal(L, tableName);
+ }
+
+ lua_pushcfunction(L, funcPointer);
+ lua_setfield(L, -2, funcName);
+ lua_pop(L, 1);
+}
+
+
+typedef struct utils_func
+{
+ int (*func)(lua_State *);
+ const char *table;
+ const char *name;
+} utils_func;
+
+static utils_func reg_funcs[] = {
+ {lua_delay, "loader", "delay"},
+ {lua_getenv, "loader", "getenv"},
+ {lua_perform, "loader", "perform"},
+ {lua_printc, "loader", "printc"},
+ {lua_setenv, "loader", "setenv"},
+ {lua_time, "loader", "time"},
+ {lua_unsetenv, "loader", "unsetenv"},
+
+ {lua_closefile, "io", "close"},
+ {lua_getchar, "io", "getchar"},
+ {lua_gets, "io", "gets"},
+ {lua_ischar, "io", "ischar"},
+ {lua_openfile, "io", "open"},
+ {lua_readfile, "io", "read"},
+
+ {NULL, NULL, NULL},
+ };
+
+void
+register_utils(lua_State *L)
+{
+ utils_func *f = reg_funcs;
+
+ while (f->func != NULL && f->name != NULL) {
+ if (f->table != NULL)
+ lregister(L, f->table, f->name, f->func);
+ else
+ lua_register(L, f->name, f->func);
+ ++f;
+ }
+}
Index: stand/liblua/math.h
===================================================================
--- /dev/null
+++ stand/liblua/math.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2018 M Warner Losh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * A replacement for math.h that's sufficient to pretend that we
+ * actually have one to keep the un-modified lua happy.
+ */
+#include <stdint.h>
+
+int64_t lstd_pow(int64_t x, int64_t y);
+int64_t lstd_floor(int64_t);
+int64_t lstd_fmod(int64_t a, int64_t b);
+int64_t lstd_frexp(int64_t a, int *);
Index: stand/liblua32/Makefile
===================================================================
--- /dev/null
+++ stand/liblua32/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+DO32=1
+
+.include "${.CURDIR}/../liblua/Makefile"
Index: stand/loader.mk
===================================================================
--- stand/loader.mk
+++ stand/loader.mk
@@ -56,9 +56,16 @@
.endif
# Forth interpreter
-.if ${MK_FORTH} != "no"
+.if ${MK_LOADER_LUA} != "no"
+SRCS+= interp_lua.c
+.include "${BOOTSRC}/lua.mk"
+LDR_INTERP= ${LIBLUA}
+LDR_INTERP32= ${LIBLUA32}
+.elif ${MK_FORTH} != "no"
SRCS+= interp_forth.c
.include "${BOOTSRC}/ficl.mk"
+LDR_INTERP= ${LIBFICL}
+LDR_INTERP32= ${LIBFICL32}
.else
SRCS+= interp_simple.c
.endif
@@ -134,9 +141,12 @@
.else
LIBFICL32= ${BOOTOBJ}/ficl32/libficl.a
.endif
-.if ${MK_FORTH} != no
-LDR_INTERP= ${LIBFICL}
-LDR_INTERP32= ${LIBFICL32}
+
+LIBLUA= ${BOOTOBJ}/liblua/liblua.a
+.if ${MACHINE} == "i386"
+LIBLUA32= ${LIBFICL}
+.else
+LIBLUA32= ${BOOTOBJ}/liblua32/liblua.a
.endif
CLEANFILES+= vers.c
Index: stand/lua.mk
===================================================================
--- /dev/null
+++ stand/lua.mk
@@ -0,0 +1,12 @@
+# $FreeBSD$
+
+# Common flags to build lua related files
+
+.include "defs.mk"
+
+.if ${MACHINE_CPUARCH} == "amd64" && ${DO32:U0} == 0
+CFLAGS+= -fPIC
+.endif
+
+CFLAGS+= -I${LUASRC} -I${LDRSRC} -I${LIBLUASRC}
+CFLAGS+= -DBOOT_LUA
Index: stand/lua/Makefile
===================================================================
--- /dev/null
+++ stand/lua/Makefile
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+.include <bsd.init.mk>
+
+FILES= color.lua \
+ config.lua \
+ core.lua \
+ drawer.lua \
+ loader.lua \
+ menu.lua \
+ password.lua \
+ screen.lua
+
+.include <bsd.prog.mk>
Index: stand/lua/config.lua
===================================================================
--- /dev/null
+++ stand/lua/config.lua
@@ -0,0 +1,371 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+local config = {};
+
+local modules = {};
+
+function config.setKey(k, n, v)
+ if modules[k] == nil then
+ modules[k] = {};
+ end
+ modules[k][n] = v;
+end
+
+local pattern_table = {
+ [1] = {
+ str = "^%s*(#.*)",
+ process = function(k, v) end
+ },
+ -- module_load="value"
+ [2] = {
+ str = "^%s*([%w_]+)_load%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ if modules[k] == nil then
+ modules[k] = {};
+ end
+ modules[k].load = string.upper(v);
+ end
+ },
+ -- module_name="value"
+ [3] = {
+ str = "^%s*([%w_]+)_name%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ config.setKey(k, "name", v);
+ end
+ },
+ -- module_type="value"
+ [4] = {
+ str = "^%s*([%w_]+)_type%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ config.setKey(k, "type", v);
+ end
+ },
+ -- module_flags="value"
+ [5] = {
+ str = "^%s*([%w_]+)_flags%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ config.setKey(k, "flags", v);
+ end
+ },
+ -- module_before="value"
+ [6] = {
+ str = "^%s*([%w_]+)_before%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ config.setKey(k, "before", v);
+ end
+ },
+ -- module_after="value"
+ [7] = {
+ str = "^%s*([%w_]+)_after%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ config.setKey(k, "after", v);
+ end
+ },
+ -- module_error="value"
+ [8] = {
+ str = "^%s*([%w_]+)_error%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ config.setKey(k, "error", v);
+ end
+ },
+ -- exec="command"
+ [9] = {
+ str = "^%s*exec%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ if loader.perform(k) ~= 0 then
+ print("Failed to exec '"..k.."'");
+ end
+ end
+ },
+ -- env_var="value"
+ [10] = {
+ str = "^%s*([%w%p]+)%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+ process = function(k, v)
+ if loader.setenv(k, v) ~= 0 then
+ print("Failed to set '"..k.."' with value: "..v.."");
+ end
+ end
+ },
+ -- env_var=num
+ [11] = {
+ str = "^%s*([%w%p]+)%s*=%s*(%d+)%s*(.*)",
+ process = function(k, v)
+ if loader.setenv(k, v) ~= 0 then
+ print("Failed to set '"..k.."' with value: "..v.."");
+ end
+ end
+ }
+};
+
+function config.isValidComment(c)
+ if c ~= nil then
+ local s = string.match(c, "^%s*#.*");
+ if s == nil then
+ s = string.match(c, "^%s*$");
+ end
+ if s == nil then
+ return false;
+ end
+ end
+ return true;
+end
+
+function config.loadmod(mod, silent)
+ local status = true;
+ for k, v in pairs(mod) do
+ if v.load == "YES" then
+ local str = "load ";
+ if v.flags ~= nil then
+ str = str .. v.flags .. " ";
+ end
+ if v.type ~= nil then
+ str = str .. "-t " .. v.type .. " ";
+ end
+ if v.name ~= nil then
+ str = str .. v.name;
+ else
+ str = str .. k;
+ end
+
+ if v.before ~= nil then
+ if loader.perform(v.before) ~= 0 then
+ if not silent then
+ print("Failed to execute '"..v.before.."' before loading '"..k.."'");
+ end
+ status = false;
+ end
+ end
+
+ if loader.perform(str) ~= 0 then
+ if not silent then
+ print("Failed to execute '" .. str .. "'");
+ end
+ if v.error ~= nil then
+ loader.perform(v.error);
+ end
+ status = false;
+ end
+
+ if v.after ~= nil then
+ if loader.perform(v.after) ~= 0 then
+ if not silent then
+ print("Failed to execute '"..v.after.."' after loading '"..k.."'");
+ end
+ status = false;
+ end
+ end
+
+ else
+ --if not silent then print("Skiping module '".. k .. "'"); end
+ end
+ end
+
+ return status;
+end
+
+function config.parse(name, silent)
+ local f = io.open(name);
+ if f == nil then
+ if not silent then
+ print("Failed to open config: '" .. name.."'");
+ end
+ return false;
+ end
+
+ local text;
+ local r;
+
+ text, r = io.read(f);
+
+ if text == nil then
+ if not silent then
+ print("Failed to read config: '" .. name.."'");
+ end
+ return false;
+ end
+
+ local n = 1;
+ local status = true;
+
+ for line in string.gmatch(text, "([^\n]+)") do
+
+ if string.match(line, "^%s*$") == nil then
+ local found = false;
+
+ for i, val in ipairs(pattern_table) do
+ local k, v, c = string.match(line, val.str);
+ if k ~= nil then
+ found = true;
+
+ if config.isValidComment(c) then
+ val.process(k, v);
+ else
+ print("Malformed line ("..n.."):\n\t'"..line.."'");
+ status = false;
+ end
+
+ break;
+ end
+ end
+
+ if found == false then
+ print("Malformed line ("..n.."):\n\t'"..line.."'");
+ status = false;
+ end
+ end
+ n = n + 1;
+ end
+
+ return status;
+end
+
+function config.loadkernel()
+ local flags = loader.getenv("kernel_options") or "";
+ local kernel = loader.getenv("kernel");
+
+ local try_load = function (names)
+ for name in names:gmatch("([^;]+)%s*;?") do
+ r = loader.perform("load "..flags.." "..name);
+ if r == 0 then
+ return name;
+ end
+ end
+ return nil;
+ end;
+
+ local load_bootfile = function()
+ local bootfile = loader.getenv("bootfile");
+
+ -- append default kernel name
+ if not bootfile then
+ bootfile = "kernel";
+ else
+ bootfile = bootfile..";kernel";
+ end
+
+ return try_load(bootfile);
+ end;
+
+ -- kernel not set, try load from default module_path
+ if kernel == nil then
+ local res = load_bootfile();
+
+ if res ~= nil then
+ return true;
+ else
+ print("Failed to load kernel '"..res.."'");
+ return false;
+ end
+ else
+ local module_path = loader.getenv("module_path");
+ local res = nil;
+
+ -- first try load kernel with module_path = /boot/${kernel}
+ -- then try load with module_path=${kernel}
+ local paths = {"/boot/"..kernel, kernel};
+
+ for k,v in pairs(paths) do
+
+ loader.setenv("module_path", v);
+ res = load_bootfile();
+
+ -- succeeded add path to module_path
+ if res ~= nil then
+ loader.setenv("module_path", v..";"..module_path);
+ return true;
+ end
+ end
+
+ -- failed to load with ${kernel} as a directory
+ -- try as a file
+ res = try_load(kernel);
+ if res ~= nil then
+ return true;
+ else
+ print("Failed to load kernel '"..res.."'");
+ return false;
+ end
+ end
+end
+
+
+function config.load(file)
+
+ if not file then
+ file = "/boot/defaults/loader.conf";
+ end
+
+ if not config.parse(file) then
+-- print("Failed to parse configuration: '"..file.."'");
+ end
+
+ local f = loader.getenv("loader_conf_files");
+ if f ~= nil then
+ for name in string.gmatch(f, "([%w%p]+)%s*") do
+ if not config.parse(name) then
+-- print("Failed to parse configuration: '"..name.."'");
+ end
+ end
+ end
+
+ print("Loading kernel...");
+ config.loadkernel();
+
+ print("Loading configurations...");
+ if not config.loadmod(modules) then
+ print("Could not load configurations!");
+ end
+end
+
+function config.reload(kernel)
+ local res = 1;
+
+ -- unload all modules
+ print("Unloading modules...");
+ loader.perform("unload");
+
+ if kernel ~= nil then
+ res = loader.perform("load "..kernel);
+ if res == 0 then
+ print("Kernel '"..kernel.."' loaded!");
+ end
+ end
+
+ -- failed to load kernel or it is nil
+ -- then load default
+ if res == 1 then
+ print("Loading default kernel...");
+ config.loadkernel();
+ end
+
+ -- load modules
+ config.loadmod(modules);
+end
+
+return config
Index: stand/lua/core.lua
===================================================================
--- /dev/null
+++ stand/lua/core.lua
@@ -0,0 +1,154 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+local core = {};
+
+function core.setVerbose(b)
+ if (b == nil) then
+ b = not core.verbose;
+ end
+
+ if (b == true) then
+ loader.setenv("boot_verbose", "YES");
+ else
+ loader.unsetenv("boot_verbose");
+ end
+ core.verbose = b;
+end
+
+function core.setSingleUser(b)
+ if (b == nil) then
+ b = not core.su;
+ end
+
+ if (b == true) then
+ loader.setenv("boot_single", "YES");
+ else
+ loader.unsetenv("boot_single");
+ end
+ core.su = b;
+end
+
+function core.setACPI(b)
+ if (b == nil) then
+ b = not core.acpi;
+ end
+
+ if (b == true) then
+ loader.setenv("acpi_load", "YES");
+ loader.setenv("hint.acpi.0.disabled", "0");
+ loader.unsetenv("loader.acpi_disabled_by_user");
+ else
+ loader.unsetenv("acpi_load");
+ loader.setenv("hint.acpi.0.disabled", "1");
+ loader.setenv("loader.acpi_disabled_by_user", "1");
+ end
+ core.acpi = b;
+end
+
+function core.setSafeMode(b)
+ if (b == nil) then
+ b = not core.sm;
+ end
+ if (b == true) then
+ loader.setenv("kern.smp.disabled", "1");
+ loader.setenv("hw.ata.ata_dma", "0");
+ loader.setenv("hw.ata.atapi_dma", "0");
+ loader.setenv("hw.ata.wc", "0");
+ loader.setenv("hw.eisa_slots", "0");
+ loader.setenv("kern.eventtimer.periodic", "1");
+ loader.setenv("kern.geom.part.check_integrity", "0");
+ else
+ loader.unsetenv("kern.smp.disabled");
+ loader.unsetenv("hw.ata.ata_dma");
+ loader.unsetenv("hw.ata.atapi_dma");
+ loader.unsetenv("hw.ata.wc");
+ loader.unsetenv("hw.eisa_slots");
+ loader.unsetenv("kern.eventtimer.periodic");
+ loader.unsetenv("kern.geom.part.check_integrity");
+ end
+ core.sm = b;
+end
+
+function core.kernelList()
+ local k = loader.getenv("kernel");
+ local v = loader.getenv("kernels") or "";
+
+ local kernels = {};
+ local i = 0;
+ if k ~= nil then
+ i = i + 1;
+ kernels[i] = k;
+ end
+
+ for n in v:gmatch("([^; ]+)[; ]?") do
+ if n ~= k then
+ i = i + 1;
+ kernels[i] = n;
+ end
+ end
+ return kernels;
+end
+
+function core.setDefaults()
+ core.setACPI(true);
+ core.setSafeMode(false);
+ core.setSingleUser(false);
+ core.setVerbose(false);
+end
+
+function core.autoboot()
+ loader.perform("autoboot");
+end
+
+function core.boot()
+ loader.perform("boot");
+end
+
+function core.bootserial()
+ local c = loader.getenv("console");
+
+ if c ~= nil then
+ if c:find("comconsole") ~= nil then
+ return true;
+ end
+ end
+
+ local s = loader.getenv("boot_serial");
+ if s ~= nil then
+ return true;
+ end
+
+ local m = loader.getenv("boot_multicons");
+ if m ~= nil then
+ return true;
+ end
+ return false;
+end
+
+return core
Index: stand/lua/drawer.lua
===================================================================
--- /dev/null
+++ stand/lua/drawer.lua
@@ -0,0 +1,309 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+local drawer = {};
+
+local color = require("color");
+local screen = require("screen");
+
+drawer.brand_position = {x = 2, y = 1};
+drawer.fbsd_logo = {
+ " ______ ____ _____ _____ ",
+ " | ____| | _ \\ / ____| __ \\ ",
+ " | |___ _ __ ___ ___ | |_) | (___ | | | |",
+ " | ___| '__/ _ \\/ _ \\| _ < \\___ \\| | | |",
+ " | | | | | __/ __/| |_) |____) | |__| |",
+ " | | | | | | || | | |",
+ " |_| |_| \\___|\\___||____/|_____/|_____/ "
+};
+
+drawer.logo_position = {x = 46, y = 1};
+drawer.beastie_color = {
+ " \027[31m, ,",
+ " /( )`",
+ " \\ \\___ / |",
+ " /- \027[37m_\027[31m `-/ '",
+ " (\027[37m/\\/ \\\027[31m \\ /\\",
+ " \027[37m/ / |\027[31m ` \\",
+ " \027[34mO O \027[37m) \027[31m/ |",
+ " \027[37m`-^--'\027[31m`< '",
+ " (_.) _ ) /",
+ " `.___/` /",
+ " `-----' /",
+ " \027[33m<----.\027[31m __ / __ \\",
+ " \027[33m<----|====\027[31mO)))\027[33m==\027[31m) \\) /\027[33m====|",
+ " \027[33m<----'\027[31m `--' `.__,' \\",
+ " | |",
+ " \\ / /\\",
+ " \027[36m______\027[31m( (_ / \\______/",
+ " \027[36m,' ,-----' |",
+ " `--{__________)\027[37m"
+};
+
+drawer.beastie = {
+ " , ,",
+ " /( )`",
+ " \\ \\___ / |",
+ " /- _ `-/ '",
+ " (/\\/ \\ \\ /\\",
+ " / / | ` \\",
+ " O O ) / |",
+ " `-^--'`< '",
+ " (_.) _ ) /",
+ " `.___/` /",
+ " `-----' /",
+ " <----. __ / __ \\",
+ " <----|====O)))==) \\) /====|",
+ " <----' `--' `.__,' \\",
+ " | |",
+ " \\ / /\\",
+ " ______( (_ / \\______/",
+ " ,' ,-----' |",
+ " `--{__________)"
+};
+
+drawer.fbsd_logo_shift = {x = 5, y = 4};
+drawer.fbsd_logo_v = {
+ " ______",
+ " | ____| __ ___ ___ ",
+ " | |__ | '__/ _ \\/ _ \\",
+ " | __|| | | __/ __/",
+ " | | | | | | |",
+ " |_| |_| \\___|\\___|",
+ " ____ _____ _____",
+ " | _ \\ / ____| __ \\",
+ " | |_) | (___ | | | |",
+ " | _ < \\___ \\| | | |",
+ " | |_) |____) | |__| |",
+ " | | | |",
+ " |____/|_____/|_____/"
+};
+
+drawer.orb_shift = {x = 2, y = 4};
+drawer.orb_color = {
+ " \027[31m``` \027[31;1m`\027[31m",
+ " s` `.....---...\027[31;1m....--.``` -/\027[31m",
+ " +o .--` \027[31;1m/y:` +.\027[31m",
+ " yo`:. \027[31;1m:o `+-\027[31m",
+ " y/ \027[31;1m-/` -o/\027[31m",
+ " .- \027[31;1m::/sy+:.\027[31m",
+ " / \027[31;1m`-- /\027[31m",
+ " `: \027[31;1m:`\027[31m",
+ " `: \027[31;1m:`\027[31m",
+ " / \027[31;1m/\027[31m",
+ " .- \027[31;1m-.\027[31m",
+ " -- \027[31;1m-.\027[31m",
+ " `:` \027[31;1m`:`",
+ " \027[31;1m.-- `--.",
+ " .---.....----.\027[37m"
+};
+
+drawer.orb = {
+ " ``` `",
+ " s` `.....---.......--.``` -/",
+ " +o .--` /y:` +.",
+ " yo`:. :o `+-",
+ " y/ -/` -o/",
+ " .- ::/sy+:.",
+ " / `-- /",
+ " `: :`",
+ " `: :`",
+ " / /",
+ " .- -.",
+ " -- -.",
+ " `:` `:`",
+ " .-- `--.",
+ " .---.....----."
+};
+
+drawer.none = {""};
+
+drawer.none_shift = {x = 17, y = 0};
+
+drawer.menu_position = {x = 6, y = 11};
+
+drawer.box_pos_dim = {x = 3, y = 10, w = 41, h = 11};
+
+function drawer.drawscreen(menu_opts)
+ -- drawlogo() must go first.
+ -- it determines the positions of other elements
+ drawer.drawlogo();
+ drawer.drawbrand();
+ drawer.drawbox();
+ return drawer.drawmenu(menu_opts);
+end
+
+function drawer.drawmenu(m)
+ x = drawer.menu_position.x;
+ y = drawer.menu_position.y;
+
+ -- print the menu and build the alias table
+ local alias_table = {};
+ local entry_num = 0;
+ for line_num, e in ipairs(m) do
+ if (e.entry_type ~= "separator") then
+ entry_num = entry_num + 1;
+ screen.setcursor(x, y + line_num);
+ print(entry_num .. ". "..e.name());
+
+ -- fill the alias table
+ alias_table[tostring(entry_num)] = e;
+ for n, a in ipairs(e.alias) do
+ alias_table[a] = e;
+ end
+ else
+ screen.setcursor(x, y + line_num);
+ print(e.name());
+ end
+ end
+ return alias_table;
+end
+
+
+function drawer.drawbox()
+ x = drawer.box_pos_dim.x;
+ y = drawer.box_pos_dim.y;
+ w = drawer.box_pos_dim.w;
+ h = drawer.box_pos_dim.h;
+
+ local hl = string.char(0xCD);
+ local vl = string.char(0xBA);
+
+ local tl = string.char(0xC9);
+ local bl = string.char(0xC8);
+ local tr = string.char(0xBB);
+ local br = string.char(0xBC);
+
+ screen.setcursor(x, y); print(tl);
+ screen.setcursor(x, y+h); print(bl);
+ screen.setcursor(x+w, y); print(tr);
+ screen.setcursor(x+w, y+h); print(br);
+
+ for i = 1, w-1 do
+ screen.setcursor(x+i, y);
+ print(hl);
+ screen.setcursor(x+i, y+h);
+ print(hl);
+ end
+
+ for i = 1, h-1 do
+ screen.setcursor(x, y+i);
+ print(vl);
+ screen.setcursor(x+w, y+i);
+ print(vl);
+ end
+
+ screen.setcursor(x+(w/2)-9, y);
+ print("Welcome to FreeBSD");
+end
+
+function drawer.draw(x, y, logo)
+ for i = 1, #logo do
+ screen.setcursor(x, y + i);
+ print(logo[i]);
+ end
+end
+
+function drawer.drawbrand()
+ local x = tonumber(loader.getenv("loader_brand_x"));
+ local y = tonumber(loader.getenv("loader_brand_y"));
+
+ if not x then
+ x = drawer.brand_position.x;
+ end
+ if not y then
+ y = drawer.brand_position.y;
+ end
+
+ local logo = load("return " .. tostring(loader.getenv("loader_brand")))();
+ if not logo then
+ logo = drawer.fbsd_logo;
+ end
+ drawer.draw(x, y, logo);
+end
+
+function drawer.drawlogo()
+ local x = tonumber(loader.getenv("loader_logo_x"));
+ local y = tonumber(loader.getenv("loader_logo_y"));
+
+ if not x then
+ x = drawer.logo_position.x;
+ end
+ if not y then
+ y = drawer.logo_position.y;
+ end
+
+ local logo = loader.getenv("loader_logo");
+ local s = {x = 0, y = 0};
+ local colored = color.isEnabled();
+
+ if logo == "beastie" then
+ if colored then
+ logo = drawer.beastie_color;
+ end
+ elseif logo == "beastiebw" then
+ logo = drawer.beastie;
+ elseif logo == "fbsdbw" then
+ logo = drawer.fbsd_logo_v;
+ s = drawer.fbsd_logo_shift;
+ elseif logo == "orb" then
+ if colored then
+ logo = drawer.orb_color;
+ end
+ s = drawer.orb_shift;
+ elseif logo == "orbbw" then
+ logo = drawer.orb;
+ s = drawer.orb_shift;
+ elseif logo == "tribute" then
+ logo = drawer.fbsd_logo;
+ elseif logo == "tributebw" then
+ logo = drawer.fbsd_logo;
+ elseif logo == "none" then
+ --centre brand and text if no logo
+ drawer.brand_position.x = drawer.brand_position.x + drawer.none_shift.x;
+ drawer.brand_position.y = drawer.brand_position.y + drawer.none_shift.y;
+ drawer.menu_position.x = drawer.menu_position.x + drawer.none_shift.x;
+ drawer.menu_position.y = drawer.menu_position.y + drawer.none_shift.y;
+ drawer.box_pos_dim.x = drawer.box_pos_dim.x + drawer.none_shift.x;
+ drawer.box_pos_dim.y = drawer.box_pos_dim.y + drawer.none_shift.y;
+ --prevent redraws from moving menu further
+ drawer.none_shift.x = 0;
+ drawer.none_shift.y = 0;
+ logo = drawer.none;
+ end
+ if not logo then
+ if colored then
+ logo = drawer.orb_color;
+ else
+ logo = drawer.orb;
+ end
+ end
+ drawer.draw(x + s.x, y + s.y, logo);
+end
+
+return drawer
Index: stand/lua/loader.lua
===================================================================
--- /dev/null
+++ stand/lua/loader.lua
@@ -0,0 +1,35 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+config = require("config");
+menu = require("menu");
+password = require("password");
+
+config.load();
+password.check();
+menu.run();
Index: stand/lua/menu.lua
===================================================================
--- /dev/null
+++ stand/lua/menu.lua
@@ -0,0 +1,379 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+
+local menu = {};
+
+local core = require("core");
+local color = require("color");
+local config = require("config");
+local screen = require("screen");
+local drawer = require("drawer");
+
+local OnOff;
+local skip;
+local run;
+local autoboot;
+
+--loader menu tree:
+--rooted at menu.welcome
+--submenu declarations:
+local kernel_options;
+local boot_options;
+local welcome;
+
+menu.kernel_options = {
+ -- this table is dynamically appended to when accessed
+ -- return to welcome menu
+ {
+ entry_type = "return",
+ name = function()
+ return "Back to main menu"..color.highlight(" [Backspace]");
+ end,
+ alias = {"\08"}
+ }
+};
+
+menu.boot_options = {
+ -- return to welcome menu
+ {
+ entry_type = "return",
+ name = function()
+ return "Back to main menu"..color.highlight(" [Backspace]");
+ end,
+ alias = {"\08"}
+ },
+
+ -- load defaults
+ {
+ entry_type = "entry",
+ name = function()
+ return "Load System "..color.highlight("D").."efaults";
+ end,
+ func = function()
+ core.setDefaults()
+ end,
+ alias = {"d", "D"}
+ },
+
+ {
+ entry_type = "separator",
+ name = function()
+ return "";
+ end
+ },
+
+ {
+ entry_type = "separator",
+ name = function()
+ return "Boot Options:";
+ end
+ },
+
+ -- acpi
+ {
+ entry_type = "entry",
+ name = function()
+ return OnOff(color.highlight("A").."CPI :", core.acpi);
+ end,
+ func = function()
+ core.setACPI();
+ end,
+ alias = {"a", "A"}
+ },
+ -- safe mode
+ {
+ entry_type = "entry",
+ name = function()
+ return OnOff("Safe "..color.highlight("M").."ode :", core.sm);
+ end,
+ func = function()
+ core.setSafeMode();
+ end,
+ alias = {"m", "M"}
+ },
+ -- single user
+ {
+ entry_type = "entry",
+ name = function()
+ return OnOff(color.highlight("S").."ingle user:", core.su);
+ end,
+ func = function()
+ core.setSingleUser();
+ end,
+ alias = {"s", "S"}
+ },
+ -- verbose boot
+ {
+ entry_type = "entry",
+ name = function()
+ return OnOff(color.highlight("V").."erbose :", core.verbose);
+ end,
+ func = function()
+ core.setVerbose();
+ end,
+ alias = {"v", "V"}
+ },
+};
+
+menu.welcome = {
+ -- boot multi user
+ {
+ entry_type = "entry",
+ name = function()
+ return color.highlight("B").."oot Multi user "..color.highlight("[Enter]");
+ end,
+ func = function()
+ core.setSingleUser(false);
+ core.boot();
+ end,
+ alias = {"b", "B", "\013"}
+ },
+
+ -- boot single user
+ {
+ entry_type = "entry",
+ name = function()
+ return "Boot "..color.highlight("S").."ingle user";
+ end,
+ func = function()
+ core.setSingleUser(true);
+ core.boot();
+ end,
+ alias = {"s", "S"}
+ },
+
+ -- escape to interpreter
+ {
+ entry_type = "return",
+ name = function()
+ return color.highlight("Esc").."ape to lua interpreter";
+ end,
+ alias = {"\027"}
+ },
+
+ -- reboot
+ {
+ entry_type = "entry",
+ name = function()
+ return color.highlight("R").."eboot";
+ end,
+ func = function()
+ loader.perform("reboot");
+ end,
+ alias = {"r", "R"}
+ },
+
+
+ {
+ entry_type = "separator",
+ name = function()
+ return "";
+ end
+ },
+
+ {
+ entry_type = "separator",
+ name = function()
+ return "Options:";
+ end
+ },
+
+ -- kernel options
+ {
+ entry_type = "submenu",
+ name = function()
+ local kernels = core.kernelList();
+ if #kernels == 0 then
+ return "Kernels (not available)";
+ end
+ return color.highlight("K").."ernels";
+ end,
+ submenu = function()
+
+ -- dynamically build the kernel menu:
+ local kernels = core.kernelList();
+ for k, v in ipairs(kernels) do
+ menu.kernel_options[#menu.kernel_options + 1] = {
+ entry_type = "entry",
+ name = function()
+ return v;
+ end,
+ func = function()
+ config.reload(v);
+ end,
+ alias = {} -- automatically enumerated
+ }
+ end
+
+ return menu.kernel_options;
+ end,
+ alias = {"k", "K"}
+ },
+
+ -- boot options
+ {
+ entry_type = "submenu",
+ name = function()
+ return "Boot "..color.highlight("O").."ptions";
+ end,
+ submenu = function()
+ return menu.boot_options;
+ end,
+ alias = {"o", "O"}
+ }
+
+};
+
+function menu.run(m)
+
+ if (menu.skip()) then
+ core.autoboot();
+ return false;
+ end
+
+ if (m == nil) then
+ m = menu.welcome;
+ end
+
+ -- redraw screen
+ screen.clear();
+ screen.defcursor();
+ local alias_table = drawer.drawscreen(m);
+
+-- menu.autoboot();
+
+ cont = true;
+ while cont do
+ local key = string.char(io.getchar());
+
+ -- check to see if key is an alias
+ local sel_entry = nil;
+ for k, v in pairs(alias_table) do
+ if (key == k) then
+ sel_entry = v;
+ end
+ end
+
+ -- if we have an alias do the assigned action:
+ if(sel_entry ~= nil) then
+ if (sel_entry.entry_type == "entry") then
+ -- run function
+ sel_entry.func();
+ elseif (sel_entry.entry_type == "submenu") then
+ -- recurse
+ cont = menu.run(sel_entry.submenu());
+ elseif (sel_entry.entry_type == "return") then
+ -- break recurse
+ cont = false;
+ end
+ -- if we got an alias key the screen is out of date:
+ screen.clear();
+ screen.defcursor();
+ alias_table = drawer.drawscreen(m);
+ end
+ end
+
+ if (m == menu.welcome) then
+ screen.defcursor();
+ print("Exiting menu!");
+ return false;
+ end
+
+ return true;
+end
+
+function menu.skip()
+ if core.bootserial() then
+ return true;
+ end
+ local c = string.lower(loader.getenv("console") or "");
+ if (c:match("^efi[ ;]") or c:match("[ ;]efi[ ;]")) ~= nil then
+ return true;
+ end
+
+ c = string.lower(loader.getenv("beastie_disable") or "");
+ print("beastie_disable", c);
+ return c == "yes";
+end
+
+function menu.autoboot()
+ if menu.already_autoboot == true then
+ return;
+ end
+ menu.already_autoboot = true;
+
+ local ab = loader.getenv("autoboot_delay");
+ if ab == "NO" or ab == "no" then
+ core.boot();
+ end
+ ab = tonumber(ab) or 10;
+
+ local x = loader.getenv("loader_menu_timeout_x") or 5;
+ local y = loader.getenv("loader_menu_timeout_y") or 22;
+
+ local endtime = loader.time() + ab;
+ local time;
+
+ repeat
+ time = endtime - loader.time();
+ screen.setcursor(x, y);
+ print("Autoboot in "..time.." seconds, hit [Enter] to boot"
+ .." or any other key to stop ");
+ screen.defcursor();
+ if io.ischar() then
+ local ch = io.getchar();
+ if ch == 13 then
+ break;
+ else
+ -- prevent autoboot when escaping to interpreter
+ loader.setenv("autoboot_delay", "NO");
+ -- erase autoboot msg
+ screen.setcursor(0, y);
+ print(" "
+ .." ");
+ screen.defcursor();
+ return;
+ end
+ end
+
+ loader.delay(50000);
+ until time <= 0
+ core.boot();
+
+end
+
+function OnOff(str, b)
+ if (b) then
+ return str .. color.escapef(color.GREEN).."On"..color.escapef(color.WHITE);
+ else
+ return str .. color.escapef(color.RED).."off"..color.escapef(color.WHITE);
+ end
+end
+
+return menu
Index: stand/lua/password.lua
===================================================================
--- /dev/null
+++ stand/lua/password.lua
@@ -0,0 +1,85 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+local password = {};
+
+local core = require("core");
+local screen = require("screen");
+
+function password.read()
+ local str = "";
+ local n = 0;
+
+ repeat
+ ch = io.getchar();
+ if ch == 13 then
+ break;
+ end
+
+ if ch == 8 then
+ if n > 0 then
+ n = n - 1;
+ -- loader.printc("\008 \008");
+ str = string.sub(str, 1, n);
+ end
+ else
+ -- loader.printc("*");
+ str = str .. string.char(ch);
+ n = n + 1;
+ end
+ until n == 16
+ return str;
+end
+
+function password.check()
+ screen.defcursor();
+ local function compare(prompt, pwd)
+ if (pwd == nil) then
+ return;
+ end
+ while true do
+ loader.printc(prompt);
+ if (pwd == password.read()) then
+ break;
+ end
+ print("\n\nloader: incorrect password!\n");
+ loader.delay(3*1000*1000);
+ end
+ end
+
+ local boot_pwd = loader.getenv("bootlock_password");
+ compare("Boot password: ", boot_pwd);
+
+ local pwd = loader.getenv("password");
+ if (pwd ~=nil) then
+ core.autoboot();
+ end
+ compare("Password: ", pwd);
+end
+
+return password
Index: stand/lua/screen.lua
===================================================================
--- /dev/null
+++ stand/lua/screen.lua
@@ -0,0 +1,73 @@
+--
+-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+local screen = {};
+
+local color = require("color");
+local core = require("core");
+
+function screen.clear()
+ if core.bootserial() then
+ return;
+ end
+ loader.printc("\027[H\027[J");
+end
+
+function screen.setcursor(x, y)
+ if core.bootserial() then
+ return;
+ end
+ loader.printc("\027["..y..";"..x.."H");
+end
+
+function screen.setforeground(c)
+ if color.disabled then
+ return c;
+ end
+ loader.printc("\027[3"..c.."m");
+end
+
+function screen.setbackground(c)
+ if color.disabled then
+ return c;
+ end
+ loader.printc("\027[4"..c.."m");
+end
+
+function screen.defcolor()
+ loader.printc(color.default());
+end
+
+function screen.defcursor()
+ if core.bootserial() then
+ return;
+ end
+ loader.printc("\027[25;0H");
+end
+
+return screen
Index: sys/sys/param.h
===================================================================
--- sys/sys/param.h
+++ sys/sys/param.h
@@ -60,7 +60,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1200057 /* Master, propagated to newvers */
+#define __FreeBSD_version 1200058 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
Index: tools/build/options/WITH_LOADER_LUA
===================================================================
--- /dev/null
+++ tools/build/options/WITH_LOADER_LUA
@@ -0,0 +1,2 @@
+.\" $FreeBSD$
+Set to build LUA bindings for the boot loader.

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 13, 6:46 AM (11 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23662791
Default Alt Text
D14295.id39135.diff (87 KB)

Event Timeline