Some weeks ago somebody posted a way to retrieve a complete message in the terminal by the msg id.
Note that this includes dot-stuffing, meaning lines beginning with a '.' are prefixed with one extra '.'.
My nc requires a port number, can't take a service name. It's 119 if others' nc are the same.
for line in io.stdin:lines() do
if line == "." then break end
if line:sub(1,1) == "." then
io.write(line:sub(2,-1).."\n")
else
io.write(line.."\n")
end
end
Wrote a little Lua script below, tested with LuaJIT.
If the stream errors out then it just throws a Lua assertion error.
I may make this into a more full-blast "newsget" for the fun of it.
One thing you highlighted I hadn't thought of before is pre-sending QUIT, pipelining it, before reading.
That feels like a very polite thing to do :)
local function nerr(s) io.stderr:write(s.."\n") os.exit(1) end
local function recvresp(stream)
return assert(stream:receive("*l")):match("^([0-9]+)[ \t]*(.-)[ \t]*$")
end
local msgid, host, port = ...
port = not port and 119 or tonumber(port)
if not (msgid and host and port) then
nerr("Usage: message-id host [port]")
end
local socket = require("socket") -- Lua Socket Library
local stream = assert(socket.connect(host, port))
local resp, line = recvresp(stream)
if resp ~= "200" and resp ~= "201" then
nerr("Fail: Server gave unhandled welcome: "..resp.." "..line)
end
assert(stream:send("ARTICLE "..msgid.."\r\n"))
stream:send("QUIT\r\n") stream:shutdown("send") -- don't care if this fails
local resp, line = recvresp(stream)
if resp == "220" then -- all good
elseif resp == "430" then
nerr("Fail: Message not found.")
else
-- Servers give a human-redable error description
-- which may be more specific than a client can come up with,
-- so it's best to just print it unless we can deal with it.
nerr("Fail: Server gave unhandled response: "..resp.." "..line)
end
-- 480: Authentication needed
-- Feel free to implement this yourself from RFC 4643
-- Easier is to pick a host that allows reading without auth.
-- 500: Server does not support ARTICLE
-- 501: Likely malformed message-id
for line in function() return assert(stream:receive("*l")) end do
if line == "." then break end
if line:sub(1,1) == "." then line = line:sub(2,-1) end
io.write(line.."\n")
end
stream:close()