mTCP Telnet client
2013-04-26 Version
Michael Brutman (mbbrutman@gmail.com)


Table of Contents (sorry, this file is big!)

  Introduction
  Hardware requirements
  Software requirements
  Setup instructions
  Starting and using Telnet
  Telnet protocol features and limitations
  Uploading and Downloading files
    Protocols
    Limitations on file transfers
    Notes for Linux/Unix
    Notes for Synchronet
  Shelling to DOS
  ANSI Emulation Notes
    Unicode
    Code pages
    Terminal types
    Monochrome adapter users
  Special note: Telnet BBSes and MUDs
  [Enter] key handling
  Advanced setup
  Support
  Recent changes



Introduction

  This is a small telnet client like other telnet clients that you
  have probably used before.  Besides communicating with a telnet server
  using the telnet protocol it also emulates a standard 'ANSI' terminal
  and has uploading and downloading capability using Xmodem and Ymodem
  Batch.  This particular telnet client features excellent screen
  updating performance and a small memory footprint.


Hardware requirements

  8088 processor or better
  190KB available RAM (using standard backscroll buffer)
  CGA, Monochrome (MDA), EGA or VGA display
  Supported Ethernet card, SLIP or PPP connection


Software requirements

  DOS 2.1 or newer (DOS 3.3 or newer recommended)
  Packet driver for your Ethernet card, SLIP or PPP connection


Setup instructions

  Telnet is built using the mTCP library. The setup instructions for mTCP
  can be found in SETUP.TXT.


Starting and using Telnet

  Telnet uses the following syntax:

    telnet [options] <telnet_server_addr> [port]

  where <telnet_server_addr> is the name or numerical IP address of the
  telnet server you wish to connect to and [port] is an optional port
  to connect to use.  By default the port is set to 23, which is the
  standard telnet server port.

  Options are:

    -help                      Show basic help text
    -debug_ansi                Create telnet.log with some extra debug info
    -debug_telnet              Create telnet.log with some extra debug info
    -sessiontype <telnet|raw>  Force telnet mode or raw mode

  Under normal operation if you connect to port 23 on a server you will be
  operating in telnet mode.  This means that the telnet client will expect
  to receive telnet options from the server, and will reply and try to
  negotiate option settings.  If you connect to any port besides port 23
  you will be operating in raw mode, where the telnet client will not
  respond to telnet options and it will not try to negotiate option
  settings.

  If you need to connect to a real telnet server on a non-standard port
  then use the -sessiontype option to force the telnet into telnet
  mode, even though you are not connecting to the standard telnet
  port.  You probably will never need to specify raw mode but it
  is there if you need it.

  For example:

    telnet bbs.retroarchive.org

  connects to a machine called 'bbs.retroarchive.org' using the standard
  telnet port (23).  It expects to find a telnet server at that port
  and it will negotiate telnet options with that server.

    telnet example.com 5500

  connects to a machine called example.com on port 5500.  This is not
  the standard telnet port so no telnet options negotiation will be
  done.  If that machine really were running a telnet server at that
  port you could force telnet mode using:

    telnet -sessiontype telnet example.com 5500

  To make the screen performance tolerable on older machines telnet will
  take incoming data and render the current screen on a virtual buffer
  before trying to repaint the real screen.  This approach uses a little
  bit more memory but it dramatically improves the performance of the
  screen handling, especially when scrolling large amounts of data.
  You will notice that the screen will pause and stop updating while
  the machine is getting flooded with incoming data - this is normal and
  it is keeping you from dying a slow and agonizing death while the display
  adapter scrolls.  A nice side-effect of the virtual buffer approach is
  that you get backscroll capability for free - if something does scroll
  past the screen you can hit Page Up and Page Down to browse around.

  The following special keys are recognized while telnet is running:

    PageUp and PageDown: Go up and down through the backscroll buffer

    Alt-H: Show a combined help and status screen

    Alt-B: Toggle sending DEL chars when the Backspace key is used on and off
    Alt-E: Toggle local echoing on and off
    Alt-N: Toggle between sending [Enter] as CR/NUL, CR/LF, CR or LF
    Alt-W: Toggle automatic wrapping around the right margin on and off

    Alt-R: Refresh the screen from our local virtual buffer.  (Should not
           be needed unless I have a screen drawing problem)

    Alt-D: Download a file using Xmodem or Ymodem Batch
    Alt-U: Upload a file using Xmodem or Ymodem Batch

    Alt-F: Drop to DOS to run some commands (make it quick!)

    Alt-X: Exit the program (Ctrl-Break does this too)

  When you use one of the toggle options a single beep means it was
  turned off, while a beep followed quickly by a higher pitched beep
  means it was turned on.

  The following special keys are sent to the server to handle:

    Cursor keys (Up, Down, Left Right)
    Home
    Insert
    Back-Tab (shift Tab)


Telnet protocol features and limitations

  This isn't a fully compliant telnet client implementation.  It has the
  following limitations:

    - SGA (Server Go Ahead) must be enabled on both sides of the connection.
      Most servers expect this behavior, as a TCP/IP socket is a full
      duplex connection.
    - This client will not do local line editing.
    - This client does not support the telnet Data Mark command.  This is
      not a big issue, but it means that you don't have an easy way to tell
      the server to squelch a flood of output if it happens.  At Ethernet
      speeds this should not be a big problem.

  It does properly support the following telnet options:

    - Binary transfer (used during file transfers)
    - Echoing - it will request or let the server offer to do echoing.  You
      can also turn on local echoing.
    - Terminal type - it will send the terminal type if asked for it
    - Window size - it will send the window size in rows and columns if asked

  Other options such as passing the environment variables are not supported,
  but that is not a big deal considering that you are connecting from a DOS
  machine.  (If you have a burning desire for a missing option let me know.)


Uploading and Downloading files

  In ye old days one would use a terminal emulation program with a
  modem to gain access to a BBS or multi-user timesharing system.
  If you wanted to download a file you used something like Xmodem,
  Kermit, or Zmodem.  Downloading was slow and agonizing, which made
  the reward for getting a good file that much more precious.

  Now people use HTTP and FTP to transfer files over broadband.  It
  just works.  It's not interesting.  Most people don't even know that
  FTP or HTTP exists - they are just "getting a file."

  In order to give you a taste of what it was like to transfer files
  back in the old days I have finally added Xmodem and Ymodem to
  telnet!  Many telnet BBSes support uploading and downloading through
  telnet connections and Unix systems have supported it using the
  sx/sb and rx/rb commands for years.  It is not as fast as FTP but
  you can do it right from telnet without quitting to run another
  program.  On faster machines the speed difference is not noticable.


  Protocols:

    Here are your options for uploading and downloading:

    Xmodem: This is the classic protocol designed by Ward Christensen
      in 1977.  It sends your file in chunks of 128 bytes; if your
      file size is not a multiple of 128 bytes it will be padded to
      the next 128 byte multiple.  Xmodem does not preserve file sizes
      or timestamps.  You may only transfer one file at a time.  The
      data is protected with a one byte checksum which is probably
      completely inadequate for unprotected data links but is not
      necessary over telnet as TCP/IP does its own error detection
      and correction.

    Xmodem CRC: This is a slight improvement on Xmodem.  Instead of
      protecting your data with a 1 byte checksum it uses a 2 byte
      CRC.  It can be used with Xmodem packets that are 128 bytes in
      length (the standard) or 1 KB in length (an extension).

    Xmodem 1K: This is major performance improvement on standard Xmodem.  
      By sending 1KB at a time instead of 128 bytes throughput is
      dramatically improved.  The speed of Xmodem is limited by how
      quickly the receiving side can tell the sending side "go ahead,
      I got that last packet" or "that last packet looked bogus, please
      resend."  Xmodem 1K reduces that overhead by a factor of eight,
      resulting in much less "dead air" on the wire.  Xmodem 1K is
      almost always used with the CRC option.

    Ymodem Batch: Ymodem is an improvement over Xmodem in several ways.
      It sends the filename, file size and timestamp to the remote side
      in a special header packet so that you don't have to re-enter
      the name or worry about the file size and timestamp being
      altered.  Ymodem is a batch protocol so it can be setup to
      send multiple files at a time.  Ymodem uses the CRC option;
      normally 1KB packets are used but 128 byte packets might be
      seen near the end of a file transfer.

  To download a file (or files) give the server the command to start
  sending the file(s) and then press Alt-D.  You will need to select the
  protocol to use - be sure this matches what the other side is going
  to use.  If you have a mismatch the file transfer will probably fail.
  If you choose one of the Xmodem variants you will have to enter
  the filename to save the file to and the saved file size will be
  rounded up to the next 128 byte size.  The file timestamp will also
  be set to the current time, as Xmodem does not preserve the file
  timestamp.  If you download using Ymodem Batch just select the protocol
  and the transfer will start.  The filename is automatically received,
  the file size will be exact, and the original file timestamp from the
  server size will be preserved.

  (Almost - If you run using DOSBox the file timestamp is not preserved
  because of a limitation in DOSBox.)

  If you try to download a file that already exists on your system you
  will be prompted to see if you really want to write over the existing
  file.  If the file can not be over written for some reason then
  the transfer is aborted.  This can happen if the filename happens to
  be the same as a directory on your local machine.

  To upload a file give the server the command to start receiving the
  file and then press Alt-U.  Select a protocol to use, and enter the name
  of the file to send.

  When uploading and downloading use the ESC key to abort the file
  transfer.  Xmodem and Ymodem transfers are normally cancelled by
  sending a special character (Ctrl-X) at least two times.  mTCP Telnet
  will do this for you, but if you need to cancel a file transfer 
  manually just hit Ctrl-X a few times and be patient.  (You might need
  to do this if you started the file transfer on the other side and
  changed your mind before starting it on the mTCP Telnet side.)

  All file operations happen in the current directory.  See the section
  on "Shelling to DOS" for details on how to change directories and
  manage files.

  Limitations on file transfers:

    When receiving using Ymodem you can tell the other side to send more
    than one file at a time.  But when sending you can only setup mTCP
    Telnet to send just one file at a time.

    Filenames must be in 8.3 format.  The sending and receiving of
    paths is not supported.

    There is no Ymodem G.  Ymodem G support on other systems is often
    implemented wrong, or does not exist at all.  It is just not worth
    the hassle.

 
  Notes for Linux/Unix:

    If you have lrzsz package installed then you have the following
    commands available:

      rx - receive on the server side using Xmodem
      rb - receive on the server side using Ymodem Batch
      sx - send from the server side using Xmodem
      sb - send from the server side using Ymodem Batch

    All of these commands have a bad habit - they write to stderr which
    in turn appears on stdout.  And that can mess up your transfer.  To
    get reliable transfers from these commands pipe the output of stderr
    to a file or /dev/nul.  For example:

      sx dosfile.exe 2> stderr.txt

    That will send the file dosfile.exe from Linux to the mTCP
    Telnet client, piping the output on stderr to a file called
    stderr.txt.  (This assumes you are using bash for your shell.
    If you use a different shell figure out how to pipe stderr using
    that shell.)

    The send commands (sx and sb) might not use 1KB packet sizes or
    CRC by default.  Not using CRC is not an issue over telnet, but
    not using 1KB packets can slow you down quite a bit.  Use the "-k"
    option to setup for 1KB packets.  (And using CRC never hurts either.)

  Notes for Synchronet:

    Synchronet BBS is great, but it has a bad habit.  When using Ymodem
    batch it will append extra bytes to your file to insert an
    advertisement for Synchronet.  This kind of defeats the purpose of
    preserving the original file size.  While I appreciate the effort
    that goes into maintaining Synchronet, this is bad behavior.


Shelling to DOS

  Sometimes you may need to suspend telnet and execute DOS commands
  while still connected to a server.  You might need to do this manage
  files that you have just transferred.  The Alt-F (File) key in
  telnet allows you to do this.

  When you use this function telnet will be suspended and you will be
  dropped at a DOS prompt.  You can execute commands here; I would limit
  it to just a few seconds and only using simple commands.  For example,
  if you need to delete a partially downloaded file, change directories,
  or check a directory for files this function is ideal.  Do not do
  anything that might alter the screen mode; the screen contents will
  be restored but telnet is not expecting the mode to change.

  While you are at the DOS shell telnet is not processing any incoming
  Ethernet packets.  If you receive something from the other system
  the connection will time out and you will be disconnected!  Keeping that
  in mind, do not use this function if you are expecting input from the
  other side.  When you are sitting at a Unix command prompt it is
  probably safe; doing it while a directory listing is coming down
  is definitely not safe.

  Use the "exit" command at the DOS prompt to return to telnet.


ANSI Emulation Notes

  Full blown ANSI terminal emulation is a complicated mess.  All of the
  different variations of ANSI emulation over the years have not helped
  anything either.  To put it politely, I've done the best I can and you
  might still see screen rendering problems.

  That being said, I've tried to do a reasonable good job of interpreting
  ANSI escape sequences and rendering them properly.  The ANSI emulation
  does not depend on ANSI.SYS or any other console device driver - it is
  all internal to the program.  I used a few sources to determine the
  required set of escape sequences, including the Linux TERMCAP entries
  for a few ANSI-like terminals, including the generic ANSI terminal
  definition and a few related PC flavors.  The emulation is good enough
  for me to write this documentation using VI, browse in text mode with
  Lynx, run the 'screen' program to get a few virtual terminals, use
  the 'info' command to browse the terminfo writeup, and run some of the
  more complicated 'system-config-*' commands provided with Fedora.

  Here are a few notes to improve your experience:

    Unicode:

      This telnet client doesn't have Unicode support in it, so
      sending a three byte sequence to it and hoping that you will get a
      Unicode character will not work.  The easiest way to supress the
      bogus Unicode characters is to set your LANG enviroment variable
      so that it doesn't trigger Unicode support.  For example, on my
      recent Linux boxes LANG looks like this:

        echo $LANG
        en_US.UTF-8

      Set it to en_US instead like this: export LANG=en_US

    Codepages:

      The standard codepage built into the monochrome card or the
      CGA card is codepage 437.  No other codepages are possible if you are
      using these two video cards.  Set Lynx to use codepage 437 to avoid
      getting weird characters.

      EGA and VGA users may be able to get other codepages loaded into memory
      using country.sys and other DOS configuration commands.  I have not
      experimented with this yet, but in theory you should be able to use
      other codepages with telnet by doing that.  (If you try this out please
      let me know how it works!)

    Terminal Types:

      By default if the telnet server asks type type of terminal is
      connecting this code will report back as 'ANSI'.  This happens during
      telnet option negotiation.

      If you want to experiment with other terminal types supported by your
      system then you can change the string that gets reported.  See the
      section entitled 'Advanced Setup' for instructions on how to do this.

      If you just want to make a temporary change most Unix systems have a
      TERM variable in the environment that you can alter.

      Depending on your system there may be several suitable terminal types
      to explore.  Older Linux systems have over 20 variants of ANSI terminals
      to choose from.  Newer Linux systems might just have 'ANSI' and
      'PCANSI' to choose from.  Look in /usr/share/terminfo/ for possible
      termcap definitions to play with.  If you want to make a custom termcap
      for this program contact me and I'll tell you exactly what I
      implemented.

    Monochrome Adapter Users:

      The monochrome adapter does not display color, but it does have the
      ability to underline characters properly.  If you are on a true
      monochrome display adapter (MDA) then you should set your terminal type
      to 'pcansi-mono', or something similar that tells the server that you
      have a terminal with true underlining capability.  The standard ANSI
      setting will work, but will not enable underlining.


Special note: Telnet BBSes and MUDs

  Not everything out there claiming to be a telnet server is actually running
  a compliant telnet server that does telnet option negotiation.  A lot of
  telnet BBBes and multi-user dungeons fall into this category.  If you are
  having trouble trying to connect to something that is not a standard
  telnet server, try using the "-sessiontype raw" option.  You will still get
  ANSI emulation but all of the telnet protocol negotiation code will be
  disabled.  This is done automatically when you connect to anything other
  than port 23.

  Assuming that works, you might need to turn on local echoing using Alt-E.


[Enter] key handling

  The telnet standard spells out that a "newline" character is comprised
  of a CR (carriage return) followed by a LF (line feed).  But it is not
  clear what it means when a user presses "Enter" at a terminal; that is
  traditionally just a CR that gets sent to the server.  This makes the
  standard ambiguous.

  After two years of struggling with the ambiguity I think I have found
  something that works for most telnet servers.  By default pressing the
  "Enter" key will send a CR/NUL pair.  If you need something different
  for a non-standard telnet server you can use Alt-N to toggle between
  the following options: CR/NUL, CR, LF, CR/LF.  The help screen will
  show you the current setting.

  Regardless of this setting you can always send a CR by pressing
  Ctrl-M and send a LF by pressing CTRL-J.


Advanced setup

  There are some options that you can specify in the MTCPCFG file to
  override default behavior, such as the initial state of toggles.
  Below is the list:

    TELNET_VIRTBUFFER_PAGES n    Replace n with a number from 1 to 8
    TELNET_CONNECT_TIMEOUT  n    N is time in seconds to wait for a connection
    TELNET_AUTOWRAP n            Use 0 for autowrap off (default), 1 for on
    TELNET_SENDBSASDEL n         Use 1 to send DEL chars when Backspace is hit
    TELNET_TERMTYPE termtype     Report 'termtype' as your terminal type
                                 during telnet option negotiation
    TELNET_SEND_NEWLINE chars    Send [Enter] as chars (see below)

  By default the number of Virtual Buffer Pages is 4, the connection timeout
  is 10 seconds, autowrap is turned on and sending DEL chars when the
  Backspace key is hit is on.  The terminal type string is set to 'ANSI'.

  The valid values for TELNET_SEND_NEWLINE are "CR/LF", "CR", "LF",
  "CR/NUL", or "AUTO".  The default is AUTO, which uses CR/NUL
  unless telnet binary mode is enabled.  If binary mode is active
  then just a CR will be sent.  (You don't have any direct control
  over binary mode so don't worry about it.) See the section on [Enter]
  key handling above for details.)

  Examples:

    TELNET_SEND_NEWLINE AUTO    (Default: use CR/NUL or just CR automatically)
    TELNET_SEND_NEWLINE CR/LF   (send both CR and LF at all times)
    TELNET_SEND_NEWLINE CR      (Send just a CR)
    TELNET_SEND_NEWLINE LF      (Send just an LF)
    TELNET_SEND_NEWLINE CR/NUL  (Send CR/NUL)


Support

  Have a comment or need help?  Please email me at mbbrutman@gmail.com.


Recent changes

  2013-03-15: Add scroll region support; Add DEC Origin Mode; add a few
              more CSI and ESC sequences; consolidate screen updating
              code.

  2012-04-29: Fix [Enter] handling;
              Add Xmodem and Ymodem file transfer

  2011-09-11: Fix telnet options bug
  2011-05-27: First open source release (GPL3)

  2011-05-18: Add Alt-N to toggle between sending [Enter] as CR/LF, CR or LF

  2010-11-27:

    Misc TCP library changes to improve handling when buffers are full.
    Watcom runtime workaround: improve compatibility with older machines

  2010-06-21:

    Ported to Open Watcom.  Note: The CGA snow code has been removed
    temporarily.

  2010-04-22:

    Maintenance release for the underlying TCP library.  TCP checksums
    should be computed correctly all of the time now, and are much faster.

  2010-03-21: Fix a bug involving servers with high numbered telnet options.

  2009-12-27:

    Add local echoing toggle
    Bug fix: [Enter] key should send CR/LF, not just CR
    Bug fix: Monochrome displays were freezing
    Bug fix: Monochrome displays were not underlining
    Add -sessiontype command line option and implement raw mode

  2009-12-12: Add support for cursor position reporting


More information: http://www.brutman.com/mTCP

Created November 2009, Last updated April 26th, 2013
(C)opyright Michael B. Brutman, mbbrutman@gmail.com
