home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / epm603b.zip / EPMMAC.ZIP / E3EMUL.E < prev    next >
Text File  |  1996-05-22  |  63KB  |  1,938 lines

  1. /**************************************************************************/
  2. /*  E3EMUL             Version  ==>    3.12/4.13/5.18         90/09/14    */
  3. /**************************************************************************/
  4.  
  5. ; Note:  The following constants should not be changed here.  Instead, anything
  6. ; you want different should be copied to your MYCNF.E and modified there.  That
  7. ; way, there's no need to merge in your changes when this file is updated.
  8.  
  9. /* Recommended for OS/2 Comm. Manager:  Copy next 3 or 4 lines to your MYCNF.E:
  10. const                  -- Configuration for E3EMUL:
  11.    HOST_SUPPORT = 'EMUL'  -- Tell E to include E3EMUL for host support.
  12.    USING = 'CM'           -- This enables multiple logical terminal support.
  13.    my_HOSTCOPY = 'AC'     -- Or whatever, *if* you renamed ALMCOS2 to something else.
  14. */
  15.  
  16. compile if not defined(SMALL)  -- Now, can be compiled stand-alone and linked in!
  17.    include 'STDCONST.E'
  18.  define INCLUDING_FILE = 'E3EMUL.E'
  19.    tryinclude 'MYCNF.E'
  20.  
  21.  compile if not defined(SITE_CONFIG)
  22.     const SITE_CONFIG = 'SITECNF.E'
  23.  compile endif
  24.  compile if SITE_CONFIG
  25.     tryinclude SITE_CONFIG
  26.  compile endif
  27.  compile if not defined(HOST_SUPPORT)
  28. *** Error:  E3EMUL being compiled, but HOST_SUPPORT was not set in MYCNF.E.
  29.  compile endif
  30. const
  31.  compile if not defined(BACKUP_PATH)
  32.    BACKUP_PATH = ''
  33.  compile endif
  34. ;compile if not defined(AUTOSAVE_PATH)  -- now use vAUTOSAVE_PATH
  35. ;  AUTOSAVE_PATH=''
  36. ;compile endif
  37.  compile if not defined(SMARTQUIT)
  38.    SMARTQUIT = 0
  39.  compile endif
  40.  compile if not defined(FILEKEY)
  41.    FILEKEY   = 'F4'  -- Note:  Must be a string (in quotes).
  42.  compile endif
  43.  compile if not defined(WANT_DBCS_SUPPORT)
  44.    WANT_DBCS_SUPPORT = 0
  45.  compile endif
  46.  compile if not defined(LINK_HOST_SUPPORT)
  47.    LINK_HOST_SUPPORT = 0
  48.  compile endif
  49.  compile if not defined(DELAY_SAVEPATH_CHECK)
  50.    DELAY_SAVEPATH_CHECK = 0
  51.  compile endif
  52.  compile if not defined(NLS_LANGUAGE)
  53.    NLS_LANGUAGE = 'ENGLISH'
  54.  compile endif
  55. include NLS_LANGUAGE'.e'
  56. compile endif  -- not defined(SMALL)
  57.  
  58. compile if HOST_SUPPORT<>'EMUL'
  59. *** Error:  E3EMUL being compiled, but HOST_SUPPORT is other than 'EMUL'.
  60. compile endif
  61.  
  62.   const              -- Constants are value 0/No, 1/Yes
  63.  
  64.       -- to include VM file support
  65. compile if not defined(VM)
  66.   VM  = 1
  67. compile endif
  68.       -- to include MVS file support
  69. compile if not defined(MVS)
  70.   MVS = 0
  71. compile endif
  72.       -- to include KENKAHN's MVS routines
  73. compile if not defined(E3MVS)
  74.   E3MVS = 0
  75. compile endif
  76.       -- RUNTIME governs whether one can configure E3EMUL when editing
  77. compile if not defined(RUNTIME)
  78.   RUNTIME = 0
  79. compile endif
  80.       -- USING could be: MYTE, BOND, E78, CP78, IBM, CM, CM+IBM, or CM+CP78
  81.       -- IBM => SEND/RECEIVE protocol, e.g.
  82.       --        OS/2 EE Communications Manager
  83.       --        3270 Control Program
  84.       --        3270 Emulation Program
  85.       --        3278/79 Emulation Program
  86.       --        INPCS(X)
  87.       --        apparently, FTTERM
  88.       -- CM  => OS/2 EE Communications Manager, using ALMCOPY instead of SEND/RECEIVE
  89.       -- CM+IBM => Multiple protocols; like CM for VM files, IBM for MVS.
  90.       -- CM+CP78 => Multiple adapters; use CM for H:xxx and CP78 for 2:xxx
  91. compile if not defined(USING)
  92.   USING = 'IBM'
  93. compile endif
  94.       -- CM Send & Receive don't work from inside a PM program, so we call them
  95.       -- via EHLLAPI if we're using EPM.  The FTTERM and PMFTERM versions do
  96.       -- work (and EHLLAPI does not), so we let the user override the default.
  97. compile if not defined(USE_EHLLAPI)
  98.  compile if EPM
  99.   USE_EHLLAPI = 1
  100.  compile else
  101.   USE_EHLLAPI = 0
  102.  compile endif
  103. compile endif
  104.       -- if you want to be allowed duplicate copies (not views) of files
  105. compile if not defined(DUPLICATES_ALLOWED)
  106.   DUPLICATES_ALLOWED = 1
  107. compile endif
  108.       -- for debug purposes, not normally changed
  109. compile if not defined(DEBUG)
  110.   DEBUG = 0
  111. compile endif
  112.       -- The following is for if you are affected by the ALMCOPY bug that leaves
  113.       -- the cursor the wrong shape:
  114. compile if not defined(FIX_CURSOR)
  115.   FIX_CURSOR = 0
  116. compile endif
  117.       -- Default file mode, if not specified, is 'A'.  Some users might prefer
  118.       -- '*'.  Caution - do not change unless you know what this will do to your
  119.       -- file transfer program.
  120. compile if not defined(DEFAULT_FILEMODE)
  121.   DEFAULT_FILEMODE = 'A'
  122. compile endif
  123.       -- This is the drive letter used on the HOSTCOPY command.
  124.       -- Distinct from HOSTDRIVE, for users who have a real H: drive on the PC.
  125. compile if not defined(HOSTCOPYDRIVE)
  126.    HOSTCOPYDRIVE= 'H'
  127. compile endif
  128.       -- If you want a USER_FTO routine to get called when files are being saved.
  129.       -- This lets you change the default FTO for special cases
  130.       -- (e.g., files that must be RECFM F LRECL 80).
  131. compile if not defined(CALL_USER_FTO)
  132.   CALL_USER_FTO = 0
  133. compile endif
  134.  
  135. /* A sample user_FTO might be:
  136.    defproc user_FTO(hostfile, var fto, verb)
  137.       universal emulator, hostcopy
  138.       universal hname, htype, hmode
  139.       if verb='SAVE' & htype='ASSEMBLE' then
  140.          if emulator = 'IBM' or emulator = 'CP78' then
  141.             fto = 'LRECL 80 RECFM V ASCII CRLF'     -- For SEND command.
  142.          elseif upcase(substr(hostcopy,1,3))='ALM' then
  143.             fto = '/f=80 /ascii /q'                 -- For ALMCOPY command.
  144.          elseif emulator = 'MYTE' then
  145.             fto = '/f=80 /ascii'                    -- For MYTECOPY command.
  146.          endif  -- (You only need support the HOSTCOPY method(s) you use.)
  147.       endif
  148. */
  149. compile if E3MVS & EVERSION >= 4
  150.  *** Error - E3MVS should only be specified for E3, not EOS2 or EPM.
  151. compile endif
  152.       -- The default is implicit host support.  If you want:  Edit TEMP FILE A
  153.       -- to load 3 PC files instead of a host file, set the following to 1.
  154. compile if not defined(HOSTDRIVE_REQUIRED)
  155.    HOSTDRIVE_REQUIRED = 0
  156. compile endif
  157.       -- Users who are used to H: as the host drive, but have a real H: drive,
  158.       -- might want to use HA:, HB:, etc. to refer to the host, while just H:
  159.       -- will refer to the workstation.  (This is an alternative to setting
  160.       -- HOSTDRIVE to 'V' or something like that.)  This implies HOSTDRIVE_REQUIRED.
  161. compile if not defined(HOST_LT_REQUIRED)
  162.    HOST_LT_REQUIRED = 0
  163. compile endif
  164.       -- ELEP78 users will want to change the commands used for SEND and RECEIVE.
  165.       -- This isn't used for USING='CP78'
  166. compile if not defined(RECEIVE_CMD)
  167.    RECEIVE_CMD = 'receive'
  168. compile endif
  169. compile if not defined(SEND_CMD)
  170.    SEND_CMD = 'send'
  171. compile endif
  172.  
  173. definit
  174.   universal emulator, hostcopy, hostcmd, LT, hostdrive, savepath, ftoptions
  175.   universal keep_temp_files, binoptions, vAUTOSAVE_PATH
  176.  
  177.   emulator = upcase(USING)
  178.  
  179. compile if defined(my_LT)
  180.   LT = my_LT
  181. compile else
  182.   LT = 'A'
  183. compile endif
  184.                           -- for MYTE with multiple logical terminals
  185.                           -- or IBM (3270CP, OS/2 EE) to indicate a
  186.                           -- default LT or window...
  187.  
  188. compile if defined(my_hostdrive)
  189.   hostdrive = my_HOSTDRIVE
  190. compile else
  191.   hostdrive = 'H'
  192. compile endif
  193.                           -- should be 'h' for myte, e38 and bond -
  194.                           -- you may attempt to use others for IBM
  195.                           -- emulators, or your own purposes...
  196.  
  197.  
  198. compile if defined(my_hostcopy)
  199.   hostcopy= my_hostcopy
  200. compile else
  201.  compile if USING = 'IBM' | USING = 'CP78'  -- 89/10/19 - CP78 now has its own Send/Receive
  202.   hostcopy = ''
  203.  compile elseif USING = 'CM' | USING = 'CM+IBM' | USING = 'CM+CP78'
  204.   hostcopy = 'almcopy'
  205.  compile else
  206.   hostcopy = USING||'copy'
  207.  compile endif
  208. compile endif
  209.  
  210.                           -- could be mytecopy, e78copy, bondcopy or
  211.                           -- any other command with a similar command
  212.                           -- line syntax, such as almcopy.
  213.                           -- (almcopy multi file capability not yet
  214.                           -- supported)
  215.                           -- Not necessary to specify for emulator =
  216.                           -- 'IBM'
  217.  
  218. compile if defined(my_hostcmd)
  219.   hostcmd= my_hostcmd
  220. compile else
  221.  compile if USING = 'IBM' | USING = 'CP78'
  222.   compile if USE_EHLLAPI
  223.      hostcmd = 'EHLLAPI'
  224.   compile elseif EOS2
  225.      hostcmd = 'OS2CMD'
  226.   compile else
  227.      hostcmd = 'HOSTSYS'
  228.   compile endif
  229.  compile elseif USING = 'CM' | USING = 'CM+IBM' | USING = 'CM+CP78'
  230.   hostcmd = 'OS2CMD'
  231.  compile elseif USING = 'BOND'
  232.   hostcmd = 'VM'
  233.  compile else
  234.   hostcmd = USING||'cmd'
  235.  compile endif
  236. compile endif
  237.                           -- could be MYTECMD, E78CMD, VM (pcvmbond)
  238.                           -- or HOSTSYS.
  239.                           -- If emulator = 'IBM', then must be
  240.                           -- 'HOSTSYS', and the hostsys device driver
  241.                           -- must be installed for applications like
  242.                           -- E3NOTE to work
  243.  
  244. compile if defined(my_FTOPTIONS)
  245.   ftoptions = my_FTOPTIONS
  246. compile else
  247.  compile if USING = 'IBM'
  248.   compile if USE_EHLLAPI
  249.   ftoptions = 'ASCII CRLF'            -- Omit redirection if EPM (uses EHLLAPI)
  250.   compile else
  251.   ftoptions = 'ASCII CRLF >nul'       -- The minimum for IBM emulators
  252.   compile endif
  253. ;  ftoptions = '(ASCII CRLF)'       -- The noisy minimum for IBM emulators
  254.  compile elseif USING = 'MYTE'
  255.   ftoptions = '/ascii'                  -- The minimum for MYTE
  256.  compile elseif USING = 'E78' or USING = 'BOND'
  257.   ftoptions = '/q'
  258.  compile elseif USING = 'CM'  | USING = 'CM+IBM' | USING = 'CM+CP78'
  259.   ftoptions = '/q /ascii'
  260.  compile elseif USING = 'CP78'
  261.     ftoptions = 'ASC Q'
  262.  compile else
  263.   ftoptions = ''
  264.  compile endif
  265. compile endif
  266.                           -- Should you desire to add any options to
  267.                           -- the invocation of your hostcopy command,
  268.                           -- you may add a default set here, and/or
  269.                           -- change them with the FTO command   --
  270.                           -- Use the proper syntax; add slashes as
  271.                           -- necessary - E3EMUL does absolutely NO
  272.                           -- syntax checking on this one!
  273.  
  274. compile if defined(my_BINOPTIONS)
  275.   binoptions = my_BINOPTIONS
  276. compile else
  277.  compile if USING = 'IBM'
  278.   compile if USE_EHLLAPI
  279.   binoptions = ''                     -- Omit redirection if EPM (uses EHLLAPI)
  280.   compile else
  281.   binoptions = '() >nul'
  282.   compile endif
  283.  compile elseif USING = 'MYTE'
  284.   binoptions = '/b'
  285.  compile elseif USING = 'E78' or USING = 'BOND' or USING = 'CM'  | USING = 'CM+IBM' | USING = 'CM+CP78'
  286.   binoptions = '/b /q'
  287.  compile elseif USING = 'CP78'
  288.     binoptions = 'BIN Q'
  289.  compile else
  290.   binoptions = ''
  291.  compile endif
  292. compile endif
  293.                           -- These options will be used if E3EMUL
  294.                           -- detects the suffix BIN on a VM host file
  295.                           -- This should make it unnecessary for you
  296.                           -- to add /fto to edit most of 'our' VM
  297.                           -- binary files.
  298.  
  299. compile if defined(my_SAVEPATH)
  300.   SAVEPATH = my_SAVEPATH
  301. compile else
  302.   SAVEPATH = vAUTOSAVE_PATH     -- Default is user's AUTOSAVE path.
  303. compile endif
  304.                           -- If you wish temporary files to be saved
  305.                           -- to a specific subdirectory, name it here
  306.                           -- NOTE: this is different from the
  307.                           -- Temp_Path used in Autosave!  This is for
  308.                           -- the files created in up/downloading your
  309.                           -- host files.
  310.                           -- The syntax is: d:\path\
  311.                           -- DON'T FORGET THE TRAILING BACKSLASH
  312.  
  313. compile if defined(my_KEEP_TEMP_FILES)
  314.   KEEP_TEMP_FILES = MY_KEEP_TEMP_FILES
  315. compile else
  316.   KEEP_TEMP_FILES = 0
  317. compile endif
  318.                           -- If you wish temporary files to be saved
  319.                           -- even after the editing session is done,
  320.                           -- this should be set to 1.  This is good
  321.                           -- for those of us with recurring file
  322.                           -- transfer problems, or just paranoia :-)
  323.  
  324. /* definit code */
  325.  
  326. compile if (not EPM or defined(my_SAVEPATH)) and not DELAY_SAVEPATH_CHECK
  327.   call check_savepath()                 -- EPM does it in MAIN.E if no savepath defined, to pick up autosave path saved from Settings dialog.
  328. compile endif
  329.   LT = strip(LT,'b',':')
  330.  
  331.  
  332. /**************************************************************************/
  333. /*                                                                        */
  334. /*   PROCS - procedures for host file support                             */
  335. /*                                                                        */
  336. /**************************************************************************/
  337.  
  338.  
  339. defproc loadfile(file,options)
  340.  
  341.   universal hostdrive, savepath, fto
  342.  
  343. ;  Sneaky use of fto here - Larry made it universal, so the EDIT command could
  344. ;  pass fto outside the argument list.  From here on in, fto is passed via
  345. ;  argument list, and is not global.
  346.  
  347.   file=strip(file,'B')
  348.   fto=strip(fto,'B')
  349.   hostfileid=''
  350.  
  351.                           -- sets hostfile, tempfile, thisLT, bin
  352.   hosttype = ishost(file, 'EDIT', hostfile, tempfile, thisLT, bin)
  353.   if hosttype then
  354.      hostfilename = hostdrive||thisLT||hostfile
  355.      create_flag = isoption(options,'C')
  356.      if isoption(options,'N') | create_flag then
  357.         if already_in_ring(file, hostfileid) and not create_flag then
  358.            activatefile hostfileid
  359.         else
  360. compile if EVERSION >= '4.10'
  361.            'xcom e /c' options tempfile    -- 'E /C' forces creation of a new file
  362. compile else
  363.            'xcom e' options tempfile
  364. compile endif
  365.           .filename=hostfilename
  366.            getfileid hostfileid
  367.            rc = -282  -- sayerror('New file')
  368.         endif
  369. compile if not DUPLICATES_ALLOWED
  370.      elseif already_in_ring(hostfilename, hostfileid) then
  371.         activatefile hostfileid
  372. compile endif
  373.      else
  374.         set_FTO(hostfilename, bin, fto)
  375.         call load_host_file(hostfile, hostfileid,
  376.                                 tempfile, thisLT, fto, bin, options)
  377.         if rc then
  378.            activatefile hostfileid     -- make hidden ring active if hidden
  379.         endif
  380.      endif
  381.      call hidden_info(hostfileid, .filename, tempfile, fto, 'EDIT', bin, hosttype)
  382.   else
  383.      'xcom e 'options file             -- vanilla PC file - complex, eh?
  384.   endif
  385.  
  386.  
  387. defproc load_host_file(hostfile, var hostfileid, tempfile,
  388.                                thisLT, fto, bin, options)
  389.  
  390.   universal hostcopy, hostdrive
  391.   universal emulator, keep_temp_files
  392. compile if WANT_DBCS_SUPPORT
  393.   universal country, codepage, ondbcs
  394. compile endif
  395.  
  396. ; LAM:  Check internal flag before doing more expensive call to OS routine:
  397.   if not keep_temp_files then          -- saving tempfiles? overwrite at will
  398.      if exist(tempfile) then           -- Check for existence of prior PC file
  399.         if askyesno(OVERLAY_TEMP1__MSG,1)<>YES_CHAR then
  400.            return 0
  401.         endif
  402.      endif
  403.   endif
  404.  
  405.   hostfilename = hostdrive||thisLT||hostfile
  406. compile if EVERSION < 5           -- Avoid trivial SAYERRORs in EPM
  407.   call message(LOADING_PROMPT__MSG hostfilename WITH__MSG fto)
  408. compile endif
  409.                                                      -- build download command
  410.   if emulator = 'IBM' | emulator = 'CP78' then
  411. compile if WANT_DBCS_SUPPORT
  412.     p = lastpos('ASCII', fto)
  413.     if p and lastpos(codepage, 932 942) then
  414.        fto = substr(fto, 1, p - 1)'JI'substr(fto, p + 1)
  415.     endif
  416. compile endif
  417.     if emulator<>'IBM' then
  418.        rcv = RECEIVE_CMD
  419.     else
  420.        rcv = 'receive'
  421.     endif
  422.     if thisLT=':' then
  423.       line = 'xcom' rcv tempfile hostfile fto
  424.     else
  425.       line = 'xcom' rcv tempfile thisLT||hostfile fto
  426.     endif
  427.   else
  428.     line = hostcopy HOSTCOPYDRIVE||thisLT||hostfile tempfile fto
  429.   endif
  430. compile if DEBUG
  431.   messagenwait(line)
  432. compile endif
  433.  
  434. compile if USE_EHLLAPI
  435.   if emulator = 'IBM' then
  436.      rc = EHLLAPI_SEND_RECEIVE(91, substr(line,14))  -- RECEIVE = 91
  437.   else
  438. compile endif
  439.   quiet_shell line                                -- do the download
  440. compile if FIX_CURSOR
  441.   insert_toggle; insert_toggle
  442. compile endif
  443. compile if EPM
  444.    endif
  445. compile endif
  446. compile if E3  -- Only E3 generates an "Insufficient memory" error.
  447.    if rc=sayerror("Insufficient memory") then     --LAM:  Not transfer error
  448.       stop
  449.    endif
  450. compile endif
  451.  
  452. compile if E3MVS
  453.   rc = isa_E3mvs_filename(rc,Error_msg,'RESET',rc,rc,rc,rc)
  454. compile endif
  455.  
  456.   getfileid startid
  457.   if rc then                                   -- assume host file not found
  458.      hostrc = rc
  459.      'xcom e 'options' /n .newfile'
  460.      if rc = -274 then  -- Unknown command
  461.         messageNwait(FILE_TRANSFER_CMD_UNKNOWN'  'line)
  462.      else
  463.         if not isoption(options,'Q') then
  464.            call message(FILE_TRANSFER_ERROR__MSG hostrc'.  'HOST_NOT_FOUND__MSG)
  465.         endif
  466.      endif
  467.      rc=-282  -- sayerror('New file')
  468.   else                                                -- good download occurred
  469.      'xcom e /d /q 'options tempfile
  470.      erc = rc
  471.      if keep_temp_files then
  472.         message(SAVED_LOCALLY_AS__MSG upcase(tempfile))
  473.      else
  474.         call erasetemp(tempfile)
  475.      endif
  476.      if erc then
  477.         call message(rc)
  478.      endif
  479.   endif
  480.  
  481.   getfileid hostfileid                               -- set pertinent file data
  482.   if hostfileid=startid then stop; endif    -- Uh oh - new file wasn't loaded.
  483.   if thisLT then
  484.     .filename=hostdrive||thisLT||hostfile
  485.   else
  486.     .filename=hostdrive':'hostfile
  487.   endif
  488.  
  489.  
  490. defproc savefile(given_name)
  491.   universal hostdrive, LT
  492. compile if BACKUP_PATH <> '' & BACKUP_PATH <> '='
  493.    universal backup_path_ok
  494. compile endif
  495.                                              -- prepare given arguments for use
  496.    parse value given_name with name '[' fto ']'
  497.    options=arg(2)
  498.  
  499.                           -- sets hostfile, tempfile, thisLT, bin
  500.   hosttype = ishost(name, 'SAVE', hostfile, tempfile, thisLT, bin)
  501.   if hosttype then
  502.      hostfilename = hostdrive||thisLT||hostfile
  503.      if .filename=hostfilename then  --assume saving this copy
  504.         getfileid hostfileid
  505.      else
  506.         getfileid hostfileid, hostfilename  --could be saving non-current file
  507.      endif
  508.      call hidden_info(hostfileid, hostfilename, tempfile, fto, 'SAVE', bin, hosttype)
  509.      src=save_host_file(hostfile, tempfile, thisLT, fto, hostfileid, options)  --LAM
  510.      if src then         -- if host error, offer to save on PC
  511.         if askyesno(SAVE_LOCALLY__MSG,1) = YES_CHAR then
  512.            dot = pos('.',tempfile,max(lastpos('\',tempfile),1))  -- Handle '.' in path
  513.            if dot then tempfile=substr(tempfile,1,dot-1); endif
  514.            if exist(tempfile'.TMP') then
  515. compile if EVERSION < 5
  516.               if askyesno(FILE__MSG tempfile'.TMP' OVERLAY_TEMP2__MSG,1) = 'N' then
  517. compile else
  518.               if winmessagebox('', FILE__MSG tempfile'.TMP' OVERLAY_TEMP3__MSG, 16449)=2 then
  519. compile endif
  520.                  stop
  521.               endif
  522.            endif
  523.            'xcom s 'tempfile'.TMP'
  524.            if rc then return rc; endif
  525.            messageNwait(SAVED_LOCALLY_AS__MSG tempfile'.TMP' PRESS_A_KEY__MSG)  --LAM
  526.         endif
  527.      endif
  528.      call message(1)
  529.      return src
  530.   endif                   --LAM: Don't need ELSE since THEN does a RETURN.
  531.    name=strip(given_name)  -- Allow for brackets in PC names
  532. compile if EVERSION >= '5.50'  --@HPFS
  533.    name_same = (name = .filename)
  534.    if pos(' ',name) & leftstr(name,1)<>'"' then
  535.       name = '"'name'"'
  536.    endif
  537. compile endif
  538. compile if BACKUP_PATH
  539.        -- jbl 1/89 new feature.  Editors in the real marketplace keep at least
  540.        -- one backup copy when a file is written.
  541.  compile if BACKUP_PATH <> '='
  542.    if backup_path_ok then
  543.  compile endif
  544.  compile if EVERSION >= '4.10'    -- OS/2 - redirect STDOUT & STDERR
  545.       quietshell 'copy' name MakeBakName() '1>nul 2>nul'
  546.  compile else
  547.       quietshell 'copy' name MakeBakName() '>nul'
  548.  compile endif
  549.  compile if BACKUP_PATH <> '='
  550.    endif
  551.  compile endif
  552. compile endif
  553.    'xcom s 'options name; src=rc    -- the save code for a vanilla PC file...
  554. compile if EVERSION >= '5.50'  --@HPFS
  555.    if not rc and name_same then
  556. compile else
  557.    if not rc and name=.filename then
  558. compile endif
  559.       .modify=0
  560.       'deleteautosavefile'
  561.    endif
  562.    return src
  563.  
  564.  
  565. defproc save_host_file(hostfile, tempfile, thisLT, fto, hostfileid, options)
  566.  
  567.   universal hostcopy, hostdrive
  568.   universal LT, emulator, keep_temp_files
  569. compile if WANT_DBCS_SUPPORT
  570.   universal country, codepage, ondbcs
  571. compile endif
  572.  
  573.   getfileid hostfileid
  574. compile if EPM32
  575.   'xcom save /o 'tempfile   -- Save in OS/2 format.
  576. compile else
  577.   'xcom save 'tempfile
  578. compile endif
  579.   if rc then stop endif
  580.  
  581.   hostfilename = hostdrive||thisLT||hostfile
  582.  
  583.   if not isoption(options,'Q') then
  584. compile if EPM & EVERSION < '5.50'
  585.      call sayatbox(SAVING_PROMPT__MSG hostfilename WITH__MSG fto)
  586. compile else
  587.      call message(SAVING_PROMPT__MSG hostfilename WITH__MSG fto)
  588. compile endif
  589.    endif
  590.                                      -- build command line
  591.   if emulator = 'IBM' | emulator = 'CP78' then
  592. compile if WANT_DBCS_SUPPORT
  593.      p = lastpos('ASCII', fto)
  594.      if p and lastpos(codepage, 932 942) then
  595.         fto = substr(fto, 1, p - 1)'JI'substr(fto, p + 1)
  596.      endif
  597. compile endif
  598.      if emulator<>'IBM' then
  599.         send = SEND_CMD
  600.      else
  601.         send = 'send'
  602.      endif
  603.      if thisLT=':' then
  604.        line = 'xcom' send tempfile hostfile fto
  605.      else
  606.        line = 'xcom' send tempfile thisLT||hostfile fto
  607.      endif
  608.   else
  609.      line = hostcopy tempfile HOSTCOPYDRIVE||thisLT||hostfile fto
  610.   endif
  611. compile if DEBUG
  612.   messagenwait(line)
  613. compile endif
  614.  
  615. compile if USE_EHLLAPI
  616.   if emulator = 'IBM' then
  617.      rc = EHLLAPI_SEND_RECEIVE(90,substr(line,11))  -- SEND = 90
  618.   else
  619. compile endif
  620.   quiet_shell line
  621. compile if FIX_CURSOR
  622.   insert_toggle; insert_toggle
  623. compile endif
  624. compile if EPM
  625.    endif
  626. compile endif
  627.  
  628. compile if E3MVS
  629.   rc = isa_E3mvs_filename(rc,Error_msg,'RESET',rc,rc,rc,rc)
  630. compile endif
  631.  
  632.   if rc then
  633. compile if E3  -- Only E3 generates an "Insufficient memory" error.
  634.       if rc=sayerror('Insufficient memory') then       --LAM
  635.          emsg = 'Insufficient memory to call 'hostcopy
  636.       else
  637.          emsg = 'Host error 'rc' - no save'
  638.       endif
  639.       messagenwait(emsg'.  File saved on PC in 'tempfile)
  640. compile else
  641.       messagenwait(HOST_ERROR__MSG rc'; 'HOST_CANCEL__MSG tempfile)
  642. compile endif
  643.      return 1
  644.   else
  645.      if .filename=hostfilename then
  646.         hostfileid.modify=0                    -- reset 'modify since saved' switch
  647.      endif
  648.      if keep_temp_files then
  649.         message(SAVED_LOCALLY_AS__MSG upcase(tempfile))
  650.      else
  651.         call erasetemp(tempfile)
  652.      endif
  653.   endif
  654.   return 0
  655.  
  656.  
  657. defproc namefile(newname)
  658.   universal hostdrive
  659.  
  660.   hostfileid=''
  661.   parse value upcase(newname) with name '[' fto ']'
  662.  
  663.                        -- sets hostfile, tempfile, thisLT, bin
  664.   hosttype = ishost(name, 'NAME', hostfile, tempfile, thisLT, bin)
  665.   if hosttype then
  666.      hostfilename = hostdrive||thisLT||hostfile
  667. compile if DUPLICATES_ALLOWED
  668.      getfileid hostfileid
  669. compile else
  670.      if already_in_ring(hostfilename, hostfileid) then -- is file being edited?
  671.         message(ALREADY_EDITING_MSG)
  672.         return 1                          -- then error - two files one name
  673.      endif
  674. compile endif
  675.      call hidden_info(hostfileid, hostfilename, tempfile, fto, 'NAME', bin, hosttype)
  676.      .filename=hostfilename
  677.   elseif parse_filename(newname,.filename) then
  678.      sayerror INVALID_FILENAME__MSG
  679.   else
  680. compile if EVERSION >= '5.50'  --@HPFS
  681.       if pos(' ',newname) & leftstr(newname,1)<>'"' then
  682.          newname = '"'newname'"'
  683.       endif
  684. compile endif
  685.      'xcom n 'newname  --  for a vanilla PC name
  686.   endif
  687.  
  688.  
  689. defproc quitfile()
  690.   universal keep_temp_files
  691.  
  692. compile if EVERSION < 5
  693.    if .windowoverlap then
  694.       modify=(.modify and .views=1)
  695.    else
  696.       modify=.modify
  697.    endif
  698.    k='Y'
  699.    if modify then
  700.  compile if SMARTQUIT
  701.       call message(QUIT_PROMPT1__MSG '('FILEKEY')')
  702.  compile else
  703.       call message(QUIT_PROMPT2__MSG)
  704.  compile endif
  705.       loop
  706.          k=upcase(getkey())
  707.  compile if SMARTQUIT
  708.          if k=$FILEKEY then 'File'; return 1              endif
  709.  compile endif
  710.          if k=YES_CHAR or k=NO_CHAR or k=esc then leave;  endif
  711.       endloop
  712.       call message(1)
  713.    endif
  714.    if k<>YES_CHAR then
  715.       return 1
  716.    endif
  717.    if not .windowoverlap or .views=1 then
  718.       .modify=0
  719.    endif
  720. compile endif
  721.  
  722.    'deleteautosavefile'
  723. ;  if not pos('.DIR',.filename) and substr(.filename,1,1) <> '.' then
  724.    if substr(.filename,1,1) <> '.' then
  725. ;;    if check_for_host_file(.filename) then
  726.       hosttype = ishost(.filename, 'CHECK', hostfile, tempfile, thisLT, bin)
  727.       if hosttype then
  728.          getfileid quitfileid
  729.          call hidden_info(quitfileid, .filename, tempfile, fto, 'QUIT', bin, hosttype)
  730.          if not keep_temp_files then
  731.             call erasetemp(tempfile)
  732.          endif
  733.       endif
  734.    endif
  735.    'xcom_quit'
  736.  
  737. /* No longer used by E3EMUL.E, but some user code may depend on it... */
  738. defproc check_for_host_file(arg1)
  739.   return ishost(arg1, 'CHECK', hostfile, tempfile, thisLT, bin)
  740.  
  741.  
  742. defproc ishost(candidate, verb, var hostfile, var tempfile, var thisLT, var bin)
  743.  
  744.    universal hostdrive, LT, binoptions, ftoptions, emulator
  745.  
  746.  -- also returns a numeric value:
  747.  --  0 -- PC  filename
  748.  --  1 -- VM  filename
  749.  --  2 -- MVS filename
  750.  
  751. compile if DEBUG
  752. ;   messagenwait('ishost sees: 'candidate verb hostfile tempfile thisLT bin)
  753. compile endif
  754.  
  755.    cand = upcase(candidate)
  756.    verb = upcase(verb)
  757.    hostfile = ''
  758.    tempfile = ''
  759.    whynot = ''
  760.    thisLT = ''
  761.    bin = 0
  762.  
  763.   /* first, find out what sort of file we got here...*/
  764.  
  765.    parse value cand with '/Q' candidate                --  PRINT command does
  766.    if not candidate then                               -- 'save /q', we strip
  767.      candidate = cand                                  -- this when checking
  768.    endif                                               -- for host file
  769.  
  770.    if candidate='' then  -- the null filename - PC file
  771.       return 0
  772.    endif
  773.    candidate = strip(candidate)
  774.  
  775. compile if VM
  776.  compile if EVERSION >= '5.50'
  777.    if verify(candidate,' ','m') & leftstr(candidate,1)<>'"' then
  778.  compile else
  779.    if verify(candidate,' ','m') then          -- space => VM filename or error
  780.  compile endif
  781.       if verb = 'CHECK' then  -- don't care about syntax, etc
  782.          return 1
  783.       endif      --LAM:  Don't use ELSEIF if THEN ended w/ RETURN.
  784.       if isa_vm_filename(candidate, hostfile, tempfile, thisLT, bin, whynot) then
  785.          setLT(thisLT)
  786.          return 1
  787.       endif
  788.  compile if HOST_LT_REQUIRED
  789.       if upcase(substr(candidate,1,1))=hostdrive & substr(candidate,3,1)=':' then
  790.  compile elseif HOSTDRIVE_REQUIRED
  791.       if upcase(substr(candidate,1,1))=hostdrive & pos(':', substr(candidate,2,3)) then
  792.  compile endif
  793.          message(candidate LOOKS_VM__MSG whynot)
  794.  compile if HOST_LT_REQUIRED | HOSTDRIVE_REQUIRED
  795.   compile if EVERSION < '5.50'
  796.       else
  797.          message(NO_SPACES__MSG)
  798.   compile endif
  799.       endif
  800.  compile endif
  801.       return 0
  802.    endif
  803. compile endif
  804.  
  805. compile if (MVS | E3MVS)
  806.    posp1 = pos('.',candidate)
  807.    posl  = pos(':',candidate)
  808.    posp2 = lastpos('.',candidate)
  809.  
  810.    test1= pos('''',candidate)   |              /* Fully qualified MVS name ?    */
  811.           pos('(',candidate)    |              /* PDS member specified ?        */
  812.  compile if HOST_LT_REQUIRED
  813.           (posl=3 &                            /* If 'Hx:' then ...             */
  814.  compile else
  815.           (posl   &                            /* If 'H:' or 'Hx:' then ...     */
  816.  compile endif
  817.           substr(candidate,1,1) = hostdrive)   /*   it must be a HOST file      */
  818.  
  819.  compile if E3          -- E3:  can assume FAT
  820.    test2=posp1 &                       /* 2nd qualifier is >3 bytes and */
  821.         (length(candidate)-posp1) > 3  /*   cannot be a valid PC Extent */
  822.  compile endif
  823.  
  824.    if not pos('\',candidate)  &                /* MVS name cannot contain '\'   */
  825.  compile if E3          -- E3:  can assume FAT
  826.       (test1                                 | /* Fully qualified MVS name ?    */
  827.        (posp1 <> posp2)                      | /* Multiple qualifiers ?         */
  828.         test2) then                            /* 2nd qualifier is >3 bytes ... */
  829.  compile else           -- OS/2; last two tests don't disqualify an HPFS filename.
  830.       test1 then                               /* Fully qualified MVS name ?    */
  831.  compile endif
  832.  compile if E3MVS
  833.       if isa_E3MVS_filename(candidate, hostfile, verb, tempfile, thisLT, bin, whynot) then
  834.  compile else
  835.       if isa_mvs_filename(candidate, hostfile, verb, tempfile, thisLT, bin, whynot) then
  836.  compile endif
  837.          setLT(thisLT)
  838.          return 2
  839.       else
  840.  compile if E3MVS
  841.          call free()
  842.  compile endif
  843.          sayerror(MVS_Error__MSG whynot)
  844.          stop
  845.       endif
  846.    endif
  847. compile endif -- (MVS | E3MVS)
  848.  
  849.   /* assume PC filename by now... */
  850.  
  851.    if verb = 'CHECK' then
  852.       return 0
  853.    endif
  854.    if verb = 'NAME' & pos('=',candidate) then
  855.       call parse_filename(candidate,.filename)
  856.    endif
  857.    if isa_pc_filename(candidate, tempfile, whynot) then
  858.       return 0
  859.    endif
  860.    message(candidate LOOKS_PC__MSG whynot)
  861.    return 0
  862.  
  863.  
  864. /**************************************************************************/
  865. /*****************************************************************************/
  866.  
  867. defproc isa_pc_filename(candidate, var tempfile, var error_msg)
  868. compile if EVERSION >= '5.50'  --@HPFS
  869.    if leftstr(candidate,1)='"' & rightstr(candidate,1)='"' then
  870.       candidate=substr(candidate,2,length(candidate)-2)
  871.    endif
  872. compile endif
  873.    parse value upcase(candidate) with drive ':' pathfile
  874.    if not pathfile then
  875.       pathfile = drive
  876.       drive = ''
  877.    endif
  878.    if length(drive) > 1 then
  879.       error_msg = PC_DRIVESPEC__MSG drive LONGER_THAN_ONE__MSG
  880.       return 0
  881.    endif
  882.    if length(drive) and verify(drive,'ABCDEFGHIJKLMNOPQRSTUVWXYZ') then
  883.       error_msg = PC_DRIVESPEC__MSG drive IS_NOT_ALPHA__MSG
  884.       return 0
  885.    endif
  886.    if substr(pathfile,1,2)='..' then  -- allow shortening path by '..'
  887.       pathfile = substr(pathfile,3)    -- strip it, check the rest of path
  888.    endif
  889.    if lastpos('\',pathfile) > 1 and pos('\',pathfile) <> 1 then
  890.                             -- We have a path, but it doesn't start with a \
  891.       pathfile = '\'pathfile
  892.    endif
  893. compile if E3
  894.    bad_chars = '."/\[]:|<>+=;,'            --LAM
  895. compile else                                          -- Don't limit to 8 chars; HPFS
  896.    bad_chars = '"/\:|<>'            --LAM
  897. compile endif
  898.    if substr(pathfile,1,1)='\' then
  899.      parse value pathfile with +1 pathpiece '\' restofname
  900.      while restofname do
  901. compile if E3
  902.        parse value pathpiece with first '.' last
  903.        if length(first) > 8 or verify(first,bad_chars,'m') then
  904.          error_msg = INVALID_PATH__MSG candidate
  905.          return 0
  906.        endif
  907.        if length(last) > 3 or verify(last,bad_chars,'m') then
  908. compile else                                          -- Don't limit to 8 chars; HPFS
  909.        if verify(pathpiece,bad_chars,'m') then
  910. compile endif
  911.          error_msg = INVALID_PATH__MSG candidate
  912.          return 0
  913.        endif
  914.        parse value restofname with pathpiece '\' restofname
  915.      endwhile
  916.      name = pathpiece
  917.    else
  918.      name=pathfile
  919.    endif
  920.    parse value name with fname '.' ext
  921. compile if E3
  922.    if length(fname) > 8 or verify(fname,bad_chars,'m') then
  923. compile else                                          -- Don't limit to 8 chars; HPFS
  924.    if verify(fname,bad_chars, 'm') then
  925. compile endif
  926.      error_msg = INVALID_FNAME__MSG fname
  927.      return 0
  928.    endif
  929.    if ext then
  930. compile if E3
  931.      if length(ext) > 3 or verify(ext,bad_chars,'m') then
  932. compile else                                          -- Don't limit to 8 chars; HPFS
  933.      if verify(ext,bad_chars,'m') then
  934. compile endif
  935.        error_msg = INVALID_EXT__MSG ext
  936.        return 0
  937.      endif
  938.    endif
  939.  
  940.    tempfile=''
  941.    return 1
  942.  
  943. compile if not defined(VALID_LTS)
  944.  compile if USING='CM+CP78'
  945. define VALID_LTS = 'ABCDEFGH12345'
  946.  compile elseif USING='CP78'
  947. define VALID_LTS = 'ABCDE12345'
  948.  compile else
  949. define VALID_LTS = 'ABCDEFGH'
  950.  compile endif
  951. compile endif
  952.  
  953. --  VM support routines  -----------------------------------------------
  954.  
  955. compile if VM
  956. defproc isa_vm_filename(candidate,
  957.                         var hostfile, var tempfile, var thisLT, var bin,
  958.                         var error_msg)
  959.  
  960.    universal hostdrive, LT, savepath, emulator
  961.    universal hname, htype, hmode
  962.  
  963.    parse value upcase(candidate) with drive ':' hname htype hmode rest
  964.  
  965.    thisLT = LT
  966.    if not hname then
  967.  compile if HOST_LT_REQUIRED | HOSTDRIVE_REQUIRED
  968.       error_msg = NO_HOST_DRIVE__MSG
  969.       return 0
  970.  compile else
  971.       parse value drive with hname htype hmode rest
  972.       drive = hostdrive||LT
  973.  compile endif
  974.    else
  975.       if length(drive)>2 then
  976.          error_msg = HOST_DRIVELETTER__MSG drive IS_TOO_LONG__MSG
  977.          return 0
  978.       endif
  979.       if substr(drive,1,1)<>hostdrive then
  980.          error_msg = HOST_DRIVELETTER__MSG substr(drive,1,1) INVALID__MSG
  981.          return 0
  982.       endif
  983.       if length(drive)>1 then
  984.          thisLT = substr(drive,2)
  985.          if verify(thisLT,VALID_LTS) then
  986.             error_msg = HOST_LT__MSG thisLT INVALID__MSG
  987.             return 0
  988.          endif
  989.  compile if HOST_LT_REQUIRED
  990.       else
  991.          error_msg = NO_LT__MSG
  992.          return 0
  993.  compile endif
  994.       endif
  995.    endif
  996. compile if USING='CM+CP78'
  997.    if isnum(thisLT) then
  998.       emulator = 'CP78'
  999.    else
  1000.       emulator = 'CM'
  1001.    endif
  1002. compile endif
  1003.  
  1004.    if not hmode then                     -- assuming host filename -
  1005.       hmode=DEFAULT_FILEMODE             -- will default to your A disk
  1006.    elseif hmode<>'*' then
  1007.       if length(hmode)>2 then
  1008.          error_msg = FM__MSG hmode IS_TOO_LONG__MSG
  1009.          return 0
  1010.       endif
  1011.       if verify(substr(hmode,1,1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ') then
  1012.          error_msg = FM1_BAD__MSG
  1013.          return 0
  1014.       endif
  1015.       if length(hmode)>1 and verify(substr(hmode,2,1),'1234567890')  then
  1016.          error_msg = FM2_BAD__MSG
  1017.          return 0
  1018.       endif
  1019.    endif
  1020.  
  1021.    if not htype then
  1022.       error_msg = NO_FT__MSG
  1023.       return 0
  1024.    endif
  1025.    if length(htype)>8 then
  1026.       error_msg = FT__MSG htype IS_TOO_LONG__MSG
  1027.       return 0
  1028.    endif
  1029.    bad_chars = ':*~`!%^&()|\{[}];"<,>.?/'
  1030.    if verify(htype, bad_chars, 'm') then
  1031.       error_msg = BAD_FT__MSG htype
  1032.       return 0
  1033.    endif
  1034.  
  1035. ;  if not hname then  -- then htype would already have been reported missing.
  1036. ;     error_msg = 'fn missing'
  1037. ;     return 0
  1038. ;  endif
  1039.    if length(hname)>8 then
  1040.       error_msg = FN__MSG hname IS_TOO_LONG__MSG
  1041.       return 0
  1042.    endif
  1043.    if verify(hname, bad_chars, 'm') then
  1044.       error_msg = BAD_FN__MSG htype
  1045.       return 0
  1046.    endif
  1047.  
  1048.    binpos=lastpos('BIN',htype)
  1049.  
  1050.    bin = binpos and (binpos = (length(htype) - 2))
  1051.  
  1052.    hostfile=hname htype hmode                   -- remove extra spaces
  1053.    tempfile=savepath||pc_chars(hname)'.'pc_chars(substr(htype,1,3))
  1054.  
  1055. compile if USING='CM+IBM'
  1056.    emulator = 'CM'
  1057. compile endif
  1058.  
  1059.    return 1
  1060. compile endif
  1061.  
  1062. --  MVS support routines -----------------------------------------
  1063.  
  1064. compile if E3MVS
  1065.    include 'e3mvsisa.e'  -- include Ken Kahn's isa-E3mvs-filename routine
  1066. compile endif
  1067.  
  1068. compile if MVS
  1069.  
  1070. defproc isa_mvs_filename(candidate,
  1071.                          var hostfile, MVSfunction, var tempfile,
  1072.                          var thisLT, var bin,
  1073.                          var error_msg)
  1074.  
  1075.    universal hostdrive, LT, savepath, emulator
  1076.  
  1077.    parse value upcase(candidate) with drive ':' datasetname rest
  1078.  
  1079. ;; MVSfunction = Upcase(MVSfunction)
  1080.    If (MVSfunction = 'QUIT') or (MVSfunction = 'CHECK') then
  1081.       return 2
  1082.    EndIf
  1083.    If (MVSfunction = 'RESET') then
  1084.       return candidate
  1085.    EndIf
  1086.  
  1087.    ThisLT=LT
  1088.    if datasetname='' then
  1089.  compile if HOST_LT_REQUIRED | HOSTDRIVE_REQUIRED
  1090.       error_msg = NO_HOST_DRIVE__MSG
  1091.       return 0
  1092.  compile else
  1093.       parse value drive with datasetname rest
  1094.  compile endif
  1095.    else
  1096.       if substr(drive,1,1)<>hostdrive then
  1097.          error_msg = HOST_DRIVELETTER__MSG substr(drive,1,1) INVALID__MSG
  1098.          return 0
  1099.       endif
  1100.       if length(drive)>2 then
  1101.          error_msg = HOST_DRIVELETTER__MSG drive IS_TOO_LONG__MSG
  1102.          return 0
  1103.       endif
  1104.       if length(drive)>1 then
  1105.          thisLT = substr(drive,2)
  1106.          if verify(thisLT,VALID_LTS) then
  1107.             error_msg = HOST_LT__MSG thisLT INVALID__MSG
  1108.             return 0
  1109.          endif
  1110.  compile if HOST_LT_REQUIRED
  1111.       else
  1112.          error_msg = NO_LT__MSG
  1113.          return 0
  1114.  compile endif
  1115.       endif
  1116.    endif
  1117. compile if USING='CM+CP78'
  1118.    if isnum(thisLT) then
  1119.       emulator = 'CP78'
  1120.    else
  1121.       emulator = 'CM'
  1122.    endif
  1123. compile endif
  1124.  
  1125.    if pos("'",datasetname) then
  1126.       datasetname = substr(datasetname,2,length(datasetname)-2)
  1127.       quotes = "'"
  1128.    else
  1129.       quotes = ''
  1130.    endif
  1131.  
  1132.    if (length(datasetname) > 44) then
  1133.       error_msg = DSN_TOO_LONG__MSG
  1134.       return 0
  1135.    endif
  1136.  
  1137.    if verify(datasetname,'(','m') and
  1138. compile if EVERSION >= '5.17'
  1139.         rightstr(datasetname,1) <> ')' then
  1140. compile else
  1141.         substr(datasetname,length(datasetname),1) <> ')' then
  1142. compile endif
  1143.       datasetname = datasetname')'
  1144.    endif
  1145.  
  1146.    parse value datasetname with DsnName '(' member ')' rest
  1147.  
  1148.    HostFile = ''
  1149.    Qualifiers = 0
  1150.    Qual1 = ''
  1151.    Qual2 = ''
  1152.    Qual3 = ''
  1153.    LastQualifier = ''
  1154.    Restof_Dsn = DsnName
  1155.    do forever
  1156.       parse value Restof_Dsn with Qualifier '.' Restof_Dsn
  1157.       if Qualifier = '' then leave; endif
  1158.       Qualifiers = Qualifiers + 1
  1159.       LastQualifier = Qualifier
  1160.       if length(Qualifier) > 8 then
  1161.          error_msg = QUAL_NUM__MSG Qualifiers '('Qualifier')' QUAL_TOO_LONG__MSG
  1162.          return 0
  1163.       endif
  1164.       if verify(qualifier, ':*~`!%^&()_-+=|\{[}];"<,>.?/', 'm') then
  1165.          error_msg = QUAL_NUM__MSG Qualifiers '('Qualifier')' QUAL_INVALID__MSG
  1166.          return 0
  1167.       endif
  1168.       if Qualifiers>1 then
  1169.          HostFile = HostFile||'.'||Qualifier
  1170.       else
  1171.          HostFile = Qualifier
  1172.       endif
  1173.       if     Qualifiers = 1 then
  1174.          Qual1 = Qualifier
  1175.       elseif Qualifiers = 2 then
  1176.          Qual2 = Qualifier
  1177.       elseif Qualifiers = 3 then
  1178.          Qual3 = Qualifier
  1179.       endif
  1180.    enddo
  1181.  
  1182.    if member <> '' then
  1183.       if substr(member,1,1) = '+' then
  1184.          if substr(member,2,1) <> '0' then
  1185.             error_msg = GENERATION_NAME__MSG member INVALID__MSG
  1186.             return 0
  1187.          endif
  1188.       elseif substr(member,1,1) = '-' then
  1189.          if verify(substr(member,2,1),'123456789') then
  1190.             error_msg = GENERATION_NAME__MSG member INVALID__MSG
  1191.             return 0
  1192.          endif
  1193.       elseif length(member) > 8 then
  1194.          error_msg = MEMBER__MSG member IS_TOO_LONG__MSG
  1195.          return 0
  1196.       elseif verify(member, ':*~`!%^&()_-+=|\{[}];"<,>.?/', 'm') then
  1197.          error_msg = INVALID_MEMBER__MSG member
  1198.          return 0
  1199.       endif
  1200.    elseif verify(datasetname,'()','m') then
  1201.       error_msg = DSN_PARENS__MSG
  1202.       return 0
  1203.    endif
  1204.  
  1205.    if member = '' then
  1206.       HostFile = quotes||HostFile||quotes
  1207.    else
  1208.       HostFile = quotes||HostFile'('member')'quotes
  1209.    endif
  1210.  
  1211.    if member = '' then
  1212.       if Qual3 = '' then
  1213.          tempFile = savepath||Qual1'.'substr(LastQualifier,1,3)
  1214.       else
  1215.          tempFile = savepath||Qual2'.'substr(LastQualifier,1,3)
  1216.       endif
  1217.    else
  1218.       tempFile = savepath||pc_chars(member)'.'substr(LastQualifier,1,3)
  1219.    endif
  1220.  
  1221. compile if USING='CM+IBM'
  1222.    emulator = 'IBM'
  1223. compile endif
  1224.  
  1225.    return (2)
  1226.  
  1227. compile endif
  1228.  
  1229.  
  1230. -- COMMON ROUTINES, ETC.  --
  1231.  
  1232. defproc pc_chars(str) -- Translate invalid PC chars to $
  1233.    do forever
  1234.       v = verify(str, '+,"/\[]:|<>=;.', 'M')
  1235.       if not v then leave; endif
  1236. compile if E3
  1237.       str = substr(str,1,v-1)'$'substr(str,v+1)
  1238. compile else
  1239.       str = overlay('$',str,v)
  1240. compile endif
  1241.    enddo
  1242.    return str
  1243.  
  1244. defproc already_in_ring(filename, var tryid)
  1245.  
  1246.   getfileid tryid, filename
  1247.   return tryid<>''            --LAM
  1248.  
  1249.  
  1250. defproc hidden_info(hostfileid, hostfilename, var tempfile, var fto, verb, bin, hosttype)
  1251.  
  1252.  /* using a hidden file, we keep track of the host files and any special  */
  1253.  /* file transfer options associated with each.                           */
  1254.  
  1255.  /* get the hidden file for the information we're keeping                 */
  1256.  
  1257.   save_rc = rc
  1258.   if verb='NAME' then
  1259.      newname=hostfilename
  1260.      hostfilename = .filename
  1261.   endif
  1262.  
  1263.   getfileid savefileid
  1264. compile if EVERSION < 5
  1265.   'xcom e /h /q /n fto.e'
  1266. compile else
  1267.    'xcom e /n fto.e'
  1268.    .visible = 0
  1269. compile endif
  1270.   '0'
  1271. compile if EVERSION >= '4.10'
  1272.   GETSEARCH search_command -- Save user's search command.
  1273.  compile if EVERSION >= 5
  1274.       display -2              -- disable display of nonfatal error messages
  1275.  compile endif
  1276. compile endif
  1277.   if hostfileid then
  1278.      'xcom l ?'hostfileid' /?'
  1279.   else
  1280.      'xcom l /'hostfilename
  1281.   endif
  1282.   found = rc<> -273 -- sayerror('String not found')        --LAM
  1283. compile if EVERSION >= '4.10'
  1284.  compile if EVERSION >= 5
  1285.       display 2               -- reenable display of nonfatal error messages
  1286.  compile endif
  1287.   SETSEARCH search_command -- Restores user's command so Ctrl-F works.
  1288. compile endif
  1289. compile if DEBUG
  1290.   if found then
  1291.      getline line
  1292.      messagenwait('hidden info>>> 'line)
  1293.   endif
  1294. compile endif
  1295.  
  1296.  
  1297.  /* now see what we're supposed to do      */
  1298.  /* verbs are EDIT, NAME, QUIT, SAVE       */
  1299.  
  1300.   if verb='QUIT' then
  1301.      if found then
  1302.         getline line
  1303.         parse value line with . '/' . '/' tempfile .
  1304.         deleteline
  1305.      else
  1306.         tempfile = ''
  1307.      endif
  1308.   elseif verb='EDIT'  then
  1309.      if found then
  1310.         replaceline hostfileid' /'hostfilename' /'tempfile' /'hosttype' /'fto
  1311.      else
  1312.         top
  1313.         insertline  hostfileid' /'hostfilename' /'tempfile' /'hosttype' /'fto
  1314.      endif
  1315.      set_FTO(hostfilename, bin, fto)
  1316.   elseif verb='NAME' then
  1317.      if found then
  1318.         getline line                                 -- use file transfer opts
  1319.         parse value line with . '/' . '/' . '/' oldhosttype '/' hidden_fto       -- kept in entry.
  1320.         if not fto then
  1321. compile if USING='CM+IBM'
  1322.            if hosttype<>oldhosttype then  -- Old ft options no good;
  1323.               set_FTO(newname, bin, fto)    -- set to default.
  1324.            else
  1325. compile endif -- USING='CM+IBM'
  1326.               fto=hidden_fto                -- Use the FTO from the hidden file.
  1327. compile if USING='CM+IBM'
  1328.            endif
  1329. compile endif -- USING='CM+IBM'
  1330.         endif
  1331.         replaceline hostfileid' /'newname' /'tempfile' /'hosttype' /'fto
  1332.      else
  1333.         top
  1334.         insertline  hostfileid' /'newname' /'tempfile' /'hosttype' /'fto
  1335.      endif
  1336. ;;   set_FTO(hostfilename, bin, fto)  -- 93/08: No reason for this when 'NAME'.
  1337.   elseif verb='SAVE' then
  1338.      if found then
  1339.         getline line                                 -- use file transfer opts
  1340.         parse value line with . '/' . '/' . '/' . '/' hidden_fto       -- kept in entry.
  1341.         if not fto then fto=hidden_fto endif
  1342.      else
  1343.         top
  1344.         insertline  hostfileid' /'hostfilename' /'tempfile' /'hosttype' /'fto
  1345.      endif
  1346.      set_FTO(hostfilename, bin, fto, savefileid)
  1347.   endif
  1348.  
  1349. compile if DEBUG
  1350.    messagenwait('hid says: 'hostfileid hostfilename tempfile fto hosttype verb bin)
  1351. compile endif
  1352.  
  1353.   activatefile savefileid
  1354. compile if EVERSION < 5
  1355.   sayerror 0
  1356. compile endif
  1357.   rc = save_rc
  1358.  
  1359.  
  1360. defproc set_FTO(hostfile, bin, var fto)  -- called by hidden_info, loadfile
  1361.   universal emulator, ftoptions, binoptions
  1362. compile if WANT_DBCS_SUPPORT
  1363.   universal country, codepage, ondbcs
  1364. compile endif
  1365.  
  1366.   fto = strip(fto)
  1367.   if not fto then
  1368. compile if USING='CM+CP78' | USING='CM+IBM'
  1369.      if bin then
  1370.         if emulator='CM' then
  1371.            fto='/q /b'
  1372.         else
  1373.  compile if USING='CM+IBM'
  1374.   compile if USE_EHLLAPI
  1375.            fto = ''                     -- Omit redirection if EPM (uses EHLLAPI)
  1376.   compile else
  1377.            fto = '() >nul'
  1378.   compile endif
  1379.  compile else  -- else USING='CM+CP78'
  1380.            fto='BIN Q'
  1381.  compile endif
  1382.         endif
  1383.      else
  1384.         if emulator='CM' then
  1385.            fto='/q /ascii'
  1386.         else
  1387.  compile if USING='CM+IBM'
  1388.   compile if USE_EHLLAPI
  1389.           fto = 'ASCII CRLF'            -- Omit redirection if EPM (uses EHLLAPI)
  1390.   compile else
  1391.           fto = 'ASCII CRLF >nul'       -- The minimum for IBM emulators
  1392.   compile endif
  1393.  compile else  -- else USING='CM+CP78'
  1394.            fto='ASC Q'
  1395.  compile endif
  1396.         endif
  1397.      endif
  1398. compile else
  1399.      if bin then
  1400.         fto=binoptions
  1401.      else
  1402.         fto=ftoptions
  1403.      endif
  1404. compile endif
  1405.   endif
  1406.  
  1407. compile if CALL_USER_FTO
  1408.    if arg(4) then
  1409.       call user_FTO(hostfile, fto, 'SAVE')
  1410.    endif
  1411. compile endif
  1412.  
  1413.   if emulator='IBM' | emulator='CP78' then
  1414. compile if MVS or E3MVS
  1415.      if not pos(')', hostfile) then  -- Only add RECFM or LRECL if not a PDS member
  1416. compile endif
  1417.         -- For ASCII upload, add LRECL 255 (avoid "Some records were segmented.").
  1418.         if arg(4) & not bin & not pos('LRECL',fto) then  -- Add iff SEND (i.e., arg(4)=1)
  1419. compile if MVS or E3MVS
  1420.            if pos('.', hostfile) then     -- MVS file
  1421. ;;            fto='LRECL(255) 'strip(fto,'l','(')  -- Do nothing for MVS files.
  1422.            else
  1423. compile endif
  1424. compile if EVERSION > 5  -- Only EPM has longestline()
  1425.               getfileid fto_fid
  1426.               savefileid = arg(4)
  1427.               activatefile savefileid
  1428.               if longestline() > 80 then
  1429. compile endif
  1430.                  fto='LRECL 255 'strip(fto,'l','(')
  1431. compile if EVERSION > 5
  1432.               endif
  1433.               activatefile fto_fid
  1434. compile endif
  1435. compile if MVS or E3MVS
  1436.            endif  -- pos('.'
  1437. compile endif
  1438.         endif
  1439.         -- For binary upload, add RECFM V (avoid padding last record so CRCs will match).
  1440.         if arg(4) & bin & not pos('RECFM',fto) then     -- Add iff SEND (i.e., arg(4)=1)
  1441.            fto='RECFM V 'strip(fto,'l','(')
  1442.         endif
  1443. compile if MVS or E3MVS
  1444.      endif  -- not pos(')'
  1445.      if not pos('.', hostfile) then     -- VM file
  1446. compile endif
  1447.         if substr(fto,1,1)<>'(' then fto='('fto; endif
  1448. compile if WANT_DBCS_SUPPORT & 0  -- @DBCS_FIX
  1449.         if pos(codepage, 932 942) & not pos('[',fto) then
  1450.            fto='['fto
  1451.         endif
  1452. compile endif
  1453. compile if MVS or E3MVS
  1454.      else
  1455.         fto = strip(strip(fto,'t',')'),'l','(')  -- remove leading '(' & trailing ')'
  1456.      endif
  1457. compile endif
  1458.   endif
  1459.  
  1460. compile if DEBUG
  1461. ;  messagenwait('FTO will be: 'fto)
  1462. compile endif
  1463.  
  1464.  
  1465.  
  1466. defproc setLT(var LT_to_use)
  1467.   universal LT, emulator
  1468.  
  1469.   if not LT_to_use then
  1470.      LT_to_use = LT||':'
  1471.   else
  1472.      LT_to_use = LT_to_use||':'
  1473.   endif
  1474.  
  1475. compile if DEBUG
  1476.   messagenwait('LT set to: 'LT_to_use)
  1477. compile endif
  1478.  
  1479.  
  1480.  
  1481. defproc check_savepath()     -- Larry Margolis - MARGOLI at YORKTOWN
  1482.    universal savepath
  1483.  
  1484. compile if BACKUP_PATH <> '' & BACKUP_PATH <> '='
  1485.    universal backup_path_ok
  1486.  compile if EVERSION >= '5.17'
  1487.    if rightstr(BACKUP_PATH,1)<>'\' then
  1488.  compile else
  1489.    if substr(BACKUP_PATH,length(BACKUP_PATH),1)<>'\' then
  1490.  compile endif
  1491.       messageNwait(BACKUP_PATH_INVALID_NO_BACKSLASH__MSG'  'NO_BACKUPS__MSG)
  1492.    else
  1493.       curpath=directory()                                     -- get current disk
  1494.       if substr(BACKUP_PATH,2,1)=':' then
  1495.          relpath=directory(substr(BACKUP_PATH,1,2))
  1496.       else
  1497.          relpath=''
  1498.       endif
  1499.       rc = 0
  1500.       call directory(substr(BACKUP_PATH,1,length(BACKUP_PATH)-1))    -- set to BACKUP_PATH
  1501.       if rc=-15 then  -- sayerror('Invalid drive')
  1502.          bad=DRIVE__MSG                                            -- did we set?
  1503.       elseif rc=-3 then  -- sayerror('Path not found')
  1504.          bad=PATH__MSG
  1505.       endif
  1506.       if rc then                                 -- didn't set - BACKUP_PATH invalid
  1507.          messageNwait(BACKUP_PATH_INVALID1__MSG bad'.  'NO_BACKUPS__MSG)
  1508.       else
  1509.          backup_path_ok = 1
  1510.       endif
  1511.       if relpath then
  1512.          call directory(relpath)
  1513.       endif
  1514.       call directory(curpath)  -- Restore original directory
  1515.    endif
  1516. compile endif  -- BACKUP_PATH
  1517.  
  1518.    if savepath='' then
  1519.       savepath=directory()
  1520.       if length(savepath)>3 then savepath=savepath'\'; endif   -- if not 'C:\'
  1521. ;     sayerror SAVEPATH_NULL__MSG
  1522.       return 0
  1523.    endif
  1524.  
  1525. compile if EVERSION >= '5.17'
  1526.    if rightstr(savepath,1)<>'\' then
  1527. compile else
  1528.    if substr(savepath,length(savepath),1)<>'\' then
  1529. compile endif
  1530.       savepath = savepath'\'
  1531.    endif
  1532.  
  1533.    curpath=directory()                                     -- get current disk
  1534.    if substr(savepath,2,1)=':' then
  1535.       relpath=directory(substr(savepath,1,2))
  1536.    else
  1537.       relpath=''
  1538.    endif
  1539.    rc = 0
  1540.    call directory(substr(savepath,1,length(savepath)-1))    -- set to savepath
  1541.    if rc=-15 then  -- sayerror('Invalid drive')
  1542.       bad=DRIVE__MSG                                            -- did we set?
  1543.    elseif rc=-3 then  -- sayerror('Path not found')
  1544.       bad=PATH__MSG
  1545.    endif
  1546.    if rc then                                 -- didn't set - savepath invalid
  1547.       sayerror(SAVEPATH_INVALID1__MSG bad SAVEPATH_INVALID2__MSG)
  1548.       savepath = substr(curpath,1,3)  -- 'C:\'
  1549.    endif
  1550.    if relpath then
  1551.       call directory(relpath)
  1552.    endif
  1553.    call directory(curpath)  -- Restore original directory
  1554.  
  1555.  
  1556. ; This procedure referenced only in SELECT.E - this one works with E3REXKEY
  1557. ; to allow syntax directed editing for EXEC or XEDIT files.
  1558. ;
  1559. ; Gracias, Ken Kahn for the updated code for MVS users
  1560. ;
  1561. ; Also works without E3REXKEY to provide syntax directed editing for files
  1562. ; that have the filetype EBIN, CBIN or PASBIN
  1563.  
  1564. defproc filetype()
  1565.    universal hostdrive
  1566.  
  1567.    filename=arg(1)
  1568.    if filename='' then filename=.filename; endif
  1569.    if substr(filename, 1, 5)=='.DOS ' then
  1570.       return ''
  1571.    endif
  1572.    filename = upcase(filename)
  1573. compile if (MVS | E3MVS)
  1574.  compile if HOST_LT_REQUIRED
  1575.    isa_host_file = substr(filename,1,1)=hostdrive & substr(filename,3,1)=':'
  1576.  compile elseif HOSTDRIVE_REQUIRED
  1577.    isa_host_file = substr(filename,1,1)=hostdrive & pos(':', substr(filename,2,3))
  1578.  compile endif
  1579. compile endif
  1580. ;        -- LAM - '.' is allowed in PC path name.  Not sure how this affects
  1581. ;                 MVS check.
  1582.    i=lastpos('\',filename)
  1583.    if i then
  1584.       filename=substr(filename,i+1)
  1585.    endif
  1586. ;         -- LAM - end
  1587.    i=lastpos('.',filename)
  1588.    if i then                             -- PC or MVS
  1589.       PCext = substr(filename,i+1)
  1590. compile if (MVS | E3MVS)
  1591.  compile if HOST_LT_REQUIRED | HOSTDRIVE_REQUIRED
  1592.       if isa_host_file then
  1593.  compile else
  1594.       if (i>pos('.', filename)) |
  1595.          (Pos('(',PCext))       |
  1596.          (Pos("'",PCext))       |
  1597.          (Length(PCext) > 3) then
  1598.  compile endif
  1599.         return breakout_mvs(filename,PCext)     -- MVS
  1600.       endif
  1601. compile endif
  1602.       return PCext                       -- PC
  1603.    else                                  -- PC (no ext) or VM
  1604.       return breakout_vm(filename)        -- handles both
  1605.    endif
  1606.  
  1607.  
  1608. compile if (MVS | E3MVS)
  1609. DefProc breakout_mvs(filename,LastQual)
  1610.    i = Pos('(',LastQual)
  1611.    If i then
  1612.       LastQual = SubStr(LastQual,1,i-1)
  1613.    EndIf
  1614.  
  1615.    if lastqual='PASCAL' then
  1616.       return 'PAS'
  1617.    endif
  1618.    if lastqual='C' then
  1619.       return 'C'
  1620.    endif
  1621.    if lastqual='SCRIPT' then
  1622.       return 'SCRIPT'
  1623.    endif
  1624.    if lastqual='REXX' | lastqual='EXEC' | lastqual='CLIST' then
  1625.       return 'CMD'
  1626.    endif
  1627. compile endif
  1628.  
  1629.  
  1630. defproc breakout_vm(filename)
  1631.    if verify(filename,' ','m') then
  1632.       parse value filename with . ftype .
  1633.       i = lastpos('BIN',ftype)
  1634.       if i then
  1635.          return substr(ftype,1,i-1)
  1636.       endif
  1637.       return ftype
  1638.    endif
  1639.  
  1640.  
  1641. defproc vmfile(var name, var cmdline)
  1642. compile if VM  -- procedure defined even if no VM - makes defc EDIT simpler.
  1643.    universal hostdrive
  1644.  
  1645.  compile if HOST_LT_REQUIRED
  1646.    if upcase(substr(name,1,1))<>hostdrive | substr(name,3,1)<>':' then return 0; endif
  1647.  compile elseif HOSTDRIVE_REQUIRED
  1648.    if upcase(substr(name,1,1))<>hostdrive | pos(':',substr(name,2,2))=0 then return 0; endif
  1649.  compile endif
  1650.  
  1651.    parse value name with fn ft fm cmdline
  1652.    if fn='' or ft='' or length(fn)>11 or pos('\',fn) or pos('.',fn) or
  1653.       length(ft)>8 or pos(':',ft) or pos('\',ft) or pos('.',ft) then
  1654.      return 0
  1655.    endif
  1656.  
  1657.    if (not fm) or length(fm)>2 or
  1658.       pos(':',fm) or pos('\',fm) or pos('.',fm) then
  1659.      cmdline = fm cmdline               -- assumption here:  VM if two
  1660.      name = fn ft
  1661.      return 1
  1662.    endif
  1663.  
  1664.    name = fn ft fm
  1665.    return 1                              --better be VM at this point
  1666. compile else
  1667.    return 0
  1668. compile endif
  1669.  
  1670. /**************************************************************************/
  1671. /*                                                                        */
  1672. /*   commands for changing variable values                                */
  1673. /*                                                                        */
  1674. /**************************************************************************/
  1675.  
  1676. compile if RUNTIME
  1677.  
  1678. defc em, emulator=
  1679.   universal hostcopy, LT, hostcmd, emulator
  1680.  
  1681.   uparg = upcase(arg(1))
  1682.   if uparg = 'IBM' then
  1683.      emulator = 'IBM'
  1684.      hostcopy = ''
  1685. compile if EPM
  1686.      hostcmd = 'EHLLAPI'
  1687. compile elseif EOS2
  1688.      hostcmd = 'os2cmd'
  1689. compile else
  1690.      hostcmd = 'hostsys'
  1691. compile endif
  1692.      sayerror EMULATOR_SET_TO__MSG uparg LT_NOW__MSG LT')'
  1693. compile if EVERSION >= 4      -- OS/2-only emulators
  1694.   elseif uparg = 'CP78' then
  1695.      emulator = 'CP78'
  1696. ;    hostcopy = 'cp78copy'
  1697. ;    hostcmd = 'cp78cmd'
  1698.      hostcopy = ''
  1699. compile if EVERSION >= 4
  1700.      hostcmd = 'os2cmd'
  1701. compile else
  1702.      hostcmd = 'hostsys'
  1703. compile endif
  1704.      LT = ''
  1705.      sayerror EMULATOR_SET_TO__MSG uparg
  1706.   elseif uparg = 'CM' then
  1707.      emulator = 'CM'
  1708.      hostcopy = 'almcopy'
  1709.      hostcmd = 'os2cmd'
  1710.      sayerror EMULATOR_SET_TO__MSG uparg LT_NOW__MSG LT')'
  1711. compile else                  -- DOS-only emulators
  1712.   elseif uparg='BOND' then
  1713.      emulator = 'BOND'
  1714.      hostcopy = 'bondcopy'
  1715.      hostcmd = 'bondcmd'
  1716.      LT = ''
  1717.      sayerror EMULATOR_SET_TO__MSG uparg
  1718.   elseif uparg = 'MYTE' then
  1719.      emulator = 'MYTE'
  1720.      hostcopy = 'mytecopy'
  1721.      hostcmd = 'mytecmd'
  1722.      sayerror EMULATOR_SET_TO__MSG uparg LT_NOW__MSG LT')'
  1723.   elseif uparg = 'E78' then
  1724.      emulator = 'E78'
  1725.      hostcopy = 'e78copy'
  1726.      hostcmd = 'e78cmd'
  1727.      LT = ''
  1728.      sayerror EMULATOR_SET_TO__MSG uparg
  1729. compile endif                 -- End of OS-specific emulators
  1730.   elseif not uparg then
  1731. compile if EVERSION < 5
  1732.      setcommand EMULATOR__MSG emulator,10,1         --LAM
  1733. compile else
  1734.      'commandline' EMULATOR__MSG emulator
  1735. compile endif
  1736.   else
  1737. compile if EVERSION >= 4      -- OS/2-only emulators
  1738.      sayerror '('uparg')' IS_INVALID_OPTS_ARE__MSG 'IBM, CM, CP78'
  1739. compile else                  -- DOS-only emulators
  1740.      sayerror '('uparg')' IS_INVALID_OPTS_ARE__MSG 'BOND, MYTE, E78, IBM'
  1741. compile endif                 -- End of OS-specific emulators
  1742.      stop
  1743.   endif
  1744.  
  1745.  
  1746. defc lt=
  1747.   universal LT
  1748.  
  1749.   uparg = upcase(arg(1))
  1750.   if verify(uparg,'ABCDEFGH','M',1) and length(uparg) = 1 then
  1751.     LT = uparg
  1752.     sayerror LT_SET_TO__MSG LT
  1753.   elseif uparg = 'NO_LT' or uparg = 'NONE' or uparg = 'NULL' then
  1754.     LT = ''
  1755.     sayerror LT_SET_NULL__MSG
  1756.   elseif not uparg then
  1757. compile if EVERSION < 5
  1758.     message('LT used only for CM, MYTE and IBM with >1 host session...')
  1759. compile endif
  1760.     if not LT then   --changed for space
  1761. compile if EVERSION < 5
  1762.        setcommand 'LT No_LT',4,1
  1763. compile else
  1764.        'commandline LT No_LT'
  1765. compile endif
  1766.     else
  1767. compile if EVERSION < 5
  1768.        setcommand 'LT 'LT,4,1
  1769. compile else
  1770.        'commandline LT 'LT
  1771. compile endif
  1772.     endif
  1773.   else
  1774.     sayerror '('uparg')' LT_INVALID__MSG
  1775.     stop
  1776.   endif
  1777.  
  1778.  
  1779. defc hd, hostdrive=
  1780.   universal hostdrive
  1781.  
  1782.   uparg = upcase(arg(1))
  1783.   if verify(uparg,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','M',1) and length(uparg)=1 then
  1784.     hostdrive = uparg
  1785.     sayerror HOSTDRIVE_NOW__MSG hostdrive
  1786.   elseif not uparg then  -- changed for space
  1787. compile if EVERSION < 5
  1788.     setcommand 'HD 'hostdrive,4,1
  1789. compile else
  1790.     'commandline HD 'hostdrive
  1791. compile endif
  1792.   else
  1793.     sayerror '('uparg')' IS_INVALID_OPTS_ARE__MSG 'A - Z'
  1794.     stop
  1795.   endif
  1796.  
  1797.  
  1798. defc savepath =
  1799.   universal savepath
  1800.  
  1801.   uparg = upcase(arg(1))
  1802.   if not uparg  then  -- changed for space
  1803. compile if EVERSION < 5
  1804.     setcommand 'SAVEPATH 'savepath,10,1
  1805. compile else
  1806.     'commandline SAVEPATH 'savepath
  1807. compile endif
  1808.   else
  1809.     savepath = uparg
  1810.     call check_savepath(TRY_AGAIN__MSG)
  1811.   endif
  1812.  
  1813. defc hostcopy =
  1814.    universal hostcopy
  1815.    if arg(1) then
  1816.       hostcopy = arg(1)
  1817.    else
  1818.       sayerror 'Hostcopy command is' hostcopy
  1819.    endif
  1820. compile endif  -- RUNTIME
  1821.  
  1822. defc fto=
  1823.   universal ftoptions
  1824.  
  1825.   uparg = upcase(arg(1))
  1826.   if not uparg then -- changed for space         -- tell 'em the default
  1827. compile if EVERSION < 5
  1828.     setcommand 'FTO 'ftoptions,5,1
  1829. compile else
  1830.     'commandline FTO 'ftoptions
  1831. compile endif
  1832.   else
  1833.     ftoptions = uparg
  1834.     sayerror FTO_WARN__MSG
  1835.   endif
  1836.  
  1837. defc bin=
  1838.   universal binoptions
  1839.  
  1840.   uparg = upcase(arg(1))
  1841.   if uparg=='' then                             -- tell 'em the default
  1842. compile if EVERSION < 5
  1843.     setcommand 'BIN 'binoptions,5,1
  1844. compile else
  1845.     'commandline BIN 'binoptions
  1846. compile endif
  1847.   else
  1848.     binoptions = uparg
  1849.     sayerror BIN_WARN__MSG
  1850.   endif
  1851.  
  1852. compile if EPM  -- SEND & RECEIVE don't work from a PM window, so call via EHLLAPI.
  1853. ; Following is a common call for Send or Receive.  It does a Set Session Parms
  1854. ; to 'QUIET', sets up the parameters the way EMUL_HLLAPI wants (VAR parameters)
  1855. ; and issues the call.
  1856. defproc EHLLAPI_SEND_RECEIVE(function, parms)
  1857. universal ondbcs                              -- @DBCS_FIX
  1858.    if ondbcs then
  1859.        parse value parms with f '(' o
  1860.        parms = f '[(' o
  1861.    endif                                      -- end DBCS_FIX
  1862.    if function=90 or function=91 then
  1863.       call EHLLAPI_SEND_RECEIVE(9, 'QUIET TIMEOUT=2')
  1864. compile if DEBUG
  1865.       messagenwait('Calling function' function' "'parms'"')
  1866. compile endif
  1867.    endif
  1868. compile if not DEBUG
  1869.    if echo() then  -- Since user wouldn't see this echoed, let's say it explicitly...
  1870.       messagenwait('EHLLAPI_SEND_RECEIVE('function', "'parms'")')
  1871.    endif
  1872. compile endif
  1873.    EHLLAPI_data_string_length = atoi(length(parms)) -- Data string length
  1874.    EHLLAPI_host_PS_position = atoi(0)
  1875.    result=HLLAPI_call(atoi(function), selector(parms), offset(parms),
  1876.                  EHLLAPI_data_string_length, EHLLAPI_host_PS_position)
  1877.    if result=3 | result=4 then return 0; endif  -- 3=File Transfer complete;
  1878.    return result                                -- 4= Complete with segmented records.
  1879.  
  1880. ; HLLAPI_call is our general interface for calling the EHLLAPI dynalink.
  1881. ; Parameters are always the same - an EHLLAPI function number, selector of
  1882. ; the data string, offset of the data string, the data string length, and
  1883. ; the host presentation space position.  They might not be used in all calls,
  1884. ; but EHLLAPI requires that they all be present.
  1885. ;
  1886. ; The data string is passed via selector and offset rather than as a VAR string,
  1887. ; since some calls (e.g., copying the entire host screen) require a string
  1888. ; larger than 255 bytes, and so we must allocate a buffer and pass that.
  1889. ; Note:  This is not taken advantage of in E3EMUL.E, but it's a small cost to
  1890. ; make it available to others, instead of having to duplicate the whole function.
  1891. defproc HLLAPI_call(EHLLAPI_function_number,
  1892.                     sel_EHLLAPI_data_string, ofs_EHLLAPI_data_string,
  1893.                 var EHLLAPI_data_string_length, -- Data str. len. or buffer size
  1894.                 var EHLLAPI_host_PS_position)   -- Host presentation space posn.
  1895.                                                 -- (on return, RC)
  1896.    rc = 0        -- Prepare for missing DLL library
  1897.  compile if EPM32
  1898.    result=dynalink('ACS3EHAP',                  -- dynamic link library name
  1899.                    'HLLAPI',                    -- HLLAPI direct call
  1900.                     Thunk(address(EHLLAPI_function_number))    ||
  1901.                     Thunk(ofs_EHLLAPI_data_string              || sel_EHLLAPI_data_string)  ||
  1902.                     Thunk(address(EHLLAPI_data_string_length)) ||
  1903.                     Thunk(address(EHLLAPI_host_PS_position)) )
  1904.  compile else
  1905.    result=dynalink('ACS3EHAP',                  -- dynamic link library name
  1906.                    'HLLAPI',                    -- HLLAPI direct call
  1907.                    address(EHLLAPI_function_number)     ||
  1908.                    sel_EHLLAPI_data_string              ||
  1909.                    ofs_EHLLAPI_data_string              ||
  1910.                    address(EHLLAPI_data_string_length)  ||
  1911.                    address(EHLLAPI_host_PS_position))
  1912.  compile endif
  1913.  compile if EPM
  1914.    if rc then sayerror ERROR__MSG rc FROM_HLLAPI__MSG '-' sayerrortext(rc); stop; endif
  1915.  compile else
  1916.    if rc then sayerror ERROR__MSG rc FROM_HLLAPI__MSG; stop; endif
  1917.  compile endif
  1918.    return itoa(EHLLAPI_host_PS_position, 10)
  1919.  
  1920. ; A simpler EHLLAPI interface - just pass a function number and data string.
  1921. ; The third and fourth parameters are optional.  Can not be used for calls
  1922. ; which return data in the data string.
  1923. defproc simple_HLLAPI_call(EHLLAPI_function_number, EHLLAPI_data_string)
  1924.    if arg(3)='' then
  1925.       EHLLAPI_data_string_length = atoi(length(EHLLAPI_data_string))
  1926.    else
  1927.       EHLLAPI_data_string_length = atoi(arg(3))
  1928.    endif
  1929.    if arg(4)='' then
  1930.       EHLLAPI_host_PS_position = atoi(0)
  1931.    else
  1932.       EHLLAPI_host_PS_position = atoi(arg(4))
  1933.    endif
  1934.    return HLLAPI_call(atoi(EHLLAPI_function_number),
  1935.                       selector(EHLLAPI_data_string), offset(EHLLAPI_data_string),
  1936.                       EHLLAPI_data_string_length, EHLLAPI_host_PS_position)
  1937. compile endif -- EPM
  1938.