1
0
mirror of https://github.com/AR2000AR/openComputers_codes.git synced 2025-09-06 21:51:14 +02:00
Files
openComputers_codes/network/bin/nc.lua
2023-11-30 21:02:08 +01:00

128 lines
4.0 KiB
Lua

local shell = require("shell")
local event = require("event")
local thread = require("thread")
local term = require("term")
local os = require("os")
local socket = require("socket")
local args, opts = shell.parse(...)
---@type TCPSocket|UDPSocket
local localSocket
---@type TCPSocket|nil
local clientSocket
---@type thread
local listenerThread
opts.p = tonumber(opts.p) or 0
opts.b = opts.b or "0.0.0.0"
---@param listenedSocket UDPSocket|TCPSocket
local function listenSocket(listenedSocket)
checkArg(1, listenedSocket, 'table')
while true do
if (listenedSocket:instanceOf(socket.tcp)) then
---@cast listenedSocket TCPSocket
if (listenedSocket:getState() ~= "ESTABLISHED") then
return false
end
end
local data = listenedSocket:recieve()
if (data) then
term.write(data)
end
os.sleep()
end
end
local function help()
print("nc [-l] [-u] [-p=local port] [address] [port]")
print("\t-l : Listen for incomming connexion. With -u make nc listen for packet from all hosts")
print("\t-u : UDP")
print("\t-p : In UDP, the local port to listen on. Default to the remote port")
print("Examples :")
print("\t nc -l -u 9999")
print("\t nc -u -p=9999 192.168.1.1 9999")
print("\t nc -u 192.168.1.1 9999")
end
---read stdin indefenitely and send what's read through the socket
---@param outSocket TCPSocket|UDPSocket
local function readUserInput(outSocket)
repeat
local msg = term.read()
if (msg) then outSocket:send(msg .. "\n") end
until not msg or listenerThread:status() == "dead"
end
local function exit()
if (localSocket) then localSocket:close() end
if (clientSocket) then clientSocket:close() end
if (listenerThread) then
if (not listenerThread:join(3)) then
listenerThread:kill()
end
end
return false
end
event.listen("interrupted", exit)
if (opts.h or opts.help) then
help()
os.exit()
elseif (opts.l and opts.u and (tonumber(args[1]) or opts.p)) then --listen UDP
localSocket = socket.udp()
assert(localSocket:setsockname("*", tonumber(args[1]) or opts.p))
print(string.format("Listening on %s:%d", localSocket:getsockname()))
listenerThread = thread.create(listenSocket, localSocket)
while true do
--no remote addr/port. We cannot send msgs
os.sleep()
end
localSocket:close()
elseif (opts.u) then --connect UDP
localSocket = socket.udp()
assert(localSocket:setsockname(opts.b, opts.p))
args[2] = assert(tonumber(args[2]), "Invalid port number")
assert(localSocket:setpeername(args[1], args[2]))
print(string.format("Listening on %s:%d", localSocket:getsockname()))
listenerThread = thread.create(listenSocket, localSocket)
readUserInput(localSocket)
localSocket:close()
elseif (opts.l) then --listen tcp
localSocket = socket.tcp()
args[1] = args[1] or opts.b
args[2] = assert(tonumber(args[2] or opts.p), "Invalid port number")
assert(localSocket:bind(args[1], args[2]))
print(string.format("Listening on %s:%d", localSocket:getsockname()))
localSocket:listen(1)
local reason
clientSocket = localSocket:accept()
localSocket:close() --client connected, we don't need the listening socket anymore
if (clientSocket) then
print(string.format("Connected to : %s:%d", clientSocket:getpeername()))
listenerThread = thread.create(listenSocket, clientSocket)
readUserInput(clientSocket)
clientSocket:close()
else
print(reason)
end
else --connect TCP
args[2] = assert(tonumber(args[2]), "Invalid port number")
localSocket = socket.tcp()
localSocket:settimeout(5)
local s = localSocket:connect(args[1], args[2])
if (s ~= 1) then
print("Timeout")
else
print(string.format("Connected to %s:%d", localSocket:getpeername()))
listenerThread = thread.create(listenSocket, localSocket)
readUserInput(localSocket)
end
localSocket:close()
end
exit()