home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / DATABASE / COMET_MP.ZIP / TERMINAL.PRG < prev   
Encoding:
Text File  |  1991-02-06  |  15.1 KB  |  463 lines

  1. ****************************  TERMINAL.PRG  **********************************
  2. *
  3. * This version runs under:  FoxPro and  DbaseIV
  4. *                           -------------------
  5. *
  6. * This is a sample program which demonstrates a number of the COMETMP library
  7. * commands used to emulate a simple terminal program.
  8. *
  9. * Command keys while in TERMINAL:
  10. *   F2 - Clears the screen
  11. *   F3 - Send a file or group of files(if Ymodem specified for protocol)
  12. *   F4 - Receive a file or files(if Ymodem)
  13. *   ESC - Suspends TERMINAL program
  14. *******************************************************************************
  15. *
  16. SET ESCAPE OFF
  17. SET TALK OFF
  18. SET BELL OFF
  19. SET STATUS OFF
  20. SET SCOREBOARD OFF
  21. SET SAFETY OFF
  22. PUBLIC Event, LF, Msg, ChkCmd, Thresh, Fox, FoxPro, LastMsg, TranHow
  23. PUBLIC ComPort, ComAddr, ComIRQn, ComBaud, ComPrty, ComDBts, ComFlow, ComPhon
  24. TranHow = ' '
  25.  
  26. DEFINE WINDOW TERMINAL FROM 0,0 TO 23,79
  27. ACTIVATE WINDOW TERMINAL
  28. CLEAR
  29.  
  30. * Let's find out if COMETMP has been LOADed by CALLing without 1st LOADing
  31. * and trapping any "File was not LOADed" (error 91) errors.
  32. DoLoad = .F.
  33. ON ERROR DoLoad = .T.
  34. CALL COMETMP
  35. IF DoLoad
  36.     LOAD COMETMP                          && Loads COMETMP.BIN communications library
  37. ENDIF
  38.  
  39. ON ERROR
  40.  
  41. * Display sign-on message
  42. @ 5, 13 TO 13,65 DOUBLE
  43. @ 7,15 SAY 'TERMINAL - A Terminal Emulation Program Using ...'
  44. @ 9,30 SAY '- COMETMP -'
  45. @ 11,15 SAY 'The  B A C K G R O U N D  Communication Library'
  46. Msg = 'COPYRIGHT(c) 1989 by  CompuSolve,  Rockaway, NJ  (201)983-9429'
  47. NULL = MsgLine24(Msg)
  48.  
  49. * Wait loop 
  50. NULL = INKEY(5)
  51.  
  52. CLEAR
  53.  
  54. * Get default settings from TERMINAL.MEM file, if present
  55. IF FILE('TERMINAL.MEM')
  56.  RESTORE FROM TERMINAL ADDITIVE
  57. ELSE
  58.  ComPort = '1'
  59.  ComAddr = 'x03F8'
  60.  ComIRQn = '4'
  61.  ComBaud = '2400 '
  62.  ComPrty = 'E'
  63.  ComDBts = '7'
  64.  ComStop = '1'
  65.  ComFlow = 'N'
  66. *
  67.  ComPhon = SPACE(20)
  68. ENDIF
  69.  
  70. @ 6,8 TO 15, 72
  71. @ 7,10 SAY 'COM Port # (1-5) ?' GET ComPort PICTURE '9' VALID  ComPort $ '12345' ERROR 'VALID CHOICES: 1 - 5'
  72. @ 8,10 SAY "I/O Address (x#### = heX) ?" GET ComAddr VALID .NOT. '?' $ ComAddr ERROR 'NEED TO SPECIFY PORT ADDRESS IN heX OR DECIMAL'
  73. @ 9,10 SAY "IRQ # (2-7) ?" GET ComIRQn PICTURE '9' VALID ComIRQn $ '234567' ERROR 'VALID CHOICES: 2 - 7'
  74. @10,10 SAY "BAUD Rate (300-38400) ?" GET ComBaud PICTURE 'X9999' VALID VAL(ComBaud) >= 300 .AND. VAL(ComBaud) <=38400 ERROR 'VALID CHOICES: 300 - 38400'
  75. @11,10 SAY "Parity (None, Odd or Even) ?" GET ComPrty PICTURE '!' VALID ComPrty $ 'NEO' ERROR 'VALID CHOICES: None, Even or Odd (N, E or O)'
  76. @12,10 SAY "# Data Bits (7 or 8) ?" GET ComDBts PICTURE '9' VALID ComDBts $ '78' ERROR 'VALID CHOICES: 7 or 8'
  77. @13,10 SAY "Flow Control (Xon/xoff, Rts/cts or None) ?" GET ComFlow PICTURE "!" VALID ComFlow $ 'XRN' ERROR 'VALID CHOICES: Xon/Xoff, Rts/cts or None (X, R or N)'
  78. @14,10 SAY "# Stop Bits (1 or 2) ?" GET ComStop VALID ComStop $ '12' ERROR 'VALID CHOICES: 1 or 2'
  79. READ
  80.  
  81. RKey = READKEY()
  82. IF MOD(RKey,256) = 12    && ESCape 
  83.  CANCEL
  84. ENDIF
  85.  
  86. Msg = 'Enter a telephone # to dial (ENTER = local mode) ?'
  87. NULL = MsgLine24(Msg)
  88. @0,0
  89. * Init variables
  90. ChkCmd = ''
  91.  
  92. * Function keys used to invoke local commands
  93. F1 = 28
  94. F2 = -1                             && Clear Screen
  95. F3 = -2                             && Send file
  96. F4 = -3                             && Receive file
  97. F5 = -4
  98.  
  99. SET FUNC 'F2' TO ''
  100. SET FUNC 'F3' TO ''
  101. SET FUNC 'F4' TO ''
  102. SET FUNC 'F5' TO ''
  103.  
  104. * INKEY() values
  105. Up = 5
  106. Dn = 24
  107. Rgt = 4
  108. Lft = 19
  109. BkSpc = 127
  110.  
  111. * Build OPEN command for COMET
  112. Open = "OPEN COM" + ComPort + "," + ComAddr + "," + ComIRQn + ":" ;
  113.  + ComBaud + "," + ComPrty + "," + ComDBts + ",1," + ComFlow
  114.  
  115. ClsPort = 'CLOSE #' + ComPort          && In case port is being redefined ...
  116. CALL COMETMP WITH ClsPort
  117.  
  118. CALL COMETMP WITH Open                && Now OPEN it for use, that was easy!
  119.  
  120.  
  121. *** Must set FLAVOR if using dBASEIV ***
  122. IF .NOT. FoxPro                    && Must be dBASEIV
  123.     Flavor = 'FLAVOR D4'
  124.     CALL COMETMP WITH Flavor
  125. ENDIF
  126.  
  127. * Now we'll dial a phone#
  128. * Request # to dial 1st
  129. PhoneNo = SPACE(20)
  130. @16,10 SAY "Phone # to Dial (ENTER = direct/local) ?" GET ComPhon
  131. READ
  132.  
  133. *Save settings
  134. SAVE TO TERMINAL ALL LIKE Com????
  135.  
  136.  
  137. IF LEN(TRIM(ComPhon)) > 0
  138.  
  139.  * The ATTD is output to instruct HAYES compatible modems to dial a #
  140.  Dial = "OUTPUT #" + ComPort + ",ATTD" + TRIM(ComPhon) + CHR(13)  && Build OUTPUT command
  141.  CALL COMETMP WITH Dial                && Have modem dial #
  142.  
  143.  * Now, wait till we sense Data Carrier Detect(DCD) from our COM port.
  144.  Msg = "CHECKING FOR MODEM'S DATA CARRIER DETECT (DCD) ..."
  145.  NULL = MsgLine24(Msg)
  146.  Elapsed = 0                         && Simple timer for our DO .. WHILE loop
  147.  LastTime = TIME()                   && Also used for timing purposes
  148.  MdmStat = "MSTAT #" + ComPort + "," + SPACE(25)        && Build MSTAT command
  149.  DO WHILE Elapsed <= 45  .AND. (.NOT. "+DCD" $ MdmStat)
  150.     CALL COMETMP WITH MdmStat         && Get COM port's modem status
  151.  
  152.     IF LastTime <> TIME()           && Test if we need to updated timer count
  153.         Elapsed = Elapsed+1         && Another second has gone by ..
  154.         LastTime = TIME()
  155.         ACTIVATE SCREEN
  156.         @ 24, 66 SAY STR(45-Elapsed,2,0) COLOR W/N  && Display #secs till abort
  157.         ACTIVATE WINDOW TERMINAL
  158.     ENDIF
  159.  
  160.    IF INKEY() = 27
  161.      EXIT
  162.    ENDIF
  163.  
  164.  ENDDO
  165.  
  166.  * Check if we timed out
  167.  IF Elapsed > 45
  168.     ??CHR(7)
  169.     Null = MsgLine24("Sorry, can't establish phone connection. Aborting ...")
  170.     CALL COMETMP WITH 'CLOSE'
  171.     CANCEL
  172.  ENDIF
  173.  
  174. ENDIF                       && If phone # was entered
  175.  
  176.  
  177.  
  178. * Now that we have a call established we have 2 things to do:
  179. *  1) Check COMETMP's receive buffer and display any incoming characters
  180. *  2) Detect any keystrokes and determine if local command or data to output
  181.  
  182. * #2 is simple, use an ONKEY approach
  183. ON KEY DO GotAkey with .f.
  184.  
  185. SET ESCAPE ON
  186. ON ESCAPE DO GotAKey WITH .t.        && 27 = INKEY() value of ESC key
  187.  
  188.  
  189. CLEAR
  190.  
  191. * Display status message on line 24
  192. Msg = "F2 - Clear | F3 - Send | F4 - Recv | TERM"
  193. LastMsg = Msg
  194. NULL =MsgLine24(Msg)
  195.  
  196. ***************************************************************************
  197. * This is main loop for testing for and displaying any incoming data
  198. DO WHILE .T.
  199.     Inp = "INPUT #" + ComPort + ","  + SPACE(100)  && Build INPUT command
  200.     CALL COMETMP WITH Inp   && Read COMET's COM port data buffer
  201.  
  202.     AmtRetd = VAL(SUBSTR(Inp,10,5))  && Determine how many chars were returned, if any
  203.     COMactive = IIF(AmtRetd > 0, .T., .F.)
  204.  
  205.     IF AmtRetd > 0
  206.       ComData = SUBSTR(Inp, 15, AmtRetd)  && Get just the COM data from <expC>
  207.       ?? ComData
  208.     ENDIF
  209.  ENDDO
  210.  
  211. ***************************************************************************
  212.  
  213. ***************************** GotAKey *************************************
  214. * Anytime a key gets pressed, we jump here
  215. *
  216. PROCEDURE GotAKey
  217. PARAMETERS EscKey
  218.  
  219. ON KEY                     && Disable ON KEY & ON ESCAPE
  220. ON ESCAPE
  221.  
  222. IF EscKey
  223.  Key = 27
  224. ELSE
  225.  Key = INKEY()
  226. ENDIF
  227.  
  228. DO CASE                     && Decide whether key is data to output or local command
  229.     CASE Key > 0 .AND. Key <> 27    && data to output ?
  230.         IF .NOT. 'ACTIVE' $ ChkCmd .OR. TranHow = 'A'   && Output if: no xfers active  OR  ASEND/ARECV active
  231.             Output = "OUTPUT #" + ComPort + "," + CHR(Key)   && Build OUTPUT command
  232.             CALL COMETMP WITH Output          && Output char to COM port
  233.         ELSE
  234.             CLEAR
  235.             ?? CHR(7)
  236.             @ 4,0 TO 12,76 DOUBLE
  237.             @ 6,2 SAY "Sorry but we're busy " + event + "ing a file now!"
  238.             @ 7,2 SAY "But, that fact that I can display this alert box "
  239.             @ 8,2 say "proves COMET is running in the background."
  240.             @ 9,2 say "Hit the 'D' key and I'll do a !DIR command in DOS."
  241.             @10,2 say "Hit any key ..."
  242.             * Wait loop using INKEY(n) if FoxBase+ otherwise Do .. While
  243.             Ky = INKEY(5)
  244.             IF ky = ASC('D') .OR. ky = ASC('d')
  245.                 !DIR
  246.             ENDIF
  247.         ENDIF
  248.  
  249.     CASE Key = 27           && ESC hit ?
  250.         IF 'ACTIVE' $ ChkCmd        && File transfer active ?
  251.             FlshPort = 'FLUSH #' + ComPort
  252.             CALL COMETMP WITH FlshPort && If so, user wants to cancel it
  253.         ELSE
  254.             CALL COMETMP WITH 'ONTIME '
  255.             DEACTIVATE WINDOW TERMINAL
  256.             ACTIVATE SCREEN
  257.             CALL COMETMP WITH 'CLOSE'
  258.             CANCEL             && If no active file transfer, then quit
  259.         ENDIF
  260.     OTHERWISE                   && If INKEY() < 0, then a function key was hit
  261.         DO Local
  262. ENDCASE
  263.  
  264. ON KEY DO GotAKey  WITH .F.      && Enable ON KEY again
  265. ON ESCAPE DO GotAKey WITH .T.
  266. RETURN
  267.  
  268.  
  269. ****************************** Local ***************************************
  270. * Support for function keys (ie. local commands like send and receive)
  271. PROCEDURE Local
  272.  
  273. DO CASE
  274.     CASE Key = F2               && Clear screen ?
  275.         CLEAR
  276.     CASE Key = F3               && Send file ?
  277.         DO TranFile WITH 'SEND'
  278.     CASE Key = F4               && Receive file ?
  279.         DO TranFile WITH 'RECV'
  280.     CASE Key = F5              && ONTIME command requesting STATUS update ?
  281.         DO Status
  282. ENDCASE
  283.  
  284. RETURN
  285.  
  286. ************************ TranFile *******************************************
  287. PROCEDURE TranFile
  288. PARAMETERS Action
  289. * Prompt for X or Ymodem  and filename to send/recv (including path)
  290. IF 'ACTIVE' $ ChkCmd        && We're good, but not that good that we can have two transfers simultaneously!
  291.     Msg = 'Request denied !  There is a file transfer ACTIVE'
  292.     NULL = MsgLine24(Msg)
  293.     NULL = INKEY(3)
  294.     Msg = LastMsg
  295.     NULL = MsgLine24(Msg)
  296.     RETURN
  297. ENDIF
  298.  
  299. ExitFlg = .F.
  300. DEFINE WINDOW INPUT FROM 15,5 TO 20,75
  301. ACTIVATE WINDOW INPUT
  302.  
  303. * Prompt for transfer protocol desired (Ascii, Xmodem or Ymodem)
  304. * We don't use a VALID clause since DBASE doesn't support
  305. TranHow = ' '
  306. DO WHILE .NOT. (ExitFlg .OR. TranHow $ 'AXY')
  307.     @ 1, 0 SAY 'Protocol(A,X or Y) ?' GET TranHow PICTURE '@! A'
  308.     READ                            && Get protocol
  309.     ExitFlg = IIF(READKEY()=12 .OR. READKEY()=268, .T., ExitFlg)
  310.     ?? IIF(.NOT. TranHow $ 'AXY', CHR(7), '')   && Beep if invalid
  311. ENDDO
  312.  
  313. * Prompt for filename except for YRECV since filename gets transmitted w/data
  314. TranFil = SPACE(40)
  315. IF .NOT. ExitFlg .AND. (TranHow <> 'Y' .OR. Action = 'SEND')
  316.     @ 1, 25 SAY 'Filename ?' GET TranFil PICTURE '@S30'
  317.     READ
  318.     ExitFlg = IIF(READKEY()=12 .OR. READKEY()=268, .T., ExitFlg)
  319. ENDIF
  320.  
  321. * Prompt for timeout in seconds if ARECV, default is 60 secs
  322. TimeOut = 60
  323. IF .NOT. ExitFlg .AND. TranHow = 'A' .AND. Action = 'RECV'
  324.     @ 2, 20 SAY 'ARECV timeout in seconds ?' GET TimeOut PICTURE "999"
  325.     READ
  326.     ExitFlg = IIF(READKEY()=12 .OR. READKEY()=268, .T., ExitFlg)
  327. ENDIF
  328.  
  329. RELEASE WINDOW INPUT
  330.  
  331. IF ExitFlg                    && Look for ESC key
  332.     RETURN
  333. ENDIF
  334.  
  335. *Now build COMETMP SEND or RECV command
  336. TranCmd = TranHow + Action + ' #' + ComPort + ',' + TRIM(TranFil)
  337. IF 'ARECV' $ TranCmd .AND. TimeOut <> 60 && Test if we need ARECV timeout option
  338.     TranCmd = TranCmd + ',' + STR(TimeOut,3,0)
  339. ENDIF
  340.  
  341.   * If X/YModem, port must be set to 8 data bits/No parity
  342. IF TranHow # 'A'        && ASCII file xfer?
  343.   DBits7 = AT(',7,', Open)              && Currently OPENed for 7 data bits ?
  344.  IF DBits7 > 0
  345.   OpnN8 = STUFF(Open,DBits7-1,3,"N,8")  && Create modified version of original Open
  346.   CALL COMETMP WITH OpnN8
  347.  ENDIF
  348. ENDIF
  349.  
  350. * Issue command to COMETMP
  351. CALL COMETMP WITH TranCmd         && Startup background file transfer
  352.  
  353. *Check that file transfer was able to start
  354. ChkCmd = 'FCHK #' + ComPort + ',' + SPACE(80)
  355. CALL COMETMP WITH ChkCmd
  356. IF .NOT. 'ACTIVE' $ ChkCmd       && Should be active if command started!
  357.     LBracAt = AT('[',ChkCmd)     && Find start of FCHK failure description, if any
  358.     IF LBracAt > 0               && If [ present, we have a failure description
  359.         RBracAt = AT(']', ChkCmd)  && Find ] which is end of description
  360.         Reason = SUBSTR(ChkCmd, LBracAt+1, RBracAt-LBracAt-1)
  361.     ELSE
  362.         Reason = 'GENERAL ERROR'
  363.     ENDIF
  364.     ?? CHR(7)                    && If wasn't successful at starting SEND, alert operator
  365.     Msg = LEFT(Msg,37) + Action + ' Command Failed - ' + Reason
  366.     NULL = MsgLine24(Msg)
  367.     NULL = INKEY(3)
  368.     Msg = LastMsg
  369.     NULL = MsgLine24(Msg)
  370.     CALL COMETMP WITH Open        && Restore original COM port OPEN params
  371.     RETURN
  372. ENDIF
  373.  
  374. Event = TranHow + Action            && This will be used by Status procedure
  375. Thresh = 0
  376. DO Status
  377.  
  378. *File Send or Recv in progress, now use ONTIME command to update status every 3 secs
  379. *STATUS procedure will now execute every 5 seconds
  380. OnTime = 'ONTIME 5,0,63'        && #secs=5, ASCII cd=0 , Aux Byte=63 (F5 key)
  381. CALL COMETMP WITH OnTime
  382.  
  383. RETURN                          && All done, returns back to Local proc
  384.  
  385.  
  386. *************************** Status ************************************
  387. * F10 key or COMETMP's ONTIME command brings us here
  388. * Updates bottom line on screen with file transfer status
  389. *
  390. PROCEDURE Status
  391. PRIVATE CurR, CurC
  392.  
  393. CurR = ROW()            && Save TERMINAL window's cursor loc
  394. CurC = COL()
  395.  
  396. ChkCmd = 'FCHK #' + ComPort + ',' + SPACE(80)
  397. CALL COMETMP WITH ChkCmd          && Get current file transfer status
  398.  
  399.  * Now extract the status info we want; FCHK's status, size and filename
  400. FCHKstat = SUBSTR(ChkCmd,25,8)  && Status - ACTIVE, COMPLETE or FAILED
  401. FCHKsize = SUBSTR(ChkCmd,34,7)  && Size in bytes - #######
  402. FCHKfile = SUBSTR(ChkCmd,42)    && Filename - path\filename (variable length)
  403.  
  404. * Adjust filename if necessary
  405. SpcAt = AT(' ',FCHKfile)        && Look for end of path\filename
  406. FCHKfile = IIF(SpcAt > 0, SUBSTR(FCHKfile,1,SpcAt-1), FCHKfile)
  407. FCHKfile = IIF(LEN(FCHKfile) > 12, RIGHT(FCHKfile,12), FCHKfile)
  408.  
  409. * Append failure description to FCHKstat - if FAILED
  410. IF 'FAILED' $ FCHKstat
  411.     LBracAt = AT('[',ChkCmd)     && Find start of FCHK failure description, if any
  412.     RBracAt = AT(']', ChkCmd)  && Find ] which is end of description
  413.     Reason = SUBSTR(ChkCmd, LBracAt+1, RBracAt-LBracAt-1)
  414.     FCHKstat = FCHKstat + Reason
  415.     FCHKfile = ""               && Need the room to display failure description
  416. ENDIF
  417.  
  418.  
  419.  
  420. * Display extracted status
  421. Msg = LEFT(Msg,37) + Event + ' | ' + FCHKstat + ' | ' + FCHKsize + ' | ' + FCHKfile
  422. NULL = MsgLine24(Msg)
  423.  
  424. IF .NOT. 'ACTIVE' $ ChkCmd    && COMPLETEd or FAILED ?
  425.     Thresh = Thresh + 1
  426.     IF Thresh > 1               && Don't want to redisplay old stat msg till 1 cycle
  427.         Ontime = 'ONTIME'
  428.         CALL COMETMP WITH Ontime      && If so, turn off timer event trapping
  429.         Msg = LastMsg
  430.         NULL = MsgLine24(Msg)
  431.     ELSE
  432.  
  433.         ?? CHR(7)               && Call attention to COMPLETE or FAILED status
  434.         IF TranHow # 'A'
  435.             CALL COMETMP WITH Open        && Restore original COM port OPEN params
  436.         ENDIF
  437.         
  438.     ENDIF
  439. ENDIF
  440.  
  441. @ CurR, CurC SAY ''
  442.  
  443. RETURN
  444.  
  445. FUNCTION MsgLine24
  446. PARAMETERS MsgToOut
  447. PRIVATE NowRow, NowCol
  448.  
  449. NowRow = ROW()
  450. NowCol = COL()
  451.  
  452. ACTIVATE SCREEN
  453. Strt =  INT( (80 - LEN(MsgToOut))/2 )
  454. @ 24,0 SAY SPACE(80) COLOR N/W
  455. @ 24, Strt SAY MsgToOut COLOR N/W
  456. ACTIVATE WINDOW TERMINAL
  457.  
  458.  
  459. @ MIN(NowRow,21), MIN(NowCol, 77) SAY ''
  460.  
  461. RETURN ''
  462.  
  463.