home *** CD-ROM | disk | FTP | other *** search
/ The Developer Connection…ice Driver Kit for OS/2 3 / DEV3-D1.ISO / editors / epm / sampmacs / e3emul.e < prev    next >
Encoding:
Text File  |  1993-09-30  |  60.9 KB  |  1,895 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 not isoption(options,'Q') then
  461.         call message(FILE_TRANSFER_ERROR__MSG hostrc'.  'HOST_NOT_FOUND__MSG)
  462.      endif
  463.      rc=-282  -- sayerror('New file')
  464.   else                                                -- good download occurred
  465.      'xcom e /d /q 'options tempfile
  466.      erc = rc
  467.      if keep_temp_files then
  468.         message(SAVED_LOCALLY_AS__MSG upcase(tempfile))
  469.      else
  470.         call erasetemp(tempfile)
  471.      endif
  472.      if erc then
  473.         call message(rc)
  474.      endif
  475.   endif
  476.  
  477.   getfileid hostfileid                               -- set pertinent file data
  478.   if hostfileid=startid then stop; endif    -- Uh oh - new file wasn't loaded.
  479.   if thisLT then
  480.     .filename=hostdrive||thisLT||hostfile
  481.   else
  482.     .filename=hostdrive':'hostfile
  483.   endif
  484.  
  485.  
  486. defproc savefile(given_name)
  487.   universal hostdrive, LT
  488. compile if BACKUP_PATH <> '' & BACKUP_PATH <> '='
  489.    universal backup_path_ok
  490. compile endif
  491.                                              -- prepare given arguments for use
  492.    parse value given_name with name '[' fto ']'
  493.    options=arg(2)
  494.  
  495.                           -- sets hostfile, tempfile, thisLT, bin
  496.   hosttype = ishost(name, 'SAVE', hostfile, tempfile, thisLT, bin)
  497.   if hosttype then
  498.      hostfilename = hostdrive||thisLT||hostfile
  499.      if .filename=hostfilename then  --assume saving this copy
  500.         getfileid hostfileid
  501.      else
  502.         getfileid hostfileid, hostfilename  --could be saving non-current file
  503.      endif
  504.      call hidden_info(hostfileid, hostfilename, tempfile, fto, 'SAVE', bin, hosttype)
  505.      src=save_host_file(hostfile, tempfile, thisLT, fto, hostfileid, options)  --LAM
  506.      if src then         -- if host error, offer to save on PC
  507.         if askyesno(SAVE_LOCALLY__MSG,1) = YES_CHAR then
  508.            dot = pos('.',tempfile,max(lastpos('\',tempfile),1))  -- Handle '.' in path
  509.            if dot then tempfile=substr(tempfile,1,dot-1); endif
  510.            if exist(tempfile'.TMP') then
  511. compile if EVERSION < 5
  512.               if askyesno(FILE__MSG tempfile'.TMP' OVERLAY_TEMP2__MSG,1) = 'N' then
  513. compile else
  514.               if winmessagebox('', FILE__MSG tempfile'.TMP' OVERLAY_TEMP3__MSG, 16449)=2 then
  515. compile endif
  516.                  stop
  517.               endif
  518.            endif
  519.            'xcom s 'tempfile'.TMP'
  520.            if rc then return rc; endif
  521.            messageNwait(SAVED_LOCALLY_AS__MSG tempfile'.TMP' PRESS_A_KEY__MSG)  --LAM
  522.         endif
  523.      endif
  524.      call message(1)
  525.      return src
  526.   endif                   --LAM: Don't need ELSE since THEN does a RETURN.
  527.    name=strip(given_name)  -- Allow for brackets in PC names
  528. compile if EVERSION >= '5.50'  --@HPFS
  529.    name_same = (name = .filename)
  530.    if pos(' ',name) & leftstr(name,1)<>'"' then
  531.       name = '"'name'"'
  532.    endif
  533. compile endif
  534. compile if BACKUP_PATH
  535.        -- jbl 1/89 new feature.  Editors in the real marketplace keep at least
  536.        -- one backup copy when a file is written.
  537.  compile if BACKUP_PATH <> '='
  538.    if backup_path_ok then
  539.  compile endif
  540.  compile if EVERSION >= '4.10'    -- OS/2 - redirect STDOUT & STDERR
  541.       quietshell 'copy' name MakeBakName() '1>nul 2>nul'
  542.  compile else
  543.       quietshell 'copy' name MakeBakName() '>nul'
  544.  compile endif
  545.  compile if BACKUP_PATH <> '='
  546.    endif
  547.  compile endif
  548. compile endif
  549.    'xcom s 'options name; src=rc    -- the save code for a vanilla PC file...
  550. compile if EVERSION >= '5.50'  --@HPFS
  551.    if not rc and name_same then
  552. compile else
  553.    if not rc and name=.filename then
  554. compile endif
  555.       .modify=0
  556.       'deleteautosavefile'
  557.    endif
  558.    return src
  559.  
  560.  
  561. defproc save_host_file(hostfile, tempfile, thisLT, fto, hostfileid, options)
  562.  
  563.   universal hostcopy, hostdrive
  564.   universal LT, emulator, keep_temp_files
  565. compile if WANT_DBCS_SUPPORT
  566.   universal country, codepage, ondbcs
  567. compile endif
  568.  
  569.   getfileid hostfileid
  570.   'xcom save 'tempfile
  571.   if rc then stop endif
  572.  
  573.   hostfilename = hostdrive||thisLT||hostfile
  574.  
  575.   if not isoption(options,'Q') then
  576. compile if EPM & EVERSION < '5.50'
  577.      call sayatbox(SAVING_PROMPT__MSG hostfilename WITH__MSG fto)
  578. compile else
  579.      call message(SAVING_PROMPT__MSG hostfilename WITH__MSG fto)
  580. compile endif
  581.    endif
  582.                                      -- build command line
  583.   if emulator = 'IBM' | emulator = 'CP78' then
  584. compile if WANT_DBCS_SUPPORT
  585.      p = lastpos('ASCII', fto)
  586.      if p and lastpos(codepage, 932 942) then
  587.         fto = substr(fto, 1, p - 1)'JI'substr(fto, p + 1)
  588.      endif
  589. compile endif
  590.      if emulator<>'IBM' then
  591.         send = SEND_CMD
  592.      else
  593.         send = 'send'
  594.      endif
  595.      if thisLT=':' then
  596.        line = 'xcom' send tempfile hostfile fto
  597.      else
  598.        line = 'xcom' send tempfile thisLT||hostfile fto
  599.      endif
  600.   else
  601.      line = hostcopy tempfile HOSTCOPYDRIVE||thisLT||hostfile fto
  602.   endif
  603. compile if DEBUG
  604.   messagenwait(line)
  605. compile endif
  606.  
  607. compile if USE_EHLLAPI
  608.   if emulator = 'IBM' then
  609.      rc = EHLLAPI_SEND_RECEIVE(90,substr(line,11))  -- SEND = 90
  610.   else
  611. compile endif
  612.   quiet_shell line
  613. compile if FIX_CURSOR
  614.   insert_toggle; insert_toggle
  615. compile endif
  616. compile if EPM
  617.    endif
  618. compile endif
  619.  
  620. compile if E3MVS
  621.   rc = isa_E3mvs_filename(rc,Error_msg,'RESET',rc,rc,rc,rc)
  622. compile endif
  623.  
  624.   if rc then
  625. compile if E3  -- Only E3 generates an "Insufficient memory" error.
  626.       if rc=sayerror('Insufficient memory') then       --LAM
  627.          emsg = 'Insufficient memory to call 'hostcopy
  628.       else
  629.          emsg = 'Host error 'rc' - no save'
  630.       endif
  631.       messagenwait(emsg'.  File saved on PC in 'tempfile)
  632. compile else
  633.       messagenwait(HOST_ERROR__MSG rc'; 'HOST_CANCEL__MSG tempfile)
  634. compile endif
  635.      return 1
  636.   else
  637.      if .filename=hostfilename then
  638.         hostfileid.modify=0                    -- reset 'modify since saved' switch
  639.      endif
  640.      if keep_temp_files then
  641.         message(SAVED_LOCALLY_AS__MSG upcase(tempfile))
  642.      else
  643.         call erasetemp(tempfile)
  644.      endif
  645.   endif
  646.   return 0
  647.  
  648.  
  649. defproc namefile(newname)
  650.   universal hostdrive
  651.  
  652.   hostfileid=''
  653.   parse value upcase(newname) with name '[' fto ']'
  654.  
  655.                        -- sets hostfile, tempfile, thisLT, bin
  656.   hosttype = ishost(name, 'NAME', hostfile, tempfile, thisLT, bin)
  657.   if hosttype then
  658.      hostfilename = hostdrive||thisLT||hostfile
  659. compile if DUPLICATES_ALLOWED
  660.      getfileid hostfileid
  661. compile else
  662.      if already_in_ring(hostfilename, hostfileid) then -- is file being edited?
  663.         message(ALREADY_EDITING_MSG)
  664.         return 1                          -- then error - two files one name
  665.      endif
  666. compile endif
  667.      call hidden_info(hostfileid, hostfilename, tempfile, fto, 'NAME', bin, hosttype)
  668.      .filename=hostfilename
  669.   elseif parse_filename(newname,.filename) then
  670.      sayerror INVALID_FILENAME__MSG
  671.   else
  672. compile if EVERSION >= '5.50'  --@HPFS
  673.       if pos(' ',newname) & leftstr(newname,1)<>'"' then
  674.          newname = '"'newname'"'
  675.       endif
  676. compile endif
  677.      'xcom n 'newname  --  for a vanilla PC name
  678.   endif
  679.  
  680.  
  681. defproc quitfile()
  682.   universal keep_temp_files
  683.  
  684. compile if EVERSION < 5
  685.    if .windowoverlap then
  686.       modify=(.modify and .views=1)
  687.    else
  688.       modify=.modify
  689.    endif
  690.    k='Y'
  691.    if modify then
  692.  compile if SMARTQUIT
  693.       call message(QUIT_PROMPT1__MSG '('FILEKEY')')
  694.  compile else
  695.       call message(QUIT_PROMPT2__MSG)
  696.  compile endif
  697.       loop
  698.          k=upcase(getkey())
  699.  compile if SMARTQUIT
  700.          if k=$FILEKEY then 'File'; return 1              endif
  701.  compile endif
  702.          if k=YES_CHAR or k=NO_CHAR or k=esc then leave;  endif
  703.       endloop
  704.       call message(1)
  705.    endif
  706.    if k<>YES_CHAR then
  707.       return 1
  708.    endif
  709.    if not .windowoverlap or .views=1 then
  710.       .modify=0
  711.    endif
  712. compile endif
  713.  
  714.    'deleteautosavefile'
  715. ;  if not pos('.DIR',.filename) and substr(.filename,1,1) <> '.' then
  716.    if substr(.filename,1,1) <> '.' then
  717. ;;    if check_for_host_file(.filename) then
  718.       hosttype = ishost(.filename, 'CHECK', hostfile, tempfile, thisLT, bin)
  719.       if hosttype then
  720.          getfileid quitfileid
  721.          call hidden_info(quitfileid, .filename, tempfile, fto, 'QUIT', bin, hosttype)
  722.          if not keep_temp_files then
  723.             call erasetemp(tempfile)
  724.          endif
  725.       endif
  726.    endif
  727.    'xcom_quit'
  728.  
  729. /* No longer used by E3EMUL.E, but some user code may depend on it... */
  730. defproc check_for_host_file(arg1)
  731.   return ishost(arg1, 'CHECK', hostfile, tempfile, thisLT, bin)
  732.  
  733.  
  734. defproc ishost(candidate, verb, var hostfile, var tempfile, var thisLT, var bin)
  735.  
  736.    universal hostdrive, LT, binoptions, ftoptions, emulator
  737.  
  738.  -- also returns a numeric value:
  739.  --  0 -- PC  filename
  740.  --  1 -- VM  filename
  741.  --  2 -- MVS filename
  742.  
  743. compile if DEBUG
  744. ;   messagenwait('ishost sees: 'candidate verb hostfile tempfile thisLT bin)
  745. compile endif
  746.  
  747.    cand = upcase(candidate)
  748.    verb = upcase(verb)
  749.    hostfile = ''
  750.    tempfile = ''
  751.    whynot = ''
  752.    thisLT = ''
  753.    bin = 0
  754.  
  755.   /* first, find out what sort of file we got here...*/
  756.  
  757.    parse value cand with '/Q' candidate                --  PRINT command does
  758.    if not candidate then                               -- 'save /q', we strip
  759.      candidate = cand                                  -- this when checking
  760.    endif                                               -- for host file
  761.  
  762.    if candidate='' then  -- the null filename - PC file
  763.       return 0
  764.    endif
  765.    candidate = strip(candidate)
  766.  
  767. compile if VM
  768.  compile if EVERSION >= '5.50'
  769.    if verify(candidate,' ','m') & leftstr(candidate,1)<>'"' then
  770.  compile else
  771.    if verify(candidate,' ','m') then          -- space => VM filename or error
  772.  compile endif
  773.       if verb = 'CHECK' then  -- don't care about syntax, etc
  774.          return 1
  775.       endif      --LAM:  Don't use ELSEIF if THEN ended w/ RETURN.
  776.       if isa_vm_filename(candidate, hostfile, tempfile, thisLT, bin, whynot) then
  777.          setLT(thisLT)
  778.          return 1
  779.       endif
  780.  compile if HOST_LT_REQUIRED
  781.       if upcase(substr(candidate,1,1))=hostdrive & substr(candidate,3,1)=':' then
  782.  compile elseif HOSTDRIVE_REQUIRED
  783.       if upcase(substr(candidate,1,1))=hostdrive & pos(':', substr(candidate,2,3)) then
  784.  compile endif
  785.          message(candidate LOOKS_VM__MSG whynot)
  786.  compile if HOST_LT_REQUIRED | HOSTDRIVE_REQUIRED
  787.   compile if EVERSION < '5.50'
  788.       else
  789.          message(NO_SPACES__MSG)
  790.   compile endif
  791.       endif
  792.  compile endif
  793.       return 0
  794.    endif
  795. compile endif
  796.  
  797. compile if (MVS | E3MVS)
  798.    posp1 = pos('.',candidate)
  799.    posl  = pos(':',candidate)
  800.    posp2 = lastpos('.',candidate)
  801.  
  802.    test1= pos('''',candidate)   |              /* Fully qualified MVS name ?    */
  803.           pos('(',candidate)    |              /* PDS member specified ?        */
  804.  compile if HOST_LT_REQUIRED
  805.           (posl=3 &                            /* If 'Hx:' then ...             */
  806.  compile else
  807.           (posl   &                            /* If 'H:' or 'Hx:' then ...     */
  808.  compile endif
  809.           substr(candidate,1,1) = hostdrive)   /*   it must be a HOST file      */
  810.  
  811.  compile if E3          -- E3:  can assume FAT
  812.    test2=posp1 &                       /* 2nd qualifier is >3 bytes and */
  813.         (length(candidate)-posp1) > 3  /*   cannot be a valid PC Extent */
  814.  compile endif
  815.  
  816.    if not pos('\',candidate)  &                /* MVS name cannot contain '\'   */
  817.  compile if E3          -- E3:  can assume FAT
  818.       (test1                                 | /* Fully qualified MVS name ?    */
  819.        (posp1 <> posp2)                      | /* Multiple qualifiers ?         */
  820.         test2) then                            /* 2nd qualifier is >3 bytes ... */
  821.  compile else           -- OS/2; last two tests don't disqualify an HPFS filename.
  822.       test1 then                               /* Fully qualified MVS name ?    */
  823.  compile endif
  824.  compile if E3MVS
  825.       if isa_E3MVS_filename(candidate, hostfile, verb, tempfile, thisLT, bin, whynot) then
  826.  compile else
  827.       if isa_mvs_filename(candidate, hostfile, verb, tempfile, thisLT, bin, whynot) then
  828.  compile endif
  829.          setLT(thisLT)
  830.          return 2
  831.       else
  832.  compile if E3MVS
  833.          call free()
  834.  compile endif
  835.          sayerror(MVS_Error__MSG whynot)
  836.          stop
  837.       endif
  838.    endif
  839. compile endif -- (MVS | E3MVS)
  840.  
  841.   /* assume PC filename by now... */
  842.  
  843.    if verb = 'CHECK' then
  844.       return 0
  845.    endif
  846.    if verb = 'NAME' & pos('=',candidate) then
  847.       call parse_filename(candidate,.filename)
  848.    endif
  849.    if isa_pc_filename(candidate, tempfile, whynot) then
  850.       return 0
  851.    endif
  852.    message(candidate LOOKS_PC__MSG whynot)
  853.    return 0
  854.  
  855.  
  856. /**************************************************************************/
  857. /*****************************************************************************/
  858.  
  859. defproc isa_pc_filename(candidate, var tempfile, var error_msg)
  860. compile if EVERSION >= '5.50'  --@HPFS
  861.    if leftstr(candidate,1)='"' & rightstr(candidate,1)='"' then
  862.       candidate=substr(candidate,2,length(candidate)-2)
  863.    endif
  864. compile endif
  865.    parse value upcase(candidate) with drive ':' pathfile
  866.    if not pathfile then
  867.       pathfile = drive
  868.       drive = ''
  869.    endif
  870.    if length(drive) > 1 then
  871.       error_msg = PC_DRIVESPEC__MSG drive LONGER_THAN_ONE__MSG
  872.       return 0
  873.    endif
  874.    if length(drive) and verify(drive,'ABCDEFGHIJKLMNOPQRSTUVWXYZ') then
  875.       error_msg = PC_DRIVESPEC__MSG drive IS_NOT_ALPHA__MSG
  876.       return 0
  877.    endif
  878.    if substr(pathfile,1,2)='..' then  -- allow shortening path by '..'
  879.       pathfile = substr(pathfile,3)    -- strip it, check the rest of path
  880.    endif
  881.    if lastpos('\',pathfile) > 1 and pos('\',pathfile) <> 1 then
  882.                             -- We have a path, but it doesn't start with a \
  883.       pathfile = '\'pathfile
  884.    endif
  885. compile if E3
  886.    bad_chars = '."/\[]:|<>+=;,'            --LAM
  887. compile else                                          -- Don't limit to 8 chars; HPFS
  888.    bad_chars = '"/\:|<>'            --LAM
  889. compile endif
  890.    if substr(pathfile,1,1)='\' then
  891.      parse value pathfile with +1 pathpiece '\' restofname
  892.      while restofname do
  893. compile if E3
  894.        parse value pathpiece with first '.' last
  895.        if length(first) > 8 or verify(first,bad_chars,'m') then
  896.          error_msg = INVALID_PATH__MSG candidate
  897.          return 0
  898.        endif
  899.        if length(last) > 3 or verify(last,bad_chars,'m') then
  900. compile else                                          -- Don't limit to 8 chars; HPFS
  901.        if verify(pathpiece,bad_chars,'m') then
  902. compile endif
  903.          error_msg = INVALID_PATH__MSG candidate
  904.          return 0
  905.        endif
  906.        parse value restofname with pathpiece '\' restofname
  907.      endwhile
  908.      name = pathpiece
  909.    else
  910.      name=pathfile
  911.    endif
  912.    parse value name with fname '.' ext
  913. compile if E3
  914.    if length(fname) > 8 or verify(fname,bad_chars,'m') then
  915. compile else                                          -- Don't limit to 8 chars; HPFS
  916.    if verify(fname,bad_chars, 'm') then
  917. compile endif
  918.      error_msg = INVALID_FNAME__MSG fname
  919.      return 0
  920.    endif
  921.    if ext then
  922. compile if E3
  923.      if length(ext) > 3 or verify(ext,bad_chars,'m') then
  924. compile else                                          -- Don't limit to 8 chars; HPFS
  925.      if verify(ext,bad_chars,'m') then
  926. compile endif
  927.        error_msg = INVALID_EXT__MSG ext
  928.        return 0
  929.      endif
  930.    endif
  931.  
  932.    tempfile=''
  933.    return 1
  934.  
  935. compile if not defined(VALID_LTS)
  936.  compile if USING='CM+CP78'
  937. define VALID_LTS = 'ABCDEFGH12345'
  938.  compile elseif USING='CP78'
  939. define VALID_LTS = 'ABCDE12345'
  940.  compile else
  941. define VALID_LTS = 'ABCDEFGH'
  942.  compile endif
  943. compile endif
  944.  
  945. --  VM support routines  -----------------------------------------------
  946.  
  947. compile if VM
  948. defproc isa_vm_filename(candidate,
  949.                         var hostfile, var tempfile, var thisLT, var bin,
  950.                         var error_msg)
  951.  
  952.    universal hostdrive, LT, savepath, emulator
  953.    universal hname, htype, hmode
  954.  
  955.    parse value upcase(candidate) with drive ':' hname htype hmode rest
  956.  
  957.    thisLT = LT
  958.    if not hname then
  959.  compile if HOST_LT_REQUIRED | HOSTDRIVE_REQUIRED
  960.       error_msg = NO_HOST_DRIVE__MSG
  961.       return 0
  962.  compile else
  963.       parse value drive with hname htype hmode rest
  964.       drive = hostdrive||LT
  965.  compile endif
  966.    else
  967.       if length(drive)>2 then
  968.          error_msg = HOST_DRIVELETTER__MSG drive IS_TOO_LONG__MSG
  969.          return 0
  970.       endif
  971.       if substr(drive,1,1)<>hostdrive then
  972.          error_msg = HOST_DRIVELETTER__MSG substr(drive,1,1) INVALID__MSG
  973.          return 0
  974.       endif
  975.       if length(drive)>1 then
  976.          thisLT = substr(drive,2)
  977.          if verify(thisLT,VALID_LTS) then
  978.             error_msg = HOST_LT__MSG thisLT INVALID__MSG
  979.             return 0
  980.          endif
  981.  compile if HOST_LT_REQUIRED
  982.       else
  983.          error_msg = NO_LT__MSG
  984.          return 0
  985.  compile endif
  986.       endif
  987.    endif
  988. compile if USING='CM+CP78'
  989.    if isnum(thisLT) then
  990.       emulator = 'CP78'
  991.    else
  992.       emulator = 'CM'
  993.    endif
  994. compile endif
  995.  
  996.    if not hmode then                     -- assuming host filename -
  997.       hmode=DEFAULT_FILEMODE             -- will default to your A disk
  998.    elseif hmode<>'*' then
  999.       if length(hmode)>2 then
  1000.          error_msg = FM__MSG hmode IS_TOO_LONG__MSG
  1001.          return 0
  1002.       endif
  1003.       if verify(substr(hmode,1,1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ') then
  1004.          error_msg = FM1_BAD__MSG
  1005.          return 0
  1006.       endif
  1007.       if length(hmode)>1 and verify(substr(hmode,2,1),'1234567890')  then
  1008.          error_msg = FM2_BAD__MSG
  1009.          return 0
  1010.       endif
  1011.    endif
  1012.  
  1013.    if not htype then
  1014.       error_msg = NO_FT__MSG
  1015.       return 0
  1016.    endif
  1017.    if length(htype)>8 then
  1018.       error_msg = FT__MSG htype IS_TOO_LONG__MSG
  1019.       return 0
  1020.    endif
  1021.    bad_chars = ':*~`!%^&()|\{[}];"<,>.?/'
  1022.    if verify(htype, bad_chars, 'm') then
  1023.       error_msg = BAD_FT__MSG htype
  1024.       return 0
  1025.    endif
  1026.  
  1027. ;  if not hname then  -- then htype would already have been reported missing.
  1028. ;     error_msg = 'fn missing'
  1029. ;     return 0
  1030. ;  endif
  1031.    if length(hname)>8 then
  1032.       error_msg = FN__MSG hname IS_TOO_LONG__MSG
  1033.       return 0
  1034.    endif
  1035.    if verify(hname, bad_chars, 'm') then
  1036.       error_msg = BAD_FN__MSG htype
  1037.       return 0
  1038.    endif
  1039.  
  1040.    binpos=lastpos('BIN',htype)
  1041.  
  1042.    bin = binpos and (binpos = (length(htype) - 2))
  1043.  
  1044.    hostfile=hname htype hmode                   -- remove extra spaces
  1045.    tempfile=savepath||pc_chars(hname)'.'pc_chars(substr(htype,1,3))
  1046.  
  1047. compile if USING='CM+IBM'
  1048.    emulator = 'CM'
  1049. compile endif
  1050.  
  1051.    return 1
  1052. compile endif
  1053.  
  1054. --  MVS support routines -----------------------------------------
  1055.  
  1056. compile if E3MVS
  1057.    include 'e3mvsisa.e'  -- include Ken Kahn's isa-E3mvs-filename routine
  1058. compile endif
  1059.  
  1060. compile if MVS
  1061.  
  1062. defproc isa_mvs_filename(candidate,
  1063.                          var hostfile, MVSfunction, var tempfile,
  1064.                          var thisLT, var bin,
  1065.                          var error_msg)
  1066.  
  1067.    universal hostdrive, LT, savepath, emulator
  1068.  
  1069.    parse value upcase(candidate) with drive ':' datasetname rest
  1070.  
  1071. ;; MVSfunction = Upcase(MVSfunction)
  1072.    If (MVSfunction = 'QUIT') or (MVSfunction = 'CHECK') then
  1073.       return 2
  1074.    EndIf
  1075.    If (MVSfunction = 'RESET') then
  1076.       return candidate
  1077.    EndIf
  1078.  
  1079.    ThisLT=LT
  1080.    if datasetname='' then
  1081.  compile if HOST_LT_REQUIRED | HOSTDRIVE_REQUIRED
  1082.       error_msg = NO_HOST_DRIVE__MSG
  1083.       return 0
  1084.  compile else
  1085.       parse value drive with datasetname rest
  1086.  compile endif
  1087.    else
  1088.       if substr(drive,1,1)<>hostdrive then
  1089.          error_msg = HOST_DRIVELETTER__MSG substr(drive,1,1) INVALID__MSG
  1090.          return 0
  1091.       endif
  1092.       if length(drive)>2 then
  1093.          error_msg = HOST_DRIVELETTER__MSG drive IS_TOO_LONG__MSG
  1094.          return 0
  1095.       endif
  1096.       if length(drive)>1 then
  1097.          thisLT = substr(drive,2)
  1098.          if verify(thisLT,VALID_LTS) then
  1099.             error_msg = HOST_LT__MSG thisLT INVALID__MSG
  1100.             return 0
  1101.          endif
  1102.  compile if HOST_LT_REQUIRED
  1103.       else
  1104.          error_msg = NO_LT__MSG
  1105.          return 0
  1106.  compile endif
  1107.       endif
  1108.    endif
  1109. compile if USING='CM+CP78'
  1110.    if isnum(thisLT) then
  1111.       emulator = 'CP78'
  1112.    else
  1113.       emulator = 'CM'
  1114.    endif
  1115. compile endif
  1116.  
  1117.    if pos("'",datasetname) then
  1118.       datasetname = substr(datasetname,2,length(datasetname)-2)
  1119.       quotes = "'"
  1120.    else
  1121.       quotes = ''
  1122.    endif
  1123.  
  1124.    if (length(datasetname) > 44) then
  1125.       error_msg = DSN_TOO_LONG__MSG
  1126.       return 0
  1127.    endif
  1128.  
  1129.    if verify(datasetname,'(','m') and
  1130. compile if EVERSION >= '5.17'
  1131.         rightstr(datasetname,1) <> ')' then
  1132. compile else
  1133.         substr(datasetname,length(datasetname),1) <> ')' then
  1134. compile endif
  1135.       datasetname = datasetname')'
  1136.    endif
  1137.  
  1138.    parse value datasetname with DsnName '(' member ')' rest
  1139.  
  1140.    HostFile = ''
  1141.    Qualifiers = 0
  1142.    Qual1 = ''
  1143.    Qual2 = ''
  1144.    Qual3 = ''
  1145.    LastQualifier = ''
  1146.    Restof_Dsn = DsnName
  1147.    do forever
  1148.       parse value Restof_Dsn with Qualifier '.' Restof_Dsn
  1149.       if Qualifier = '' then leave; endif
  1150.       Qualifiers = Qualifiers + 1
  1151.       LastQualifier = Qualifier
  1152.       if length(Qualifier) > 8 then
  1153.          error_msg = QUAL_NUM__MSG Qualifiers '('Qualifier')' QUAL_TOO_LONG__MSG
  1154.          return 0
  1155.       endif
  1156.       if verify(qualifier, ':*~`!%^&()_-+=|\{[}];"<,>.?/', 'm') then
  1157.          error_msg = QUAL_NUM__MSG Qualifiers '('Qualifier')' QUAL_INVALID__MSG
  1158.          return 0
  1159.       endif
  1160.       if Qualifiers>1 then
  1161.          HostFile = HostFile||'.'||Qualifier
  1162.       else
  1163.          HostFile = Qualifier
  1164.       endif
  1165.       if     Qualifiers = 1 then
  1166.          Qual1 = Qualifier
  1167.       elseif Qualifiers = 2 then
  1168.          Qual2 = Qualifier
  1169.       elseif Qualifiers = 3 then
  1170.          Qual3 = Qualifier
  1171.       endif
  1172.    enddo
  1173.  
  1174.    if member <> '' then
  1175.       if substr(member,1,1) = '+' then
  1176.          if substr(member,2,1) <> '0' then
  1177.             error_msg = GENERATION_NAME__MSG member INVALID__MSG
  1178.             return 0
  1179.          endif
  1180.       elseif substr(member,1,1) = '-' then
  1181.          if verify(substr(member,2,1),'123456789') then
  1182.             error_msg = GENERATION_NAME__MSG member INVALID__MSG
  1183.             return 0
  1184.          endif
  1185.       elseif length(member) > 8 then
  1186.          error_msg = MEMBER__MSG member IS_TOO_LONG__MSG
  1187.          return 0
  1188.       elseif verify(member, ':*~`!%^&()_-+=|\{[}];"<,>.?/', 'm') then
  1189.          error_msg = INVALID_MEMBER__MSG member
  1190.          return 0
  1191.       endif
  1192.    elseif verify(datasetname,'()','m') then
  1193.       error_msg = DSN_PARENS__MSG
  1194.       return 0
  1195.    endif
  1196.  
  1197.    if member = '' then
  1198.       HostFile = quotes||HostFile||quotes
  1199.    else
  1200.       HostFile = quotes||HostFile'('member')'quotes
  1201.    endif
  1202.  
  1203.    if member = '' then
  1204.       if Qual3 = '' then
  1205.          tempFile = savepath||Qual1'.'substr(LastQualifier,1,3)
  1206.       else
  1207.          tempFile = savepath||Qual2'.'substr(LastQualifier,1,3)
  1208.       endif
  1209.    else
  1210.       tempFile = savepath||pc_chars(member)'.'substr(LastQualifier,1,3)
  1211.    endif
  1212.  
  1213. compile if USING='CM+IBM'
  1214.    emulator = 'IBM'
  1215. compile endif
  1216.  
  1217.    return (2)
  1218.  
  1219. compile endif
  1220.  
  1221.  
  1222. -- COMMON ROUTINES, ETC.  --
  1223.  
  1224. defproc pc_chars(str) -- Translate invalid PC chars to $
  1225.    do forever
  1226.       v = verify(str, '+,"/\[]:|<>=;.', 'M')
  1227.       if not v then leave; endif
  1228. compile if E3
  1229.       str = substr(str,1,v-1)'$'substr(str,v+1)
  1230. compile else
  1231.       str = overlay('$',str,v)
  1232. compile endif
  1233.    enddo
  1234.    return str
  1235.  
  1236. defproc already_in_ring(filename, var tryid)
  1237.  
  1238.   getfileid tryid, filename
  1239.   return tryid<>''            --LAM
  1240.  
  1241.  
  1242. defproc hidden_info(hostfileid, hostfilename, var tempfile, var fto, verb, bin, hosttype)
  1243.  
  1244.  /* using a hidden file, we keep track of the host files and any special  */
  1245.  /* file transfer options associated with each.                           */
  1246.  
  1247.  /* get the hidden file for the information we're keeping                 */
  1248.  
  1249.   save_rc = rc
  1250.   if verb='NAME' then
  1251.      newname=hostfilename
  1252.      hostfilename = .filename
  1253.   endif
  1254.  
  1255.   getfileid savefileid
  1256. compile if EVERSION < 5
  1257.   'xcom e /h /q /n fto.e'
  1258. compile else
  1259.    'xcom e /n fto.e'
  1260.    .visible = 0
  1261. compile endif
  1262.   '0'
  1263. compile if EVERSION >= '4.10'
  1264.   GETSEARCH search_command -- Save user's search command.
  1265.  compile if EVERSION >= 5
  1266.       display -2              -- disable display of nonfatal error messages
  1267.  compile endif
  1268. compile endif
  1269.   if hostfileid then
  1270.      'xcom l ?'hostfileid' /?'
  1271.   else
  1272.      'xcom l /'hostfilename
  1273.   endif
  1274.   found = rc<> -273 -- sayerror('String not found')        --LAM
  1275. compile if EVERSION >= '4.10'
  1276.  compile if EVERSION >= 5
  1277.       display 2               -- reenable display of nonfatal error messages
  1278.  compile endif
  1279.   SETSEARCH search_command -- Restores user's command so Ctrl-F works.
  1280. compile endif
  1281. compile if DEBUG
  1282.   if found then
  1283.      getline line
  1284.      messagenwait('hidden info>>> 'line)
  1285.   endif
  1286. compile endif
  1287.  
  1288.  
  1289.  /* now see what we're supposed to do      */
  1290.  /* verbs are EDIT, NAME, QUIT, SAVE       */
  1291.  
  1292.   if verb='QUIT' then
  1293.      if found then
  1294.         getline line
  1295.         parse value line with . '/' . '/' tempfile .
  1296.         deleteline
  1297.      else
  1298.         tempfile = ''
  1299.      endif
  1300.   elseif verb='EDIT'  then
  1301.      if found then
  1302.         replaceline hostfileid' /'hostfilename' /'tempfile' /'hosttype' /'fto
  1303.      else
  1304.         top
  1305.         insertline  hostfileid' /'hostfilename' /'tempfile' /'hosttype' /'fto
  1306.      endif
  1307.      set_FTO(hostfilename, bin, fto)
  1308.   elseif verb='NAME' then
  1309.      if found then
  1310.         getline line                                 -- use file transfer opts
  1311.         parse value line with . '/' . '/' . '/' oldhosttype '/' hidden_fto       -- kept in entry.
  1312.         if not fto then
  1313. compile if USING='CM+IBM'
  1314.            if hosttype<>oldhosttype then  -- Old ft options no good;
  1315.               set_FTO(newname, bin, fto)    -- set to default.
  1316.            else
  1317. compile endif -- USING='CM+IBM'
  1318.               fto=hidden_fto                -- Use the FTO from the hidden file.
  1319. compile if USING='CM+IBM'
  1320.            endif
  1321. compile endif -- USING='CM+IBM'
  1322.         endif
  1323.         replaceline hostfileid' /'newname' /'tempfile' /'hosttype' /'fto
  1324.      else
  1325.         top
  1326.         insertline  hostfileid' /'newname' /'tempfile' /'hosttype' /'fto
  1327.      endif
  1328. ;;   set_FTO(hostfilename, bin, fto)  -- 93/08: No reason for this when 'NAME'.
  1329.   elseif verb='SAVE' then
  1330.      if found then
  1331.         getline line                                 -- use file transfer opts
  1332.         parse value line with . '/' . '/' . '/' . '/' hidden_fto       -- kept in entry.
  1333.         if not fto then fto=hidden_fto endif
  1334.      else
  1335.         top
  1336.         insertline  hostfileid' /'hostfilename' /'tempfile' /'hosttype' /'fto
  1337.      endif
  1338.      set_FTO(hostfilename, bin, fto, savefileid)
  1339.   endif
  1340.  
  1341. compile if DEBUG
  1342.    messagenwait('hid says: 'hostfileid hostfilename tempfile fto hosttype verb bin)
  1343. compile endif
  1344.  
  1345.   activatefile savefileid
  1346. compile if EVERSION < 5
  1347.   sayerror 0
  1348. compile endif
  1349.   rc = save_rc
  1350.  
  1351.  
  1352. defproc set_FTO(hostfile, bin, var fto)  -- called by hidden_info, loadfile
  1353.   universal emulator, ftoptions, binoptions
  1354. compile if WANT_DBCS_SUPPORT
  1355.   universal country, codepage, ondbcs
  1356. compile endif
  1357.  
  1358.   fto = strip(fto)
  1359.   if not fto then
  1360. compile if USING='CM+CP78' | USING='CM+IBM'
  1361.      if bin then
  1362.         if emulator='CM' then
  1363.            fto='/q /b'
  1364.         else
  1365.  compile if USING='CM+IBM'
  1366.   compile if USE_EHLLAPI
  1367.            fto = ''                     -- Omit redirection if EPM (uses EHLLAPI)
  1368.   compile else
  1369.            fto = '() >nul'
  1370.   compile endif
  1371.  compile else  -- else USING='CM+CP78'
  1372.            fto='BIN Q'
  1373.  compile endif
  1374.         endif
  1375.      else
  1376.         if emulator='CM' then
  1377.            fto='/q /ascii'
  1378.         else
  1379.  compile if USING='CM+IBM'
  1380.   compile if USE_EHLLAPI
  1381.           fto = 'ASCII CRLF'            -- Omit redirection if EPM (uses EHLLAPI)
  1382.   compile else
  1383.           fto = 'ASCII CRLF >nul'       -- The minimum for IBM emulators
  1384.   compile endif
  1385.  compile else  -- else USING='CM+CP78'
  1386.            fto='ASC Q'
  1387.  compile endif
  1388.         endif
  1389.      endif
  1390. compile else
  1391.      if bin then
  1392.         fto=binoptions
  1393.      else
  1394.         fto=ftoptions
  1395.      endif
  1396. compile endif
  1397.   endif
  1398.  
  1399. compile if CALL_USER_FTO
  1400.    if arg(4) then
  1401.       call user_FTO(hostfile, fto, 'SAVE')
  1402.    endif
  1403. compile endif
  1404.  
  1405.   if emulator='IBM' | emulator='CP78' then
  1406. compile if MVS or E3MVS
  1407.      if not pos(')', hostfile) then  -- Only add RECFM or LRECL if not a PDS member
  1408. compile endif
  1409.         -- For ASCII upload, add LRECL 255 (avoid "Some records were segmented.").
  1410.         if arg(4) & not bin & not pos('LRECL',fto) then  -- Add iff SEND (i.e., arg(4)=1)
  1411. compile if MVS or E3MVS
  1412.            if pos('.', hostfile) then     -- MVS file
  1413. ;;            fto='LRECL(255) 'strip(fto,'l','(')  -- Do nothing for MVS files.
  1414.            else
  1415. compile endif
  1416. compile if EVERSION > 5  -- Only EPM has longestline()
  1417.               getfileid fto_fid
  1418.               savefileid = arg(4)
  1419.               activatefile savefileid
  1420.               if longestline() > 80 then
  1421. compile endif
  1422.                  fto='LRECL 255 'strip(fto,'l','(')
  1423. compile if EVERSION > 5
  1424.               endif
  1425.               activatefile fto_fid
  1426. compile endif
  1427. compile if MVS or E3MVS
  1428.            endif  -- pos('.'
  1429. compile endif
  1430.         endif
  1431.         -- For binary upload, add RECFM V (avoid padding last record so CRCs will match).
  1432.         if arg(4) & bin & not pos('RECFM',fto) then     -- Add iff SEND (i.e., arg(4)=1)
  1433.            fto='RECFM V 'strip(fto,'l','(')
  1434.         endif
  1435. compile if MVS or E3MVS
  1436.      endif  -- not pos(')'
  1437.      if not pos('.', hostfile) then     -- VM file
  1438. compile endif
  1439.         if substr(fto,1,1)<>'(' then fto='('fto; endif
  1440. compile if WANT_DBCS_SUPPORT & 0  -- @DBCS_FIX
  1441.         if pos(codepage, 932 942) & not pos('[',fto) then
  1442.            fto='['fto
  1443.         endif
  1444. compile endif
  1445. compile if MVS or E3MVS
  1446.      else
  1447.         fto = strip(strip(fto,'t',')'),'l','(')  -- remove leading '(' & trailing ')'
  1448.      endif
  1449. compile endif
  1450.   endif
  1451.  
  1452. compile if DEBUG
  1453. ;  messagenwait('FTO will be: 'fto)
  1454. compile endif
  1455.  
  1456.  
  1457.  
  1458. defproc setLT(var LT_to_use)
  1459.   universal LT, emulator
  1460.  
  1461.   if not LT_to_use then
  1462.      LT_to_use = LT||':'
  1463.   else
  1464.      LT_to_use = LT_to_use||':'
  1465.   endif
  1466.  
  1467. compile if DEBUG
  1468.   messagenwait('LT set to: 'LT_to_use)
  1469. compile endif
  1470.  
  1471.  
  1472.  
  1473. defproc check_savepath()     -- Larry Margolis - MARGOLI at YORKTOWN
  1474.    universal savepath
  1475.  
  1476. compile if BACKUP_PATH <> '' & BACKUP_PATH <> '='
  1477.    universal backup_path_ok
  1478.  compile if EVERSION >= '5.17'
  1479.    if rightstr(BACKUP_PATH,1)<>'\' then
  1480.  compile else
  1481.    if substr(BACKUP_PATH,length(BACKUP_PATH),1)<>'\' then
  1482.  compile endif
  1483.       messageNwait(BACKUP_PATH_INVALID_NO_BACKSLASH__MSG'  'NO_BACKUPS__MSG)
  1484.    else
  1485.       curpath=directory()                                     -- get current disk
  1486.       rc = 0
  1487.       call directory(substr(BACKUP_PATH,1,length(BACKUP_PATH)-1))    -- set to BACKUP_PATH
  1488.       if rc=-15 then  -- sayerror('Invalid drive')
  1489.          bad=DRIVE__MSG                                            -- did we set?
  1490.       elseif rc=-3 then  -- sayerror('Path not found')
  1491.          bad=PATH__MSG
  1492.       endif
  1493.       if rc then                                 -- didn't set - BACKUP_PATH invalid
  1494.          messageNwait(BACKUP_PATH_INVALID1__MSG bad'.  'NO_BACKUPS__MSG)
  1495.       else
  1496.          backup_path_ok = 1
  1497.       endif
  1498.       call directory(curpath)  -- Restore original directory
  1499.    endif
  1500. compile endif  -- BACKUP_PATH
  1501.  
  1502.    if savepath='' then
  1503.       savepath=directory()
  1504.       if length(savepath)>3 then savepath=savepath'\'; endif   -- if not 'C:\'
  1505. ;     sayerror SAVEPATH_NULL__MSG
  1506.       return 0
  1507.    endif
  1508.  
  1509. compile if EVERSION >= '5.17'
  1510.    if rightstr(savepath,1)<>'\' then
  1511. compile else
  1512.    if substr(savepath,length(savepath),1)<>'\' then
  1513. compile endif
  1514.       savepath = savepath'\'
  1515.    endif
  1516.  
  1517.    curpath=directory()                                     -- get current disk
  1518.    rc = 0
  1519.    call directory(substr(savepath,1,length(savepath)-1))    -- set to savepath
  1520.    if rc=-15 then  -- sayerror('Invalid drive')
  1521.       bad=DRIVE__MSG                                            -- did we set?
  1522.    elseif rc=-3 then  -- sayerror('Path not found')
  1523.       bad=PATH__MSG
  1524.    endif
  1525.    if rc then                                 -- didn't set - savepath invalid
  1526.       sayerror(SAVEPATH_INVALID1__MSG bad SAVEPATH_INVALID2__MSG)
  1527.       savepath = substr(curpath,1,3)  -- 'C:\'
  1528.    endif
  1529.    call directory(curpath)  -- Restore original directory
  1530.  
  1531.  
  1532. ; This procedure referenced only in SELECT.E - this one works with E3REXKEY
  1533. ; to allow syntax directed editing for EXEC or XEDIT files.
  1534. ;
  1535. ; Gracias, Ken Kahn for the updated code for MVS users
  1536. ;
  1537. ; Also works without E3REXKEY to provide syntax directed editing for files
  1538. ; that have the filetype EBIN, CBIN or PASBIN
  1539.  
  1540. defproc filetype()
  1541.    universal hostdrive
  1542.  
  1543.    filename=arg(1)
  1544.    if filename='' then filename=.filename; endif
  1545.    filename = upcase(filename)
  1546. compile if (MVS | E3MVS)
  1547.  compile if HOST_LT_REQUIRED
  1548.    isa_host_file = substr(filename,1,1)=hostdrive & substr(filename,3,1)=':'
  1549.  compile elseif HOSTDRIVE_REQUIRED
  1550.    isa_host_file = substr(filename,1,1)=hostdrive & pos(':', substr(filename,2,3))
  1551.  compile endif
  1552. compile endif
  1553. ;        -- LAM - '.' is allowed in PC path name.  Not sure how this affects
  1554. ;                 MVS check.
  1555.    i=lastpos('\',filename)
  1556.    if i then
  1557.       filename=substr(filename,i+1)
  1558.    endif
  1559. ;         -- LAM - end
  1560.    i=lastpos('.',filename)
  1561.    j=pos('.', filename)
  1562.    if i then                             -- PC or MVS
  1563.       PCext = substr(filename,i+1)
  1564. compile if (MVS | E3MVS)
  1565.  compile if HOST_LT_REQUIRED | HOSTDRIVE_REQUIRED
  1566.       if isa_host_file then
  1567.  compile else
  1568.       if (i>j)            |
  1569.          (Pos('(',PCext)) |
  1570.          (Pos("'",PCext)) |
  1571.          (Length(PCext) > 3) then
  1572.  compile endif
  1573.         return breakout_mvs(filename,PCext)     -- MVS
  1574.       endif
  1575. compile endif
  1576.       return PCext                       -- PC
  1577.    else                                  -- PC (no ext) or VM
  1578.       return breakout_vm(filename)        -- handles both
  1579.    endif
  1580.  
  1581.  
  1582. compile if (MVS | E3MVS)
  1583. DefProc breakout_mvs(filename,LastQual)
  1584.    i = Pos('(',LastQual)
  1585.    If i then
  1586.       LastQual = SubStr(LastQual,1,i-1)
  1587.    EndIf
  1588.  
  1589.    if lastqual='PASCAL' then
  1590.       return 'PAS'
  1591.    endif
  1592.    if lastqual='C' then
  1593.       return 'C'
  1594.    endif
  1595. compile endif
  1596.  
  1597.  
  1598. defproc breakout_vm(filename)
  1599.    if verify(filename,' ','m') then
  1600.       parse value filename with . ftype .
  1601.       i = lastpos('BIN',ftype)
  1602.       if i then
  1603.          return substr(ftype,1,i-1)
  1604.       endif
  1605.       return ftype
  1606.    endif
  1607.  
  1608.  
  1609. defproc vmfile(var name, var cmdline)
  1610. compile if VM  -- procedure defined even if no VM - makes defc EDIT simpler.
  1611.    universal hostdrive
  1612.  
  1613.  compile if HOST_LT_REQUIRED
  1614.    if upcase(substr(name,1,1))<>hostdrive | substr(name,3,1)<>':' then return 0; endif
  1615.  compile elseif HOSTDRIVE_REQUIRED
  1616.    if upcase(substr(name,1,1))<>hostdrive | pos(':',substr(name,2,2))=0 then return 0; endif
  1617.  compile endif
  1618.  
  1619.    parse value name with fn ft fm cmdline
  1620.    if fn='' or ft='' or length(fn)>11 or pos('\',fn) or pos('.',fn) or
  1621.       length(ft)>8 or pos(':',ft) or pos('\',ft) or pos('.',ft) then
  1622.      return 0
  1623.    endif
  1624.  
  1625.    if (not fm) or length(fm)>2 or
  1626.       pos(':',fm) or pos('\',fm) or pos('.',fm) then
  1627.      cmdline = fm cmdline               -- assumption here:  VM if two
  1628.      name = fn ft
  1629.      return 1
  1630.    endif
  1631.  
  1632.    name = fn ft fm
  1633.    return 1                              --better be VM at this point
  1634. compile else
  1635.    return 0
  1636. compile endif
  1637.  
  1638. /**************************************************************************/
  1639. /*                                                                        */
  1640. /*   commands for changing variable values                                */
  1641. /*                                                                        */
  1642. /**************************************************************************/
  1643.  
  1644. compile if RUNTIME
  1645.  
  1646. defc em, emulator=
  1647.   universal hostcopy, LT, hostcmd, emulator
  1648.  
  1649.   uparg = upcase(arg(1))
  1650.   if uparg = 'IBM' then
  1651.      emulator = 'IBM'
  1652.      hostcopy = ''
  1653. compile if EPM
  1654.      hostcmd = 'EHLLAPI'
  1655. compile elseif EOS2
  1656.      hostcmd = 'os2cmd'
  1657. compile else
  1658.      hostcmd = 'hostsys'
  1659. compile endif
  1660.      sayerror EMULATOR_SET_TO__MSG uparg LT_NOW__MSG LT')'
  1661. compile if EVERSION >= 4      -- OS/2-only emulators
  1662.   elseif uparg = 'CP78' then
  1663.      emulator = 'CP78'
  1664. ;    hostcopy = 'cp78copy'
  1665. ;    hostcmd = 'cp78cmd'
  1666.      hostcopy = ''
  1667. compile if EVERSION >= 4
  1668.      hostcmd = 'os2cmd'
  1669. compile else
  1670.      hostcmd = 'hostsys'
  1671. compile endif
  1672.      LT = ''
  1673.      sayerror EMULATOR_SET_TO__MSG uparg
  1674.   elseif uparg = 'CM' then
  1675.      emulator = 'CM'
  1676.      hostcopy = 'almcopy'
  1677.      hostcmd = 'os2cmd'
  1678.      sayerror EMULATOR_SET_TO__MSG uparg LT_NOW__MSG LT')'
  1679. compile else                  -- DOS-only emulators
  1680.   elseif uparg='BOND' then
  1681.      emulator = 'BOND'
  1682.      hostcopy = 'bondcopy'
  1683.      hostcmd = 'bondcmd'
  1684.      LT = ''
  1685.      sayerror EMULATOR_SET_TO__MSG uparg
  1686.   elseif uparg = 'MYTE' then
  1687.      emulator = 'MYTE'
  1688.      hostcopy = 'mytecopy'
  1689.      hostcmd = 'mytecmd'
  1690.      sayerror EMULATOR_SET_TO__MSG uparg LT_NOW__MSG LT')'
  1691.   elseif uparg = 'E78' then
  1692.      emulator = 'E78'
  1693.      hostcopy = 'e78copy'
  1694.      hostcmd = 'e78cmd'
  1695.      LT = ''
  1696.      sayerror EMULATOR_SET_TO__MSG uparg
  1697. compile endif                 -- End of OS-specific emulators
  1698.   elseif not uparg then
  1699. compile if EVERSION < 5
  1700.      setcommand EMULATOR__MSG emulator,10,1         --LAM
  1701. compile else
  1702.      'commandline' EMULATOR__MSG emulator
  1703. compile endif
  1704.   else
  1705. compile if EVERSION >= 4      -- OS/2-only emulators
  1706.      sayerror '('uparg')' IS_INVALID_OPTS_ARE__MSG 'IBM, CM, CP78'
  1707. compile else                  -- DOS-only emulators
  1708.      sayerror '('uparg')' IS_INVALID_OPTS_ARE__MSG 'BOND, MYTE, E78, IBM'
  1709. compile endif                 -- End of OS-specific emulators
  1710.      stop
  1711.   endif
  1712.  
  1713.  
  1714. defc lt=
  1715.   universal LT
  1716.  
  1717.   uparg = upcase(arg(1))
  1718.   if verify(uparg,'ABCDEFGH','M',1) and length(uparg) = 1 then
  1719.     LT = uparg
  1720.     sayerror LT_SET_TO__MSG LT
  1721.   elseif uparg = 'NO_LT' or uparg = 'NONE' or uparg = 'NULL' then
  1722.     LT = ''
  1723.     sayerror LT_SET_NULL__MSG
  1724.   elseif not uparg then
  1725. compile if EVERSION < 5
  1726.     message('LT used only for CM, MYTE and IBM with >1 host session...')
  1727. compile endif
  1728.     if not LT then   --changed for space
  1729. compile if EVERSION < 5
  1730.        setcommand 'LT No_LT',4,1
  1731. compile else
  1732.        'commandline LT No_LT'
  1733. compile endif
  1734.     else
  1735. compile if EVERSION < 5
  1736.        setcommand 'LT 'LT,4,1
  1737. compile else
  1738.        'commandline LT 'LT
  1739. compile endif
  1740.     endif
  1741.   else
  1742.     sayerror '('uparg')' LT_INVALID__MSG
  1743.     stop
  1744.   endif
  1745.  
  1746.  
  1747. defc hd, hostdrive=
  1748.   universal hostdrive
  1749.  
  1750.   uparg = upcase(arg(1))
  1751.   if verify(uparg,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','M',1) and length(uparg)=1 then
  1752.     hostdrive = uparg
  1753.     sayerror HOSTDRIVE_NOW__MSG hostdrive
  1754.   elseif not uparg then  -- changed for space
  1755. compile if EVERSION < 5
  1756.     setcommand 'HD 'hostdrive,4,1
  1757. compile else
  1758.     'commandline HD 'hostdrive
  1759. compile endif
  1760.   else
  1761.     sayerror '('uparg')' IS_INVALID_OPTS_ARE__MSG 'A - Z'
  1762.     stop
  1763.   endif
  1764.  
  1765.  
  1766. defc savepath =
  1767.   universal savepath
  1768.  
  1769.   uparg = upcase(arg(1))
  1770.   if not uparg  then  -- changed for space
  1771. compile if EVERSION < 5
  1772.     setcommand 'SAVEPATH 'savepath,10,1
  1773. compile else
  1774.     'commandline SAVEPATH 'savepath
  1775. compile endif
  1776.   else
  1777.     savepath = uparg
  1778.     call check_savepath(TRY_AGAIN__MSG)
  1779.   endif
  1780.  
  1781. compile endif  -- RUNTIME
  1782.  
  1783. defc fto=
  1784.   universal ftoptions
  1785.  
  1786.   uparg = upcase(arg(1))
  1787.   if not uparg then -- changed for space         -- tell 'em the default
  1788. compile if EVERSION < 5
  1789.     setcommand 'FTO 'ftoptions,5,1
  1790. compile else
  1791.     'commandline FTO 'ftoptions
  1792. compile endif
  1793.   else
  1794.     ftoptions = uparg
  1795.     sayerror FTO_WARN__MSG
  1796.   endif
  1797.  
  1798. defc bin=
  1799.   universal binoptions
  1800.  
  1801.   uparg = upcase(arg(1))
  1802.   if uparg=='' then                             -- tell 'em the default
  1803. compile if EVERSION < 5
  1804.     setcommand 'BIN 'binoptions,5,1
  1805. compile else
  1806.     'commandline BIN 'binoptions
  1807. compile endif
  1808.   else
  1809.     binoptions = uparg
  1810.     sayerror BIN_WARN__MSG
  1811.   endif
  1812.  
  1813. compile if EPM  -- SEND & RECEIVE don't work from a PM window, so call via EHLLAPI.
  1814. ; Following is a common call for Send or Receive.  It does a Set Session Parms
  1815. ; to 'QUIET', sets up the parameters the way EMUL_HLLAPI wants (VAR parameters)
  1816. ; and issues the call.
  1817. defproc EHLLAPI_SEND_RECEIVE(function, parms)
  1818. universal ondbcs                              -- @DBCS_FIX
  1819.    if ondbcs then
  1820.        parse value parms with f '(' o
  1821.        parms = f '[(' o
  1822.    endif                                      -- end DBCS_FIX
  1823.    if function=90 or function=91 then
  1824.       call EHLLAPI_SEND_RECEIVE(9, 'QUIET TIMEOUT=2')
  1825. compile if DEBUG
  1826.       messagenwait('Calling function' function' "'parms'"')
  1827. compile endif
  1828.    endif
  1829. compile if not DEBUG
  1830.    if echo() then  -- Since user wouldn't see this echoed, let's say it explicitly...
  1831.       messagenwait('EHLLAPI_SEND_RECEIVE('function', "'parms'")')
  1832.    endif
  1833. compile endif
  1834.    EHLLAPI_data_string_length = atoi(length(parms)) -- Data string length
  1835.    EHLLAPI_host_PS_position = atoi(0)
  1836.    result=HLLAPI_call(atoi(function), selector(parms), offset(parms),
  1837.                  EHLLAPI_data_string_length, EHLLAPI_host_PS_position)
  1838.    if result=3 | result=4 then return 0; endif  -- 3=File Transfer complete;
  1839.    return result                                -- 4= Complete with segmented records.
  1840.  
  1841. ; HLLAPI_call is our general interface for calling the EHLLAPI dynalink.
  1842. ; Parameters are always the same - an EHLLAPI function number, selector of
  1843. ; the data string, offset of the data string, the data string length, and
  1844. ; the host presentation space position.  They might not be used in all calls,
  1845. ; but EHLLAPI requires that they all be present.
  1846. ;
  1847. ; The data string is passed via selector and offset rather than as a VAR string,
  1848. ; since some calls (e.g., copying the entire host screen) require a string
  1849. ; larger than 255 bytes, and so we must allocate a buffer and pass that.
  1850. ; Note:  This is not taken advantage of in E3EMUL.E, but it's a small cost to
  1851. ; make it available to others, instead of having to duplicate the whole function.
  1852. defproc HLLAPI_call(EHLLAPI_function_number,
  1853.                     sel_EHLLAPI_data_string, ofs_EHLLAPI_data_string,
  1854.                 var EHLLAPI_data_string_length, -- Data str. len. or buffer size
  1855.                 var EHLLAPI_host_PS_position)   -- Host presentation space posn.
  1856.                                                 -- (on return, RC)
  1857.    rc = 0        -- Prepare for missing DLL library
  1858.  compile if EPM32
  1859.    result=dynalink('ACS3EHAP',                  -- dynamic link library name
  1860.                    'HLLAPI',                    -- HLLAPI direct call
  1861.                     Thunk(offset(EHLLAPI_function_number)    || selector(EHLLAPI_function_number))    ||
  1862.                     Thunk(ofs_EHLLAPI_data_string            || sel_EHLLAPI_data_string)              ||
  1863.                     Thunk(offset(EHLLAPI_data_string_length) || selector(EHLLAPI_data_string_length)) ||
  1864.                     Thunk(offset(EHLLAPI_host_PS_position)   || selector(EHLLAPI_host_PS_position)) )
  1865.  compile else
  1866.    result=dynalink('ACS3EHAP',                  -- dynamic link library name
  1867.                    'HLLAPI',                    -- HLLAPI direct call
  1868.                    address(EHLLAPI_function_number)     ||
  1869.                    sel_EHLLAPI_data_string              ||
  1870.                    ofs_EHLLAPI_data_string              ||
  1871.                    address(EHLLAPI_data_string_length)  ||
  1872.                    address(EHLLAPI_host_PS_position))
  1873.  compile endif
  1874.    if rc then sayerror ERROR__MSG rc FROM_HLLAPI__MSG; stop; endif
  1875.    return result
  1876.  
  1877. ; A simpler EHLLAPI interface - just pass a function number and data string.
  1878. ; The third and fourth parameters are optional.  Can not be used for calls
  1879. ; which return data in the data string.
  1880. defproc simple_HLLAPI_call(EHLLAPI_function_number, EHLLAPI_data_string)
  1881.    if arg(3)='' then
  1882.       EHLLAPI_data_string_length = atoi(length(EHLLAPI_data_string))
  1883.    else
  1884.       EHLLAPI_data_string_length = atoi(arg(3))
  1885.    endif
  1886.    if arg(4)='' then
  1887.       EHLLAPI_host_PS_position = atoi(0)
  1888.    else
  1889.       EHLLAPI_host_PS_position = atoi(arg(4))
  1890.    endif
  1891.    return HLLAPI_call(atoi(EHLLAPI_function_number),
  1892.                       selector(EHLLAPI_data_string), offset(EHLLAPI_data_string),
  1893.                       EHLLAPI_data_string_length, EHLLAPI_host_PS_position)
  1894. compile endif -- EPM
  1895.