/*--------------------------------------------------------------------------*\
|  IgLouIAK.cmd                                                              |
|                                                                            |
|  PPP Login Script for IgLou and OS/2 Warp Internet Access Kit              |
|                                                                            |
|  Copy this script into C:\TCPIP\BIN. Modify the modem init strings for     |
|  your modem (the strings in the unmodified program are for a U.S. Robotics |
|  Sportster 28.8). In the "Dial Other Provider" program, enter the          |
|  following as your login sequence:                                         |
|                                                                            |
|    iglouiak.cmd atdt968-8228 <userid> <password> 15 25 24000               |
|                                                                            |
|  This gives you 25 redials with a 15-second pause in between attempts.     |
|  If the baud rate when connecting is less than 24000, the program will     |
|  hang up and redial. You can, of course, change the last three numbers.    |
|  Make sure there are no blank lines after this one-line command.           |
|                                                                            |
|  If you have questions about this script, please give me a holler...       |
|  Doug Happel, dhappel@iglou.com or 72772.323@compuserve.com                |
|                                                                            |
|  This program is freeware-- distribute freely                              |
\*--------------------------------------------------------------------------*/

PARSE ARG interface, ppp_com, ppp_cmd, dialcmd, userid, password, nRedialPause, nRedials, nMinBaud
SIGNAL ON Syntax

/*--------------------------------------------------------------------------*\
|  User-defined constants                                                    |
\*--------------------------------------------------------------------------*/
nMinBaudDefault = 14400
mdm_str. = ''
mdm_str.0 = 2   /* number of modem init strings */
mdm_str.1 = 'ATB0E1F1M3Q0V1X4&A3&B1&C1&D2'
mdm_str.2 = 'AT&H1&I0&K1&M4&N0&R2&S1S0=2'
hangupcmd = 'ATH0'
nBadBaudPause = 3
nRedialPauseDefault = 10
nRedialsDefault = 20
nMdmInitWait = 3
nMdmEscapeWait = 5
nMdmHangupWait = 15

/*--------------------------------------------------------------------------*\
|  Constants                                                                 |
\*--------------------------------------------------------------------------*/
cr='0d'x
crlf='0d0a'x
szPrompt_ID = 'gin:'
szPrompt_Password = 'sword:'
szPrompt_Service = 'ice:'
szService = 'PPP'

/*--------------------------------------------------------------------------*\
|  Initialization                                                            |
\*--------------------------------------------------------------------------*/
IF RxFuncQuery('SysLoadFuncs') <> 0 THEN DO
  rcy = RxFuncAdd('SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs')
  CALL Sysloadfuncs
  END
  
PARSE SOURCE . . szPgm
szPgm = FileSpec('Name', szPgm)

SAY ''
SAY 'IgLou - PPP Connection Script by (c) Doug Happel, 1995',
'(interface' interface')'

/*--------------------------------------------------------------------------*\
|  Check for missing information                                             |
\*--------------------------------------------------------------------------*/
IF dialcmd = '' | dialcmd = 'DIALCMD' THEN DO
  SAY szPgm || ': Dial command missing'
  EXIT -1
  END

IF userid = '' | userid = '*' | userid = 'USERID' THEN DO
  SAY szPgm || ': Userid missing'
  EXIT -1
  END
ELSE DO
  SAY szPgm || ': Userid:' userid
  END

IF password = '' | password = '*' | password = 'PASSWORD' THEN DO
  SAY szPgm || ': Password missing'
  EXIT -1
  END

IF nRedialPause = '' | nRedialPause = 'NREDIALPAUSE' THEN
  nRedialPause = nRedialPauseDefault
  
IF nRedials = '' | nRedials = 'NREDIALS' THEN
  nRedials = nRedialsDefault
  
IF nMinBaud = '' | nMinBaud = 'NMINBAUD' THEN
  nMinBaud = nMinBaudDefault

/*--------------------------------------------------------------------------*\
|  Flush any stuff left over from previous COM activity                      |
\*--------------------------------------------------------------------------*/
CALL FlushRcvBuf

/*--------------------------------------------------------------------------*\
|  Initialize the modem                                                      |
\*--------------------------------------------------------------------------*/
SAY szPgm || ': Initializing Modem...' || crlf
DO i = 1 TO mdm_str.0
  IF mdm_str.i \= '' THEN DO
    CALL Send mdm_str.i || cr
    rsp = WaitFor('OK', nMdmInitWait)
    IF rsp \= 1 THEN DO
      SAY szPgm || ': Modem not responding'
      EXIT -1
      END
    CALL FlushRcvBuf 'echo'
    END
  END i

/*--------------------------------------------------------------------------*\
|  Dial the remote server                                                    |
\*--------------------------------------------------------------------------*/
fSuccess = 0
nOrgRedials = nRedials
nRedials = nRedials + 1

DO WHILE nRedials > 0
  nRedials = nRedials - 1
  SAY szPgm || ': Dialing...(attempt nr.' nOrgRedials - nRedials + 1 ,
        || ' of' nOrgRedials || ')'
  CALL Send dialcmd || cr
  CALL FlushRcvBuf 'echo'
  rsp = WaitFor_m(2, 'CONNECT' || '00'x || 'BUSY')
  SELECT
    WHEN rsp = 1 THEN DO
      /*
       * We have connected, but make sure baud rate is acceptable.
       */
      baud_buffer = WaitFor_buffer
      CALL WaitFor crlf, 10
      baud_buffer = baud_buffer || WaitFor_buffer
      PARSE VAR baud_buffer . 'CONNECT ' nBaud '/' .
      SAY szPgm || ': Baud Rate is "' || nBaud || '"'
      IF Datatype(nBaud, 'N') = 0 THEN DO
        SAY szPgm || ': Non-numeric Baud Rate "' || nBaud || '".'
        CALL Hangup
        ITERATE
        END
      IF nBaud < nMinBaud THEN DO
        SAY szPgm || ': Unacceptable baud rate.'
        CALL Hangup
        ITERATE
        end
      fSuccess = 1
      LEAVE
      END
    WHEN rsp = 2 THEN DO
      SAY szPgm || ': Busy signal detected-- Redial in' nRedialPause 'seconds'
      CALL SysSleep nRedialPause
      END
    OTHERWISE DO
      SAY szPgm || ': Unable to connect'
      EXIT -1
      END
    END
  END

CALL FlushRcvBuf 'echo'

IF fSuccess = 0 THEN DO
  SAY szPgm || ': Unable to connect after' nOrgRedials 'attempts'
  EXIT -1
  END

/*--------------------------------------------------------------------------*\
|  Negotiate the login with IgLou.                                           |
\*--------------------------------------------------------------------------*/
CALL Send  cr
CALL WaitFor szPrompt_ID
CALL FlushRcvBuf 'echo'
CALL Send userid || cr
CALL WaitFor szPrompt_Password
CALL FlushRcvBuf 'echo'
CALL Send password || cr
CALL FlushRcvBuf 'echo'
CALL WaitFor szPrompt_Service
CALL FlushRcvBuf 'echo'
CALL Send szService || cr
CALL FlushRcvBuf 'echo'

/*--------------------------------------------------------------------------*\
|  Clean up and exit                                                         |
\*--------------------------------------------------------------------------*/
EXIT 0

/*--------------------------------------------------------------------------*\
|  Send ( sendstring )                                                       |
|                                                                            |
|  Send a string to the host.                                                |
\*--------------------------------------------------------------------------*/
Send:
  PARSE ARG sendstring
  CALL ppp_com_output interface , sendstring
  RETURN

/*--------------------------------------------------------------------------*\
|  WaitFor_m ( argcount, args, [timeout] )                                   |
|                                                                            |
|  waits for one of the specified strings to show up in the COM input. All   |
|  input from the time this function is called until one of the strings      |
|  shows up is accumulated in the "WaitFor_buffer" variable.                 |
|                                                                            |
|  the format of the "args" is a single string of all concatenated target    |
|  strings, separated by a single null character.                            |
|                                                                            |
|  If timeout is specified, it says how long to wait if data stops showing   |
|  up on the COM port (in seconds).                                          |
|                                                                            |
|  RETURNS: index of the string that was matched, or zero if no match.       |
\*--------------------------------------------------------------------------*/
WaitFor_m:

  PARSE ARG argcount, waitstring , timeout
  match = 0
  
  /*
   *  Pick off each target string
   */
  wf_idx = 1
  DO WHILE wf_idx < argcount
    PARSE VAR waitstring waits.wf_idx '00'x waitstring
    wf_idx = wf_idx + 1
    END
  waits.wf_idx = waitstring
  waits.0 = wf_idx
  
  IF timeout = '' THEN
    timeout = 5000    /* L O N G   delay IF not specified */
    
  WaitFor_buffer = ''
  done = -1
  curpos = 1
  ORI_TIME=TIME('E')
    
  IF (remain_buffer = 'REMAIN_BUFFER') THEN DO
    remain_buffer = ''
    END
  
  DO WHILE (done = -1)
    IF (remain_buffer \= '') THEN DO
      line = remain_buffer
      remain_buffer = ''
      END
    ELSE DO
      line = ppp_com_input(interface,,10)
      END
    WaitFor_buffer = WaitFor_buffer || line
    DO wf_idx = 1 TO waits.0
      index = Pos(waits.wf_idx, WaitFor_buffer)
      IF index > 0 THEN DO
        match = wf_idx
        LEAVE
        END
      END
    IF (index > 0) THEN DO
      remain_buffer = substr(WaitFor_buffer,index+length(waits.match))
      WaitFor_buffer = delstr(WaitFor_buffer,index+length(waits.match))
      done = 0
      END
    CALL charout , substr(WaitFor_buffer,curpos)
    x_val = '[' || C2X(substr(WaitFor_buffer,curpos)) || ']'
    curpos = length(WaitFor_buffer)+1
    IF ((done \= 0) & (TIME('E')>timeout)) THEN DO
      SAY szPgm || ': Timeout waiting for text'
      match = 0
      done = 0
      END
    END
  
  timeout=0
  RC=match
  RETURN RC

/*--------------------------------------------------------------------------*\
|  WaitFor ( waitstring, [timeout] )                                         |
|                                                                            |
|  Shorthand call to wait for a single string. Just calls WaitFor_m.         |
\*--------------------------------------------------------------------------*/
WaitFor:
  PARSE ARG waitstring , timeout
  rc2 = WaitFor_m(1, waitstring, timeout)
  RETURN rc2

/*--------------------------------------------------------------------------*\
|  FlushRcvBuf ()                                                            |
|                                                                            |
|  Routine to flush any pending characters to be read from the COM port.     |
|  Reads everything it can until nothing new shows up for 100ms, at which    |
|  point it returns.                                                         |
|                                                                            |
|  The optional echo argument, if 1, says to echo flushed information.       |
\*--------------------------------------------------------------------------*/
FlushRcvBuf:
  PARSE ARG echo
  /*
   *  If echo requested, display contents of WaitFor buffer.
   */
  IF (echo \= '') & (length(remain_buffer) > 0) THEN DO
    CALL charout , remain_buffer
    remain_buffer = ''
    END
  /*
   *  Eat anything left in the modem or COM buffers. Stop when nothing new
   *  appears for 100 ms.
   */
  DO UNTIL line = ''
    line = ppp_com_input(interface,,100)
    IF echo \= '' THEN
      CALL charout , line
    END
    
  RETURN

/*--------------------------------------------------------------------------*\
|  Hangup ()                                                                 |
|                                                                            |
|  Hang up after connection made with host.                                  |
\*--------------------------------------------------------------------------*/
Hangup:
  CALL Send '+++'
  rsp = WaitFor('OK', nMdmEscapeWait)
  CALL FlushRcvBuf 'echo'
  IF rsp \= 1 THEN DO
    SAY szPgm || ': Modem escape failure'
    EXIT -1
    END
  CALL send hangupcmd || cr
  rsp = WaitFor('OK', nMdmHangupWait)
  CALL FlushRcvBuf 'echo'
  IF rsp \= 1 THEN DO
    SAY szPgm || ': Modem hangup failure'
    EXIT -1
    END
  SAY szPgm || ': Connection terminated-- Redial in' nBadBaudPause 'seconds'
  CALL SysSleep nBadBaudPause
  RETURN

/*--------------------------------------------------------------------------*\
|  Syntax ()                                                                 |
|                                                                            |
|  Routine to trap syntax errors.                                            |
\*--------------------------------------------------------------------------*/
Syntax:
  err = rc
  SAY szPgm || ': Syntax error on line' sigl || ':'
  SAY SourceLine(sigl)
  SAY ErrorText(err)
  EXIT -1

