• Please review our updated Terms and Rules here

Telnet BBSing double-spacing issue

Read my post above--I said:
"Clearly, the two CRs and the rubout were there to give time for the (mechanical) terminal to complete the action. Should result in single-spacing, unless your terminal interprets a carriage-return as having an implicit linefeed. The rubout is non-printing and is there to insert a delay in the data stream."
I was not aware that the VT510 or any other CRT terminal was "mechanical" or that it required time to return the "carriage".

Also: https://www.revk.uk/2022/02/crlf-has-long-history.html doesn't call it DEL; I suspect that the 7-level folks on Greenkeys call it "Rubout".

I suspect that experience with mechanical terminals is lacking here.
 
Last edited:
"Clearly, the two CRs and the rubout were there to give time for the (mechanical) terminal to complete the action.
Well, I was addressing other issues, such as your incorrect claim that "RO is only alternately known as DEL because of its application in paper tape." (I hope I've made it clear that the name of the ASCII character is, and always has been, DEL; some people like to casually call it "rubout," but that's both not the character name and is a name also used for other things, such as $FF, which is not an ASCII character code.)

As for your claim that the sequence 13, 13, 10, 255, 0, 13, 10 is for time for a mechanical terminal to complete the action, I find this implausible. These are BBSs, which were not a thing in the mechanical terminal age, and I doubt anybody has ever been a regular user of a dial-up BBS on a printing terminal (and most from the early '80s onwards will not work on printing terminals). As you say:
I was not aware that the VT510 or any other CRT terminal was "mechanical" or that it required time to return the "carriage".

It would also be weird, if this were for padding, that they use three entirely different padding characters, and then drop two of the three for non-padding characters in a similar sequence slightly later on: 13, 10, 97, 47, 255, 1, 13, 10.

This doesn't appear to be a valid TELNET connection: 255, 0 certainly starts with an IAC character, but 0 is not a valid command as far as I'm aware (they intentionally seem to have kept all commands above 127), and it's also violating the TELNET dictum that "bare" CRs must be followed by a NUL. (Presumably this can be negotiated away, but my understanding is that the client side here isn't doing TELNET.)

This could, of course, be a particularly confused attempt at implementing the TELNET protocol, or there could be something between the host and client that's changing things around.
 
Whatever; I gave a possible explanation. Could be that we're all mistaken.

In a way, I could see a terminal (electronic) that could not scroll fast enough to keep sync with the stream. I recall that the INT 10H routines on the 5150 were very slow at scrolling after a line feed (rather than change the starting address of the display, they used a REP MOVSW which IIRC, couldn't track a stream at 9600 BPS). Who knows?
 
In a way, I could see a terminal (electronic) that could not scroll fast enough to keep sync with the stream. I recall that the INT 10H routines on the 5150 were very slow at scrolling after a line feed (rather than change the starting address of the display, they used a REP MOVSW which IIRC, couldn't track a stream at 9600 BPS). Who knows?
I can totally see that happening; the 5150 is not the only computer that was, well, "unenthusiastic" in scrolling its display.

Unfortunately adding CRs as padding doesn't help there at all, since they come before the LF that causes the scroll. My current suspicion is that it's just a side effect of the way the particular BBS was programmed. (Remember the pagers that gave you a "more" line at the bottom of the screen, but overwrote that line rather than scrolling it up as you moved on to the next page?)

But who knows. What we've got so far is:
  1. The extra CRs should not be an issue for any terminal program in the first place, since they are effectively no-ops. (Which is possibly why nobody bothered to remove them, if it's the original code that's generating them.)
  2. It looks like the connection is not a TELNET protocol connection, or is almost certainly an incorrect implementation in several ways, as far as I can tell from reading some of the RFCs.
Perhaps the OP will give us more detail about what he's connecting to and how exactly the connections are set up, and we can start to work out those problems. Given a TCP address to which to connect, it's simple enough to connect to it and see if you get any TELNET protocol negotiation messages from it.
 
I think things might have gotten a little off track and that's largely my fault for using some incorrect terminology up front.

Let me re-state my issue and some recent findings as I believe this may only be happening on WWIV boards.

Let's suppose a few different scenarios:
  1. Hardware C128 (64 mode) with Link232 Cartridge. Software: StrikeTerm
  2. Hardware C128 (128 mode) with Link232 Cartridge. Software: my (work-in-progress) terminal program
  3. Hardware C128 (128 mode) with Link232 Cartridge. Software: DesTerm
  4. Hardware Apple //c with WiFi Modem Software: ProTerm 2.2
  5. Hardware Apple //c with WiFi Modem. Software: AppleTerm
  6. Hardware PC (DOS). Software: Terminate
  7. Hardware PC (DOS). Software: mbbrutman's own mTcpSuite Telnet client
  8. Hardware PC (Linux). Software: SyncTerm
For #1 you can swap out StrikeTerm with NovaTerm, CCGMS, or probably any other term that supports ASCII
For #3 you can swap out DesTerm for Dialog.
For #6 you could swap out Terminate with Telix or probably any other dos-based terminal emu

These are the scenarios I've tested so far.

What I'm finding is that on some boards (specifically, and I didn't find this out until this morning so don't get mad at me for not mentioning it sooner) with WWIV boards. With scenarios #2 and #4 I am getting two CR's (character 13) at the end of each line. Whereas on that same board, using all other scenarios I am getting one CR at the end of each line.

For #4 I don't really care to correct this issue I include it only that it might provide some clues as to why this is happening.
What I want to solve is #2 since this is the program I'm writing.

The question I'm asking myself is why with some boards (what I now believe to be isolated to WWIV boards but I might find other BBS software in the future that also exhibits this behavior) am I getting two CRs at the end of every line whereas with other terminal emulators I am not.

I don't think this has anything to do with the Telnet protocol as I doubt WWIV is doing any kind of telnet negotiation, unless something sitting in the middle between WWIV and TCP is doing it. But even if that was the case it wouldn't explain why terminal emulators that were never designed to do telnet ... anything, such as AppleTerm, NovaTerm, etc. would behave "as expected" (one CR per line).

Whatever is making these term programs display only single CRs it isn't due to telnet negotiation because why would a term program written to communicate serial data over a modem be doing telnet negotiation? You might say "well TCPSER / Link232 / WiFiModem is doing it" but then why would they not be doing it with scenarios 2 and 4?

If the answer is that it is just in WWIV's nature to be sending two CRs after each line, then why am I only seeing that in two of the above scenarios?
 
I'll agree that two consecutive CRs don't make a lot of sense for electronic displays. Even on Teletypes, the hardware could accept another code while CR was being executed, IIRC.
I suppose that the source code for the emulators isn't available...that might answer a lot of questions.
 
I agree that it's hugely unlikely that any of the native terminal programs you discussed are doing any sort of TELNET negotiation.

The first thing to check is whether the remote BBS is actually sending one or two CRs. Make a direct connection from a machine that speaks TCP natively and use a tool like netcat to find out. Or, even better yet, use tcpdump to record the exact bytes that were sent across the TCP connection. (If that's difficult to set up, you can also just use netcat as a proxy, and have it log the data moving across the connection.)
 
I'm going to skip around the digressions and ask if you have an "Auto Newline" or similar feature enabled in your terminal program.

Normally the received data from Telnet should correspond to what a dumb terminal does with it (NOT what Unix interprets it as in a text file), and CR means "go to the start of the current line". To go to the next line, LF must be sent, which moves the cursor to the same horizontal position on the next line. (When CRs aren't being sent, you will see output in a stair step format.) Conversely, the normal handling of "readline" style input (the way that lets you backspace over stuff) is that when the host sees a CR, it interprets it as ending the current input line without waiting for LF, and will respond with CR and LF.

"Auto Newline" is a feature in the terminal emulation to work around situations where the host doesn't work this way (or if you've just hooked up two dumb terminals to each other), and only sends a bare CR. If the terminal sees CR, then auto-newline will make it act as though it also received LF. If a newline comes in after the CR, it will be interpreted as yet another newline. If enabled in the 99% of cases where it is not appropriate, this will cause double-spacing.
 
I'm going to skip around the digressions and ask if you have an "Auto Newline" or similar feature enabled in your terminal program.
He's seeing multiple CRs, not multiple LFs. And one of the terminal programs is the one he is writing, so I presume he's fairly familiar with its features. :-P
 
Yeah there's no auto newline or anything like that. I like the idea of using netcat I think I'll try to set that up today after work. That would give me an independent source of data outside of the vice/tcpser setup.
 
If you are using the mTCP NetCat then look at the debugging section of the PDF documentation. There is a packet trace mode so that you can see *exactly* what comes in on the wire from the packet driver, before anything else has a chance to manipulate it.
 
Okay I did some testing with tcpdump and I can see double CR characters coming in, here's a snippet (double CRs highlighted):

0x0000: 4500 00a4 0178 4000 2f06 6260 18ff 0d61 E....x@./.b`...a
0x0010: c0a8 0074 1966 e1b2 2137 8b26 f708 339d ...t.f..!7.&..3.
0x0020: 8018 01fe b498 0000 0101 080a 2a3a 2be0 ............*:+.
0x0030: f17e d9b3 0d0d 0a57 5749 5620 352e 372e .~.....WWIV.5.7.
0x0040: 322e 3335 3532 0d0d 0a43 6f70 7972 6967 2.3552...Copyrig
0x0050: 6874 2028 6329 2031 3939 382d 3230 3232 ht.(c).1998-2022
0x0060: 2c20 5757 4956 2053 6f66 7477 6172 6520 ,.WWIV.Software.
0x0070: 5365 7276 6963 6573 2e0d 0d0a 416c 6c20 Services....All.
0x0080: 5269 6768 7473 2052 6573 6572 7665 642e Rights.Reserved.
0x0090: 0d0d 0a1b 5b73 1b5b 3939 393b 3939 3948 ....[s.[999;999H

There's also a few single CRs in there.

I did the same capture using SyncTerm instead of my term program and got the same data.
 
That's not a binary program file. That's a TCP/IP packet. The first 20 bytes are the IP header. After that you'll have at least 20 bytes of the TCP header, and then the TCP payload. There is also an ANSI escape code visible at the very end of the packet.

The total length of the packet is 164. That leaves 144 for the TCP part of the packet. That TCP header seems to be 32 bytes long, so there are 20 bytes of fixed header and 12 bytes of options data. The first 0D0D is the start of the TCP payload.

Clearly this is a WWIV "feature" ... Also, it does not look to be doing Telnet options negotiation - you would see that as the very first bytes.
 
  • Like
Reactions: cjs
No, what made me think "binary file" was the sequence of text messages that one might find in a binary file. Just a blind stab in the dark. I can see by the escape sequence at 0093 that it's not. Oh well...
 
Maybe it's on the source side? Maybe something on the other end is translating LFs into CRLF, and it was already CRLF, thus ending up with CRCRLF?
That is definitely something a misconfigured Unix TTY or PTY driver would do.
 
Here is another snippet of two captures, A using my term + tcpser + vice and B using SyncTerm
A:
0x0100: 74 69 65 73 20 5d 5b 20 26 20 5d 5b 20 42 65 65 ties.][.&.][.Bee
0x0110: 72 20 5d 5b 45 74 63 5d 0d 0d 0a 20 20 5b 2e 54 r.][Etc].....[.T
0x0120: 68 69 73 2e 73 70 61 63 65 2e 66 6f 72 2e 72 65 his.space.for.re
0x0130: 6e 74 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e nt..............

B:
0x01a0: 69 65 73 20 5d 5b 20 26 20 5d 5b 20 42 65 65 72 ies.][.&.][.Beer
0x01b0: 20 5d 5b 45 74 63 5d 0d 0d 0a 20 20 5b 2e 54 68 .][Etc].....[.Th
0x01c0: 69 73 2e 73 70 61 63 65 2e 66 6f 72 2e 72 65 6e is.space.for.ren
0x01d0: 74 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e t...............

to make it easier to compare them I broke up the two-byte pairs so that it's easier to see individual bytes. The packets don't exactly line up (off by one) but if you ignore the 74 at the start of A then you can see it's the same data, and the double CRs (0d 0d) are in both.

So I'm getting the same data regardless of which terminal programs I'm using (well okay this is just testing my term program and SyncTerm). However SyncTerm (and presumably almost all other term programs) are somehow not showing the two CRs, just one.
 
As stated before, that's the expected behavior. A CR immediately after another CR is a wasted byte because once you do the carriage return, doing it again doesn't change the state of the terminal. (Generating delays for electro-mechanical devices are a different discussion.)

If your program is doing something on the second CR that visibly changes the state of the terminal, well, that's a bug for you to fix.
 
Back
Top