chat
is a general-purpose scripting language that is used to
control the modem, dial the remote server, and perform the remote system
login. chat
is less powerful than
dip
but is widely used. The
“expect/send” structure of a chat
script is the fundamental structure used in most scripting
languages.
A chat
script is composed of
expect/send pairs. These pairs consist of the string expected from the
remote system, separated by whitespace from the response that is sent to
the remote host when the expected string is received. If no string is
expected from the remote system, two quotes (""
) or two apostrophes (''
) are used to “expect nothing.” A simple
chat
script is:
"" \r name> jane word> TOga!toGA
The script expects nothing (""
)
until it sends the remote system a carriage return (\r). Then the script
expects the remote system to send the string name>
, which is part of the system’s
Username>
prompt. In response to
this prompt, the script sends the username jane
. Finally the script waits for part of the
Password>
prompt and responds with
TOga!toGA
. A script this simple can
be defined directly on the chat
command line:
% chat -v -t30 "" \r name> jane word> TOga!toGA
This command runs chat
in
verbose mode, sets the length of time the script waits for an expected
string to 30 seconds, and then executes the simple login script
described above.
The syntax of the chat
command
is:
chat [options
] [script
]
-e
Echo all output from the modem to stderr. This has the same
effect as using the ECHO keyword inside the chat
script.
-E
Enables the use of environment variables inside the chat
script.
-s
Send all log entries and all error messages to stderr.
-S
Do not send log messages or error messages to the SYSLOG.
-T
phone-number
Replace the \T escape sequence in the chat
script with the values specified
for phone-number
.
-U
phone-number-2
Replace the \U escape sequence in the chat
script with the value specified for
phone-number-2
.
-v
Runs the chat
script in
verbose mode. Verbose mode logs informational messages via
syslogd
.
-V
Runs the chat
script in
stderr verbose mode. The stderr verbose mode displays
informational messages on the stderr device. See Chapter 6 for an example of this being
used with pppd
.
-t
timeout
Sets the maximum time to wait for an expected string. If the
expected string is not received in
timeout
seconds, the reply string is
not sent and the script terminates—unless an alternate send is
defined. If defined, the alternate send (more about this later) is
sent and the remote system is given one more
timeout
period to respond. If this
fails, the script is terminated with a nonzero error code. By
default, the timeout period is 45 seconds.
-f
scriptfile
Reads the chat
script
from the scriptfile
instead of from the
command line. Multiple lines of expect/send pairs are permitted in
the file.
-r
reportfile
Writes the output generated by REPORT strings to the
reportfile
. By default, REPORT strings
are written to stderr. The REPORT keyword is covered below.
In order to make the scripts more useful and robust, chat
provides special keywords, escape
sequences, and alternate send/expect pairs that can be used in the
script. First let’s look at the six basic chat
keywords.
Two keywords transmit special signals to the remote system. The keyword EOT sends the End of Transmission character. On Unix systems, this is usually the End of File character, which is a Ctrl-D. The BREAK keyword sends a line break to the remote system. The five remaining keywords (TIMEOUT, ABORT, REPORT, CONNECT, and SAY) define processing characteristics for the script itself.
The TIMEOUT keyword defines the amount of time to wait for an
expected string. Because it is defined inside the script, the timeout
value can be changed for each expected string. For example, assume you
want to allow the remote server 30 seconds to display the initial
Username>
prompt but only 5
seconds to display Password>
once
the username has been sent. Enter this script command:
TIMEOUT 30 name> karen TIMEOUT 5 word> beach%PARTY
The ABORT keyword and the REPORT keyword are similar. They both define strings that,
when received, cause a special action to take place. The ABORT keyword
defines strings that cause the script to abort if they are received when
the system is expecting the string CONNECT from the modem. The REPORT
keyword defines substrings that determine what messages received on the
serial port should be written to stderr or the report file. A sample
chat
script file illustrates both of
these keywords:
REPORT CONNECT ABORT BUSY ABORT 'NO CARRIER' ABORT 'RING - NO ANSWER' SAY "Dialing your PPP server..." "" ATDT5551234 CONNECT \r name> karen word> beach%PARTY
The first line says that any message received by the script that
contains the word CONNECT will be logged. If the -r
command-line option was used when chat
was started, the message is logged in the
file defined by that option. Otherwise the message is displayed on
stderr. The point of this command is to display the modem’s connect
message to the user. For example, the complete message might be CONNECT 28,800 LAPM/V
, which tells the user
the link speed and the transmission protocol used by the modems. The
CONNECT message means success. The next three lines of the script begin
with the keyword ABORT and define the modem messages that mean failure.
If the modem responds with BUSY, NO CARRIER, or RING - NO ANSWER, the
script aborts.
The SAY keyword sends the specified string to the user’s terminal. In this case, we are telling the user that the dialing process has begun.
The last four lines are the basic expect/send pairs we have seen
repeatedly in this section. We expect nothing (""
) and send the dial command to the modem
(ATDT
). We expect CONNECT from the
modem and send a carriage return (\r
)
to the remote server. We expect Username>
from the remote server and send
karen
. Finally, we expect Password>
from the server and send beach%PARTY
.
chat
extends the standard
expect/send pair with an alternate send and an alternate expect to
improve robustness. You may define an alternate send string and an
alternate expect value to be used when the script times out waiting for
the primary expected value. The alternate send and the alternate expect
are indicated in the script by preceding them with dashes. For
example:
gin:-BREAK-gin: becca
In this sample we wait for the string gin:
and send the string becca
. The first string and the last string
compose the standard expect/send pair. The alternate send/expect is used
only if the timer expires and the expected gin:
string has not been received. When this
occurs, the script sends a line break, restarts the timer, and waits for
gin:
again, because that is what our
alternate send/expect pair (-BREAK-gin:
) tells the script to do. Note that
unlike the standard expect/send pair, in the send/expect pair a value is
transmitted before a string is expected, i.e., the send comes before the
expect. Another example more in keeping with our other script examples
is:
name>--name> karen
Here the script expects the name>
string. If it is not received, the
script sends an empty line, which is simply a carriage return, and again
waits for the name>
string. This
action is dictated by the alternate send/expect pair, --name>
. The pair begins with a dash that
signals the start of the send string, but the next character is the
second dash that marks the beginning of the alternate expect string.
There is no send string. It is this “empty string” that causes the
script to send a single return character. This example is more common
than the BREAK example shown above, though a little harder to
explain.
The carriage return character is not the only special character
that can be sent from a chat
script.
chat
provides several escape
sequences for sending and receiving special characters. Table A-2 lists these.
Table A-2. chat escape sequences
Escape sequence | Meaning |
---|---|
\b | The backspace character |
\ | Send without the terminating return character |
\d | Delay sending for one second |
\K | Send a BREAK |
\n | Send a newline character |
\N | Send a null character |
\ | Delay sending 1/10th of a second |
\xd5 | Send the string but don’t log it |
\r | The carriage return |
\s | The space character |
\T | Send the value provided on the chat command line by the -T argument |
\t | The tab character |
\U | Send the value provided on the chat command line by the -U argument |
\\ | The backslash character |
\ddd | The ASCII character with the octal value ddd |
^C | A control character |
All of the escape sequences start with a backslash (\) except for the sequence used to enter a control character. Control characters are entered as a caret (^) followed by an uppercase letter. For example, control X is entered as ^X. The escape sequences that are described in Table A-2 with the words “send” or “sending” can be used only in a send string; all others can be used in either a send or expect string. Several escape sequences are used in the following example:
"" \d\d^G\p^G\p\p^GWake\sUp!\nSleepy\sHead!
Expect nothing (""
). Wait two
seconds (\d\d
). Send three ASCII BELL
characters, which is Ctrl-G on the keyboard, at intervals of 1/10 of a
second (^G\p^G\p\p^G
). Send the
string Wake Up!
. Go to a new line
(\n
) and send the string Sleepy Head!
.
For security reasons, some servers call the client back before allowing the connection. This allows the server to verify that the client call is coming from an approved telephone number. It works this way:
The client calls the server and provides an identifying string.
The server hangs up after receiving the string.
The server uses the identifying string to find out the valid phone number for the client and calls the client back.
The client continues with the login process.
The fact that the server hangs up the connection could cause a
problem for a chat
script. Normally,
a hangup unconditionally ends the connection. chat
provides the HANGUP command to handle “callback” servers. The command
HANGUP OFF prevents chat
from ending
the login script when the server breaks the connection. Place the HANGUP
OFF command immediately after the command that sends the identifying
script to the server. After the server calls back and the connection is
established, use the HANGUP ON command to return to normal hangup
processing. HANGUP ON is the default. With HANGUP ON, the script
terminates when a hangup is detected.
When a chat script terminates, a termination code is set. A termination code is a numeric value that represents the state of the script when it exited. The basic numeric codes and what those codes mean is shown below:
The script terminated normally.
The script failed because of an invalid parameter or an expect string that overflowed the internal buffer.
The script shut down because of an I/O error or a termination signal (SIGINT/SIGTERM).
The program terminated because an expected string was not received before the timeout.
A condition defined by an ABORT command occurred. The numeric value indicates which condition occurred. The condition defined by the first ABORT command is assigned the value 4; the condition defined by the second ABORT command is assigned the value 5; the condition defined by the third ABORT command is assigned the value 6; and so on.
The termination codes 0 through 3 are self-explanatory. An example is useful for understanding the codes above 3.
The sample script shown earlier in this section contained three ABORT commands: the first one for the BUSY condition, the second one for the NO CARRIER condition, and the third one for the RING - NO ANSWER condition. If the modem returns the BUSY string, the script aborts and returns the termination code 4. If the modem returns the string RING - NO ANSWER, the script aborts and returns the termination code 6. The codes are “position dependent.” If another user rewrote this script and placed the ABORT RING - NO ANSWER command before the other ABORT commands, aborting on the RING - NO ANSWER condition would return a termination code of 4 instead of the 6 it returns in our script.