Just a few comments, as I really should try to get some sleep... :-)
On 2026-01-12 04:14, Terri Kennedy wrote:
On 2026-01-11 09:36, Johnny Billquist wrote:
First of all we have the TCP/IP finger protocol.
This is defined in RFC 1288.
This protocol talks over TCP, with the server listening on port 79. A
client opens the connection and sends a one line query, terminated by
CR+LF. The query as such is basically in the form user@host2@host1,
where all the parts are optional. However, note that the username is
the leftmost component before the first @, and the host to communicate
to is the rightmost component, after the last @.
Forwarding from host1 to host2 is up to host1 if it will do it or not.
But it really means that hosts are processed right to left, and the
optional username is the leftmost part. Any host that talks finger
over TCP really should follow this RFC. Anything else is fundamentally
bad, and I hope all would agree with that.
Agreed. I would just add that optional arguments (which the RFChand-
waves as "Query Tokens" and only mentions in passing (but does not de-
scribe the function of) the /W token, so there are other possible arg-
uments, which a given server implementation may or may not implement.
Exactly what switches a client or server implements is something I
happily leave implementation defined. And I agree that unless it makes
sense to process a switch locally, it should be passed along with the
query to the remote node.
Can we agree that one or more optional
"tokens" (/foo) MAY appear in
the query, that implementations SHOULD ignore tokens they do not under-
stand/implement, SHOULD implement a /HELP token, and MUST pass the com-
plete query (after removing their own name), including any tokens, in-
cluding /HELP to the next host (if any). To clarify, if a system that
receives a Finger query is just "passing it along", it should not re-
spond to /HELP itself, but just pass it along as well.
Tokens (switches, options, or whatever you want to call them) makes
sense to pass along if they are not processed locally.
Having something like /HELP always expected to be implemented is fine. I
wouldn't be very upset if it wasn't, but I don't have a strong opinion
about it.
Next we have
finger over DECnet.
There are no formal standard for this. But there have existed
implementations since the 80s. Thomas tried to summarize how it should
work, which is aligned with those old implementations, and is also
what both him and me have tried to follow.
This protocol then talks over DECnet, with the server defined as the
DECnet object 117. A client opens the connection and sends a one line
query. The query as such is basically in the form host1::host2::user,
where all the parts are optional. However, note that the username is
the rightmost component, after the last ::, and the host to
communicate to is the leftmost component, before the first ::.
Forwarding from host1 to host2 is up to host1 if it will do it or not.
But it really means that hosts are processed left to right, and the
optional username is the rightmost part. Any host that talks finger
over DECnet really should follow this spec. Anything else is pretty
bad, and I hope all would agree with that.
Agreed, subject to my comments on RFC 1288 above.
I'd also add that "An implementation MAY decide to forward the re-
quest to another DECnet node if it does not have an node definition
for the host being queried.
That's fine. It might be considered unexpected, but this is boiling down
to implementation details that I prefer to leave to each implementation
on how to process it.
Gatewaying is implementation-specific and MAY be
provided. If it is
provided, it SHOULD follow the appropriate rules for left-to-right and
right-to-left parsing as described above.
Yes, and that in turn depends on the server understanding the context
(ie. DECnet or TCP). And so having the same notation for both is a bad idea.
Before I go on
I want to make a small comment on the topic of
streaming connections in DECnet. DECnet is inherently packet based.
Some operating systems provide an abstraction to streams on top of
this, but not all OSes do. And this stream abstraction is not the same
thing as TCP, and it is important to understand this. If your host
pretends you use a stream, it can still arrive as packets on the peer
side. There is no explicit stream type, and the packing/unpacking of
data from a stream into packets are done at a layer above DECnet
itself. This became obvious when me and Thomas were doing some initial
work on interoperability between TOPS-20 and RSX. The problem being
that Thomas was letting TOPS-20 treat the connection as a stream, and
we got into trouble on the RSX side.
TOPS-20 were just putting all the data to send into one packet in the
end. In RSX when receiving, you give a buffer with a size where
received data should be placed. And if the packet contain more data
than fits in the buffer, the remaining data is not kept, but
discarded, and you get a data overrun status in the receive.
So it's not actually a problem with streaming as such, but the size of
packets you might end up with. If TOPS-20 streams would just limit the
actual eventual packet to no more than some certain size, RSX will
play just fine. The fact that TOPS-20 pretend it's a stream is not a
problem. The problem is identical if you use packets, and just use a
packet size that is larger than what the receiver is expecting.
So if there is a way for any streaming abstraction layer to just say
what the maximum size of the packets should be, then by all means, run
with a stream if you want to, and it will work fine (just let me know
what your upper limit is set to, and I can adjust the RSX code
correspondingly).
I'd never heard of streaming until this discussion came around the
first time (2024). I've always written lines as records in my imple-
mentation.
I wasn't fully aware of it either, until I noticed the truncation when
fingering a TOPS-20 node, after which Thomas brought up the whole
streaming thing. I've since also come to understand that Ultrix (and
possibly other Unix implementations) might also implement that
"feature". I guess it makes more sense on OSes where files also are more
like a stream of bytes.
But in the end, it's just a question of making sure data isn't lost,
which means avoiding data overrun errors on packets, for OSes where that
is relevant.
If someone can just tell me what the packet size this streaming layer is
using in different OSes, I can just make sure the receive buffer is
large enough to accommodate it.
Ok. Final
part. Things become "interesting" when you start mixing
TCP/IP and DECnet. Since TCP/IP requests do hosts and users processing
right to left, and DECnet requests do hosts and users processing left
to right, and they also use different separators between hosts and
usernames, how do you get this to mix?
Terri's example:
finger terry@spc11d::
is a complete mess. How should this be parsed. If we go by TCP/IP
standard, anything to the right of the last @ should be the host,
which is "spc11d::". But that's not a host you would find in DNS.
But it's also not useful to process according to DECnet, because then
we say that everything before the first :: is the node, which would be
"terry@spc11d", which is clearly not a DECnet node.
So, please, drop that. That is pretty obviously illegal, no matter
which way you want to look at it.
This is entirely a matter of how the user command line is parsed
by the Finger client. It SHOULD be free to parse things however it
likes. but MUST only send a properly-formed query to a Finger server.
For sure. But as I point out, you can't actually parse that in any sane
way. Sure, if you decide to break standards, and do some liberal
heuristics and just random guessing, you can make it work. But that
shouldn't really be the way a client is implemented, in my opinion.
Just because a host name is no more than 6 letters does not mean it is a
DECnet node. That can just as well be a perfectly fine TCP/IP host name.
Back in the day, we had DECnet, BITNET, and TCP/IP
(and some other
protocols). So you could say "finger user(a)node.decnet" (and use "fin-
ger user@node::" as a shortcut). Likewise for "finger user(a)node.bitnet"
- these were all treated as ".decnet" and ".bitnet" pseudo-TLDs.
This
is also what PMDF (see prior references to Ned Freed) does.
The "fake" .decnet domain is one way to make it (hopefully) clear that
it's a DECnet node we're talking about. But then you still have the
problem of ordering.
If you do "finger bqt@node.decnet@host.net", what address should you
connect to? And is bqt a username or a host?
Unless there were cases where DECnet host FOO::.
BITNET host FOO,
and TCP/IP host
foo.example.com differed, you could just say "finger
user@host" and Finger would figure out the appropriate transport by
querying the host tables / DNS in that order - DECnet, BITNET, and
TCP/IP.
Which might be a very bad idea. Because they could differ, but all
exist. Really, if you want DECnet, say HOST::USER. Don't say USER@HOST,
because that's a TCP/IP format request.
This made it easy for users (who often didn't
know what sort of
network connection was used to talk to their buddy Fred on host
foobar). "finger fred@foobar" would just Do The Right Thing.
Except it can do the wrong thing, and you'll be very messed up.
But note that all this optional work MUST be done
entirely on the
user's local finger client, and what gets emitted as a Finger comm-
and line MUST be appropriate for the next hop's Finger server. It
SHOULD reject a message it considers ill-formed with an appropriate
error message.
For sure some part of the argument line needs to be processed by the
local host, but not all of it. Some parts you hand over to the server to
then sort out.
To summarize, in addition to supporting canonical
DNS (user@foo.
example.com) and DECnet (FOO::USER) address forms, a client MAY
support any other syntax, including (perhaps) user- or system-wide
mappings (for example, FOO::ERNIE -> FOO::ERNEST, or even joe@
oldjob.example.com -> Joseph.Lastname(a)otherjob.blah.org). This all
happens in the client, and as a server implementer you don't need
to worry about it at all.
Mapping usernames with aliases and whatnot is entirely legitimate, but
completely outside the scope of the finger protocol.
And no, that does not happen at the client. The client just sends
whatever name the user specified to the remote server, which then can do
whatever makes sense there. The local machine have no clue about what
translations, services or handling any remote machine is doing, and it
should not try to.
All I'm asking for on the server side is:
1) If acting as a smarthost, remove your node from the command
line (if it wasn't already) and pass it alongto the next host.
As pointed out in my other mail, the finger protocol should actually
strip out both the local *and* next hop from the request.
If the user types "finger mim::bqt", the client should connect to MIM
(using DECnet), and just send the string "bqt". Just as per the RFC for
TCP/IP finger.
And the same is true for a server that forwards the request to yet
another machine.
So if a user do "finger mim::jocke::bqt", the client connects to MIM,
and sends the string "jocke::bqt". The server on MIM process that line,
connects to JOCKE, and sends just the line "bqt" to it.
JOCKE in turn gets a username, and provide information about that user,
if he exists. It can translate aliases if it wants to, have spelling
correction, or other heuristics as much as it wants.
But the actual request lines sent at each step is as mentioned.
And if forwarding is not supported/allowed/whatever, give an error.
2) Support whatever restrictions the server wants
as to whether
lists of logged-in users can be provided, whether queries
must match a specific username or can providea list of users,
decide to show .plan (or site equivalent) data, etc.
Right.
3) At the implementations choice, handle unknown
qualifiers via
one of these methods (from most preferred to least preferred):
a) Report "Unknown command qualifier /FOO" for each unknown
qualifier, one per line, but return the requested informa-
tion (see the example below).
b) As a) above, except exit without returningany user infor-
mation after reporting errors as in a) above.
c) Silently ignore unknown qualifiers and return output for
the requested information.
All would be acceptable.
4) Implement the qualifier /HELP which will provide
(at a mini-
mum) the list of supported qualifiers.
Would be nice.
The user's Finger client is stripping off the
first host (DECnet or
DNS, let's forget about BITNET) and so your:
finger spc11d::terry@mim.softjar.se
gets turned into "open a connection to the finger server on mim.soft-
jar.se and send it the query 'spc11d::terry'". Whether or not it de-
cides to forward that request is an implementation and/or site-specif-
ic determination. As an example, while debugging this with the folks
at FNAL, it was important that their public-facing servers not allow
unrestricted DECnet Fingering of the various internal hosts, some of
which held classified data.
Agreed. With the added point that it's not given which takes precedence
when you have both DECnet and TCP/IP hosts on the line. Should it
connect to SPC11D and pass the line "terry(a)mim.softjar.se" or should it
connect to mim.softjar.se and pass the line "spc11d::terry"? Both are
equally valid. In my RSX code, I've decided to by default give
precedence to DECnet, and have a switch if you want the TCP/IP part to
take precedence.
And guess
what, here is how it looks on my MAC, right now:
Gromit:/Users/bqt> finger spc11d::terry@mim.softjar.se
[mim.softjar.se]
[SPC11D::]
SPC Memorial PDP-11/70
SPC11D PDP-11/70, RSTS V10.1-L, Monday, 11-Jan-1926 09:29, 8 Jobs, 63
Max.
Uptime 7 08:54:20, since Monday, 4-Jan-1926 00:35
05-Sep-24 - Your message could be here! Edit FINGER$:FINGER.MSG to
change it.
Job Username PPN Progrm Term Login CPU ST Location TTType
1 SYSTEM 1,2 ERRCPY Det 00:00 SR - Detached -
2 SYSTEM 1,2 MAILQ Det 00:01 SR - Detached -
3 SYSTEM 1,2 OMS Det 00:06 SL - Detached -
4 SYSTEM 1,2 PBS... Det 00:14 SL - Detached -
5 SYSTEM 1,2 EVTLOG Det 00:00 SL - Detached -
6 SYSTEM 1,2 MESMAN Det 00:00 SL - Detached -
7 TERRY 20,254 DCL KB0: 01:10 21:38 ^C PiDP-11 Console
VT100
8 SYSTEM 1,2 FINSRV Det 00:00 RN - Detached -
Gromit:/Users/bqt>
Are you actually seeing blank lines in the output, or is this
just the way this message was formatted?
Those empty lines are some effect of the cut-and-paste. Probably because
the lines got all the way to column 80.
The implementation stuff as I've described it
above is how RSTS/E
Finger currently operates (modulo a few bugs, which I'll fix) and
we can have a DECnet "bake-off" at some point in the future, once
we've settled on a spec.
The point I tried (and failed miserably) to make in earlier emails
is that whatever form of address the user gives the finger client on
their system is immaterial (beyond being something that generally
makes sense to users on that system) but what actually gets send as
a command line to a remote Finger server has to match the canonical
format, as described in the DECnet/E finger draft and (hopefully) as
amended by me above.
The form is not immaterial. That's my point. Because if you give a
DECnet address, the host is the leftmost component, and if it's TCP/IP,
it's the rightmost component. Which starts to be an important difference
if there is more than one hop required, as well as when we mix DECnet
and TCP/IP.
So I can
actually finger a RSTS/E host from a MAC. How fun isn't that?
(Don't ask me why I'm not getting information about Terry, though,
because I get the exact same result if I just do a "finger
spc11d::terry" on Mim directly.
I'm going to need to implement logging (as defined in the draft
spec).
I have a suspicion what the problem is...
You are expecting the "FINGER" keyword to come first, before the actual
thing being asked for.
Neither RSX, nor the TOPS-20 version does that. It just gives the actual
user asked for.
Which is also why the "FINGER" user error pops up in your attempts to
talk with RSX.
I'm not logging at the moment, but that can easily be thrown in when needed.
"finger spc11d::terry" works here from
spcpi2:
Like I said - I suspect you're expecting the actual command line, and
not just the user to look up.
If I do ''finger "spc11d::terry terry"`` I do get the information about
user terry. So it seems clear you're looking at the second word in the
argument string, which is different to RSX and TOPS-20 (and the TCP/IP RFC).
Or you have some other additional processing/expectations on the string
that cause some similar effect.
If you do this
on MIM, it will by default first try to process DECnet
nodes, so it will take the first node name, up to the first :: as the
node to connect to, and then pass everything after that to the server,
meaning "terry(a)mim.softjar.se" as the query. Now, if spc11d don't talk
TCP/IP, you'll get an error here. But if it do talk TCP/IP, and is
following the RFC, it will understand that query just fine, and should
do the right thing without any funniness.
If you were "on" MIM and not just passing through the finger request,
you'd just say "finger spc11d::terry". If you said "finger
terry(a)mim.soft-
jar.se" you'd get an error unless you actually had a user named terry.
Correct.
If, on MIM,
you actually want
spc11d::terry@mim.softjar.se to be doing the TCP/IP part first, then
you need to add a switch to make it so. And then it will be the same
as any other TCP/IP finger client, and work the same as described in
that bit above. So still all good.
Not sure I follow. But then again, cross-network routing is a more
complicated issue. Let's get the basic DECnet interoperability done
first.
There is the ambiguity of the line "spc11d::terry@mim.softjar.se", as
I've mentioned several times. Should it connect to spc11d using DECnet,
and send the line "terry(a)mim.softjar.se"r.se", or should it connect to
mim.softjar.se using TCP/IP, and send it the line "spc11d::terry".
Both are valid alternatives. But it can't do both. So by default it will
do one, and then I have switches if you want to force one or the other
instead of just relying on the defaults.
But yes, finger over DECnet should work first. Then we can get into
these details...
Any other
notations will break either the RFC or the DECnet finger
spec. Now, as I said before, I'm not going to force anyone to change
their code. But I really do find it broken to have code which tries to
decide if something is TCP/IP or DECnet by guessing and some
heuristics. And since the inherent order of hosts are in the opposite
directions in TCP/IP and DECnet, no heuristics in the world can
actually make this actually work right according to the two specs.
You'll have to break compatibility with one or the other protocol.
Just about all of that is in the client, in what it decides to do
with the user's command line (but which it must convert into the stan-
dard format).
Well, no. It's partially in the client, and partially in the server.
"Your client's broken" reports should
only pertain to the client
emitting incorrect standard-format commands (which, in the case of
RSTS/E Finger, is doing the unwanted /IAM business).
Agreed. But if it tries to talk DECnet when I say "bqt@mim" that is also
broken, and if it connects to host2, when I say "finger bqt@host2@host1"
that is also broken.
And I can come up with more variants if you want to. But I hope you get
the point.
"Your server's broken" reports can
cover a wider range of subjects.
Ideally, I'd like to see other DECnet servers behave about the same
as the RSTS/E one (aside from any breakage I need to fix, like why
Johnny's Finger client can't request info on a specific username and
always gets the "who is logged in" display). The enhancements I sug-
gested above in #1-4 for servers are a request for things which are
mostly optional in the existing implementations. The only MUST from
the above list is #4, implementing /HELP.
There can definitely be a lot of brokenness also on the server side, and
in various ways. But if we start with just the hostname and user bits,
they should really work the same as for the client, unless the server
just don't relay.
And please be
aware that gmail reception is broken, and they don't
accept mails from HECnet because of that. Nothing I can do about it.
gmail basically do not accept mails with a from address in the form of
"node::user"@mim.softjar.se, although it is correct according to RFC
5321. Google apparently don't care that they are violating the RFC.
If Ned Freed was still alive we could sic him on them, but sadly not.
Google has a zillion screwball requirements for mail, many of which are
undocumented. And they don't do anything with spam reports (I think that
abuse@ goes directly into the bitbucket).
I know. I used to work at Google... But most weird stuff at Google is
not at this level of brokenness. Really, this one takes some sort of
price in my book (I can go into the details in another thread, if
someone really wants to know...).
Johnny
--
Johnny Billquist || "I'm on a bus
|| on a psychedelic trip
email: bqt(a)softjar.se || Reading murder books
pdp is alive! || tryin' to stay hip" - B. Idol