diff options
author | bptato <nincsnevem662@gmail.com> | 2024-10-12 17:14:01 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-10-12 17:19:44 +0200 |
commit | c4a75720959a968004fec1996d6870d0874c953d (patch) | |
tree | 428407444b6aa0199060629047f5393f3b590218 /adapter/tools/nc.nim | |
parent | 828716e78b5b1a9fea93c2839d89e189c1fcb252 (diff) | |
download | chawan-c4a75720959a968004fec1996d6870d0874c953d.tar.gz |
Add `nc' tool & adjust finger/spartan to use it
Simple netcat clone, useful for portable scripts. Especially because some netcats will close the connection as soon as I close stdin... this one only quits when either stdout or the socket refuses new data. Also, it uses our standard TCP connection routine, meaning it respects ALL_PROXY. (i.e. now spartan works with socks5 too)
Diffstat (limited to 'adapter/tools/nc.nim')
-rw-r--r-- | adapter/tools/nc.nim | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/adapter/tools/nc.nim b/adapter/tools/nc.nim new file mode 100644 index 00000000..c9e3735b --- /dev/null +++ b/adapter/tools/nc.nim @@ -0,0 +1,50 @@ +# Minimal, TCP-only nc clone. Intended for use in shell scripts in +# simple protocols (e.g. finger, spartan). +# +# This program respects ALL_PROXY (if set). +import std/os +import std/posix + +import ../protocol/lcgi +import io/poll + +proc usage() {.noreturn.} = + stderr.write("Usage: " & paramStr(0) & " [host] [port]\n") + quit(1) + +proc main() = + if paramCount() != 2: + usage() + let os = newPosixStream(STDOUT_FILENO) + let ips = newPosixStream(STDIN_FILENO) + let ps = os.connectSocket(paramStr(1), paramStr(2)) + var pollData = PollData() + pollData.register(STDIN_FILENO, POLLIN) + pollData.register(ps.fd, POLLIN) + var buf {.noinit.}: array[4096, uint8] + var i = 0 # unregister counter + while i < 2: + pollData.poll(-1) + for event in pollData.events: + assert (event.revents and POLLOUT) == 0 + if (event.revents and POLLIN) != 0: + if event.fd == STDIN_FILENO: + let n = ips.recvData(buf) + if n == 0: + pollData.unregister(ips.fd) + inc i + continue + ps.sendDataLoop(buf.toOpenArray(0, n - 1)) + else: + assert event.fd == ps.fd + let n = ps.recvData(buf) + if n == 0: + pollData.unregister(ips.fd) + inc i + continue + os.sendDataLoop(buf.toOpenArray(0, n - 1)) + if (event.revents and POLLERR) != 0 or (event.revents and POLLHUP) != 0: + pollData.unregister(event.fd) + inc i + +main() |