Re: Telnet entry routines.

From: Carter T. Shock (ctso@umiacs.UMD.EDU)
Date: 09/11/95


I'll try to nuke as much of the originals as possible to reduce spam.

> 
> select "polls" the descriptors, it sets a flag in the descriptor if that 
> descriptor has input/output pending. Don't worry about the exception set.

Yes and no. Select does poll open descriptors, but in the circle code
it is wholly unnecessary. All of the circle sockets are set to non-blocking.
A socket listed in the input set after select is called is assured not
to block on a read(). i.e. redundant. Kill the select calls and just attempt
to read all of the sockets. read() can return in basically two ways:
1) it can return the number of bytes read. Even if interrupted by a signal.
2) It can return -1 and set the external global "errno" in the event of error.
All you have to do is check for the -1 on return. For a non-blocking socket
if errno == EWOULDBLOCK, make read return 0, any other error, close the socket.
And you _should_ worry about the exception set if you use select. Close any
sockets in that set... they are corrupt.

> the newline into the descriptor buffer inbuf. I'm not real clear on 
> whether telnet sends everything or just sends upon a newline. 

Depends on the mode telnet is in. Remember not to confuse the telnet 
application with the telnet protocol. To find out what mode telnet is in
you can negotiate the mode with the application. Look at the functions
that turn character echo on and off for password entry. The full list
of telnet options is usually found in /usr/include/arpa/telnet.h

Also of concern is that the telnet application handles control characters
differently depending on its mode. For starters, if telnet is in line-by-line
mode, it only sends on receipt of a newline. All backspace and control
characters within a line are handled locally. EOT (ctrl-D) is only
sent to the host if it is the first character on a line. In char-by-char
mode you can have telnet send all control chars or handle them locally.
Needless to say, a robust input parser has to handle all of these 
situations.
> 
> And for 2) . . hmm, hmm. I'm not real sure about this, but if the socket 
> were read using stdio functions, you could probably do it . . .
> 
How else do you plan to read a socket? :)


If anyone is interested, I've worked up a C++ class to do socket handling
and I'm working on a class to negotiate telnet options. It would seem that the
best solution would be to handle both instances of user input - 
line-by-line and char-by-char. If the user is in line-by-line mode
don't bother with all of the command line completion/editing stuff
(though it is reasonable to try to complete any abbreviations sent).
If they're in char-by-char mode, then searching the input stream for 
special characters is trivial. Defaulting to char-by-char mode is always
the safest tact however... If you start to rely on the terminating newline
from line-by-line mode everything blows up if that last pair of bytes
is lost on the net. Have I babbled enough?

	-Todd (slart at The Void rosebud.umiacs.umd.edu 4000)

PS: for the command line completion (and other tricks) you can treat
the set of circle commands as a grammar and parse it with lex/yacc.
Any interest in a discussion of this?



This archive was generated by hypermail 2b30 : 12/07/00 PST