~aleteoryx/nex.nelua

37f6f96031eb61668061d105f5bed2b0ee547c94 — Aleteoryx 16 days ago 073d0bb
and that's a wrap, folks
3 files changed, 86 insertions(+), 10 deletions(-)

M nex.nelua
A nps.nelua
M socket.nelua
M nex.nelua => nex.nelua +15 -3
@@ 1,14 1,26 @@
local socket = require 'socket'

socket.listen_tcp("127.0.0.1:1900", function()
if #arg ~= 1 then
  print("Usage: nex.nelua <ADDRESS>")
  print("ADDRESS may be one of:")
  print("  `<ipv4 addr>:<port>'")
  print("  `{<ipv6 addr>}:<port>'")
end

socket.listen_tcp(arg[1], function()
  local line = socket.recv_line():gsub("\r", "")

  if line:subview(1, 1) == "/" then line = line:subview(2) end

  if line == "" then
    socket.send_line("Hello!\nThis is the index page!\n\nThe protocol's originator:\n=> nex://nightfall.city")
    socket.send_line([[Hello!

This is the index page, edit nex.nelua to change it.

For more info, go here:
=> nex://nightfall.city/nex/info/specification.txt]])
  else
    socket.send_line("Page not Found.")
    socket.send_line("Page not Found. Try the root.")
  end

  socket.end_conn()

A nps.nelua => nps.nelua +37 -0
@@ 0,0 1,37 @@
local socket = require 'socket'
require 'vector'
require 'io'
require 'arg'

if #arg ~= 1 then
  print("Usage: nps.nelua <ADDRESS>")
  print("ADDRESS may be one of:")
  print("  `<ipv4 addr>:<port>'")
  print("  `{<ipv6 addr>}:<port>'")
end

socket.listen_tcp(arg[1], function()
  local target = socket.recv_line():gsub("\r", "")

  local lines: vector(string)
  local line = socket.recv_line()

  while line:gsub("\r", "") ~= "." do
    lines:push(line)
    line = socket.recv_line()
  end

  local ok, matches
  if (do ok, matches = target:match("^mail/(.+)$"); in ok end) then
    io.writef("Mail for %s:\n", matches[1])
    for i=0,<#lines do
      print("Mail:", lines[i])
    end
  else
    socket.send("Unknown target: ")
    socket.send_line(target)
    socket.send_line("If you're testing this out, try editing nps.nelua!")
  end

  socket.end_conn()
end)

M socket.nelua => socket.nelua +34 -7
@@ 82,11 82,6 @@ require 'allocators.default'

local function fakeuse(...: varargs) end

-- 192.168.2.1:2000 -> 192.168.2.1,2000
local inet_re = '^(%d?%d?%d%.%d?%d?%d%.%d?%d?%d%.%d?%d?%d):(%d?%d?%d?%d?%d)$'
-- {::1}:2000 -> ::1,2000
local inet6_re = '^{([^}]+)}:(%d?%d?%d?%d?%d)$'

local function die_errno(cond: boolean, msg: string): void
  if cond then
    C.perror(nilptr)


@@ 255,9 250,13 @@ function export.listen_sock(sock: cint, handler: function(): void): void
  end
end

-- 192.168.2.1:2000 -> 192.168.2.1,2000
local inet_re = '^(%d?%d?%d%.%d?%d?%d%.%d?%d?%d%.%d?%d?%d):(%d?%d?%d?%d?%d)$'
-- {::1}:2000 -> ::1,2000
local inet6_re = '^{([^}]+)}:(%d?%d?%d?%d?%d)$'
function export.listen_tcp(address: string, handler: function(): void): void
  local matched, matches = string.match(address, inet_re)
  if matched then
  local matched, matches
  if (do matched, matches = address:match(inet_re); in matched end) then
    local c_err: cint = 0

    local s_addr, s_port = matches:unpack(1, 2)


@@ 285,6 284,34 @@ function export.listen_tcp(address: string, handler: function(): void): void
    defer c_close(fd) end

    export.listen_sock(fd, handler)
  elseif (do matched, matches = address:match(inet6_re); in matched end) then
    local c_err: cint = 0

    local s_addr, s_port = matches:unpack(1, 2)
    local addr: [16]byte
    die_errno(c_inet_pton(AF_INET6, (@cstring)(s_addr), &addr) <= 0,
              "bad IPv6 address")
    local i_port = tointeger(s_port)
    assert((i_port >= 0) and (i_port < 65535), "port not within range [0,65536)")
    local port: uint16 = c_htons(i_port)

    local fd = c_socket(AF_INET6, SOCK_STREAM, 0)
    die_errno(fd == -1, "couldn't open TCP socket")

    fakeuse(port)
    ##[==[ cemit [[
      struct sockaddr_in6 sa;
      memset(&sa, 0, sizeof(sa));
      sa.sin6_family = AF_INET6;
      sa.sin6_port = port;
      memcpy(&sa.sin6_addr.s6_addr, &addr, sizeof(addr));
      c_err = bind(fd, &sa, sizeof(sa));
    ]] ]==]
    die_errno(c_err == -1, "couldn't bind TCP socket")

    defer c_close(fd) end

    export.listen_sock(fd, handler)
  end
end