The main program.

def real_main():
    """The main program."""
    global RTS
    global DTR
    try:
        default_baud = int(os.getenv('RSHELL_BAUD'))
    except:
        default_baud = 115200
    default_port = os.getenv('RSHELL_PORT')
    default_rts = os.getenv('RSHELL_RTS') or RTS
    default_dtr = os.getenv('RSHELL_DTR') or DTR
    default_user = os.getenv('RSHELL_USER') or 'micro'
    default_password = os.getenv('RSHELL_PASSWORD') or 'python'
    default_editor = os.getenv('RSHELL_EDITOR') or os.getenv('VISUAL') or os.getenv('EDITOR') or 'vi'
    global BUFFER_SIZE
    try:
        default_buffer_size = int(os.getenv('RSHELL_BUFFER_SIZE'))
    except:
        default_buffer_size = BUFFER_SIZE
    parser = argparse.ArgumentParser(
        prog="rshell",
        usage="%(prog)s [options] [command]",
        description="Remote Shell for a MicroPython board.",
        epilog=("You can specify the default serial port using the " +
                "RSHELL_PORT environment variable.")
    )
    parser.add_argument(
        "-b", "--baud",
        dest="baud",
        action="store",
        type=int,
        help="Set the baudrate used (default = %d)" % default_baud,
        default=default_baud
    )
    parser.add_argument(
        "--buffer-size",
        dest="buffer_size",
        action="store",
        type=int,
        help="Set the buffer size used for transfers "
             "(default = %d for USB, %d for UART)" %
             (USB_BUFFER_SIZE, UART_BUFFER_SIZE),
    )
    parser.add_argument(
        "-p", "--port",
        dest="port",
        help="Set the serial port to use (default '%s')" % default_port,
        default=default_port
    )
    parser.add_argument(
        "--rts",
        dest="rts",
        help="Set the RTS state (default '%s')" % default_rts,
        default=default_rts
    )
    parser.add_argument(
        "--dtr",
        dest="dtr",
        help="Set the DTR state (default '%s')" % default_dtr,
        default=default_dtr
    )
    parser.add_argument(
        "-u", "--user",
        dest="user",
        help="Set username to use (default '%s')" % default_user,
        default=default_user
    )
    parser.add_argument(
        "-w", "--password",
        dest="password",
        help="Set password to use (default '%s')" % default_password,
        default=default_password
    )
    parser.add_argument(
        "-e", "--editor",
        dest="editor",
        help="Set the editor to use (default '%s')" % default_editor,
        default=default_editor
    )
    parser.add_argument(
        "-f", "--file",
        dest="filename",
        help="Specifies a file of commands to process."
    )
    parser.add_argument(
        "-d", "--debug",
        dest="debug",
        action="store_true",
        help="Enable debug features",
        default=False
    )
    parser.add_argument(
        "-n", "--nocolor",
        dest="nocolor",
        action="store_true",
        help="Turn off colorized output",
        default=False
    )
    parser.add_argument(
        "-l", "--list",
        dest="list",
        action="store_true",
        help="Display serial ports",
        default=False
    )
    parser.add_argument(
        "-a", "--ascii",
        dest="ascii_xfer",
        action="store_true",
        help="ASCII encode binary files for transfer",
        default=False
    )
    parser.add_argument(
        "--wait",
        dest="wait",
        type=int,
        action="store",
        help="Seconds to wait for serial port",
        default=0
    )
    parser.add_argument(
        "--timing",
        dest="timing",
        action="store_true",
        help="Print timing information about each command",
        default=False
    )
    parser.add_argument(
        '-V', '--version',
        dest='version',
        action='store_true',
        help='Reports the version and exits.',
        default=False
    )
    parser.add_argument(
        "--quiet",
        dest="quiet",
        action="store_true",
        help="Turns off some output (useful for testing)",
        default=False
    )
    parser.add_argument(
        "cmd",
        nargs=argparse.REMAINDER,
        help="Optional command to execute"
    )
    args = parser.parse_args(sys.argv[1:])

    if args.buffer_size is not None:
        BUFFER_SIZE = args.buffer_size

    if args.debug:
        print("Debug = %s" % args.debug)
        print("Port = %s" % args.port)
        print("Baud = %d" % args.baud)
        print("User = %s" % args.user)
        print("Password = %s" % args.password)
        print("Wait = %d" % args.wait)
        print("List = %d" % args.list)
        print("nocolor = %d" % args.nocolor)
        print("ascii = %d" % args.ascii_xfer)
        print("Timing = %d" % args.timing)
        print("Quiet = %d" % args.quiet)
        print("BUFFER_SIZE = %d" % BUFFER_SIZE)
        print("Cmd = [%s]" % ', '.join(args.cmd))

    if args.version:
        print(__version__)
        return

    global DEBUG
    DEBUG = args.debug

    global QUIET
    QUIET = args.quiet

    global EDITOR
    EDITOR = args.editor

    if args.nocolor:
        global DIR_COLOR, PROMPT_COLOR, PY_COLOR, END_COLOR
        DIR_COLOR = ''
        PROMPT_COLOR = ''
        PY_COLOR = ''
        END_COLOR = ''
    else:
        if sys.platform == 'darwin':
            # The readline that comes with OSX screws up colors in the prompt
            global FAKE_INPUT_PROMPT
            FAKE_INPUT_PROMPT = True

    global ASCII_XFER
    ASCII_XFER = args.ascii_xfer
    RTS = args.rts
    DTR = args.dtr

    if args.list:
        listports()
        return

    if args.port:
        ASCII_XFER = True
        if args.buffer_size is None:
          if is_micropython_usb_port(args.port):
              BUFFER_SIZE = USB_BUFFER_SIZE
          else:
              BUFFER_SIZE = UART_BUFFER_SIZE
        QUIET or print('Using buffer-size of', BUFFER_SIZE)
        try:
            connect(args.port, baud=args.baud, wait=args.wait, user=args.user, password=args.password)
        except DeviceError as err:
            print(err)
    else:
        autoscan()
    autoconnect()

    if args.filename:
        with open(args.filename) as cmd_file:
            shell = Shell(stdin=cmd_file, filename=args.filename, timing=args.timing)
            shell.cmdloop('')
    else:
        cmd_line = ' '.join(args.cmd)
        if cmd_line == '':
            print('Welcome to rshell.', EXIT_STR)
        if num_devices() == 0:
            print('')
            print('No MicroPython boards connected - use the connect command to add one')
            print('')
        shell = Shell(timing=args.timing)
        try:
            shell.cmdloop(cmd_line)
        except KeyboardInterrupt:
            print('')