Section A.3. chat

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]

The chat command options are:

-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 terminatesunless 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:

0

The script terminated normally.

1

The script failed because of an invalid parameter or an expect string that overflowed the internal buffer.

2

The script shut down because of an I/O error or a termination signal (SIGINT/SIGTERM).

3

The program terminated because an expected string was not received before the timeout.

4 or more

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.