Пример #1
0
Файл: top.py Проект: hick/x84
def main(handle=None):
    """ Main procedure. """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    session, term = getsession(), getterminal()
    session.activity = 'top'

    # attempt to coerce encoding of terminal to match session.
    coerce_terminal_encoding(term, session.encoding)

    # fetch user record
    user = get_user_record(handle)

    # register call
    login(session, user)

    # display art and prompt for quick login
    quick = do_intro_art(term, session)

    echo(term.move_down() * 3)

    # only display news if the account has not
    # yet read the news since last update.
    gosub('news', quick=True)

    if not quick:
        # display last 10 callers, if any
        gosub('lc')

        # one-liners
        gosub('ol')

    goto('main')
Пример #2
0
def main(handle=u''):
    """ Main procedure. """
    # pylint: disable=R0914
    #        Too many local variables
    from x84.bbs import getsession, getterminal, echo, ini, User, goto
    from x84.bbs import showcp437
    session, term = getsession(), getterminal()
    import os
    session.activity = u'Applying for an account'
    artfile = os.path.join(os.path.dirname(__file__), 'art', 'nua.asc')
    msg_header = u'NEW USER APPliCAtiON'
    # pylint: disable=E1103
    #         Instance of '_Chainmap' has no 'split' member
    #         (but some types could not be inferred)
    newcmds = ini.CFG.get('matrix', 'newcmds').split()
    topscript = ini.CFG.get('matrix', 'topscript')

    # display art and msg_header as banner
    echo(u'\r\n\r\n')
    for line in showcp437(artfile):
        echo(line)
    echo(u'\r\n\r\n' + term.reverse + msg_header.center(term.width))

    # create new user record for manipulation
    user = User(handle if handle.lower() not in newcmds else u'')
    while True:
        set_handle(user)
        set_location(user)
        set_email(user)
        set_password(user)
        set_sacookies(user)
        if prompt_ok():
            user.save()
            goto(topscript, user.handle)
Пример #3
0
def main(anonymous=False, new=False):
    """
    Script entry point.

    This is the default login matrix for the bbs system.

    It takes no arguments or keyword arguments, because it assumes
    the user should now be authenticated, such as occurs for example
    on telnet.
    """
    term = getterminal()

    display_banner(term)

    if anonymous:
        # user rlogin'd in as anonymous@
        goto(top_script, 'anonymous')
    elif new:
        # user rlogin'd in as new@
        goto(new_script)

    # do_login will goto/gosub various scripts, if it returns, then
    # either the user entered 'bye', or had too many failed attempts.
    do_login(term)

    log.debug('Disconnecting.')

    # it is necessary to provide sufficient time to send any pending
    # output across the transport before disconnecting.
    term.inkey(1.5)
Пример #4
0
def main(anonymous=False, new=False):
    """
    Script entry point.

    This is the default login matrix for the bbs system.

    It takes no arguments or keyword arguments, because it assumes
    the user should now be authenticated, such as occurs for example
    on telnet.
    """
    term = getterminal()

    display_banner(term)

    if anonymous:
        # user rlogin'd in as anonymous@
        goto(top_script, 'anonymous')
    elif new:
        # user rlogin'd in as new@
        goto(new_script)

    # do_login will goto/gosub various scripts, if it returns, then
    # either the user entered 'bye', or had too many failed attempts.
    do_login(term)

    log.debug('Disconnecting.')

    # it is necessary to provide sufficient time to send any pending
    # output across the transport before disconnecting.
    term.inkey(1.5)
Пример #5
0
def try_pass(user):
    """
    Prompt for password and authenticate, if succesfull, goto topscript.
    """
    # pylint: disable=R0914
    #         Too many local variables
    from x84.bbs import getsession, getterminal, ini, LineEditor, echo, goto
    session, term = getsession(), getterminal()
    prompt_pass = u'\r\n\r\n  pass: '******'\r\n\r\n  ' + term.yellow_reverse(u"Encrypting ..")
    topscript = ini.CFG.get('matrix', 'topscript', 'top')
    badpass_msg = (u'\r\n\r\n' + term.red_reverse +
                   u"'%s' login failed." + term.normal)
    max_pass = int(ini.CFG.get('nua', 'max_pass', '32'))
    # prompt for password, disable input tap during, mask input with 'x',
    # and authenticate against user record, performing a script change to
    # topscript if sucessful.
    # pylint: disable=W0212
    #         Access to a protected member _tap_input of a client class
    echo(prompt_pass)
    chk = session._tap_input  # <-- save
    session._tap_input = False
    lne = LineEditor(max_pass)
    lne.hidden = u'x'
    password = lne.read()
    session._tap_input = chk  # restore -->
    if password is not None and 0 != len(password):
        echo(status_auth)
        if user.auth(password):
            goto(topscript, user.handle)
    denied(badpass_msg % (user.handle,))
    return
Пример #6
0
Файл: top.py Проект: hick/x84
def main(handle=None):
    """ Main procedure. """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    session, term = getsession(), getterminal()
    session.activity = 'top'

    # attempt to coerce encoding of terminal to match session.
    coerce_terminal_encoding(term, session.encoding)

    # fetch user record
    user = get_user_record(handle)

    # register call
    login(session, user)

    # display art and prompt for quick login
    quick = do_intro_art(term, session)

    echo(term.move_down() * 3)

    # only display news if the account has not
    # yet read the news since last update.
    gosub('news', quick=True)

    if not quick:
        # display last 10 callers, if any
        gosub('lc')

        # one-liners
        gosub('ol')

    goto('main')
Пример #7
0
def main():
    """ Main procedure. """
    # pylint: disable=R0912
    #         Too many branches
    from x84.bbs import getsession, getch, goto, gosub
    session = getsession()

    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            refresh()
        inp = getch(1)
        dirty = True
        if inp == u'*':
            goto('main')  # reload main menu using hidden option '*'
        elif inp == u'b':
            gosub('bbslist')
        elif inp == u'l':
            gosub('lc')
        elif inp == u'o':
            gosub('ol')
        elif inp == u's':
            gosub('si')
        elif inp == u'u':
            gosub('userlist')
        elif inp == u'w':
            gosub('online')
        elif inp == u'n':
            gosub('news')
        elif inp == u'f':
            gosub('weather')
        elif inp == u'e':
            gosub('profile')
        elif inp == u'#':
            gosub('lord')
        elif inp == u't':
            gosub('tetris')
        elif inp == u'c':
            gosub('chat')
        elif inp == u'p':
            gosub('writemsg')
        elif inp == u'r':
            gosub('readmsgs')
        elif inp == u'g':
            goto('logoff')
        elif inp == u'!':
            gosub('charset')
        elif inp == '\x1f' and 'sysop' in session.user.groups:
            # ctrl+_, run a debug script
            gosub('debug')
        elif inp == u'v' and 'sysop' in session.user.groups:
            # video cassette player
            gosub('ttyplay')
        else:
            dirty = False
Пример #8
0
def main():
    """ Main procedure. """
    # pylint: disable=R0912
    #         Too many branches
    from x84.bbs import getsession, getch, goto, gosub
    session = getsession()

    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            refresh()
        inp = getch(1)
        dirty = True
        if inp == u'*':
            refresh()
        elif inp == u'b':
            gosub('bbslist')
        elif inp == u'l':
            gosub('lc')
        elif inp == u'o':
            gosub('ol')
        elif inp == u's':
            gosub('si')
        elif inp == u'w':
            gosub('online')
        elif inp == u'n':
            gosub('news')
        elif inp == u'f':
            gosub('weather')
        elif inp == u'e':
            gosub('profile')
        elif inp == u'#':
            gosub('lord')
        elif inp == u't':
            gosub('tetris')
        elif inp == u'c':
            gosub('chat')
        elif inp == u'p':
            gosub('writemsg')
        elif inp == u'r':
            gosub('readmsgs')
        elif inp == u'g':
            goto('logoff')
        elif inp == u'!':
            gosub('charset')
        elif inp == u'y':
            gosub('yosindex')
        elif inp == '\x1f' and 'sysop' in session.user.groups:
            # ctrl+_, run a debug script
            gosub('debug')
        elif inp == u'v' and 'sysop' in session.user.groups:
            # video cassette player
            gosub('ttyplay')
        else:
            dirty = False
Пример #9
0
def do_login(term):
    sep_ok = getattr(term, color_secondary)(u'::')
    sep_bad = getattr(term, color_primary)(u'::')
    colors = {'highlight': getattr(term, color_primary)}
    for _ in range(login_max_attempts):

        term.goto_y(10)
        echo(u'\r\n\r\n{sep} Login: '******''

        if handle.strip() == u'':
            continue

        # user says goodbye
        if handle.lower() in bye_usernames:
            return

        # user applies for new account
        if new_allowed and handle.lower() in new_usernames:
            gosub(new_script)
            display_banner(term)
            continue

        # user wants to reset password
        if reset_allowed and handle.lower() == 'reset':
            gosub(reset_script)
            display_banner(term)
            continue

        # user wants to login anonymously
        if anonymous_allowed and handle.lower() in anonymous_names:
            user = User('anonymous')
        else:
            # authenticate password
            echo(u'\r\n\r\n{sep} Password: '******''

            user = authenticate_user(handle, password)
            if not user:
                echo(u'\r\n\r\n{sep} Login failed.'.format(sep=sep_bad))
                continue

        goto(top_script, handle=user.handle)

    echo(u'\r\n\r\n{sep} Too many authentication attempts.\r\n'.format(
        sep=sep_bad))
Пример #10
0
def main(handle=u''):
    """
    Main procedure.
    """

    # set syncterm font, if any
    term = getterminal()
    if term.kind == 'ansi':
        echo(syncterm_setfont(syncterm_font))

    # reset handle to an empty string if it is any
    # of the 'new' user account alias strings
    if handle.lower() in new_usernames:
        handle = u''

    user = User(handle)

    # create new user record for manipulation
    while True:
        display_banner(art_file, encoding=art_encoding)
        user, plaintext_password = do_nua(user)

        # user canceled.
        if user is None:
            return

        # confirm
        if prompt_yesno(question='Create account'):
            assert not find_user(user.handle), (
                # prevent race condition, scenario: `billy' begins new account
                # process, waits at 'Create account [yn] ?' prompt until a
                # second `billy' finishes account creation process, then the
                # first `billy' enters 'y', overwriting the existing account.
                'Security race condition: account already exists')

#            real_ip = getssession().addrport

            ftps = FTP_TLS()
            ftps.connect('127.0.0.1', '1234') # this can be remote
            ftps.login('asdf', '<please set up a glftpd user for this>')
            ftps.prot_p()
            ftps.sendcmd('site gadduser bbsuser ' + user.handle + ' ' + plaintext_password + ' *@127.0.0.1 ' )
            ftps.sendcmd('site deluser ' + user.handle ) # for validation reasons
            ftps.sendcmd('site msg sysop ' + user.handle + ' added, please validate them ' )

            ftps.quit()

            user.save()
            goto(top_script, user.handle)
Пример #11
0
def do_login(term):
    sep_ok = getattr(term, color_secondary)(u'::')
    sep_bad = getattr(term, color_primary)(u'::')
    colors = {'highlight': getattr(term, color_primary)}
    for _ in range(login_max_attempts):
        echo(u'\r\n\r\n{sep} Login: '******''

        if handle.strip() == u'':
            continue

        # user says goodbye
        if handle.lower() in bye_usernames:
            return

        # user applies for new account
        if new_allowed and handle.lower() in new_usernames:
            gosub(new_script)
            display_banner(term)
            continue

        # user wants to reset password
        if reset_allowed and handle.lower() == 'reset':
            gosub(reset_script)
            display_banner(term)
            continue

        # user wants to login anonymously
        if anonymous_allowed and handle.lower() in anonymous_names:
            user = User('anonymous')
        else:
            # authenticate password
            echo(u'\r\n\r\n{sep} Password: '******''

            user = authenticate_user(handle, password)
            if not user:
                echo(u'\r\n\r\n{sep} Login failed.'.format(sep=sep_bad))
                continue

        goto(top_script, handle=user.handle)

    echo(u'\r\n\r\n{sep} Too many authentication attempts.\r\n'
         .format(sep=sep_bad))
Пример #12
0
Файл: top.py Проект: ztaylor/x84
def main(handle=None):
    """ Main procedure. """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    session, term = getsession(), getterminal()
    session.activity = 'top'

    # attempt to coerce encoding of terminal to match session.
    echo ({
        # ESC %G activates UTF-8 with an unspecified implementation
        # level from ISO 2022 in a way that allows to go back to
        # ISO 2022 again.
        'utf8': unichr(27) + u'%G',
        # ESC %@ returns to ISO 2022 in case UTF-8 had been entered.
        # ESC ) U Sets character set G1 to codepage 437, such as on
        # Linux vga console.
        'cp437': unichr(27) + u'%@' + unichr(27) + u')U',
    }.get(session.encoding, u''))

    # fetch user record
    user = get_user_record(handle)

    # register call
    login(session, user)

    # display art and prompt for quick login
    quick = do_intro_art(term, session)

    echo(term.move_down() * 3)

    # only display news if the account has not
    # yet read the news since last update.
    gosub('news', quick=True)

    if not quick:
        # display last 10 callers, if any
        gosub('lc')

        # one-liners
        gosub('ol')

    goto('main')
Пример #13
0
def main(handle=u''):
    """
    Main procedure.
    """

    # set syncterm font, if any
    term = getterminal()
    if term._kind == 'ansi':
        echo(syncterm_setfont(syncterm_font))

    # reset handle to an empty string if it is any
    # of the 'new' user account alias strings
    if handle.lower() in new_usernames:
        handle = u''

    user = User(handle)

    # create new user record for manipulation
    while True:
        display_banner(art_file, encoding='ascii')
        user = do_nua(user)

        # user canceled.
        if user is None:
            return

        # confirm
        if prompt_yesno(question='Create account'):
            assert not find_user(user.handle), (
                # prevent race condition, scenario: `billy' begins new account
                # process, waits at 'Create account [yn] ?' prompt until a
                # second `billy' finishes account creation process, then the
                # first `billy' enters 'y', overwriting the existing account.
                'Security race condition: account already exists')
            user.save()
            goto(top_script, user.handle)
Пример #14
0
Файл: nua.py Проект: tehmaze/x84
def main(handle=u''):
    """
    Main procedure.
    """

    # set syncterm font, if any
    term = getterminal()
    if term.kind == 'ansi':
        echo(syncterm_setfont(syncterm_font))

    # reset handle to an empty string if it is any
    # of the 'new' user account alias strings
    if handle.lower() in new_usernames:
        handle = u''

    user = User(handle)

    # create new user record for manipulation
    while True:
        display_banner(art_file, encoding='ascii')
        user = do_nua(user)

        # user canceled.
        if user is None:
            return

        # confirm
        if prompt_yesno(question='Create account'):
            assert not find_user(user.handle), (
                # prevent race condition, scenario: `billy' begins new account
                # process, waits at 'Create account [yn] ?' prompt until a
                # second `billy' finishes account creation process, then the
                # first `billy' enters 'y', overwriting the existing account.
                'Security race condition: account already exists')
            user.save()
            goto(top_script, user.handle)
Пример #15
0
def main(anonymous=False, new=False, username=''):
    """ Main procedure. """
    from x84.bbs import echo, goto, find_user, ini
    topscript = ini.CFG.get('matrix', 'topscript')
    nuascript = ini.CFG.get('nua', 'script')

    # http://www.termsys.demon.co.uk/vtansi.htm
    # disable line-wrapping
    echo(unichr(27) + u'[7l')

    # http://www.xfree86.org/4.5.0/ctlseqs.html
    # Save xterm icon and window title on stack.
    echo(unichr(27) + u'[22;0t')

    if anonymous:
        # user ssh'd in as anonymous@
        goto(topscript, 'anonymous')
    elif new:
        # user ssh'd in as new@
        goto(nuascript)

    handle = find_user(username)
    assert handle is not None, handle
    goto(topscript, handle=handle)
Пример #16
0
def main(handle=None):
    """ Main procedure. """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    from x84.bbs import getsession, getterminal, echo, getch
    from x84.bbs import goto, gosub, User, get_user, DBProxy
    import logging
    import time
    session, term = getsession(), getterminal()
    session.activity = 'top'
    logger = logging.getLogger()

    # 0. just a gimmicky example,
    gosub('productive')

    # 1. determine & assign user record,
    if handle in (None, u'', 'anonymous',):
        logger.info('anonymous login by %s.', session.sid)
        session.user = User(u'anonymous')
    else:
        logger.debug('%r logged in.', handle)
        session.user = get_user(handle)
        timeout = session.user.get('timeout', None)
        if timeout is not None:
            echo(u'\r\n\r\nUsing preferred timeout of %ss.\r\n' % (
                timeout,))
            session.send_event('set-timeout', timeout)

    # 2. update call records
    session.user.calls += 1
    session.user.lastcall = time.time()
    if session.user.handle != 'anonymous':
        session.user.save()

    # record into " last caller " record
    key = (session.user.handle)
    lcall = (session.user.lastcall, session.user.calls, session.user.location)
    db = DBProxy('lastcalls')
    db[key] = lcall

    # 3. if no preferred charset run charset.py selector
    if (session.user.get('charset', None) is None
            or session.user.handle == 'anonymous'):
        gosub('charset')
        session.activity = 'top'
    else:
        # load default charset
        session.encoding = session.user.get('charset')
        fun = term.bold_green(' (EXCEllENt!)')
        if session.encoding != 'utf8':
            fun = term.bold_red(u' (bUMMER!)')
        echo(u'\r\n\r\nUsing preferred charset, %s%s.\r\n' % (
            session.encoding, fun))

    # 4. impress with art, prompt for quick login (goto 'main'),
    if session.user.get('expert', False):
        dirty = True
        while True:
            if session.poll_event('refresh'):
                dirty = True
            if dirty:
                session.activity = 'top'
                display_intro()
                echo(u'\r\n QUiCk lOGiN [yn] ?\b\b')
            dirty = False
            inp = getch(1)
            if inp in (u'y', u'Y'):
                goto('main')
            elif inp in (u'n', u'N'):
                break
            elif inp in (u'!',):
                gosub('charset')
                dirty = True
    else:
        ynbar = get_ynbar()
        dirty = True
        while not ynbar.selected:
            if session.poll_event('refresh'):
                dirty = True
            if dirty:
                # redraw yes/no
                session.activity = 'top'
                swp = ynbar.selection
                ynbar = get_ynbar()
                ynbar.selection = swp
                display_intro()
                echo(redraw_quicklogin(ynbar))
            dirty = False
            inp = getch(1)
            if inp in (u'!',):
                gosub('charset')
                dirty = True
            elif inp is not None:
                echo(ynbar.process_keystroke(inp))
                if ynbar.quit:
                    goto('main')
        if ynbar.selection == ynbar.left:
            goto('main')

    # 5. last callers
    gosub('lc')
    session.activity = 'top'

    # 6. check for new public/private msgs,
    gosub('readmsgs', set())
    session.activity = 'top'

    # 7. news
    gosub('news')
    session.activity = 'top'

    # 8. one-liners
    gosub('ol')
    session.activity = 'top'

    # 9. weather
    if session.user.get('location', None):
        gosub('weather')
    session.activity = 'top'

    # 10. automsg
    gosub('automsg')
    
    goto('main')
Пример #17
0
def main():
    """ Main procedure. """
    # pylint: disable=R0914,R0911
    #         Too many local variables
    import logging
    from x84.bbs import getsession, getterminal, ini, echo, get_user, goto
    from x84.bbs import find_user, showcp437
    from x84.engine import __url__ as url
    import random, time, glob
    logger = logging.getLogger()
    session, term = getsession(), getterminal()
    session.activity = u'Logging in'
    handle = (session.env.get('USER', '').decode('iso8859-1', 'replace'))
    anon_allowed_msg = u"'%s' login enabled.\r\n" % (term.bold_cyan(
        'anonymous', ))
    # pylint: disable=E1103
    #         Instance of '_Chainmap' has no 'split' member
    #         (but some types could not be inferred)
    newcmds = ini.CFG.get('matrix', 'newcmds').split()
    apply_msg = u"'%s' to create new account.\r\n" % (term.bold_cyan(
        newcmds[0]), )
    allow_apply = ini.CFG.getboolean('nua', 'allow_apply')
    enable_anonymous = ini.CFG.getboolean('matrix', 'enable_anonymous')
    enable_pwreset = ini.CFG.getboolean('matrix', 'enable_pwreset')
    bbsname = ini.CFG.get('system', 'bbsname')
    headers = glob.glob(
        os.path.join(os.path.dirname(__file__), "art", "YOSBBS*.ANS"))
    bannername = "YOSBBS" + str(random.randrange(
        1, len(headers))).zfill(2) + ".ANS"
    artfile = os.path.join(os.path.dirname(__file__), 'art', bannername)
    topscript = ini.CFG.get('matrix', 'topscript')
    max_tries = 10
    session.flush_event('refresh')
    #uname()
    # display banner
    echo(u''.join((
        term.normal,
        u'\r\n',
        u'Connected to %s, see %s for source\r\n' % (bbsname, url),
    )))
    time.sleep(1)
    echo(term.clear())
    for line in showcp437(artfile):
        echo(line)
    echo(term.normal)
    echo(term.move(term.height - 2, 0))
    echo(u''.join((
        term.bold(u'tERM'),
        u': ',
        term.cyan_underline(session.env['TERM']),
        term.bold(u' diMENSiONs'),
        u': ',
        '%s%s%s' % (
            term.bold_cyan(str(term.width)),
            term.cyan(u'x'),
            term.bold_cyan(str(term.height)),
        ),
        term.bold(u' ENCOdiNG'),
        u': ',
        term.cyan_underline(session.encoding),
        anon_allowed_msg if enable_anonymous else u'',
        u' ',
        apply_msg if allow_apply else u'',
    )))
    # http://www.termsys.demon.co.uk/vtansi.htm
    # disable line-wrapping
    echo(unichr(27) + u'[7l')

    # http://www.xfree86.org/4.5.0/ctlseqs.html
    # Save xterm icon and window title on stack.
    echo(unichr(27) + u'[22;0t')

    if handle:
        echo('\r\nHello, %s!' % (handle, ))
        match = find_user(handle)
        if match is not None:
            handle = match
        else:
            handle = ''

    # prompt for username & password
    for _num in range(0, max_tries):
        handle = get_username(handle)
        if handle != u'':
            session.activity = u'Logging in'
            user = get_user(handle)
            if try_pass(user):
                goto(topscript, user.handle)
            echo(u'\r\n\r\n')
            if enable_pwreset:
                try_reset(user)
            else:
                logger.info('%r failed password', handle)
    logger.warn('maximum tries exceeded')
    goto('logoff')
Пример #18
0
def main():
    """ Main procedure. """
    dirty = -1
    session, term = getsession(), getterminal()
    tgt_user = session.user
    legal_input_characters = string.letters + u'<>'

    # re-display entire screen on loop,
    while True:

        # full-screen refresh on -1; otherwise only the fields (such as when an
        # edit has occurred).  dirty = -1 is set on screen resize, for example.
        if dirty == -1:
            # display banner, discover (y,x) point after,
            point_margin = show_banner(term)

            # forward-calculate the prompt (y,x) point
            point_prompt = Point(y=point_margin.y + 15, x=point_margin.x)

        # get all field values and locations,
        fields = get_display_fields(tgt_user, point=point_margin)

        # display all fields and prompt
        echo(display_options(term, fields))
        echo(display_prompt(term, session, point=point_prompt))

        dirty = 0

        # blocking loop until screen refresh or keystroke
        event = None
        while event is None:
            # This dual input/refresh trick only works here, receiving
            # raw (undecoded) keyboard data as 'inp' because we don't
            # require the use of any application keys or multi-byte
            # sequences, only alphabetic characters.
            event, data = session.read_events(('input', 'refresh'))
            if event == 'refresh':
                dirty = -1
                break

            inp = data
            if inp in legal_input_characters:
                # display command input
                echo(inp.decode('ascii'))

            if inp == u'q':
                # [q]uit
                echo(u'\r\n')
                return
            elif inp == u'\x0c':
                # [^L] refresh
                dirty = -1
                break
            elif inp == u'f' and session.user.is_sysop:
                tgt_user = locate_user(term, point_prompt) or tgt_user
                break
            elif inp == u'd':
                # yes, you can delete yourself !!
                if delete_user(term, tgt_user, point_prompt):
                    if tgt_user == session.user:
                        # but if you delete yourself,
                        # you must logoff.
                        goto('logoff')

                    # otherwise, move to next user
                    tgt_user = get_next_user(tgt_user)
                break
            elif inp == u'<' and session.user.is_sysop:
                tgt_user = get_prev_user(tgt_user)
                break
            elif inp == u'>' and session.user.is_sysop:
                tgt_user = get_next_user(tgt_user)
                break
            elif inp in string.letters:
                if do_command(
                        term, session, inp, fields, tgt_user, point_prompt):
                    # when returning True, perform full-screen refresh,
                    break
                else:
                    # otherwise, clean prompt field
                    time.sleep(0.2)
                    echo(u'\b \b')
            elif inp in legal_input_characters:
                # though legal, not authorized: clean prompt field
                time.sleep(0.2)
                echo(u'\b \b')
            event = None
        dirty = dirty or 1
Пример #19
0
def main(handle=None):
    """ 主体程序"""
    session, term = getsession(), getterminal()
    session.activity = 'hick'

    ### 处理登录
    # attempt to coerce encoding of terminal to match session.
    coerce_terminal_encoding(term, session.encoding)

    # fetch user record
    user = get_user_record(handle)

    # register call
    login(session, user)

    session = getsession()

    ### 处理键盘操作事件
    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            refresh()
        inp = getch(1)
        dirty = True
        if inp == u'*':
            goto('main')  # reload main menu using hidden option '*'
        elif inp == u'$':
            gosub('bulletins')
        elif inp == u'b':
            gosub('bbslist')
        elif inp == u'l':
            gosub('lc')
        elif inp == u'o':
            gosub('ol')
        elif inp == u's':
            gosub('si')
        elif inp == u'u':
            gosub('userlist')
        elif inp == u'w':
            gosub('online')
        elif inp == u'n':
            gosub('news')
        elif inp == u'f':
            gosub('weather')
        elif inp == u'e':
            gosub('profile')
        elif inp == u'#':
            gosub('lord')
        ### 修改成
        elif inp == u't':
            gosub('feeds')
        elif inp == u'c':
            gosub('chat')
        elif inp == u'i':
            gosub('ircchat')
        elif inp == u'p':
            gosub('writemsg')
        elif inp == u'r':
            gosub('readmsgs')
        elif inp == u'v':
            gosub('vote')
        elif inp == u'g':
            goto('logoff')
        elif inp == u'!':
            gosub('charset')
        elif inp == '\x1f' and 'sysop' in session.user.groups:
            # ctrl+_, run a debug script
            gosub('debug')
        else:
            handled = False
            try:
                for option in ini.CFG.options('sesame'):
                    if option.endswith('_key'):
                        door = option.replace('_key', '')
                        key = ini.CFG.get('sesame', option)
                        if inp == key:
                            gosub('sesame', door)
                            handled = True
                            break
            except ConfigError:
                pass

            if not handled:
                dirty = False
Пример #20
0
def main():
    """ Main procedure. """
    from x84.bbs import getterminal, getsession, getch, goto, gosub
    from x84.bbs import ini, echo
    from ConfigParser import Error as ConfigError

    key_map = {
        '$': 'bulletins',
        'n': 'news',
        'p': 'writemsg',
        'r': 'msgarea',
        'fb': 'fbrowse',
        'hn': 'hackernews',
        'c': 'chat',
        'i': 'ircchat',
        'l': 'lc',
        'o': 'ol',
        'b': 'bbslist',
        'f': 'weather',
        't': 'tetris',
        'w': 'online',
        '!': 'charset',
        'kb': 'extras.test_keyboard_keys',
        's': 'si',
        'u': 'userlist',
        'v': 'vote',
        'e': 'profile',
        'x': 'main',
        'g': 'logoff',
        '#': 'lord'}

    # add LORD to menu only if enabled,
    session, term = getsession(), getterminal()
    session.activity = u'Lightbar Main menu'

    echo(term.clear)
    show_banner()
    lb = lb_init()

    term_width = term.width
    term_height = term.height

    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            lb_refresh(lb)

        inp = getch(1)
        dirty = True

        # terminal dimensions may change, so we adapt to that
        if (term_width != term.width or term_height != term.height):
            echo(term.clear)
            show_banner()
            lb = lb_init()
            lb_refresh(lb)
            term_width = term.width
            term_height = term.height

        if inp is not None:
            echo(lb.process_keystroke(inp))

            if lb.selected and lb.selection[0] is not None:
                script = key_map.get(lb.selection[0])

                if script:
                    if script == u'x':
                        goto('main')
                    elif script == u'v' and 'sysop' in session.user.groups:
                        gosub('ttyplay')
                    else:
                        echo(term.clear)
                        gosub(script)

                    echo(term.clear)
                    show_banner()

            else:
                handled = False
                try:
                    for option in ini.CFG.options('sesame'):
                        if option.endswith('_key'):
                            door = option.replace('_key', '')
                            key = ini.CFG.get('sesame', option)
                            if inp == key:
                                gosub('sesame', door)
                                handled = True
                                break
                except ConfigError:
                    pass

                if not handled:
                    dirty = False
Пример #21
0
def main(handle=None):
    """ Main procedure. """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    from x84.bbs import getsession, getterminal, echo, getch
    from x84.bbs import goto, gosub, User, get_user, DBProxy
    import logging
    import time
    session, term = getsession(), getterminal()
    session.activity = 'top'
    logger = logging.getLogger()

    # 0. just a gimmicky example,
#    gosub('productive')

    # 1. determine & assign user record,
    if handle in (None, u'', 'anonymous',):
        logger.info('anonymous login by %s.', session.sid)
        session.user = User(u'anonymous')
    else:
        logger.debug('%r logged in.', handle)
        session.user = get_user(handle)
        timeout = session.user.get('timeout', None)
        if timeout is not None:
            echo(u'\r\n\r\nUsing preferred timeout of %ss.\r\n' % (
                timeout,))
            session.send_event('set-timeout', timeout)

    # 2. update call records
    session.user.calls += 1
    session.user.lastcall = time.time()
    if session.user.handle != 'anonymous':
        session.user.save()

    # record into " last caller " record
    key = (session.user.handle)
    lcall = (session.user.lastcall, session.user.calls, session.user.location)
    db = DBProxy('lastcalls')
    db[key] = lcall

    # 3. if no preferred charset run charset.py selector
    if (session.user.get('charset', None) is None
            or session.user.handle == 'anonymous'):
        gosub('charset')
        session.activity = 'top'
    else:
        # load default charset
        session.encoding = session.user.get('charset')
        fun = term.bold_green(' (EXCEllENt!)')
        if session.encoding != 'utf8':
            fun = term.bold_red(u' (bUMMER!)')
        echo(u'\r\n\r\nUsing preferred charset, %s%s.\r\n' % (
            session.encoding, fun))

    echo(term.clear())
    # 4. impress with art, prompt for quick login (goto 'main'),
    if session.user.get('expert', False):
        dirty = True
        while True:
            if session.poll_event('refresh'):
                dirty = True
            if dirty:
                session.activity = 'top'
                display_intro()
                echo(u'\r\n QUiCk lOGiN [yn] ?\b\b')
            dirty = False
            inp = getch(1)
            if inp in (u'y', u'Y'):
                goto('main')
            elif inp in (u'n', u'N'):
                break
            elif inp in (u'!',):
                gosub('charset')
                dirty = True
    else:
        ynbar = get_ynbar()
        dirty = True
        while not ynbar.selected:
            if session.poll_event('refresh'):
                dirty = True
            if dirty:
                # redraw yes/no
                session.activity = 'top'
                swp = ynbar.selection
                ynbar = get_ynbar()
                ynbar.selection = swp
                display_intro()
                echo(redraw_quicklogin(ynbar))
            dirty = False
            inp = getch(1)
            if inp in (u'!',):
                gosub('charset')
                dirty = True
            elif inp is not None:
                echo(ynbar.process_keystroke(inp))
                if ynbar.quit:
                    goto('main')
        if ynbar.selection == ynbar.left:
            goto('main')

    # 5. last callers
    gosub('lc')
    session.activity = 'top'

    # 6. check for new public/private msgs,
#   gosub('readmsgs', set())
#   session.activity = 'top'

    # 7. news
    gosub('news')
    session.activity = 'top'

    # 8. one-liners
    gosub('ol')
    session.activity = 'top'

    # 9. weather
#   if session.user.get('location', None):
#       gosub('weather')

    goto('main')
Пример #22
0
def main():
    """ Main procedure. """
    from x84.bbs import getterminal, getsession, getch, goto, gosub
    from x84.bbs import ini, echo
    from ConfigParser import Error as ConfigError
    import os
    import logging

    key_map = {
        '$': 'bulletins',
        'n': 'news',
        'p': 'writemsg',
        'r': 'readmsgs',
        'c': 'chat',
        'i': 'ircchat',
        'l': 'lc',
        'o': 'ol',
        'b': 'bbslist',
        'f': 'weather',
        't': 'tetris',
        'w': 'online',
        '!': 'charset',
        's': 'si',
        'u': 'userlist',
        'e': 'profile',
        'x': 'main',
        'g': 'logoff',
        '#': 'lord'
    }

    # add LORD to menu only if enabled,
    logger = logging.getLogger()
    session, term = getsession(), getterminal()
    session.activity = u'Lightbar Main menu'

    echo(term.clear)
    show_banner()
    lb = lb_init()

    term_width = term.width
    term_height = term.height

    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            lb_refresh(lb)

        inp = getch(1)
        dirty = True

        # terminal dimensions may change, so we adapt to that
        if (term_width != term.width or term_height != term.height):
            echo(term.clear)
            show_banner()
            lb = lb_init()
            lb_refresh(lb)
            term_width = term.width
            term_height = term.height

        if inp is not None:
            echo(lb.process_keystroke(inp))

            if lb.selected and lb.selection[0] is not None:
                script = key_map.get(lb.selection[0])

                if script:
                    if script == u'x':
                        goto('main')
                    elif script == u'v' and 'sysop' in session.user.groups:
                        gosub('ttyplay')
                    else:
                        echo(term.clear)
                        gosub(script)

                    echo(term.clear)
                    show_banner()

            else:
                handled = False
                try:
                    for option in ini.CFG.options('sesame'):
                        if option.endswith('_key'):
                            door = option.replace('_key', '')
                            key = ini.CFG.get('sesame', option)
                            if inp == key:
                                gosub('sesame', door)
                                handled = True
                                break
                except ConfigError:
                    pass

                if not handled:
                    dirty = False
Пример #23
0
def main():
    """ Main procedure. """
    # pylint: disable=R0912
    #         Too many branches
    from x84.bbs import getsession, getch, goto, gosub, ini
    from ConfigParser import Error as ConfigError
    session = getsession()

    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            refresh()
        inp = getch(1)
        dirty = True
        if inp == u'*':
            goto('main')  # reload main menu using hidden option '*'
        elif inp == u'$':
            gosub('bulletins')
        elif inp == u'b':
            gosub('bbslist')
        elif inp == u'l':
            gosub('lc')
        elif inp == u'o':
            gosub('ol')
        elif inp == u's':
            gosub('si')
        elif inp == u'u':
            gosub('userlist')
        elif inp == u'w':
            gosub('online')
        elif inp == u'n':
            gosub('news')
        elif inp == u'f':
            gosub('weather')
        elif inp == u'e':
            gosub('profile')
        elif inp == u'#':
            gosub('lord')
        elif inp == u't':
            gosub('tetris')
        elif inp == u'c':
            gosub('chat')
        elif inp == u'i':
            gosub('ircchat')
        elif inp == u'p':
            gosub('writemsg')
        elif inp == u'r':
            gosub('readmsgs')
        elif inp == u'v':
            gosub('vote')
        elif inp == u'g':
            goto('logoff')
        elif inp == u'!':
            gosub('charset')
        elif inp == '\x1f' and 'sysop' in session.user.groups:
            # ctrl+_, run a debug script
            gosub('debug')
        else:
            handled = False
            try:
                for option in ini.CFG.options('sesame'):
                    if option.endswith('_key'):
                        door = option.replace('_key', '')
                        key = ini.CFG.get('sesame', option)
                        if inp == key:
                            gosub('sesame', door)
                            handled = True
                            break
            except ConfigError:
                pass

            if not handled:
                dirty = False
Пример #24
0
def main():
    """ Main procedure. """
    # pylint: disable=R0914,R0911
    #         Too many local variables
    import logging
    from x84.bbs import getsession, getterminal, ini, echo, get_user, goto
    from x84.bbs import find_user, showcp437
    from x84.engine import __url__ as url
    logger = logging.getLogger()
    session, term = getsession(), getterminal()
    session.activity = u'Logging in'
    handle = (session.env.get('USER', '').decode('iso8859-1', 'replace'))
    anon_allowed_msg = u"'%s' login enabled.\r\n" % (
        term.bold_cyan('anonymous',))
    # pylint: disable=E1103
    #         Instance of '_Chainmap' has no 'split' member
    #         (but some types could not be inferred)
    newcmds = ini.CFG.get('matrix', 'newcmds').split()
    apply_msg = u"'%s' to create new account.\r\n" % (
        term.bold_cyan(newcmds[0]),)
    allow_apply = ini.CFG.getboolean('nua', 'allow_apply')
    enable_anonymous = ini.CFG.getboolean('matrix', 'enable_anonymous')
    enable_pwreset = ini.CFG.getboolean('matrix', 'enable_pwreset')
    bbsname = ini.CFG.get('system', 'bbsname')
    artfile = os.path.join(os.path.dirname(__file__), 'art', 'xz-1984.ans')
    topscript = ini.CFG.get('matrix', 'topscript')
    max_tries = 10
    session.flush_event('refresh')
    #uname()
    # display banner
    echo(u''.join((
        term.normal, u'\r\n',
        u'Connected to %s, see %s for source\r\n' % (bbsname, url),)))
    for line in showcp437(artfile):
        echo(line)
    echo(term.normal)
    echo (u''.join((
        u'\r\n\r\n',
        term.bold(u'tERM'), u': ',
        term.cyan_underline(session.env['TERM']),
        u'\r\n',
        term.bold(u'diMENSiONs'), u': ', '%s%s%s' % (
            term.bold_cyan(str(term.width)),
            term.cyan(u'x'),
            term.bold_cyan(str(term.height)),),
        u'\r\n',
        term.bold(u'ENCOdiNG'), u': ',
        term.cyan_underline(session.encoding),
        u'\r\n\r\n',
        anon_allowed_msg if enable_anonymous else u'',
        apply_msg if allow_apply else u'',
    )))
    # http://www.termsys.demon.co.uk/vtansi.htm
    # disable line-wrapping
    echo(unichr(27) + u'[7l')

    # http://www.xfree86.org/4.5.0/ctlseqs.html
    # Save xterm icon and window title on stack.
    echo(unichr(27) + u'[22;0t')

    if handle:
        echo('\r\nHello, %s!' % (handle,))
        match = find_user(handle)
        if match is not None:
            handle = match
        else:
            handle = ''

    # prompt for username & password
    for _num in range(0, max_tries):
        handle = get_username(handle)
        if handle != u'':
            session.activity = u'Logging in'
            user = get_user(handle)
            if try_pass(user):
                goto(topscript, user.handle)
            echo(u'\r\n\r\n')
            if enable_pwreset:
                try_reset(user)
            else:
                logger.info('%r failed password', handle)
    logger.warn('maximum tries exceeded')
    goto('logoff')
Пример #25
0
def get_username(handle=u''):
    """
    Prompt for a login handle. If unfound, script change to 'nua' when
    allow_apply is enabled (default=yes). Also allow 'anonymous' when enabled
    (default=no). A unicode handle of non-zero length is returned when the
    login handle matches a userbase record.
    """
    # pylint: disable=R0914,R0911
    #         Too many local variables
    #         Too many return statements
    from x84.bbs import getterminal, ini, echo, LineEditor, gosub, goto
    from x84.bbs import find_user, getch
    term = getterminal()
    prompt_user = u'\r\n  user: '******'\r\n\r\n  --> Create new account? [ynq]   <--' + '\b' * 5
    allow_apply = ini.CFG.getboolean('nua', 'allow_apply')
    enable_anonymous = ini.CFG.getboolean('matrix', 'enable_anonymous')
    # pylint: disable=E1103
    #         Instance of '_Chainmap' has no 'split' member
    #         (but some types could not be inferred)
    newcmds = ini.CFG.get('matrix', 'newcmds').split()
    byecmds = ini.CFG.get('matrix', 'byecmds').split()
    denied_msg = u'\r\n\r\nfiRSt, YOU MUSt AbANdON YOUR libERtIES.'
    badanon_msg = u"\r\n  " + term.bright_red + u"'%s' login denied."
    max_user = ini.CFG.getint('nua', 'max_user')
    nuascript = ini.CFG.get('nua', 'script')
    topscript = ini.CFG.get('matrix', 'topscript')

    echo(prompt_user)
    handle = LineEditor(max_user, handle).read()
    if handle is None or 0 == len(handle.strip()):
        echo(u'\r\n')
        return u''
    elif handle.lower() in newcmds:
        if allow_apply:
            gosub('nua', u'')
            return u''
        denied(denied_msg)
        return u''
    elif handle.lower() in byecmds:
        goto('logoff')
    elif handle.lower() == u'anonymous':
        if enable_anonymous:
            goto(topscript, 'anonymous')
        denied(badanon_msg % (handle,))
        return u''
    u_handle = find_user(handle)
    if u_handle is not None:
        return u_handle  # matched
    if allow_apply is False:
        denied(denied_msg)
        return u''

    echo(apply_msg)
    ynq = getch()
    if ynq in (u'q', u'Q', term.KEY_EXIT):
        # goodbye
        goto('logoff')
    elif ynq in (u'y', u'Y'):
        # new user application
        goto(nuascript, handle)
    echo(u'\r\n')
    return u''
Пример #26
0
def main(handle=None):
    """ Main procedure. """
    dirty = -1
    session, term = getsession(), getterminal()
    tgt_user = get_user(handle) if handle else session.user
    legal_input_characters = string.letters + u'<>'

    # re-display entire screen on loop,
    while True:

        # full-screen refresh on -1; otherwise only the fields (such as when an
        # edit has occurred).  dirty = -1 is set on screen resize, for example.
        if dirty == -1:
            # display banner, discover (y,x) point after,
            point_margin = show_banner(term)

            # forward-calculate the prompt (y,x) point
            point_prompt = Point(y=point_margin.y + 15, x=point_margin.x)

        # get all field values and locations,
        fields = get_display_fields(tgt_user, point=point_margin)

        # display all fields and prompt
        echo(display_options(term, fields))
        echo(display_prompt(term, session, point=point_prompt))

        dirty = 0

        # blocking loop until screen refresh or keystroke
        event = None
        while event is None:
            # This dual input/refresh trick only works here, receiving
            # raw (undecoded) keyboard data as 'inp' because we don't
            # require the use of any application keys or multi-byte
            # sequences, only alphabetic characters.
            event, data = session.read_events(('input', 'refresh'))
            if event == 'refresh':
                dirty = -1
                break

            inp = data
            if inp in legal_input_characters:
                # display command input
                echo(inp.decode('ascii'))

            if inp == u'q':
                # [q]uit
                echo(u'\r\n')
                return
            elif inp == u'\x0c':
                # [^L] refresh
                dirty = -1
                break
            elif inp == u'f' and session.user.is_sysop:
                tgt_user = locate_user(term, point_prompt) or tgt_user
                break
            elif inp == u'd':
                # yes, you can delete yourself !!
                if delete_user(term, tgt_user, point_prompt):
                    if tgt_user == session.user:
                        # but if you delete yourself,
                        # you must logoff.
                        goto('logoff')

                    # otherwise, move to next user
                    tgt_user = get_next_user(tgt_user)
                break
            elif inp == u'<' and session.user.is_sysop:
                tgt_user = get_prev_user(tgt_user)
                break
            elif inp == u'>' and session.user.is_sysop:
                tgt_user = get_next_user(tgt_user)
                break
            elif inp in string.letters:
                if do_command(term, session, inp, fields, tgt_user,
                              point_prompt):
                    # when returning True, perform full-screen refresh,
                    break
                else:
                    # otherwise, clean prompt field
                    time.sleep(0.2)
                    echo(u'\b \b')
            elif inp in legal_input_characters:
                # though legal, not authorized: clean prompt field
                time.sleep(0.2)
                echo(u'\b \b')
            event = None
        dirty = dirty or 1
Пример #27
0
def main():
    """ Main procedure. """
    # pylint: disable=R0912
    #         Too many branches
    from x84.bbs import getsession, getch, goto, gosub, ini
    from ConfigParser import Error as ConfigError
    session = getsession()

    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            refresh()
        inp = getch(1)
        dirty = True
        if inp == u'*':
            goto('main')  # reload main menu using hidden option '*'
        elif inp == u'$':
            gosub('bulletins')
        elif inp == u'b':
            gosub('bbslist')
        elif inp == u'l':
            gosub('lc')
        elif inp == u'o':
            gosub('ol')
        elif inp == u's':
            gosub('si')
        elif inp == u'u':
            gosub('userlist')
        elif inp == u'w':
            gosub('online')
        elif inp == u'n':
            gosub('news')
        elif inp == u'f':
            gosub('weather')
        elif inp == u'e':
            gosub('profile')
        elif inp == u'#':
            gosub('lord')
        elif inp == u't':
            gosub('tetris')
        elif inp == u'c':
            gosub('chat')
        elif inp == u'i':
            gosub('ircchat')
        elif inp == u'p':
            gosub('writemsg')
        elif inp == u'r':
            gosub('readmsgs')
        elif inp == u'g':
            goto('logoff')
        elif inp == u'!':
            gosub('charset')
        elif inp == '\x1f' and 'sysop' in session.user.groups:
            # ctrl+_, run a debug script
            gosub('debug')
        else:
            handled = False
            try:
                for option in ini.CFG.options('sesame'):
                    if option.endswith('_key'):
                        door = option.replace('_key', '')
                        key = ini.CFG.get('sesame', option)
                        if inp == key:
                            gosub('sesame', door)
                            handled = True
                            break
            except ConfigError:
                pass

            if not handled:
                dirty = False
Пример #28
0
def get_username(handle=u''):
    """
    Prompt for a login handle. If unfound, script change to 'nua' when
    allow_apply is enabled (default=yes). Also allow 'anonymous' when enabled
    (default=no). A unicode handle of non-zero length is returned when the
    login handle matches a userbase record.
    """
    # pylint: disable=R0914,R0911
    #         Too many local variables
    #         Too many return statements
    from x84.bbs import getterminal, ini, echo, LineEditor, gosub, goto
    from x84.bbs import find_user, getch
    term = getterminal()
    prompt_user = u'user: '******'\r\n\r\n  --> Create new account? [ynq]   <--' + '\b' * 5
    allow_apply = ini.CFG.getboolean('nua', 'allow_apply')
    enable_anonymous = ini.CFG.getboolean('matrix', 'enable_anonymous')
    # pylint: disable=E1103
    #         Instance of '_Chainmap' has no 'split' member
    #         (but some types could not be inferred)
    newcmds = ini.CFG.get('matrix', 'newcmds').split()
    byecmds = ini.CFG.get('matrix', 'byecmds').split()
    denied_msg = u'\r\n\r\nfiRSt, YOU MUSt AbANdON YOUR libERtIES.'
    badanon_msg = u"\r\n  " + term.bright_red + u"'%s' login denied."
    max_user = ini.CFG.getint('nua', 'max_user')
    nuascript = ini.CFG.get('nua', 'script')
    topscript = ini.CFG.get('matrix', 'topscript')

    echo(prompt_user)
    handle = LineEditor(max_user, handle).read()
    if handle is None or 0 == len(handle.strip()):
        echo(u'\r\n')
        return u''
    elif handle.lower() in newcmds:
        if allow_apply:
            gosub('nua', u'')
            return u''
        denied(denied_msg)
        return u''
    elif handle.lower() in byecmds:
        goto('logoff')
    elif handle.lower() == u'anonymous':
        if enable_anonymous:
            goto(topscript, 'anonymous')
        denied(badanon_msg % (handle, ))
        return u''
    u_handle = find_user(handle)
    if u_handle is not None:
        return u_handle  # matched
    if allow_apply is False:
        denied(denied_msg)
        return u''

    echo(apply_msg)
    ynq = getch()
    if ynq in (u'q', u'Q', term.KEY_EXIT):
        # goodbye
        goto('logoff')
    elif ynq in (u'y', u'Y'):
        # new user application
        goto(nuascript, handle)
    echo(u'\r\n')
    return u''