yeti <ye...@tilde.institute> writes:
>
> Marco Moock <
mm+use...@dorfdsl.de> writes:
>
> > Some weeks ago somebody posted a way to retrieve a complete message in the terminal by the msg id.
>
> ...but this is one way that kind of does the trick:
>
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 example with your article:
> ....but this is one way that kind of does the trick:
Easily undone with a little script like:
> 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()