Make improvements

- Expand redbean UNIX module
- Expand redbean documentation
- Ensure Lua copyright is embedded in binary
- Increase the PATH_MAX limit especially on NT
- Use column major sorting for linenoise completions
- Fix some suboptimalities in redbean's new UNIX API
- Figured out right flags for Multics newline in raw mode
This commit is contained in:
Justine Tunney 2022-04-24 09:59:22 -07:00
parent cf3174dc74
commit 2046c0d2ae
305 changed files with 6602 additions and 4221 deletions

View file

@ -34,3 +34,7 @@ function OnHttpRequest()
end
SetHeader('Server', 'redbean!')
end
function Adder(x, y)
return x + y
end

View file

@ -12,7 +12,7 @@ function dosomething(param1, x)
SetHeader('Content-Type', 'text/plain; charset=utf-8')
Write('preprae to crash... now\r\n')
res = x / y
Write(string.format('42 / 0 is %d\r\n', res))
Write('42 / 0 is %d\r\n' % {res})
end
function start(param1)

View file

@ -2,7 +2,7 @@
local function WriteForm(url)
Write('<!doctype html>\r\n')
Write(string.format([[
Write([[
<title>redbean fetch demo</title>
<style>
body {
@ -41,7 +41,7 @@ local function WriteForm(url)
value="%s" placeholder="uri" autofocus>
<input type="submit" value="fetch">
</form>
]], EscapeHtml(url)))
]] % {EscapeHtml(url)})
end
local function main()
@ -54,7 +54,7 @@ local function main()
WriteForm(GetParam('url'))
Write('<dl>\r\n')
Write('<dt>Status\r\n')
Write(string.format('<dd><p>%d %s\r\n', status, GetHttpReason(status)))
Write('<dd><p>%d %s\r\n' % {status, GetHttpReason(status)})
Write('<dt>Headers\r\n')
Write('<dd>\r\n')
for k,v in pairs(headers) do

View file

@ -167,7 +167,7 @@ local function main()
Write('<dt>GetRemoteAddr() <small>(from Berkeley Sockets or X-Forwarded-For header)</small>\r\n')
Write('<dd>')
ip, port = GetRemoteAddr()
Write(string.format('%s, %d', FormatIp(ip), port))
Write('%s, %d' % {FormatIp(ip), port})
if CategorizeIp(ip) then
Write('<br>\r\n')
Write(CategorizeIp(ip))
@ -176,7 +176,7 @@ local function main()
Write('<dt>GetClientAddr()\r\n')
Write('<dd>')
ip, port = GetClientAddr()
Write(string.format('%s, %d', FormatIp(ip), port))
Write('%s, %d' % {FormatIp(ip), port})
if CategorizeIp(ip) then
Write('<br>\r\n')
Write(CategorizeIp(ip))
@ -185,7 +185,7 @@ local function main()
Write('<dt>GetServerIp()\r\n')
Write('<dd>')
ip, port = GetServerAddr()
Write(string.format('%s, %d', FormatIp(ip), port))
Write('%s, %d' % {FormatIp(ip), port})
if CategorizeIp(ip) then
Write('<br>\r\n')
Write(CategorizeIp(ip))
@ -269,28 +269,28 @@ local function main()
m,a,b,c,d = pat:search(s) -- m and rest are nil if match not found
Write('<pre>\r\n')
Write([[pat = re.compile('([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})')]])
Write(string.format('\r\nm,a,b,c,d = pat:search(%q)\r\n', s))
Write('\r\nm,a,b,c,d = pat:search(%q)\r\n' % {s})
Write('</pre>\r\n')
Write('<dl>\r\n')
Write('<dt>m\r\n')
Write('<dd>')
Write(string.format("%q", m))
Write("%q" % {m})
Write('\r\n')
Write('<dt>a\r\n')
Write('<dd>')
Write(string.format("%q", a))
Write("%q" % {a})
Write('\r\n')
Write('<dt>b\r\n')
Write('<dd>')
Write(string.format("%q", b))
Write("%q" % {b})
Write('\r\n')
Write('<dt>c\r\n')
Write('<dd>')
Write(string.format("%q", c))
Write("%q" % {c})
Write('\r\n')
Write('<dt>d\r\n')
Write('<dd>')
Write(string.format("%q", d))
Write("%q" % {d})
Write('\r\n')
Write('</dl>\r\n')
@ -328,7 +328,7 @@ local function main()
Write(FormatHttpDateTime(GetLastModifiedTime(paths[i])))
Write('<br>\r\n')
Write('Mode: ')
Write(string.format("0%o", GetAssetMode(paths[i])))
Write("0%o" % {GetAssetMode(paths[i])})
Write('<br>\r\n')
Write('Size: ')
Write(tostring(GetAssetSize(paths[i])))

View file

@ -3,53 +3,58 @@ local unix = require 'unix'
Write('<!doctype html>\r\n')
Write('<title>redbean</title>\r\n')
Write('<h3>UNIX Information Demo</h3>\r\n')
Write('<style>dt { margin: .5em 0; font-style:italic; }</style>\r\n')
Write('<dl>\r\n')
Write('<dt>getuid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getuid()))
Write('<dt>getgid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getgid()))
Write('<dt>getpid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getpid()))
Write('<dt>getppid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getppid()))
Write('<dt>getpgrp()\r\n')
Write(string.format('<dd>%d\r\n', unix.getpgrp()))
Write('<dt>unix.getuid()\r\n')
Write('<dd>%d\r\n' % {unix.getuid()})
Write('<dt>unix.getgid()\r\n')
Write('<dd>%d\r\n' % {unix.getgid()})
Write('<dt>unix.getpid()\r\n')
Write('<dd>%d\r\n' % {unix.getpid()})
Write('<dt>unix.getppid()\r\n')
Write('<dd>%d\r\n' % {unix.getppid()})
Write('<dt>unix.getpgrp()\r\n')
Write('<dd>%d\r\n' % {unix.getpgrp()})
Write('<dt>unix.umask()\r\n')
mask = unix.umask(027)
unix.umask(mask)
Write('<dd>%.4o\r\n' % {mask})
Write('<dt>getsid(0)\r\n')
Write('<dt>unix.getsid(0)\r\n')
sid, errno = unix.getsid(0)
if sid then
Write(string.format('<dd>%d\r\n', sid))
Write('<dd>%d\r\n' % {sid})
else
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.strerrno(errno))))
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
end
Write('<dt>gethostname()\r\n')
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.gethostname())))
Write('<dt>getcwd()\r\n')
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.getcwd())))
Write('<dt>unix.gethostname()\r\n')
Write('<dd>%s\r\n' % {EscapeHtml(unix.gethostname())})
Write('<dt>unix.getcwd()\r\n')
Write('<dd>%s\r\n' % {EscapeHtml(unix.getcwd())})
function PrintResourceLimit(name, id)
soft, hard, errno = unix.getrlimit(id)
Write(string.format('<dt>getrlimit(%s)\r\n', name))
Write('<dt>getrlimit(%s)\r\n' % {name})
if soft then
Write('<dd>')
Write('soft ')
if soft == -1 then
Write('')
else
Write(string.format('%d', soft))
Write('%d' % {soft})
end
Write('<br>\r\n')
Write('hard ')
if hard == -1 then
Write('')
else
Write(string.format('%d', hard))
Write('%d' % {hard})
end
Write('\r\n')
else
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.strerrno(errno))))
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
end
end
PrintResourceLimit('RLIMIT_AS', unix.RLIMIT_AS)
@ -59,7 +64,7 @@ PrintResourceLimit('RLIMIT_FSIZE', unix.RLIMIT_FSIZE)
PrintResourceLimit('RLIMIT_NPROC', unix.RLIMIT_NPROC)
PrintResourceLimit('RLIMIT_NOFILE', unix.RLIMIT_NOFILE)
Write('<dt>siocgifconf()\r\n')
Write('<dt>unix.siocgifconf()\r\n')
Write('<dd>\r\n')
ifs, errno = unix.siocgifconf()
if ifs then
@ -69,12 +74,217 @@ if ifs then
else
cidr = 0
end
Write(string.format('%s %s/%d<br>\r\n',
EscapeHtml(ifs[i].name),
FormatIp(ifs[i].ip),
cidr))
Write('%s %s/%d<br>\r\n' % {EscapeHtml(ifs[i].name), FormatIp(ifs[i].ip), cidr})
end
else
Write(string.format('%s\r\n', EscapeHtml(unix.strerrno(errno))))
Write('%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
end
Write('</dl>\r\n')
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DEBUG)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DEBUG)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEADDR)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEADDR)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEPORT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEPORT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_KEEPALIVE)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_KEEPALIVE)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NODELAY)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NODELAY)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, secs, micros = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVTIMEO)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVTIMEO)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d sec %d µs\r\n' % {secs, micros})
end
errno, secs, micros = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDTIMEO)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDTIMEO)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d sec %d µs\r\n' % {secs, micros})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DONTROUTE)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DONTROUTE)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDBUF)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDBUF)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVBUF)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVBUF)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_BROADCAST)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_BROADCAST)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_CORK)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_CORK)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_QUICKACK)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_QUICKACK)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_DEFER_ACCEPT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_DEFER_ACCEPT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN_CONNECT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN_CONNECT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDLOWAT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDLOWAT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVLOWAT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVLOWAT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPCNT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPCNT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_MAXSEG)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_MAXSEG)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_SYNCNT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_SYNCNT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NOTSENT_LOWAT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NOTSENT_LOWAT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_WINDOW_CLAMP)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_WINDOW_CLAMP)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPIDLE)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPIDLE)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPINTVL)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPINTVL)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
Write('<dt>unix.environ()\r\n')
Write('<dd>\r\n')
Write('<ul>\r\n')
env = unix.environ()
for i = 1,#env do
Write('<li>%s\r\n' % {EscapeHtml(env[i])})
end
Write('</ul>\r\n')

View file

@ -32,8 +32,9 @@ local function main()
-- steal client from redbean
fd = GetClientFd()
rc, errno = unix.fork()
-- this function returns twice
pid, errno = unix.fork()
if errno then
SetStatus(400)
SetHeader('Content-Type', 'text/html; charset=utf-8')
@ -44,7 +45,7 @@ local function main()
Write(EncodeBase64(LoadAsset('/redbean.png')))
Write('">\r\n')
Write('redbean unix demo\r\n')
Write(string.format('<span style="color:red">&nbsp;%s</span>\r\n', unix.strerrno(errno)))
Write('<span style="color:red">&nbsp;%s</span>\r\n' % {unix.strerrno(errno)})
Write('</h1>\r\n')
Write([[
<p>
@ -57,11 +58,13 @@ local function main()
return
end
if rc ~= 0 then
-- the parent process gets the pid
if pid ~= 0 then
unix.close(fd)
return
end
-- if pid is zero then we're the child
-- turn into a daemon
unix.umask(0)
unix.setsid()
@ -119,7 +122,7 @@ local function main()
else
st, err = unix.stat(name)
if st then
unix.write(fd, string.format(' (%d bytes)', st:size()))
unix.write(fd, ' (%d bytes)' % {st:size()})
end
end
unix.write(fd, '\r\n')
@ -127,7 +130,7 @@ local function main()
unix.write(fd, '</ul>\r\n')
else
unix.write(fd, '<p>\r\n')
unix.write(fd, string.format('failed: %s\r\n', EscapeHtml(VisualizeControlCodes(unix:strerror(err)))))
unix.write(fd, 'failed: %s\r\n' % {EscapeHtml(VisualizeControlCodes(unix:strerror(err)))})
unix.write(fd, '</p>\r\n')
end

View file

@ -2,15 +2,20 @@
-- and pipe its output to the http user
local unix = require "unix"
function main()
if GetHostOs() == 'WINDOWS' then
cmd = 'dir'
else
cmd = 'ls'
end
syscall = 'commandv'
ls, errno = unix.commandv("ls")
ls, errno = unix.commandv(cmd)
if ls then
syscall = 'pipe'
reader, writer, errno = unix.pipe()
if reader then
oldint = unix.sigaction(unix.SIGINT, unix.SIG_IGN)
oldquit = unix.sigaction(unix.SIGQUIT, unix.SIG_IGN)
oldmask = unix.sigprocmask(unix.SIG_BLOCK, unix.SIGCHLD)
-- oldint = unix.sigaction(unix.SIGINT, unix.SIG_IGN)
-- oldquit = unix.sigaction(unix.SIGQUIT, unix.SIG_IGN)
-- oldmask = unix.sigprocmask(unix.SIG_BLOCK, unix.SIGCHLD)
syscall = 'fork'
child, errno = unix.fork()
if child then
@ -19,10 +24,10 @@ function main()
unix.dup(writer)
unix.close(writer)
unix.close(reader)
unix.sigaction(unix.SIGINT, oldint)
unix.sigaction(unix.SIGQUIT, oldquit)
unix.sigprocmask(unix.SIG_SETMASK, oldmask)
unix.execve(ls, {ls, "-Shal"})
-- unix.sigaction(unix.SIGINT, oldint)
-- unix.sigaction(unix.SIGQUIT, oldquit)
-- unix.sigprocmask(unix.SIG_SETMASK, oldmask)
unix.execve(ls, {ls, '-Shal'})
unix.exit(127)
else
unix.close(writer)
@ -31,21 +36,21 @@ function main()
while true do
data, errno = unix.read(reader)
if data then
if data ~= "" then
if data ~= '' then
Write(data)
else
break
end
elseif errno ~= unix.EINTR then
Log(kLogWarn, string.format('read() failed: %s', unix.strerror(errno)))
Log(kLogWarn, 'read() failed: %s' % {unix.strerror(errno)})
break
end
end
unix.close(reader)
unix.wait(-1)
unix.sigaction(unix.SIGINT, oldint)
unix.sigaction(unix.SIGQUIT, oldquit)
unix.sigprocmask(unix.SIG_SETMASK, oldmask)
-- unix.sigaction(unix.SIGINT, oldint)
-- unix.sigaction(unix.SIGQUIT, oldquit)
-- unix.sigprocmask(unix.SIG_SETMASK, oldmask)
return
end
end
@ -53,6 +58,6 @@ function main()
end
SetStatus(200)
SetHeader('Content-Type', 'text/plain')
Write(string.format('error %s calling %s()', unix.strerrno(errno), syscall))
Write('error %s calling %s()' % {unix.strerrno(errno), syscall})
end
main()

View file

@ -46,12 +46,10 @@ function main()
unix.bind(server, ifs[i].ip)
unix.listen(server)
ip, port = unix.getsockname(server)
addr = string.format('%s:%d', FormatIp(ip), port)
url = string.format('http://%s', addr)
Log(kLogInfo, string.format('listening on %s', addr))
unix.write(mainfd, string.format(
'listening on <a target="_blank" href="%s">%s</a><br>\r\n',
url, url))
addr = '%s:%d' % {FormatIp(ip), port}
url = 'http://%s' % {addr}
Log(kLogInfo, 'listening on %s' % {addr})
unix.write(mainfd, 'listening on <a target="_blank" href="%s">%s</a><br>\r\n' % {url, url})
pollfds[server] = unix.POLLIN | unix.POLLHUP
servers[server] = true
addrs[server] = addr
@ -67,7 +65,7 @@ function main()
if fd == mainfd then
data, errno = unix.read(mainfd)
if not data then
Log(kLogInfo, string.format('got %s from parent client', unix.strerrno(errno)))
Log(kLogInfo, 'got %s from parent client' % {unix.strerrno(errno)})
-- prevent redbean core from writing a response
unix.exit(1)
end
@ -80,20 +78,20 @@ function main()
-- echo it back for fun
unix.write(mainfd, data)
elseif servers[fd] then
unix.write(mainfd, string.format('preparing to accept from %d<br>\r\n', fd))
unix.write(mainfd, 'preparing to accept from %d<br>\r\n' % {fd})
client, clientip, clientport = unix.accept(fd)
unix.write(mainfd, string.format('preparing to accept from %d<br>\r\n', fd))
addr = string.format('%s:%d', FormatIp(clientip), clientport)
unix.write(mainfd, 'preparing to accept from %d<br>\r\n' % {fd})
addr = '%s:%d' % {FormatIp(clientip), clientport}
addrs[client] = addr
unix.write(mainfd, string.format('got client %s<br>\r\n', addr))
unix.write(mainfd, 'got client %s<br>\r\n' % {addr})
pollfds[client] = unix.POLLIN
evs[server] = nil
else
unix.write(mainfd, string.format('preparing to read from %d<br>\r\n', fd))
unix.write(mainfd, 'preparing to read from %d<br>\r\n' % {fd})
data = unix.read(fd)
unix.write(mainfd, string.format('done reading from %d<br>\r\n', fd))
unix.write(mainfd, 'done reading from %d<br>\r\n' % {fd})
if data and #data ~= 0 then
unix.write(mainfd, string.format('got %d bytes from %s<br>\r\n', #data, addrs[fd]))
unix.write(mainfd, 'got %d bytes from %s<br>\r\n' % {#data, addrs[fd]})
unix.write(fd, 'HTTP/1.0 200 OK\r\n' ..
'Date: '.. FormatHttpDateTime(GetDate()) ..'\r\n' ..
'Content-Type: text/html; charset=utf-8\r\n' ..

File diff suppressed because it is too large Load diff

562
tool/net/lfuncs.c Normal file
View file

@ -0,0 +1,562 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "dsp/scale/cdecimate2xuint8x8.h"
#include "libc/bits/popcnt.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/bsf.h"
#include "libc/nexgen32e/bsr.h"
#include "libc/nexgen32e/crc32.h"
#include "libc/nexgen32e/rdtsc.h"
#include "libc/nexgen32e/rdtscp.h"
#include "libc/rand/rand.h"
#include "libc/runtime/gc.internal.h"
#include "libc/sock/sock.h"
#include "libc/sysv/consts/af.h"
#include "libc/time/time.h"
#include "libc/x/x.h"
#include "net/http/escape.h"
#include "net/http/http.h"
#include "net/http/ip.h"
#include "net/http/url.h"
#include "third_party/lua/cosmo.h"
#include "third_party/lua/lauxlib.h"
#include "third_party/lua/lua.h"
#include "third_party/mbedtls/md.h"
#include "third_party/mbedtls/md5.h"
#include "third_party/mbedtls/platform.h"
#include "third_party/mbedtls/sha1.h"
#include "third_party/mbedtls/sha256.h"
#include "third_party/mbedtls/sha512.h"
#include "tool/net/lfuncs.h"
int LuaGetTime(lua_State *L) {
lua_pushnumber(L, nowl());
return 1;
}
int LuaSleep(lua_State *L) {
usleep(1e6 * luaL_checknumber(L, 1));
return 0;
}
int LuaRdtsc(lua_State *L) {
lua_pushinteger(L, rdtsc());
return 1;
}
int LuaGetCpuNode(lua_State *L) {
lua_pushinteger(L, TSC_AUX_NODE(rdpid()));
return 1;
}
int LuaGetCpuCore(lua_State *L) {
lua_pushinteger(L, TSC_AUX_CORE(rdpid()));
return 1;
}
int LuaGetLogLevel(lua_State *L) {
lua_pushinteger(L, __log_level);
return 1;
}
int LuaSetLogLevel(lua_State *L) {
__log_level = luaL_checkinteger(L, 1);
return 0;
}
static int LuaRand(lua_State *L, uint64_t impl(void)) {
lua_pushinteger(L, impl());
return 1;
}
int LuaLemur64(lua_State *L) {
return LuaRand(L, lemur64);
}
int LuaRand64(lua_State *L) {
return LuaRand(L, rand64);
}
int LuaRdrand(lua_State *L) {
return LuaRand(L, rdrand);
}
int LuaRdseed(lua_State *L) {
return LuaRand(L, rdseed);
}
int LuaDecimate(lua_State *L) {
size_t n, m;
const char *s;
unsigned char *p;
s = luaL_checklstring(L, 1, &n);
m = ROUNDUP(n, 16);
p = xmalloc(m);
bzero(p + n, m - n);
cDecimate2xUint8x8(m, p, (signed char[8]){-1, -3, 3, 17, 17, 3, -3, -1});
lua_pushlstring(L, (char *)p, (n + 1) >> 1);
free(p);
return 1;
}
int LuaMeasureEntropy(lua_State *L) {
size_t n;
const char *s;
s = luaL_checklstring(L, 1, &n);
lua_pushnumber(L, MeasureEntropy(s, n));
return 1;
}
int LuaGetHostOs(lua_State *L) {
const char *s = NULL;
if (IsLinux()) {
s = "LINUX";
} else if (IsMetal()) {
s = "METAL";
} else if (IsWindows()) {
s = "WINDOWS";
} else if (IsXnu()) {
s = "XNU";
} else if (IsOpenbsd()) {
s = "OPENBSD";
} else if (IsFreebsd()) {
s = "FREEBSD";
} else if (IsNetbsd()) {
s = "NETBSD";
}
if (s) {
lua_pushstring(L, s);
} else {
lua_pushnil(L);
}
return 1;
}
int LuaFormatIp(lua_State *L) {
char b[16];
uint32_t ip;
ip = htonl(luaL_checkinteger(L, 1));
inet_ntop(AF_INET, &ip, b, sizeof(b));
lua_pushstring(L, b);
return 1;
}
int LuaParseIp(lua_State *L) {
size_t n;
const char *s;
s = luaL_checklstring(L, 1, &n);
lua_pushinteger(L, ParseIp(s, n));
return 1;
}
static int LuaIsIp(lua_State *L, bool IsIp(uint32_t)) {
lua_pushboolean(L, IsIp(luaL_checkinteger(L, 1)));
return 1;
}
int LuaIsPublicIp(lua_State *L) {
return LuaIsIp(L, IsPublicIp);
}
int LuaIsPrivateIp(lua_State *L) {
return LuaIsIp(L, IsPrivateIp);
}
int LuaIsLoopbackIp(lua_State *L) {
return LuaIsIp(L, IsLoopbackIp);
}
int LuaCategorizeIp(lua_State *L) {
lua_pushstring(L, GetIpCategoryName(CategorizeIp(luaL_checkinteger(L, 1))));
return 1;
}
int LuaFormatHttpDateTime(lua_State *L) {
char buf[30];
lua_pushstring(L, FormatUnixHttpDateTime(buf, luaL_checkinteger(L, 1)));
return 1;
}
int LuaParseHttpDateTime(lua_State *L) {
size_t n;
const char *s;
s = luaL_checklstring(L, 1, &n);
lua_pushinteger(L, ParseHttpDateTime(s, n));
return 1;
}
int LuaParseParams(lua_State *L) {
void *m;
size_t size;
const char *data;
struct UrlParams h;
data = luaL_checklstring(L, 1, &size);
bzero(&h, sizeof(h));
m = ParseParams(data, size, &h);
LuaPushUrlParams(L, &h);
free(h.p);
free(m);
return 1;
}
int LuaParseHost(lua_State *L) {
void *m;
size_t n;
struct Url h;
const char *p;
bzero(&h, sizeof(h));
p = luaL_checklstring(L, 1, &n);
m = ParseHost(p, n, &h);
lua_newtable(L);
LuaPushUrlView(L, &h.host);
LuaPushUrlView(L, &h.port);
free(m);
return 1;
}
int LuaPopcnt(lua_State *L) {
lua_pushinteger(L, popcnt(luaL_checkinteger(L, 1)));
return 1;
}
int LuaBsr(lua_State *L) {
long x;
if ((x = luaL_checkinteger(L, 1))) {
lua_pushinteger(L, bsr(x));
return 1;
} else {
luaL_argerror(L, 1, "zero");
unreachable;
}
}
int LuaBsf(lua_State *L) {
long x;
if ((x = luaL_checkinteger(L, 1))) {
lua_pushinteger(L, bsf(x));
return 1;
} else {
luaL_argerror(L, 1, "zero");
unreachable;
}
}
static int LuaHash(lua_State *L, uint32_t H(uint32_t, const void *, size_t)) {
long i;
size_t n;
const char *p;
i = luaL_checkinteger(L, 1);
p = luaL_checklstring(L, 2, &n);
lua_pushinteger(L, H(i, p, n));
return 1;
}
int LuaCrc32(lua_State *L) {
return LuaHash(L, crc32_z);
}
int LuaCrc32c(lua_State *L) {
return LuaHash(L, crc32c);
}
int LuaIndentLines(lua_State *L) {
void *p;
size_t n, j;
p = luaL_checklstring(L, 1, &n);
j = luaL_optinteger(L, 2, 1);
if (!(0 <= j && j <= 65535)) {
luaL_argerror(L, 2, "not in range 0..65535");
unreachable;
}
p = IndentLines(p, n, &n, j);
lua_pushlstring(L, p, n);
free(p);
return 1;
}
int LuaGetMonospaceWidth(lua_State *L) {
int w;
if (lua_isinteger(L, 1)) {
w = wcwidth(lua_tointeger(L, 1));
} else if (lua_isstring(L, 1)) {
w = strwidth(luaL_checkstring(L, 1), luaL_optinteger(L, 2, 0) & 7);
} else {
luaL_argerror(L, 1, "not integer or string");
unreachable;
}
lua_pushinteger(L, w);
return 1;
}
int LuaSlurp(lua_State *L) {
char *p, *f;
size_t n;
f = luaL_checkstring(L, 1);
if ((p = xslurp(f, &n))) {
lua_pushlstring(L, p, n);
free(p);
return 1;
} else {
lua_pushnil(L);
lua_pushstring(L, gc(xasprintf("Can't slurp file %`'s: %m", f)));
return 2;
}
}
static int LuaCheckControlFlags(lua_State *L, int idx) {
int f = luaL_checkinteger(L, idx);
if (f & ~(kControlWs | kControlC0 | kControlC1)) {
luaL_argerror(L, idx, "invalid control flags");
unreachable;
}
return f;
}
int LuaHasControlCodes(lua_State *L) {
int f;
size_t n;
const char *p;
p = luaL_checklstring(L, 1, &n);
f = LuaCheckControlFlags(L, 2);
lua_pushboolean(L, HasControlCodes(p, n, f) != -1);
return 1;
}
int LuaEncodeLatin1(lua_State *L) {
int f;
char *p;
size_t n;
p = luaL_checklstring(L, 1, &n);
f = LuaCheckControlFlags(L, 2);
p = EncodeLatin1(p, n, &n, f);
lua_pushlstring(L, p, n);
free(p);
return 1;
}
int LuaGetRandomBytes(lua_State *L) {
char *p;
size_t n = luaL_optinteger(L, 1, 16);
if (!(n > 0 && n <= 256)) {
luaL_argerror(L, 1, "not in range 1..256");
unreachable;
}
p = malloc(n);
CHECK_EQ(n, getrandom(p, n, 0));
lua_pushlstring(L, p, n);
free(p);
return 1;
}
int LuaGetHttpReason(lua_State *L) {
lua_pushstring(L, GetHttpReason(luaL_checkinteger(L, 1)));
return 1;
}
int LuaGetCryptoHash(lua_State *L) {
size_t hl, pl, kl;
uint8_t d[64];
mbedtls_md_context_t ctx;
// get hash name, payload, and key
void *h = luaL_checklstring(L, 1, &hl);
void *p = luaL_checklstring(L, 2, &pl);
void *k = luaL_optlstring(L, 3, "", &kl);
const mbedtls_md_info_t *digest = mbedtls_md_info_from_string(h);
if (!digest) return luaL_argerror(L, 1, "unknown hash type");
if (kl == 0) {
// no key provided, run generic hash function
if ((digest->f_md)(p, pl, d)) return luaL_error(L, "bad input data");
} else if (mbedtls_md_hmac(digest, k, kl, p, pl, d)) {
return luaL_error(L, "bad input data");
}
lua_pushlstring(L, (void *)d, digest->size);
mbedtls_platform_zeroize(d, sizeof(d));
return 1;
}
static dontinline int LuaIsValid(lua_State *L, bool V(const char *, size_t)) {
size_t size;
const char *data;
data = luaL_checklstring(L, 1, &size);
lua_pushboolean(L, V(data, size));
return 1;
}
int LuaIsValidHttpToken(lua_State *L) {
return LuaIsValid(L, IsValidHttpToken);
}
int LuaIsAcceptablePath(lua_State *L) {
return LuaIsValid(L, IsAcceptablePath);
}
int LuaIsReasonablePath(lua_State *L) {
return LuaIsValid(L, IsReasonablePath);
}
int LuaIsAcceptableHost(lua_State *L) {
return LuaIsValid(L, IsAcceptableHost);
}
int LuaIsAcceptablePort(lua_State *L) {
return LuaIsValid(L, IsAcceptablePort);
}
static dontinline int LuaCoderImpl(lua_State *L,
char *C(const char *, size_t, size_t *)) {
void *p;
size_t n;
p = luaL_checklstring(L, 1, &n);
p = C(p, n, &n);
lua_pushlstring(L, p, n);
free(p);
return 1;
}
static dontinline int LuaCoder(lua_State *L,
char *C(const char *, size_t, size_t *)) {
return LuaCoderImpl(L, C);
}
int LuaUnderlong(lua_State *L) {
return LuaCoder(L, Underlong);
}
int LuaEncodeBase64(lua_State *L) {
return LuaCoder(L, EncodeBase64);
}
int LuaDecodeBase64(lua_State *L) {
return LuaCoder(L, DecodeBase64);
}
int LuaDecodeLatin1(lua_State *L) {
return LuaCoder(L, DecodeLatin1);
}
int LuaEscapeHtml(lua_State *L) {
return LuaCoder(L, EscapeHtml);
}
int LuaEscapeParam(lua_State *L) {
return LuaCoder(L, EscapeParam);
}
int LuaEscapePath(lua_State *L) {
return LuaCoder(L, EscapePath);
}
int LuaEscapeHost(lua_State *L) {
return LuaCoder(L, EscapeHost);
}
int LuaEscapeIp(lua_State *L) {
return LuaCoder(L, EscapeIp);
}
int LuaEscapeUser(lua_State *L) {
return LuaCoder(L, EscapeUser);
}
int LuaEscapePass(lua_State *L) {
return LuaCoder(L, EscapePass);
}
int LuaEscapeSegment(lua_State *L) {
return LuaCoder(L, EscapeSegment);
}
int LuaEscapeFragment(lua_State *L) {
return LuaCoder(L, EscapeFragment);
}
int LuaEscapeLiteral(lua_State *L) {
return LuaCoder(L, EscapeJsStringLiteral);
}
int LuaVisualizeControlCodes(lua_State *L) {
return LuaCoder(L, VisualizeControlCodes);
}
static dontinline int LuaHasherImpl(lua_State *L, size_t k,
int H(const void *, size_t, uint8_t *)) {
void *p;
size_t n;
uint8_t d[64];
p = luaL_checklstring(L, 1, &n);
H(p, n, d);
lua_pushlstring(L, (void *)d, k);
mbedtls_platform_zeroize(d, sizeof(d));
return 1;
}
static dontinline int LuaHasher(lua_State *L, size_t k,
int H(const void *, size_t, uint8_t *)) {
return LuaHasherImpl(L, k, H);
}
int LuaMd5(lua_State *L) {
return LuaHasher(L, 16, mbedtls_md5_ret);
}
int LuaSha1(lua_State *L) {
return LuaHasher(L, 20, mbedtls_sha1_ret);
}
int LuaSha224(lua_State *L) {
return LuaHasher(L, 28, mbedtls_sha256_ret_224);
}
int LuaSha256(lua_State *L) {
return LuaHasher(L, 32, mbedtls_sha256_ret_256);
}
int LuaSha384(lua_State *L) {
return LuaHasher(L, 48, mbedtls_sha512_ret_384);
}
int LuaSha512(lua_State *L) {
return LuaHasher(L, 64, mbedtls_sha512_ret_512);
}
int LuaIsHeaderRepeatable(lua_State *L) {
int h;
bool r;
size_t n;
const char *s;
s = luaL_checklstring(L, 1, &n);
if ((h = GetHttpHeader(s, n)) != -1) {
r = kHttpRepeatable[h];
} else {
r = false;
}
lua_pushboolean(L, r);
return 1;
}
void LuaPushUrlView(lua_State *L, struct UrlView *v) {
if (v->p) {
lua_pushlstring(L, v->p, v->n);
} else {
lua_pushnil(L);
}
}

84
tool/net/lfuncs.h Normal file
View file

@ -0,0 +1,84 @@
#ifndef COSMOPOLITAN_TOOL_NET_LFUNCS_H_
#define COSMOPOLITAN_TOOL_NET_LFUNCS_H_
#include "net/http/url.h"
#include "third_party/lua/lua.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int LuaMaxmind(lua_State *);
int LuaRe(lua_State *);
int LuaUnix(lua_State *);
int luaopen_argon2(lua_State *);
int luaopen_lsqlite3(lua_State *);
int LuaBsf(lua_State *);
int LuaBsr(lua_State *);
int LuaCategorizeIp(lua_State *);
int LuaCrc32(lua_State *);
int LuaCrc32c(lua_State *);
int LuaDecimate(lua_State *);
int LuaDecodeBase64(lua_State *);
int LuaDecodeLatin1(lua_State *);
int LuaEncodeBase64(lua_State *);
int LuaEncodeLatin1(lua_State *);
int LuaEscapeFragment(lua_State *);
int LuaEscapeHost(lua_State *);
int LuaEscapeHtml(lua_State *);
int LuaEscapeIp(lua_State *);
int LuaEscapeLiteral(lua_State *);
int LuaEscapeParam(lua_State *);
int LuaEscapePass(lua_State *);
int LuaEscapePath(lua_State *);
int LuaEscapeSegment(lua_State *);
int LuaEscapeUser(lua_State *);
int LuaFormatHttpDateTime(lua_State *);
int LuaFormatIp(lua_State *);
int LuaGetCpuCore(lua_State *);
int LuaGetCpuNode(lua_State *);
int LuaGetCryptoHash(lua_State *);
int LuaGetHostOs(lua_State *);
int LuaGetHttpReason(lua_State *);
int LuaGetLogLevel(lua_State *);
int LuaGetMonospaceWidth(lua_State *);
int LuaGetRandomBytes(lua_State *);
int LuaGetTime(lua_State *);
int LuaHasControlCodes(lua_State *);
int LuaIndentLines(lua_State *);
int LuaIsAcceptableHost(lua_State *);
int LuaIsAcceptablePath(lua_State *);
int LuaIsAcceptablePort(lua_State *);
int LuaIsHeaderRepeatable(lua_State *);
int LuaIsLoopbackIp(lua_State *);
int LuaIsPrivateIp(lua_State *);
int LuaIsPublicIp(lua_State *);
int LuaIsReasonablePath(lua_State *);
int LuaIsValidHttpToken(lua_State *);
int LuaLemur64(lua_State *);
int LuaMd5(lua_State *);
int LuaMeasureEntropy(lua_State *);
int LuaParseHost(lua_State *);
int LuaParseHttpDateTime(lua_State *);
int LuaParseIp(lua_State *);
int LuaParseParams(lua_State *);
int LuaPopcnt(lua_State *);
int LuaRand64(lua_State *);
int LuaRdrand(lua_State *);
int LuaRdseed(lua_State *);
int LuaRdtsc(lua_State *);
int LuaSetLogLevel(lua_State *);
int LuaSha1(lua_State *);
int LuaSha224(lua_State *);
int LuaSha256(lua_State *);
int LuaSha384(lua_State *);
int LuaSha512(lua_State *);
int LuaSleep(lua_State *);
int LuaSlurp(lua_State *);
int LuaUnderlong(lua_State *);
int LuaVisualizeControlCodes(lua_State *);
void LuaPushUrlView(lua_State *, struct UrlView *);
char *FormatUnixHttpDateTime(char *, int64_t);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_TOOL_NET_LFUNCS_H_ */

File diff suppressed because it is too large Load diff

View file

@ -90,7 +90,8 @@ o/$(MODE)/tool/net/%.com.dbg: \
o/$(MODE)/tool/net/redbean.com.dbg: \
$(TOOL_NET_DEPS) \
o/$(MODE)/tool/net/redbean.o \
o/$(MODE)/tool/net/redbean.o \
o/$(MODE)/tool/net/lfuncs.o \
o/$(MODE)/tool/net/lre.o \
o/$(MODE)/tool/net/lunix.o \
o/$(MODE)/tool/net/lmaxmind.o \
@ -208,7 +209,8 @@ o/$(MODE)/tool/net/demo/virtualbean.html.zip.o: \
o/$(MODE)/tool/net/redbean-demo.com.dbg: \
$(TOOL_NET_DEPS) \
o/$(MODE)/tool/net/redbean.o \
o/$(MODE)/tool/net/redbean.o \
o/$(MODE)/tool/net/lfuncs.o \
o/$(MODE)/tool/net/lre.o \
o/$(MODE)/tool/net/lunix.o \
o/$(MODE)/tool/net/lmaxmind.o \
@ -326,6 +328,7 @@ o/$(MODE)/tool/net/redbean-unsecure.com: \
o/$(MODE)/tool/net/redbean-unsecure.com.dbg: \
$(TOOL_NET_DEPS) \
o/$(MODE)/tool/net/redbean-unsecure.o \
o/$(MODE)/tool/net/lfuncs.o \
o/$(MODE)/tool/net/lre.o \
o/$(MODE)/tool/net/lunix.o \
o/$(MODE)/tool/net/lmaxmind.o \
@ -408,6 +411,9 @@ o/$(MODE)/tool/net/redbean-original.com.dbg: \
o/$(MODE)/tool/net/redbean-original.o: tool/net/redbean.c o/$(MODE)/tool/net/redbean.o
@$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -DSTATIC -DUNSECURE -DREDBEAN=\"redbean-original\" $(OUTPUT_OPTION) $<
o/$(MODE)/tool/net/redbean-original.s: tool/net/redbean.c o/$(MODE)/tool/net/redbean.o
@$(COMPILE) -AOBJECTIFY.c $(COMPILE.c) -DSTATIC -DUNSECURE -DREDBEAN=\"redbean-original\" $(OUTPUT_OPTION) $<
# REDBEAN-ASSIMILATE.COM
#
# Same as REDBEAN.COM except without no-modify-self behavior.

File diff suppressed because it is too large Load diff