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