home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / OS2BBSHL.ZIP / OS2BBS.CMD next >
OS/2 REXX Batch file  |  1992-08-14  |  21KB  |  832 lines

  1. /**
  2. ***  This will logon to IBMLink and provide the requested services.
  3. ***  ────────────────────────────────────────────────────────────────────
  4. ***  This REXX exec is submitted automatically on a daily basis to login
  5. ***  and download the new messages on the BBS.  The code that automates
  6. ***  the timed submission is Chron from Hilbert Computing.  Hilbert
  7. ***  can be reached at the address and BBS number listed below:
  8. ***
  9. ***       Hilbert Computing
  10. ***       1022 N. Cooper
  11. ***       Olathe, KS 66061
  12. ***       Voice:  (913) 780-5051
  13. ***       BBS:    (913) 829-2450
  14. **/
  15.  
  16. arg Function Pswd . '(' Options
  17.  
  18. call ParseOptions Options
  19.  
  20. /* Set up global values */
  21.  
  22. Host.             = ''
  23. Host.Session      = 'D'
  24. Host.Application  = 'IBMLink'
  25. Host.Applid       = 'IBM0MON2'
  26. Host.Account      = 'xxxx'
  27. Host.Userid       = 'yyyyyyy'
  28. Host.Logmode      = 'PC3270M2'
  29. Host.Password     = Pswd
  30. Host.OpSys        = 'VM'
  31.  
  32. Bbs.              = ''            /* List of the BBS forums to visit */
  33. Bbs.Forum.0       = 10
  34. Bbs.Forum.1       = 'OS2PRG'
  35. Bbs.Forum.2       = 'OS2PMPGM'
  36. Bbs.Forum.3       = 'OS2TLKIT'
  37. Bbs.Forum.4       = 'C-SET2'
  38. Bbs.Forum.5       = 'OS2REXX'
  39. Bbs.Forum.6       = 'OS2TCPIP'
  40. Bbs.Forum.7       = 'OS2WPS'
  41. Bbs.Forum.8       = 'OS2DOS'
  42. Bbs.Forum.9       = 'OS2DBM'
  43. Bbs.Forum.10      = 'OS2LAN'
  44.  
  45. call LoadFunctions
  46. call HapiConnect
  47.  
  48. if Opt.Logon then
  49.    call HostLogon
  50.  
  51. call Os2bbs Function
  52.  
  53. if Opt.Logon then
  54.    call HostLogoff
  55.  
  56. call HapiDisconnect
  57. exit
  58.  
  59.  
  60. /**
  61. *** ┌──────────────────────────────────────────────────────────────────────┐
  62. *** │                        Misc Support Functions                        │
  63. *** └──────────────────────────────────────────────────────────────────────┘
  64. **/
  65.  
  66. ParseOptions: procedure expose Opt.
  67.    /**
  68.    ***  This will parse the options passed and return the values in the stem
  69.    ***  variable opt.
  70.    **/
  71.  
  72.    arg opt
  73.  
  74.    /* Set defaults */
  75.  
  76.    Opt.      = ''
  77.    Opt.Logon = 1
  78.  
  79.    do i = 1 to words(opt)
  80.       option = word(opt, i)
  81.       parse upper var option option
  82.       select
  83.          when option = "LOGON"   then Opt.Logon = 1
  84.          when option = "NOLOGON" then Opt.Logon = 0
  85.          when option = "NOLOG"   then Opt.Logon = 0
  86.          otherwise
  87.             say "Warning: Unrecognized option" option". It was ignored"
  88.       end /* select */
  89.    end
  90.    return
  91.  
  92.  
  93. LoadFunctions: procedure
  94.    /**
  95.    ***  This will load all of the DLLs that are used by this exec.
  96.    **/
  97.  
  98.    if RxFuncQuery('HLLAPI') then
  99.       call RxFuncAdd 'HLLAPI','SAAHLAPI','HLLAPISRV'
  100.  
  101.    call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  102.    call SysLoadFuncs
  103.    return
  104.  
  105.  
  106. GetPassword: procedure
  107.    /**
  108.    ***  This will grab keystrokes and enter them back as '*' characters
  109.    **/
  110.  
  111.    Password = ''
  112.    Key = SysGetKey('NoEcho')
  113.    do while c2x(Key) <> '0D'
  114.       select
  115.          when c2x(Key) = '08' then
  116.             Password = left(Password, (length(password)-1))
  117.          otherwise
  118.             Password = Password || Key
  119.       end /* select */
  120.       Key = SysGetKey('NoEcho')
  121.    end
  122.    say "Password Received."
  123.    return Password
  124.  
  125.  
  126. /**
  127. *** ┌──────────────────────────────────────────────────────────────────────┐
  128. *** │                          OS/2 BBS Routines                           │
  129. *** └──────────────────────────────────────────────────────────────────────┘
  130. **/
  131.  
  132. Os2bbs: procedure expose Host. Bbs.
  133.    /**
  134.    ***  This routine will download information on the OS/2 BBS on IBMLink.
  135.    ***  it will either grab the NEW information or ALL information and
  136.    ***  store it in a local file.
  137.    ***
  138.    ***  On Entry:  IBMLink Main Menu
  139.    ***  On Exit:   IBMLink Main Menu
  140.    ***
  141.    **/
  142.  
  143.    arg Scope .
  144.  
  145.    /* Get to the main menu */
  146.  
  147.    code = hllapi('Sendkey', '@0OS2BBS@E')
  148.    code = HostWaitFor(120, 'Main Menu')
  149.    if code = -1 then
  150.       call HostError
  151.  
  152.    say "OS/2 BBS Main Menu"
  153.  
  154.    /* Get to the Forums */
  155.  
  156.    code = hllapi('Sendkey', '@0@E')
  157.    rc = hllapi('Wait')
  158.  
  159.    do i = 1 to Bbs.Forum.0
  160.       Bbs.FHandle = Open(Bbs.Forum.i'.BBS', 'Append')
  161.       call Os2bbsVisitForum Bbs.Forum.i Scope
  162.       call lineout Bbs.FHandle, copies('═', 79)
  163.       Bbs.FHandle = Close(Bbs.FHandle)
  164.    end
  165.  
  166.    /* Exit the OS/2 BBS and get back to IBMLink */
  167.  
  168.    call Os2bbsExit
  169.    return
  170.  
  171.  
  172. Os2bbsExit: procedure
  173.    /**
  174.    ***  This will exit the user from the OS2BBS appliction on IBMLink
  175.    **/
  176.  
  177.  
  178.    say "Exiting the OS/2 BBS"
  179.  
  180.    Position = hllapi('Search_ps',' eXit',1)
  181.    if Position <> 0 then
  182.       do
  183.       code = hllapi('Set_cursor_pos', (Position-2))
  184.       code = hllapi('Sendkey', '@E')
  185.       code = hllapi('Wait')
  186.       end
  187.  
  188.    /* We should now be at the main menu */
  189.  
  190.    code = hllapi('Sendkey', '@3')
  191.    code = hllapi('Wait')
  192.    code = HostWaitFor(45, 'Press PF3 again to CONFIRM your request.')
  193.    code = hllapi('Sendkey', '@3')
  194.    code = hllapi('Wait')
  195.    return
  196.  
  197.  
  198. Os2bbsVisitForum: procedure expose Screen. Host. Bbs.
  199.    /**
  200.    ***  This will visit an OS/2 BBS forum and grab either the NEW posts
  201.    ***  or ALL of the posts based on the Scope passed.
  202.    ***
  203.    ***  On Entry: OS/2 Bulletin Board Topics panel
  204.    ***  On Exit:  OS/2 Bulletin Board Topics panel
  205.    **/
  206.  
  207.    parse arg Forum Scope .
  208.  
  209.    say "Visiting the" Forum "forum to download" Scope "messages."
  210.  
  211.    /* Get a screen shot */
  212.  
  213.    call HostScreenToStem
  214.  
  215.    /* Find out how many panels there are */
  216.  
  217.    parse var Screen.2 'Panel' PanelCurrent 'of' PanelMax
  218.  
  219.    /* Make sure we are on the first panel */
  220.  
  221.    do Panel = (PanelCurrent - 1) to 1 by -1
  222.       call HostPageUp
  223.    end
  224.  
  225.    /* Scan the screen(s) for the requested forum */
  226.  
  227.    FoundRow = 0
  228.    do Panel = 1 to PanelMax while FoundRow = 0
  229.       do i = 9 to (Screen.Rows - 2) while FoundRow = 0
  230.          if pos(Forum, Screen.i) > 0 then
  231.             FoundRow = i
  232.       end /* row loop */
  233.  
  234.       if FoundRow = 0 then
  235.          call HostPageDown
  236.    end /* panel loop */
  237.  
  238.    if FoundRow = 0 then
  239.       do
  240.       say "Forum '"Forum"' not found on the IBMLink OS/2 BBS."
  241.       return
  242.       end
  243.  
  244.    /* If we get here, then we know the row on the current screen where */
  245.    /* the desired forum is.   Put the cursor there and press Enter     */
  246.  
  247.    code = HostEnterXY(2, FoundRow)
  248.  
  249.    /* Check to see what the scope is.  If ALL notes are requested, then */
  250.    /* tab down to the next spot and hit enter, otherwise just hit enter */
  251.  
  252.    if Scope = 'ALL' then
  253.       do
  254.       code = hllapi('Sendkey', '@T@E')
  255.       rc= hllapi('Wait')
  256.       end
  257.    else
  258.       do
  259.       code = hllapi('Sendkey', '@E')
  260.       rc= hllapi('Wait')
  261.  
  262.       /* Make a quick check to see if there are no new entries */
  263.  
  264.       call HostScreenToStem
  265.       StatusLine = Screen.Rows - 1;
  266.       if pos("You have seen all the", Screen.StatusLine) = 0 then
  267.          do
  268.          call Os2bbsPullEntries
  269.  
  270.          /* Go back to the forum menu */
  271.  
  272.          code = hllapi('Sendkey', '@3')
  273.          code = hllapi('Wait')
  274.          end
  275.       end
  276.  
  277.    /* See if there are any replies queued to be uploaded to the OS/2 BBS */
  278.  
  279.    if Exists(Forum'.rpl') then
  280.       call Os2bbsUploadReplies Forum
  281.  
  282.    /* Get back to the Topics panel */
  283.  
  284.    code = hllapi('Sendkey', '@3')
  285.    code = hllapi('Wait')
  286.    return
  287.  
  288.  
  289. Os2bbsPullEntries: procedure expose Host. Bbs.
  290.    /**
  291.    ***  This will cycle through all of the notes in the list and place
  292.    ***  them in a file.
  293.    ***
  294.    ***  On Entry: Forum Entries
  295.    ***  On Exit:  Forum Entries
  296.    **/
  297.  
  298.    say "Pulling entries."
  299.  
  300.    call HostScreenToStem
  301.  
  302.    /* Pull the number of panels of entries */
  303.  
  304.    parse var Screen.2 'Panel' PanelCurrent 'of' PanelMax
  305.    do Panels = 1 to PanelMax
  306.  
  307.       /* Read each individual note */
  308.  
  309.       do Row = 9 to (Screen.Rows - 2) while strip(Screen.Row) <> ""
  310.          code = hllapi('Sendkey', '@E')
  311.          code = hllapi('Wait')
  312.          call Os2bbsReadEntry Forum
  313.          code = hllapi('Sendkey', '@T')
  314.       end
  315.  
  316.       if Panels <> PanelMax then
  317.          call HostPageDown
  318.    end /* Panels */
  319.    return
  320.  
  321.  
  322. Os2bbsReadEntry: procedure expose Host. Bbs.
  323.    /**
  324.    ***  This will cycle through all of the notes in the list and place
  325.    ***  them in a file.
  326.    ***
  327.    ***  On Entry: Text for a single note
  328.    ***  On Exit:  Forum Entries
  329.    **/
  330.  
  331.    parse arg Forum .
  332.  
  333.    call HostScreenToStem
  334.  
  335.    call lineout Bbs.FHandle, copies('═', 79)
  336.  
  337.    /* Pull the number of panels of entries */
  338.  
  339.    parse var Screen.2 'Panel' PanelCurrent 'of' PanelMax
  340.    do Panels = 1 to PanelMax
  341.  
  342.       /* Find the last non-blank line */
  343.  
  344.       do Row = (Screen.Rows - 1) to 3 by -1 while strip(Screen.Row) = ""
  345.          nop
  346.       end
  347.       LastRow = Row
  348.  
  349.       /* Write the lines to the forum file */
  350.  
  351.       do Row = 3 to LastRow
  352.          call lineout Bbs.FHandle, strip(Screen.Row, 'Trailing')
  353.       end
  354.  
  355.       if Panels <> PanelMax then
  356.          call HostPageDown
  357.    end /* Panels */
  358.  
  359.    /* Exit back to the Forum Entries */
  360.  
  361.    code = hllapi('Sendkey', '@3')
  362.    code = hllapi('Wait')
  363.    return
  364.  
  365.  
  366. Os2bbsUploadReplies: procedure expose Host. Bbs.
  367.    /**
  368.    ***  This routine if called if there is a reply file for this forum.
  369.    ***  It will upload the information into the forum as a new note.
  370.    ***
  371.    ***  On Entry: Forum Menu
  372.    ***  On Exit:  Forum Menu
  373.    **/
  374.  
  375.    arg Forum .
  376.  
  377.    say "Uploading replies to the" Forum "forum."
  378.  
  379.    /* Open the replies file */
  380.  
  381.    ReplyFile = Open(Forum'.rpl', 'READ')
  382.    if ReplyFile = '' then
  383.       return
  384.  
  385.    /* Skip the first line of the file (separator line) */
  386.  
  387.    line = linein(ReplyFile)
  388.  
  389.    /* Find the start of the reply */
  390.  
  391.    do while(lines(ReplyFile) > 0)
  392.       call Os2bbsReplyToStem ReplyFile
  393.       call Os2bbsUploadReply
  394.    end
  395.    code = Close(ReplyFile)
  396.    '@copy'  ReplyFile '*.snt'
  397.    '@erase' ReplyFile
  398.    return
  399.  
  400.  
  401. Os2bbsReplyToStem: procedure expose Reply.
  402.    /**
  403.    ***  This will load a single reply into a stem variable
  404.    **/
  405.  
  406.    arg ReplyFile
  407.  
  408.    line = linein(ReplyFile) /* Skip the forum line */
  409.    line = linein(ReplyFile) /* Should be the subject line */
  410.  
  411.    Reply. = ''
  412.  
  413.    parse var line . 'Subject: ' Reply.Subject
  414.  
  415.    i = 1
  416.    line = linein(ReplyFile)
  417.    do while(lines(ReplyFile) > 0) & (pos("══════════════════════", line) = 0)
  418.       Reply.i = line
  419.       i = i + 1
  420.       line = linein(ReplyFile)
  421.    end /* while */
  422.  
  423.    if pos("══════════════════════", line) = 0 then
  424.       Reply.0 = i - 1
  425.    else
  426.       Reply.0 = i
  427.    return
  428.  
  429.  
  430. Os2bbsUploadReply: procedure expose Host. Bbs. Reply.
  431.    /**
  432.    ***  This routine if called if there is a reply file for this forum.
  433.    ***  It will upload the information into the forum as a new note.
  434.    ***
  435.    ***  On Entry: Forum Menu
  436.    ***  On Exit:  Forum Menu
  437.    **/
  438.  
  439.  
  440.    call HostScreenToStem
  441.  
  442.    /* Look for the correct line containing the menu selection for */
  443.    /* submitting a new item                                       */
  444.  
  445.    do Row = 3 to Screen.Rows while pos("Submit A New Item", Screen.Row) = 0
  446.       nop
  447.    end
  448.    if Row = Screen.Row then
  449.       do
  450.       say "Error: Expected to find a 'Submit New Item' menu and didn''t."
  451.       return
  452.       end
  453.  
  454.    code = HostEnterXY(2, Row)
  455.  
  456.    /* We are now at the append screen */
  457.  
  458.    code = hllapi('Sendkey', Reply.Subject'@T@E')
  459.  
  460.    /* We are now at the text entry screen */
  461.  
  462.    Row = 3
  463.    do i = 1 to Reply.0
  464.       code = hllapi('Sendkey', substr(Reply.i, 1, 78)'@T')
  465.  
  466.       /* Page down if we have filled a screen */
  467.  
  468.       if Row >= (Screen.Rows - 2) then
  469.          do
  470.          call HostPageDown
  471.          Row = 3
  472.          end
  473.  
  474.       Row = Row + 1
  475.    end
  476.  
  477.    /* Return from the edit screen */
  478.  
  479.    code = hllapi('Sendkey', '@3')
  480.    code = hllapi('Wait')
  481.  
  482.    /* Tab twice to the append mark and press enter */
  483.  
  484.    code = hllapi('Sendkey', '@T@T@E')
  485.    code = hllapi('Wait')
  486.    return
  487.  
  488.  
  489.  
  490. /**
  491. *** ┌──────────────────────────────────────────────────────────────────────┐
  492. *** │                            Host Routines                             │
  493. *** └──────────────────────────────────────────────────────────────────────┘
  494. **/
  495.  
  496. HostEnterXY: procedure expose Host.
  497.    /**
  498.    ***  This will position the cursor at a row and column and press the
  499.    ***  Enter key.
  500.    **/
  501.  
  502.    parse arg x, y .
  503.    rcode = HostCursorXY(x,y)
  504.    code = hllapi('Sendkey', '@E')
  505.    rcode = hllapi('Wait')
  506.    return code
  507.  
  508.  
  509. HostCursorXY: procedure expose Host.
  510.    /**
  511.    ***  This will position the cursor at the proper row and column
  512.    **/
  513.    parse arg x, y .
  514.  
  515.    Position = hllapi('Convert_pos', Host.Session, x, y)
  516.    code = hllapi('Set_cursor_pos', Position)
  517.    return code
  518.  
  519.  
  520. HostPageDown: procedure expose Screen. Host.
  521.    /**
  522.    ***  This will page down to the next screen and refresh the Screen.
  523.    ***  stem variable with the new screen.
  524.    **/
  525.  
  526.    code = hllapi('Sendkey', '@8')
  527.    rc = hllapi('Wait')
  528.    call HostScreenToStem
  529.    return
  530.  
  531. HostPageUp: procedure expose Screen. Host.
  532.    /**
  533.    ***  This will page up to the previous screen and refresh the Screen.
  534.    ***  stem variable with the new screen.
  535.    **/
  536.  
  537.    code = hllapi('Sendkey', '@7')
  538.    rc = hllapi('Wait')
  539.    call HostScreenToStem
  540.    return
  541.  
  542.  
  543. HostScreenToStem: procedure expose Host. Screen.
  544.    /**
  545.    ***  This will get the current screen and break it into the stem
  546.    ***  variable called Screen.
  547.    **/
  548.  
  549.    call HostGetScreenSize
  550.    PresSpace = hllapi('Copy_PS_to_str', 1, (Screen.Rows * Screen.Cols))
  551.  
  552.    do i = 1 to Screen.Rows
  553.       Screen.i = left(PresSpace, Screen.Cols)
  554.       PresSpace = substr(PresSpace, Screen.Cols+1)
  555.    end
  556.    return
  557.  
  558.  
  559. HostGetScreenSize: procedure expose Host. Screen.
  560.    /**
  561.    ***  This will fill the stem variable with the number of rows and
  562.    ***  columns in the current screen.
  563.    **/
  564.  
  565.    SessionStatus = hllapi('Query_session_status', Host.Session)
  566.    Screen.Rows = c2d(reverse(substr(SessionStatus, 12, 2)))
  567.    Screen.Cols = c2d(reverse(substr(SessionStatus, 14, 2)))
  568.    return
  569.  
  570.  
  571. HostError: procedure expose Host.
  572.    /**
  573.    ***  This will handle unexpected response errors from the host session
  574.    **/
  575.  
  576.    arg code .
  577.  
  578.    select
  579.       when code = 1001 then say 'Host could not process QUERY TIME command.'
  580.       when code = 1002 then say 'Can''t synch time on this host operating system.'
  581.       when code = 1003 then say 'Don''t know how to logon to this host operating system.'
  582.       otherwise             say 'Unexpected response from host.'
  583.    end /* select */
  584.    call HapiDisconnect
  585.    exit
  586.  
  587.  
  588. HostLogon: procedure expose Host.
  589.    /**
  590.    ***  This will log the use on to the host.
  591.    **/
  592.  
  593.  
  594.    call HostLogonClMenu
  595.  
  596.    if Host.Logmode = '' then
  597.       Logmode = ''
  598.    else
  599.       Logmode = 'M('Host.Logmode')'
  600.  
  601.    rc = hllapi('Sendkey', '/L' Host.Applid Host.Userid Logmode'@E')
  602.    rc = hllapi('Wait')
  603.  
  604.    do while Host.Password = ''
  605.       say 'Enter the password for' Host.Applid '['Host.Application']'
  606.       Host.Password = GetPassword()
  607.    end
  608.  
  609.    say "Logging on."
  610.  
  611.    call HostEnterIBMLinkInfo
  612.    return
  613.  
  614.  
  615. HostLogoff: procedure expose Host.
  616.    /**
  617.    ***  This will log off from the host assuming that the first valid
  618.    ***  entry field will support a logoff command.  This does no error
  619.    ***  checking or screen validation.
  620.    **/
  621.  
  622.    say "Logging off."
  623.  
  624.    rc = hllapi('Sendkey', '@0LOGOFF@E')
  625.    rc = hllapi('Wait')
  626.    return
  627.  
  628.  
  629. HostEnterIBMLinkInfo: procedure expose Host.
  630.    /**
  631.    ***   This will enter the account, userid, password and service (IBMLINK)
  632.    ***   to connect to the IBMLink main menu
  633.    ***
  634.    ***   On Entry:  CL/Menu
  635.    ***   On Exit:   IBMLink Main Menu
  636.    **/
  637.  
  638.    code = HostWaitFor(60, 'I N F O R M A T I O N     N E T W O R K')
  639.    if code = -1 then
  640.       call HostError
  641.  
  642.    code = hllapi('Sendkey', '@0'Host.Account'@T'Host.Userid)
  643.    if (length(Host.Userid) < 7) then
  644.       code = hllapi('Sendkey', '@T')
  645.    code = hllapi('Sendkey', Host.Password'@TIBMLink@E')
  646.  
  647.    code = HostWaitFor(180, 'MAINMENU')
  648.    if code = -1 then
  649.       call HostError
  650.    return
  651.  
  652.  
  653. HostLogonClMenu: procedure expose Host.
  654.    /**
  655.    ***  This will check to see if the session is at the Quality logo
  656.    ***  or the CLMenu screen or the "Press Enter..." one-liner screen.
  657.    ***  Upon exit, you will be placed at the CL/Menu screen.
  658.    **/
  659.  
  660.    pos = hllapi('Search_ps','CLM095I - PRESS ENTER OR PF KEY TO GET CL/MENU DISPLAY',1)
  661.    if pos <> 0 then
  662.       do
  663.       rc=hllapi('Sendkey', '@E')
  664.       rc=hllapi('Wait')
  665.       end
  666.  
  667.    pos = hllapi('Search_ps','To start, enter MENU ====>',1)
  668.    if pos <> 0 then
  669.       do
  670.  
  671.       /* Enter the menu command */
  672.  
  673.       call HapiClear
  674.       rc=hllapi('Sendkey', 'MENU@E')
  675.       rc=hllapi('Wait')
  676.       end
  677.  
  678.    /* Wait for the CL/Menu main screen to appear.  If it doesn't after */
  679.    /* a few retries, bomb out.                                         */
  680.  
  681.    code = HostWaitFor(10, '/L - LOGON TO VTAM APPLICATION')
  682.    if code = -1 then
  683.       call HostError
  684.    return
  685.  
  686.  
  687. HostWaitFor: procedure expose Host.
  688.    /**
  689.    ***  This will wait for a certain string to appear on the screen.  Some
  690.    ***  applications will unlock the keyboard while processing (e.g. most
  691.    ***  VM applictions), so the HLLAPI code can't just wait for keyboard
  692.    ***  unlock.  This will check for a particular character string before
  693.    ***  returning.  If the string doesn't appear within the number of
  694.    ***  seconds passed, it will return a '-1' return code.
  695.    **/
  696.  
  697.    parse arg MaxSeconds, SearchString
  698.  
  699.    sleeps = 0
  700.    do until pos <> 0
  701.       pos=hllapi('Search_ps', SearchString, 1)
  702.       call SysSleep 1
  703.       sleeps = sleeps + 1
  704.  
  705.       if sleeps >= MaxSeconds then
  706.          return -1
  707.    end /* until */
  708.    return 0
  709.  
  710.  
  711. /**
  712. *** ┌──────────────────────────────────────────────────────────────────────┐
  713. *** │                           HLLAPI Routines                            │
  714. *** └──────────────────────────────────────────────────────────────────────┘
  715. **/
  716.  
  717. HapiError: procedure expose Host.
  718.    /**
  719.    ***
  720.    **/
  721.    arg code verb .
  722.  
  723.    say 'Return code' code 'from HLLAPI command:' verb'.'
  724.    call HapiDisconnect
  725.    exit
  726.  
  727.  
  728. HapiDisconnect: procedure expose Host.
  729.    /**
  730.    ***  This will disconnect the HLLAPI session from the host
  731.    **/
  732.    call hllapi 'disconnect'
  733.    call hllapi 'reset_system'
  734.    return
  735.  
  736.  
  737. HapiConnect: procedure expose Host.
  738.    /**
  739.    ***  This will connect to the host session and make sure the keyboard is
  740.    ***  unlocked.
  741.    **/
  742.  
  743.    rc = hllapi('Connect',Host.Session)
  744.    if rc <> 0 then
  745.       call HapiError rc 'Connect'
  746.  
  747.    rc=hllapi('Wait')
  748.    if rc <> 0 then
  749.       call HapiError rc 'Wait'
  750.    return
  751.  
  752.  
  753. HapiClear: procedure expose Host.
  754.    /**
  755.    ***  This will clear the host screen
  756.    **/
  757.    rc=hllapi('Sendkey', '@C')    /* Send a clear key */
  758.    rc=hllapi('Wait')             /* Wait for clear key to complete */
  759.    return
  760.  
  761. /**
  762. *** ┌──────────────────────────────────────────────────────────────────────┐
  763. *** │ OPEN                                                                 │
  764. *** └──────────────────────────────────────────────────────────────────────┘
  765. **/
  766. Open: procedure
  767.  
  768.    arg file, mode
  769.  
  770.    FileExists = stream(file,c,'QUERY EXIST')
  771.  
  772.    /* Take special actions based on certain open modes */
  773.  
  774.    select
  775.       when Mode = 'READ'   then
  776.          OpenMsg = stream(file, c, 'OPEN READ')
  777.       when Mode = 'WRITE'  then
  778.          do
  779.          if (FileExists <> '') then
  780.             do
  781.             if (mode = 'WRITE') then
  782.                '@erase' file
  783.             file = FileExists
  784.             end
  785.          OpenMsg = stream(file, c, 'OPEN WRITE')
  786.          end
  787.       when Mode = 'APPEND' then
  788.          OpenMsg = stream(file, c, 'OPEN WRITE')
  789.       otherwise
  790.          do
  791.          say 'Error: Invalid open mode' mode'.'
  792.          return ''
  793.          end
  794.    end /* select */
  795.  
  796.    if (OpenMsg <> 'READY:') then
  797.       do
  798.       say 'Error: Open failure on' file'.' message
  799.       return ''
  800.       end
  801.    return file
  802.  
  803. /**
  804. *** ┌──────────────────────────────────────────────────────────────────────┐
  805. *** │ CLOSE                                                                │
  806. *** └──────────────────────────────────────────────────────────────────────┘
  807. **/
  808. Close: procedure
  809.  
  810.    arg file
  811.    message = stream(file,c,'CLOSE')
  812.    if (message \= 'READY:') & (message \= '') then
  813.       do
  814.       say 'Error: Close failure on' file'.' message
  815.       exit
  816.       end
  817.    return file
  818. /**
  819. *** ┌──────────────────────────────────────────────────────────────────────┐
  820. *** │ EXISTS                                                               │
  821. *** └──────────────────────────────────────────────────────────────────────┘
  822. **/
  823. Exists: procedure
  824.  
  825.    arg file
  826.  
  827.    file = stream(file,c,'QUERY EXIST')
  828.    if (file = '') then
  829.       return 0
  830.    else
  831.       return 1
  832.