Sample code for 30+ languages & platforms
Visual FoxPro

SSH to a Cisco Switch - Processing "More" Responses

See more SSH Examples

Demonstrates connecting to a Cisco switch, entering privileged mode with the ena command, and running a command whose response is paged. Each page ends with --More-- and requires a SPACE character to request the next page.

Note: QuickShell allocates a PTY, which is what a network device console expects. The device presents an interactive prompt, and each command's output is read up to the next prompt.

Background: Paged output is the console equivalent of a pager like more, and a client must reproduce the keypress a human would make. Matching a set of patterns is what makes this tractable: each read ends either at the device prompt (output complete) or at --More-- (another page waiting), and the code branches accordingly. Note the prompt pattern includes the device name rather than a bare #, because that character also appears inside configuration text and would otherwise match far too early.

Chilkat Visual FoxPro Downloads

Visual FoxPro
LOCAL lnSuccess
LOCAL loSsh
LOCAL lnPort
LOCAL lcPassword
LOCAL lnChannelNum
LOCAL lnCaseSensitive
LOCAL lcReceived
LOCAL lcEnablePassword
LOCAL loSaMatch
LOCAL loSbReceived
LOCAL lnMoreComing
LOCAL lcPageText

lnSuccess = 0

*  This example requires the Chilkat API to have been previously unlocked.
*  See Global Unlock Sample for sample code.

*  Demonstrates connecting to a Cisco switch, entering privileged mode, and running a command
*  whose response is paged -- each page ends with "--More--" and requires a SPACE character to
*  request the next page.

loSsh = CreateObject('Chilkat.Ssh')

lnPort = 22
lnSuccess = loSsh.Connect("172.16.16.100",lnPort)
IF (lnSuccess = 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

*  Normally you would not hard-code the password in source.  You should instead obtain it
*  from an interactive prompt, environment variable, or a secrets vault.
lcPassword = "mySshPassword"

lnSuccess = loSsh.AuthenticatePw("mySshLogin",lcPassword)
IF (lnSuccess = 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

lnChannelNum = loSsh.QuickShell()
IF (lnChannelNum < 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

*  IMPORTANT: Set a read timeout before receiving until a match.  ReadTimeoutMs defaults to 0,
*  which means no limit -- without it, this call waits forever if the received data never
*  contains a match.
loSsh.ReadTimeoutMs = 15000

lnCaseSensitive = 1

*  In unprivileged mode the switch prompt ends with ">".
lnSuccess = loSsh.ChannelReceiveUntilMatch(lnChannelNum,">","utf-8",lnCaseSensitive)
IF (lnSuccess = 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

lcReceived = loSsh.GetReceivedText(lnChannelNum,"utf-8")
IF (loSsh.LastMethodSuccess = 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

? lcReceived

*  Send "ena" to enter privileged mode.  Cisco devices expect a bare CR to terminate a command.
lnSuccess = loSsh.ChannelSendString(lnChannelNum,"ena" + CHR(13),"utf-8")
IF (lnSuccess = 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

lnSuccess = loSsh.ChannelReceiveUntilMatch(lnChannelNum,"Password:","utf-8",lnCaseSensitive)
IF (lnSuccess = 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

lcReceived = loSsh.GetReceivedText(lnChannelNum,"utf-8")
IF (loSsh.LastMethodSuccess = 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

? lcReceived

*  The enable password is separate from the login password, and likewise should come from a
*  secure source rather than being hard-coded.
lcEnablePassword = "myEnablePassword"
lnSuccess = loSsh.ChannelSendString(lnChannelNum,lcEnablePassword,"utf-8")
IF (lnSuccess = 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

lnSuccess = loSsh.ChannelSendString(lnChannelNum,CHR(13),"utf-8")
IF (lnSuccess = 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

*  In privileged mode the prompt ends with "#" instead of ">".
lnSuccess = loSsh.ChannelReceiveUntilMatch(lnChannelNum,"#","utf-8",lnCaseSensitive)
IF (lnSuccess = 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

lcReceived = loSsh.GetReceivedText(lnChannelNum,"utf-8")
IF (loSsh.LastMethodSuccess = 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

? lcReceived

*  Run a command whose output is delivered a page at a time.
lnSuccess = loSsh.ChannelSendString(lnChannelNum,"show running-config" + CHR(13),"utf-8")
IF (lnSuccess = 0) THEN
    ? loSsh.LastErrorText
    RELEASE loSsh
    CANCEL
ENDIF

*  Each read ends either at the device prompt (output complete) or at "--More--" (another page
*  is waiting).  Match the full prompt rather than a bare "#", because "#" also appears inside
*  configuration text and would match too early.
loSaMatch = CreateObject('Chilkat.StringArray')
loSaMatch.Append("MySwitchName#")
loSaMatch.Append("--More--")

loSbReceived = CreateObject('Chilkat.StringBuilder')
lnMoreComing = 1

DO WHILE lnMoreComing
    lnSuccess = loSsh.ChannelReceiveUntilMatchN(lnChannelNum,loSaMatch,"utf-8",lnCaseSensitive)
    IF (lnSuccess = 0) THEN
        ? loSsh.LastErrorText
        RELEASE loSsh
        RELEASE loSaMatch
        RELEASE loSbReceived
        CANCEL
    ENDIF

    loSbReceived.Clear()
    lcPageText = loSsh.GetReceivedText(lnChannelNum,"utf-8")
    IF (loSsh.LastMethodSuccess = 0) THEN
        ? loSsh.LastErrorText
        RELEASE loSsh
        RELEASE loSaMatch
        RELEASE loSbReceived
        CANCEL
    ENDIF

    loSbReceived.Append(lcPageText)
    ? lcPageText

    *  If this page ended with "--More--", send a SPACE to request the next page.
    lnMoreComing = loSbReceived.Contains("--More--",lnCaseSensitive)
    IF (lnMoreComing) THEN
        lnSuccess = loSsh.ChannelSendString(lnChannelNum," ","utf-8")
        IF (lnSuccess = 0) THEN
            ? loSsh.LastErrorText
            RELEASE loSsh
            RELEASE loSaMatch
            RELEASE loSbReceived
            CANCEL
        ENDIF

    ENDIF

ENDDO

loSsh.Disconnect()

RELEASE loSsh
RELEASE loSaMatch
RELEASE loSbReceived