home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rxexp1.zip / install.cmd
OS/2 REXX Batch file  |  1995-02-11  |  47KB  |  1,156 lines

  1. /* ------------------------------------------------------------------ */
  2. /* Contents:     Some useful REXX functions                           */
  3. /*                                                                    */
  4. /* Author:       Bernd Schemmer                                       */
  5. /*               Baeckerweg 48                                        */
  6. /*               60316 Frankfurt am Main                              */
  7. /*               Germany                                              */
  8. /*               CIS: 100104,613                                      */
  9. /*                                                                    */
  10. /* Last Update:  11.02.1995                                           */
  11. /*                                                                    */
  12. /* Distribution: Freeware, no warranty, use this functions on your    */
  13. /*               own risk but please give credit were credit is due.  */
  14. /*               Report all bugs and suggestions to the author.       */
  15. /*                                                                    */
  16. /* Notes:        See comments below for documentation.                */
  17. /* ------------------------------------------------------------------ */
  18.  
  19.  
  20. /* -------------------------- INSTALL CODE -------------------------- */
  21.  
  22. authornotice = '/* --------- written by Bernd Schemmer, CIS: 100104,613 ------------- */'
  23.  
  24. newFileLine = '/* ' || copies( '=', 66 ) || ' */'
  25.  
  26.                         /* install some error handlers                */
  27. SIGNAL ON HALT Name InstallEnd
  28. SIGNAL ON NOVALUE
  29.  
  30. call charOut, 'Install the examples in the current directory (Y/n)? Y' || '08'x
  31. userResponse = translate( left( strip( lineIn() ),1 ) )
  32.  
  33. if userResponse <> 'N' then
  34. do
  35.   parse source . . installProgram
  36.  
  37.   installCode = CharIn( installProgram, 1, Chars( InstallProgram ) )
  38.   if length( InstallCode ) <> 0 then
  39.   do
  40.     exampleEnd = 1
  41.     curExampleNo = 0
  42.     outputFileName = ''
  43.  
  44.     do until exampleEnd = 0
  45.       exampleStart = pos( newFileLine, installCode, exampleEnd )
  46.  
  47.       curExampleNo = curExampleNo + 1
  48.  
  49.       exampleEnd = pos( newFileLine, installCode, exampleStart+1 )
  50.  
  51.       outputFileName = 'EXP' || curExampleNo || '.CMD'
  52.  
  53.       call CharOut , ' Creating the file "' || outputFileName || '" ...'
  54.       if stream( outputFileName, 'c', 'QUERY EXIST' ) <> '' then
  55.         '@del ' outputfileName '2>NUL 1>NUL'
  56.  
  57.       call LineOut outputFileName, newFileLine
  58.       call LineOut outputFileName, authorNotice
  59.  
  60.       if exampleEnd = 0 then
  61.         call CharOut outputFileName, substr( installCode ,,
  62.                                              exampleStart )
  63.       else
  64.         call CharOut outputFileName, substr( installCode ,,
  65.                                              exampleStart,,
  66.                                              exampleEnd - exampleStart )
  67.       call LineOut outputFileName
  68.       call lineOut , 'done.'
  69.  
  70.     end /* do forever */
  71.  
  72.     call lineOut , curExampleNo || ' example files written.'
  73.  
  74.   end /* if length( installCode ) <> 0 then */
  75.  
  76. end /* if userResponse <> 'N' then */
  77.  
  78. InstallEnd:
  79.  
  80. exit 0
  81.  
  82. /* ---------------------- END OF INSTALL CODE ----------------------- */
  83.  
  84. /* ================================================================== */
  85. /* check if this program is executed from within the macrospace       */
  86.  
  87. if InMacroSpace() = 1 then
  88.   say "This program is executed from within the macro space"
  89. else
  90.   say "This program is NOT executed from within the macro space"
  91.  
  92. RETURN
  93.  
  94. /* ------------------------------------------------------------------ */
  95. /* function: check if the program is in the macrospace                */
  96. /*                                                                    */
  97. /* call:     InMacroSpace                                             */
  98. /*                                                                    */
  99. /* returns:  1 - yes                                                  */
  100. /*           0 - no                                                   */
  101. /*                                                                    */
  102. InMacroSpace: PROCEDURE
  103.  
  104.   SIGNAL ON SYNTAX   NAME NotInMacroSpace
  105.   inMacroSpace = 1
  106.  
  107.   dummy = sourceLine( 1 )
  108.   inMacroSpace = 0
  109.  
  110. NotInMacroSpace:
  111.  
  112.   if inMacroSpace = 1 then
  113.   do
  114.                       /* program seems to be in the macro space       */
  115.                       /* do a second check to be sure                 */
  116.     parse source . . thisFile
  117.     if fileSpec( "drive", thisFile ) <> '' then
  118.       inMacroSpace = 0        /* Oops, we are not in the macro space  */
  119.   end /* if inMacroSpace = 1 */
  120.  
  121. RETURN inMacroSpace
  122.  
  123.  
  124. /* ================================================================== */
  125. /* sample code to test if a drive is ready                            */
  126.  
  127. do forever
  128.   call lineOut , "Enter the name of the drive to test " ,
  129.                  "(RETURN to end): "
  130.   thisDrive = strip( lineIn() )
  131.   if thisDrive = "" then
  132.     leave
  133.  
  134.   if DriveReady( thisDrive ) = 1 then
  135.     say "The drive <" || thisDrive || "> is ready."
  136.   else
  137.     say "The drive <" || thisDrive || "> is not ready."
  138. end /* do forever */
  139.  
  140. exit 0
  141.  
  142. /* ------------------------------------------------------------------ */
  143. /* function: test if a drive is ready                                 */
  144. /*                                                                    */
  145. /* call:     DriveReady( testDrive )                                  */
  146. /*                                                                    */
  147. /* where:    testdrive - Name of the drive to test (e.g. "A:")        */
  148. /*                                                                    */
  149. /* returns:  1 - drive is ready                                       */
  150. /*           0 - drive is not ready                                   */
  151. /*                                                                    */
  152. DriveReady: PROCEDURE
  153.   parse arg driveToTest ":" .
  154.  
  155.   thisRC = 0
  156.  
  157.                       /* install a temporary error handler to check   */
  158.                       /* if the drive ready                           */
  159.   SIGNAL ON NOTREADY Name DriveReadyEnd
  160.  
  161.   call stream driveToTest || ":\*", "D"
  162.   thisRC = 1
  163.  
  164. DriveReadyEnd:
  165.   RETURN thisRC
  166.  
  167.  
  168. /* ================================================================== */
  169. /* sample code to test if a directory exist with restoring all        */
  170. /* directorys                                                         */
  171.  
  172. do forever
  173.   call lineOut , "Enter the name of the directory to test " ,
  174.                  "(RETURN to end): "
  175.   thisDir = strip( lineIn() )
  176.   if thisDir = "" then
  177.     leave
  178.  
  179.   if DirExist( thisDir ) <> "" then
  180.     say "The directory <" || thisDir || "> exist."
  181.   else
  182.     say "The directory <" || thisDir || "> does not exist."
  183. end /* do forever */
  184.  
  185. exit 0
  186.  
  187. /* ------------------------------------------------------------------ */
  188. /* function: test if a directory exist                                */
  189. /*                                                                    */
  190. /* call:     DirExist( testDir )                                      */
  191. /*                                                                    */
  192. /* where:    testDir - name of the directory to test                  */
  193. /*                                                                    */
  194. /* returns:  full name of the directory or "" if the directory        */
  195. /*           don't exist                                              */
  196. /*                                                                    */
  197. DirExist: PROCEDURE
  198.   parse arg testDir .
  199.  
  200.                       /* init the return code                         */
  201.   thisRC = ""
  202.  
  203.                       /* install a temporary error handler to check   */
  204.                       /* if the drive with the directory to test is   */
  205.                       /* ready                                        */
  206.   SIGNAL ON NOTREADY NAME DirDoesNotExist
  207.   call stream testDir || "\*", "D"
  208.  
  209.  
  210.                       /* save the current directory of the current    */
  211.                       /* drive                                        */
  212.   curDir = directory()
  213.  
  214.                       /* save the current directory of the drive      */
  215.                       /* with the directory to test                   */
  216.   curDir1 = directory( fileSpec( "drive", testDir ) )
  217.  
  218.  
  219.                       /* test if the directory exist                  */
  220.   thisRC = directory( testDir )
  221.  
  222.                       /* restore the current directory of the drive   */
  223.                       /* with the directory to test                   */
  224.   call directory curDir1
  225.  
  226.                       /* restore the current directory of the current */
  227.                       /* drive                                        */
  228.   call directory curDir
  229. DirDoesNotExist:
  230.  
  231. return thisRC
  232.  
  233. /* ================================================================== */
  234. /* code sequence to get the no. of a sourceline at runtime            */
  235. /* Note that this code also functions in compiled REXX programs       */
  236. /* and in REXX programs loaded in the macro space.                    */
  237. /* Usage example:                                                     */
  238. /* You can use this technique in your programs to write an error      */
  239. /* handler which ignores errors in some lines but not in all.         */
  240.  
  241.  
  242. /** DO NOT CHANGE, ADD OR DELETE ONE OF THE FOLLOWING FOUR LINES!  **/
  243.   SIGNAL I!.__CallUserProc1
  244. I!.__CallUserProc1:
  245.   LineNo = sigl+2     /* no. of THIS line                           */
  246.   say "This is the line no. " || LineNo+1 || " of the source code."
  247. /** DO NOT CHANGE, ADD OR DELETE ONE OF THE PRECEEDING FOUR LINES! **/
  248.  
  249.  
  250. /* ================================================================== */
  251. /* check if a name is the name of a file or the name of a device      */
  252.  
  253. say 'Enter the name of a file or device:'
  254. testFileName = lineIN()
  255.  
  256. if stream( testFileName, "c", "QUERY EXIST" ) <> "" then
  257.   if stream( testFileName, "c", "QUERY DATETIME" ) = "" then
  258.     say TestFileName || " is a device!"
  259.   else
  260.     say TestFileName || " is a file!"
  261. else
  262.   say TestFileName || " does not exist!"
  263.  
  264.  
  265. /* ================================================================== */
  266. /* routine(s) to search a file in the directorys saved in an          */
  267. /* environment variable (e.g. "PATH")                                 */
  268.  
  269.                       /* example call                                 */
  270. do forever
  271.   say "Enter a filename ("""" to abort):"
  272.   searchFile = strip( lineIn() )
  273.  
  274.   if searchFile = '' then
  275.     leave
  276.  
  277.   say "Result of SearchDataFile(" || searchFile || ") is: "
  278.   say "  """ || SearchDataFile( searchFile ) || """"
  279.   say "Result of SearchProgram(" || searchFile || ") is: "
  280.   say "  """ || SearchProgram( searchFile ) || """"
  281. end /* do forever */
  282.  
  283. exit 0
  284.  
  285. /* ------------------------------------------------------------------ */
  286. /* function: Search a file in the current directory and in the        */
  287. /*           directorys saved in an environment variable              */
  288. /*           (e.g. PATH, DPATH, ... )                                 */
  289. /*                                                                    */
  290. /* call:     SearchFile( fileName, varName {,environment})            */
  291. /*                                                                    */
  292. /* where:    fileName - name of the file to search                    */
  293. /*           varName - name of the environment variable containing    */
  294. /*                     the directorys to search                       */
  295. /*           environment - environment with the environment Variable  */
  296. /*                         (Def.: OS2ENVIRONMENT)                     */
  297. /*                                                                    */
  298. /* returns:  full name of the file or "" if not found                 */
  299. /*                                                                    */
  300. SearchFile: PROCEDURE
  301.   parse arg fileName , envVar, environment
  302.   resultStr = ""
  303.  
  304.   if fileName <> "" & envVar <> "" then
  305.   do
  306.     if environment = '' then
  307.       environment = "OS2ENVIRONMENT"
  308.  
  309.     searchDirs = ".;" || value( envVar, , environment )
  310.  
  311.     do forever
  312.       parse var searchDirs curSearchDir ";" searchDirs
  313.  
  314.       curSearchDir = strip( curSearchDir )
  315.  
  316.       if curSearchDir = "" then
  317.         iterate
  318.  
  319.       if right( curSearchDir, 1 ) <> "\" & ,
  320.          right( curSearchDir, 1 ) <> ":" then
  321.         curSearchDir = curSearchDir || "\"
  322.  
  323.       resultStr = stream( curSearchDir || fileName, "c", "QUERY EXIST" )
  324.       if resultStr <> "" then
  325.         leave
  326.  
  327.       if SearchDirs = "" then
  328.         leave
  329.  
  330.     end /* do forverver */
  331.   end /* if fileName <> "" & ... */
  332.  
  333. RETURN resultStr
  334.  
  335. /* ------------------------------------------------------------------ */
  336. /* function: Search a file in the current directory and in the        */
  337. /*           directorys saved in the environment variable PATH        */
  338. /*                                                                    */
  339. /* call:     SearchProgram( progName {,environment})                  */
  340. /*                                                                    */
  341. /* where:    progName - name of the program to search                 */
  342. /*           environment - environment with the environment Variable  */
  343. /*                         (Def.: OS2ENVIRONMENT)                     */
  344. /*                                                                    */
  345. /* returns:  full name of the program or "" if not found              */
  346. /*                                                                    */
  347. SearchProgram: PROCEDURE
  348.   parse arg progName , environment
  349.   resultStr = ""
  350.   if progName <> "" then
  351.     resultStr = SearchFile( progName, "PATH", environment )
  352. RETURN resultStr
  353.  
  354. /* ------------------------------------------------------------------ */
  355. /* function: Search a datafile in the current directory and in the    */
  356. /*           directorys saved in the environment variable DPATH       */
  357. /*                                                                    */
  358. /* call:     SearchProgram( datafileName {,environment})              */
  359. /*                                                                    */
  360. /* where:    datafileName - name of the datafile to search            */
  361. /*           environment - environment with the environment Variable  */
  362. /*                         (Def.: OS2ENVIRONMENT)                     */
  363. /*                                                                    */
  364. /* returns:  full name of the datafile or "" if not found             */
  365. /*                                                                    */
  366. SearchDataFile: PROCEDURE
  367.   parse arg dataFileName , environment
  368.   resultStr = ""
  369.   if dataFileName <> "" then
  370.     resultStr = SearchFile( datafileName, "DPATH", environment )
  371. RETURN resultStr
  372.  
  373.  
  374. /* ================================================================== */
  375. /* example for working on a directory tree without loading the dll    */
  376. /* REXXUTIL                                                           */
  377.  
  378. say 'Reading the directory tree of drive C: ...'
  379.  
  380.                         /* put a list of all directorys in the queue  */
  381.                         /* (use /FIFO to get the directorys in the    */
  382.                         /*  right sequence)                           */
  383. "@dir /s/f /Ad C:\ 2>NUL | RXQUEUE /FIFO"
  384.  
  385. say 'Copying the directorys into a stem ...'
  386.  
  387. foundedDirs.0 = 0
  388.                         /* put the names of all founded directorys    */
  389.                         /* in a stem variable for further processing  */
  390. do while queued() <> 0
  391.   curDir = strip( lineIn( "QUEUE:" ) )
  392.   if curDir <> "" & ,
  393.      right( CurDir, 2 ) <> "\."  & ,
  394.      right( CurDir, 3 ) <> "\.." then
  395.   do
  396.     j = foundedDirs.0 + 1
  397.     foundedDirs.j = curDir
  398.     foundedDirs.0 = j
  399.   end /* if curDir <> "" then */
  400. end /* do while queued <> 0 */
  401.  
  402. do j = 1 to foundedDirs.0
  403.   say 'Directory no. ' || j || ' is: ' || foundedDirs.j
  404. end /* do j = foundedDirs.0 */
  405.  
  406.  
  407. /* ================================================================== */
  408. /* example for simulating the BASIC input command                     */
  409.  
  410.                               /* example call ...                     */
  411. thisString = input( "Enter a string: " )
  412. say "You entered '" || thisString || "'."
  413.  
  414. exit
  415.  
  416. /* ------------------------------------------------------------------ */
  417. /* function: simulate the BASIC command INPUT                         */
  418. /*                                                                    */
  419. /* call:     input( prompt )                                          */
  420. /*                                                                    */
  421. /* where:    prompt - prompt for the input                            */
  422. /*                                                                    */
  423. /* returns:  entered string                                           */
  424. /*                                                                    */
  425. input:
  426.   parse arg prompt
  427.  
  428.   call charOut , prompt
  429.  
  430. RETURN lineIn()
  431.  
  432.  
  433. /* ================================================================== */
  434. /* example for a simple yes/no question without loading the dll       */
  435. /* REXXUTIL                                                           */
  436.  
  437. '@cls'                        /* this technique won't work in the     */
  438.                               /* last line of the display!            */
  439.  
  440.                               /* example call ...                     */
  441. thisKey = AskUser( "YN" "Enter Y or N: " )
  442. say "You entered '" || thisKey || "'."
  443.  
  444. exit 0
  445.  
  446. /* ------------------------------------------------------------------ */
  447. /* AskUser - get input from the user                                  */
  448. /*                                                                    */
  449. /* Usage:    AskUser akeys prompt                                     */
  450. /*                                                                    */
  451. /* where:                                                             */
  452. /*           akeys - allowed keys (all keys are translated to         */
  453. /*                   uppercase)                                       */
  454. /*           prompt - prompt for the ask                              */
  455. /*                                                                    */
  456. /* Returns:  the pressed key in uppercase                             */
  457. /*                                                                    */
  458. /* note:     This routine uses ESC sequences to position the cursor   */
  459. /*           This routine only works, if you do not use the           */
  460. /*           last line of the screen for the prompt!                  */
  461. /*                                                                    */
  462. AskUser: PROCEDURE
  463.   parse arg aKeys prompt
  464.  
  465.   aKeys = translate( akeys )
  466.  
  467.   call charout ,  prompt
  468.  
  469.   thisKey = " "
  470.   do UNTIL pos( thisKey ,  aKeys ) <> 0
  471.     call charOut ,"1B"x || "[s" || "1B"x || "[K"
  472.     thisKey = translate( charIn() )
  473.     call CharOut , "1B"x || "[u"
  474.                                 /* delete the CR/LF sequence from     */
  475.                                 /* the keyboard buffer!               */
  476.     dummy = lineIn()
  477.  
  478.   end /* do until ... */
  479.  
  480.                                 /* do a linefeed                      */
  481.   say ""
  482.  
  483. RETURN thisKey
  484.  
  485.  
  486. /* ================================================================== */
  487. /* example for an in progress output                                  */
  488.  
  489. /* note:     This code uses ESC sequences to position the cursor      */
  490.  
  491. progressChar="\"
  492.  
  493. do until lines( "C:\OS2\INSTALL\DATABASE.TXt" ) = 0
  494.                                 /* get next cmd from input channel    */
  495.                                 /* this is an example to do something */
  496.   curLine = LINEIN( "C:\OS2\INSTALL\DATABASE.TXT" )
  497.  
  498.                                 /* show progress indicator            */
  499.   if progressChar="\" then
  500.     progressChar="/"
  501.   else
  502.     progressChar="\"
  503.                                 /* use ESC sequences to position      */
  504.                                 /* the cursor                         */
  505.   call charOut , "1B"x || "[s Reading " || progressChar || "1B"x || "[u"
  506.  
  507.   /* ... */
  508.  
  509. end /* do until lines() = 0 */
  510.  
  511.                                 /* do a linefeed                      */
  512. say ""
  513.  
  514. exit 0
  515.  
  516. /* ================================================================== */
  517. /* example code to show how to use a directory name to get an unique  */
  518. /* name                                                               */
  519.  
  520. uniqueName = ""
  521. do i = 1 to 999 until rc = 0
  522.   uniqueName = "C:\TEMP\unique." || i
  523.                                 /* try to create a directory          */
  524.                                 /* OS/2 checks that only ONE process  */
  525.                                 /* can create the directory!          */
  526.   "@md " uniqueName "1>NUL 2>NUL"
  527. end /* do i = 1 to 999 */
  528.  
  529. if rc == 0 then
  530.   say "The unique name is" uniqueName
  531. else
  532.   say "No unique name found!"
  533.  
  534. /* do something */
  535. /* ... */
  536.                                 /* free the name                      */
  537. "@rd " uniqueName "1>NUL 2>NUL"
  538. exit 0
  539.  
  540.  
  541. /* ================================================================== */
  542. /* example code to show how to use a queue name to get an unique      */
  543. /* name                                                               */
  544.  
  545.                                 /* create a queue with an unique name */
  546. uniqueName = rxqueue( "create" )
  547.  
  548. say "The unique name is" uniqueName
  549.  
  550. /* do something */
  551. /* ... */
  552.                                 /* free the name                      */
  553. call rxqueue "Delete", uniqueName
  554. exit 0
  555.  
  556.  
  557. /* ================================================================== */
  558. /* example code to show how to use a directory name as semaphor in    */
  559. /* REXX                                                               */
  560.  
  561. semName = "C:\TEMP\MYSEM"
  562.                                 /* test and set the semaphor          */
  563. do until rc = 0
  564.                                 /* note: in a real program you should */
  565.                                 /*       also check for a timeout!    */
  566.   "@md " semName "1>NUL 2>NUL"
  567. end /* do until rc = 0 */
  568.  
  569.                                 /* semaphor set -- now it's our turn  */
  570.                                 /* to do something                    */
  571. /* ... */
  572.  
  573.                                 /* free the semaphor                  */
  574. "@rd " semName  "1>NUL 2>NUL"
  575. exit 0
  576.  
  577.  
  578. /* ================================================================== */
  579. /* example code to show how to use a queue name as semaphor in        */
  580. /* REXX                                                               */
  581.  
  582. semName = "MYSEM"
  583.                                 /* test and set the semaphor          */
  584. do until uniqueName == semName
  585.                                 /* note: in a real program you should */
  586.                                 /*       also check for a timeout!    */
  587.  
  588.   uniqueName = rxqueue( "create", semName )
  589.   if uniqueName <> semName then
  590.   do
  591.                                 /* queue already exists -- delete the */
  592.                                 /* new created queue!                 */
  593.     call rxqueue "delete", uniqueName
  594.   end /* if uniqueName <> semName then */
  595. end /* do until uniqueName == semName */
  596.  
  597.                                 /* semaphor set -- now it's our turn  */
  598.                                 /* to do something                    */
  599. /* ... */
  600.  
  601.                                 /* free the semaphor                  */
  602. call rxqueue  'Delete', semName
  603. exit 0
  604.  
  605.  
  606. /* ================================================================== */
  607. /* sample code to show how to get the filesystem (FAT, HPFS, CDFS     */
  608. /* or LAN) of a drive                                                 */
  609. /* Tested with OS/2 v2.99 WARP BETA 2 (english) and OS/2 Version 3    */
  610. /* Warp (german)                                                      */
  611.  
  612.                                 /* drives to check                    */
  613. possibleDrives = "CDEFGHI"
  614.  
  615. do i = 1 to length( possibleDrives )
  616.   curdrive = substr( possibleDrives,i,1 )
  617.                                 /* use an unknown parameter for       */
  618.                                 /* CHKDSK to suppress all actions     */
  619.                                 /* (except the print of the           */
  620.                                 /* filesystem)                        */
  621.   "@chkdsk " curDrive || ": /dfadfaf 2>NUL | rxqueue 2>NUL"
  622.  
  623.   do while queued() <> 0
  624.     curLine = lineIN( "QUEUE:" )
  625.     if abbrev( curLine, "Dateisystemtyp für den Datenträger ist:" ) | ,
  626.        abbrev( curLine, "The type of file system for the disk is" ) then
  627.     do
  628.       curFileSystem = word( curLine, words( curLine ) )
  629.       if right( curFileSystem,1 ) == "." then
  630.         curFileSystem = dbrright( curFileSystem,1 )
  631.       say "The filesystem of drive " || curDrive || ": is " curFileSystem
  632.     end /* if abbrev( ... */
  633.   end /* do while queued() <> 0 */
  634. end /* do i = 1 to ... */
  635.  
  636.  
  637. /* ================================================================== */
  638. /* example code to check if a file exists. This function also checks, */
  639. /* if the name is already used by a directory or a device (e.g. CON)  */
  640.  
  641.   do until fileName = ""
  642.     call charOut, "Enter a filename to check: "
  643.     fileName = lineIN()
  644.     say "The result of FileExist(" || fileName || ") is: " || ,
  645.         FileExist( fileName )
  646.   end /* do until iLIne = "" */
  647.  
  648.   exit 0
  649.  
  650. /* ------------------------------------------------------------------ */
  651. /* function: check if a file exists                                   */
  652. /*                                                                    */
  653. /* call:     FileExist fileToTest                                     */
  654. /*                                                                    */
  655. /* where:    fileToTest - name of the file to test                    */
  656. /*                                                                    */
  657. /* returns:  -2 - invalid parameter                                   */
  658. /*           -1 - can not detect (e.g. the drive is not ready)        */
  659. /*            0 - neither a file, a device nor a directory with this  */
  660. /*                name exist                                          */
  661. /*            1 - the file exist                                      */
  662. /*            2 - a device driver with the name exists                */
  663. /*            3 - a directory with the name exists                    */
  664. /*                                                                    */
  665. FileExist: PROCEDURE
  666.   parse arg fileName .
  667.  
  668.                         /* install temporary error handler            */
  669.   SIGNAL ON NOTREADY NAME FileExistError
  670.   SIGNAL ON FAILURE  NAME FileExistError
  671.   SIGNAL ON ERROR    NAME FileExistError
  672.  
  673.   thisRC = -2           /* rc = -2 ->> invalid parameter              */
  674.  
  675.                         /* check the parameter                        */
  676.   if strip( fileName ) <> "" then
  677.   do
  678.     thisRC = -1         /* rc = -1 ->> can not detect the result      */
  679.  
  680.                         /* check if the drive with the file is ready  */
  681.     call stream fileName
  682.                         /* turn of some error handling so we can      */
  683.                         /* determine if the given name is the name of */
  684.                         /* a device (for example "LPT1")              */
  685.     SIGNAL OFF NOTREADY
  686.  
  687.     if stream( fileName, "c", "QUERY EXIST" ) <> "" then
  688.     do
  689.                         /* seems that the file exists -- check if     */
  690.                         /* it is a device                             */
  691.       if stream( fileName, "c", "QUERY DATETIME" ) == "" then
  692.         thisRC = 2      /* rc = 2 ->> this is a device name           */
  693.       else
  694.         thisRC = 1      /* rc = 1 ->> this is a file name             */
  695.     end /* if stream( ... */
  696.     else
  697.     do
  698.                         /* seems that the file does not exist --      */
  699.                         /* check if a directory with the name for the */
  700.                         /* file exist                                 */
  701.  
  702.                         /* save the current directory of the current  */
  703.                         /* drive                                      */
  704.       thisDir = directory()
  705.                         /* save the current directory of the drive    */
  706.                         /* with the file to check                     */
  707.       tempDir = directory( fileSpec( "Drive", fileName ) )
  708.  
  709.       if directory( fileName ) <> "" then
  710.         thisRC = 3      /* rc = 3 ->> a dir with this name exist      */
  711.       else
  712.         thisRC = 0      /* rc = 0 ->> neither a file, a device nor a  */
  713.                         /*            dir with this name exist        */
  714.  
  715.                         /* restore the current directory of the drive */
  716.                         /* with the directory to check                */
  717.       call directory tempDir
  718.                         /* restore the current directory of the       */
  719.                         /* current drive                              */
  720.       call directory thisDir
  721.     end /* else */
  722.   end /* if strip( fileName ) <> "" then */
  723.  
  724. FileExistError:
  725.  
  726. RETURN thisRC
  727.  
  728. /* ================================================================== */
  729. /* sample code to extend the FILESPEC function with code to extract   */
  730. /* the extension of a filename                                        */
  731.  
  732. do until myInput = ""
  733.   say "Enter the parameter for FILESPEC(option, fileName): "
  734.   myInput = strip( lineIn() )
  735.   if myInput <> "" then
  736.   do
  737.     parse var myInput myOption "," myFileName
  738.     say "The result of FILESPEC( " myOption "," myFileName ") is: "
  739.     say "<" || fileSpec( myOption, myFileName ) || ">"
  740.   end /* if myInput <> "" then */
  741. end /* do until myInput = "" */
  742.  
  743. exit 0
  744.  
  745. /* ------------------------------------------------------------------ */
  746. /* function: extended FILESPEC function                               */
  747. /*                                                                    */
  748. /* call:     FileSpec option,filename                                 */
  749. /*                                                                    */
  750. /* where:    option                                                   */
  751. /*             - E{xtension}                                          */
  752. /*               return the extension of the file                     */
  753. /*             All other values for "option" are processed by the     */
  754. /*             original FILESPEC function.                            */
  755. /*           filename                                                 */
  756. /*             - name of the file                                     */
  757. /*                                                                    */
  758. /* returns:  if option = E{xtension}:                                 */
  759. /*             the extension of the filename or "" if none            */
  760. /*           else                                                     */
  761. /*             the return code of the original FILESPEC function      */
  762. /*             or "SYNTAX ERROR" if called with invalid parameter(s)  */
  763. /*                                                                    */
  764. /* notes:    To call the original FILESPEC function direct use        */
  765. /*             myResult = "FILESPEC"( option, filename )              */
  766. /*                                                                    */
  767. FileSpec: PROCEDURE
  768.   parse arg option, fileName
  769.  
  770.                         /* init the return code                       */
  771.   thisRC = "SYNTAX ERROR"
  772.                         /* install a local error handler              */
  773.   SIGNAL ON SYNTAX NAME FileSpecError
  774.  
  775.   option = translate( strip( option ) )
  776.                         /* check the option code                      */
  777.   if abbrev( "EXTENSION", option ) = 1 then
  778.   do
  779.                         /* process the new added option code          */
  780.     i = lastPos( ".", fileName )
  781.     if i > lastPos( "\", fileName ) then
  782.       thisRC = substr( fileName, i+1 )
  783.     else
  784.       thisRC = ""
  785.   end
  786.   else                  /* call the original FILESPEC function        */
  787.     thisRC = "FILESPEC"( option, fileName )
  788.  
  789. FileSpecError:
  790.  
  791. RETURN thisRC
  792.  
  793. /* ================================================================== */
  794.  
  795. say 'See source file for functions.'
  796.  
  797. /* ------------------------------------------------------------------ */
  798. /* function: create a directory(tree)                                 */
  799. /*                                                                    */
  800. /* call:     CreateDirectory dirToCreate                              */
  801. /*                                                                    */
  802. /* where:    dirToCreate - directory to create                        */
  803. /*                                                                    */
  804. /*                                                                    */
  805. /* returns:  0 - okay                                                 */
  806. /*           else OS Error                                            */
  807. /*                                                                    */
  808. CreateDirectory: PROCEDURE
  809.   parse arg dirToCreate
  810.  
  811.                       /* file or device for messages                  */
  812.   prog.__LogAll = "2>NUL 1>NUL"
  813.  
  814.                         /* init the return code                       */
  815.   thisRC = -1
  816.                         /* check if the drive is ready                */
  817.   SIGNAL ON NOTREADY Name CreateDirectoryError
  818.   call stream fileSpec( "drive", dirToCreate ) || "\*"
  819.  
  820.   thisRC = 0
  821.                         /* save the current directory(s)              */
  822.   curDir = directory()
  823.   curDir1 = directory( fileSpec( "drive", dirToCreate ) )
  824.  
  825.   newDir = translate( dirToCreate, "\", "/" )
  826.  
  827.   i = pos( ":", dirToCreate )
  828.   if i <> 0 then
  829.   do
  830.     parse var dirToCreate lwForTheDir ":" dirToCreate
  831.     if directory( lwForTheDir || ":\" ) = "" then
  832.       thisRC = 1
  833.   end /* if i <> 0 then */
  834.  
  835.   if thisRC = 0 then
  836.   do
  837.     if right( dirToCreate, 1 ) <> "\" then
  838.       dirToCreate = dirToCreate || "\"
  839.  
  840.     do until dirToCreate = "" | thisRC <> 0
  841.       parse var dirToCreate newSubDir "\" dirToCreate
  842.       dirToCreate = strip( dirToCreate )
  843.  
  844.       if directory( newSubDir ) = "" then
  845.       do
  846.         "@md " newSubDir prog.__LogAll
  847.         if rc = 2 | rc = 1 then
  848.         do
  849.           if stream( newSubDir , "c", "QUERY EXIST" ) <> "" then
  850.             thisRC = rc
  851.         end /* if rc = 2 | rc = 1 */
  852.         else
  853.           thisRC = rc
  854.  
  855.         if thisRC = 0 then
  856.           call directory newSubDir
  857.       end /* if directory( newSubDir ) = "" then */
  858.     end /* do until dirToCreate = "" | thisRC <> 0 */
  859.   end /* if thisRC = 0 then */
  860.  
  861.                         /* restore the current directory(s)           */
  862.   call directory curDir1
  863.   call directory curDir
  864.  
  865. CreateDirectoryError:
  866.  
  867. RETURN thisRC
  868.  
  869. /* ------------------------------------------------------------------ */
  870. /* function: delete all files in a directory and in all it's          */
  871. /*           sub directorys!                                          */
  872. /*                                                                    */
  873. /* call:     DeleteDirectory dirToDelete                              */
  874. /*                                                                    */
  875. /* where:    dirToDelete - directory to delete                        */
  876. /*                                                                    */
  877. /* returns:  0 - okay                                                 */
  878. /*          -1 - drive not ready                                      */
  879. /*                                                                    */
  880. DeleteDirectory: PROCEDURE
  881.   parse arg dirToDelete
  882.  
  883.                       /* file or device for messages                  */
  884.   prog.__LogAll = "2>NUL 1>NUL"
  885.  
  886.                         /* init the return code                       */
  887.   thisRC = -1
  888.                         /* check if the drive is ready                */
  889.   SIGNAL ON NOTREADY Name DeleteDirectoryError
  890.   call stream fileSpec( "drive", dirToDelete ) || "\*"
  891.  
  892.                         /* put a list of all subdirectorys in the     */
  893.                         /* queue                                      */
  894.   "@dir /s/f /Ad " dirToDelete "2>NUL | RXQUEUE /lifo "
  895.  
  896.   do while queued() <> 0
  897.     dirToDel = lineIn( "QUEUE:" )
  898.     if dirTodel <> "" & right( dirToDel,2 ) <> "\." & ,
  899.        right( dirToDel,3 )  <> "\.." then
  900.     do
  901.       "@attrib -r -s -h " dirToDel || "\*.*" prog.__LogAll
  902.       "@(echo Y & echo J ) | del " dirToDel || "\*.*" prog.__LogAll
  903.       if dirToDel <> dirToDelete then
  904.         "@rd  " dirToDel prog.__LogAll
  905.     end /* if dirToDel <> "" then */
  906.   end /* do while queued <> 0 */
  907.  
  908.   "@attrib -r -s -h " dirToDelete || "\*.*" prog.__LogAll
  909.   "@(echo Y & echo J) | del " dirToDelete || "\*.*" prog.__LogAll
  910.   "@rd " dirToDelete prog.__logAll
  911.  
  912.   thisRC = 0
  913.  
  914. DeleteDirectoryError:
  915.  
  916. RETURN thisRC
  917.  
  918. /* ================================================================== */
  919. /* example code to navigate a program by monitoring its output and    */
  920. /* sending the neccessary keystrokes to it.                           */
  921. /*                                                                    */
  922. /* Notes: The program to navigate must use STDIN for its input and    */
  923. /*        STDOUT and/or STDERR for its output.                        */
  924. /*                                                                    */
  925. /*        Some OS/2 commands write all or parts of their output to    */
  926. /*        STDERR if STDOUT is redirected to a file or into a pipe!    */
  927. /*        Some OS/2 commands do NOT write a CR/LF after a prompt for  */
  928. /*        an input. This is for example true for the FORMAT program.  */
  929. /*        To get around this, we always wait for the line preceding   */
  930. /*        the prompts from the FORMAT program (see below).            */
  931. /*                                                                    */
  932. /*                                                                    */
  933. /* In this example we use "FORMAT A: /q"                              */
  934. /*                                                                    */
  935. /* Save this code in a file with the name "TEST.CMD" and call it with */
  936. /*  TEST <RETURN>                                                     */
  937. /*                                                                    */
  938. /* Tested with OS/2 WARP Version 3 (german) and OS/2 WARP BETA 2      */
  939. /* Version 2.99 (english)                                             */
  940. /*                                                                    */
  941. /*                                                                    */
  942.  
  943.                         /* get the name of our program                */
  944.   parse source . . prog.__Name
  945.  
  946.                         /* output device for our messages (we can not */
  947.                         /* use STDOUT for the messages!!!             */
  948.   prog.__outputDevice = "STDERR:"
  949.  
  950.                         /* get the parameter to check if this is the  */
  951.                         /* first, second or third call                */
  952.   parse arg prog.__Parameter .
  953.  
  954.   select
  955.  
  956. /*************************** third process ****************************/
  957. /* --- put the output of the format command into the queue (FIFO) --- */
  958.  
  959.     when prog.__Parameter == "$$THIRD$$" then
  960.     do
  961.  
  962.       thisLine = ""
  963.  
  964.                         /* this process ends after writing the last   */
  965.                         /* output message of FORMAT into the queue    */
  966.  
  967.     /* message 1273 = "Eine weitere Diskette formatieren (J/N)?" GER  */
  968.     /*                "Format another diskette (Y/N)?            USA  */
  969.       lastFormatMsg = SysGetMessage( 1273 )
  970.  
  971.       do until pos( lastFormatMsg, thisLine ) <> 0
  972.         if lines() <> 0 then
  973.         do
  974.                         /* read the output of the FORMAT program ...  */
  975.           thisLine = lineIN()
  976.                         /* ... and write it into the REXX queue       */
  977.           queue thisLine
  978.         end /* if lines() <> 0 then */
  979.       end /* do until pos( lastFormatMsg, ... */
  980.  
  981.                         /* put the end marker for process 2 into the  */
  982.                         /* queue                                      */
  983.       queue "***END***"
  984.  
  985.     end /* when */
  986.  
  987. /*************************** second process ***************************/
  988. /*  --- monitor the output of the FORMAT command and write the ---    */
  989. /*         neccessary input for the FORMAT command to STDOUT          */
  990.  
  991.     when prog.__Parameter == "$$SECOND$$" then
  992.     do
  993.                         /* init the variables with the messages       */
  994.                         /* indicating that FORMAT needs some input    */
  995.  
  996.     /* message 1507 = "Dateisystemtyp für den Datenträger ist: "  GER */
  997.     /*                "The type of file system for the disk is "  USA */
  998.       firstAskForInput = substr( SysGetMessage( 1507 ), 1, 25 )
  999.  
  1000.     /* message 1288 = "Namen für den Datenträger (max. ... "      GER */
  1001.     /*                "Enter up to 11 characters for the ..."     USA */
  1002.       secondAskForInput = substr( SysGetMessage( 1288 ), 1, 45 )
  1003.  
  1004.     /* message 1306 = "%1 verfügbare Zuordnungseinheiten ... "    GER */
  1005.     /*                "%1 available allocation units on disk."    USA */
  1006.       thirdAskForInput = substr( SysGetMessage( 1306 ), 3, 20 )
  1007.  
  1008.  
  1009.       outputOK = 0
  1010.  
  1011.                     /* just for fun: Show an "in progress" message    */
  1012.       call charOut prog.__OutputDevice , "Formating "
  1013.  
  1014.       do until OutputOK == 1
  1015.  
  1016.         call charOut prog.__OutputDevice, "\" || "08"X || "/" || "08"x
  1017.  
  1018.                         /* wait until output of the FORMAT command is */
  1019.                         /* available                                  */
  1020.         if queued() == 0 then
  1021.           iterate
  1022.  
  1023.                         /* monitor the output from the FORMAT command */
  1024.         curFormatLine = strip( lineIn( "QUEUE:" ) )
  1025.  
  1026.                         /* check if the FORMAT command ended          */
  1027.         if curFormatLine = "***END***" then
  1028.           OutputOk = 1
  1029.  
  1030.         select
  1031.  
  1032.           when pos( FirstAskForInput, curFormatLine ) <> 0 then
  1033.           do
  1034.                         /* FORMAT needs some input to begin the       */
  1035.                         /* format -- so give it a CR/LF               */
  1036.             call lineOut , ""
  1037.           end /* when */
  1038.  
  1039.           when pos( SecondAskForInput, curFormatLine ) <> 0 then
  1040.           do
  1041.                         /* FORMAT needs some input for the volume     */
  1042.                         /* label -- so give it the label              */
  1043.             call lineOut , "Test"
  1044.           end /* when */
  1045.  
  1046.           when pos( thirdAskForInput, curFormatLine ) <> 0 then
  1047.           do
  1048.                         /* FORMAT needs to know if it should format   */
  1049.                         /* another diskette -- tell it that we won't  */
  1050.                         /* format another diskette                    */
  1051.             call lineOut, "N"
  1052.           end /* when */
  1053.  
  1054.           otherwise
  1055.           do
  1056.                         /* do nothing                                 */
  1057.           end /* otherwise */
  1058.  
  1059.         end /* select */
  1060.  
  1061.       end /* do until OutputOK == 1 */
  1062.  
  1063.                         /* end the in progress message                */
  1064.       call lineOut prog.__OutputDevice, "... done."
  1065.  
  1066.     end /* when */
  1067.  
  1068. /***************************** first call *****************************/
  1069. /*                 --- execute the FORMAT command ---                  */
  1070.     otherwise
  1071.     do
  1072.  
  1073.       "@cls"
  1074.       call lineOut prog.__OutputDevice, ""
  1075.  
  1076.       call lineOut prog.__OutputDevice,,
  1077.                    "Example for navigating a program " || ,
  1078.                    "by monitoring the output"
  1079.       call lineOut prog.__outputDevice,,
  1080.                    "Here we call FORMAT A: /Q to show how it works."
  1081.       call lineOut prog.__OutputDevice, ""
  1082.  
  1083.       if queued() <> 0 then
  1084.       do
  1085.                         /* flush the REXX queue                       */
  1086.         do while queued() <> 0
  1087.           tempLine = lineIn( "QUEUE:" )
  1088.         end /* do while queued() <> 0 */
  1089.       end /* if queued() <> 0 then */
  1090.  
  1091.  
  1092.                         /* load the neccessary functions from the DLL */
  1093.                         /* REXXUTIL                                   */
  1094.       call LoadREXXUtil
  1095.  
  1096.                         /* wait until theres a diskette in drive A:   */
  1097.       call InsertDiskDialog
  1098.  
  1099.                         /* execute the FORMAT command with the input  */
  1100.                         /* coming from a second copy of this program  */
  1101.                         /* and the output written to a REXX queue by  */
  1102.                         /* a third copy of this program               */
  1103.       "@cmd /c " prog.__Name "$$SECOND$$ | " || ,  /* second process  */
  1104.                " format A: /q  | "           || ,  /* FORMAT command  */
  1105.                prog.__Name "$$THIRD$$"             /* third process   */
  1106.  
  1107.     end /* otherwise */
  1108.  
  1109.   end /* select */
  1110.  
  1111.   EXIT 0
  1112.  
  1113.  
  1114. /* ****************************************************************** */
  1115. /*                            sub routines                            */
  1116.  
  1117.  
  1118. /* ------------------------------------------------------------------ */
  1119. /*         routine to wait until a diskette is in drive A:            */
  1120. /* ------------------------------------------------------------------ */
  1121.  
  1122.   InsertDiskDialog: PROCEDURE
  1123.  
  1124.   InsertDiskDialogAgain:
  1125.                         /* install a local error handler to check if  */
  1126.                         /* the drive A: is ready                      */
  1127.     SIGNAL ON NOTREADY Name InsertDiskDialogAgain
  1128.  
  1129.     call lineOut , "Insert a disk to FORMAT into drive A: " || ,
  1130.                    "and press enter"
  1131.  
  1132.     tempLine = lineIn()
  1133.  
  1134.     call stream "A:\*"
  1135.   RETURN
  1136.  
  1137. /* ------------------------------------------------------------------ */
  1138. /*       routine to load the neccessary functions from REXXUTIL       */
  1139. /* ------------------------------------------------------------------ */
  1140.  
  1141.   LoadREXXUtil: PROCEDURE
  1142.     call rxFuncAdd "SysGetMessage", "REXXUTIL", "SysGetMessage"
  1143.  
  1144.                         /* install a local error handler to check if  */
  1145.                         /* the DLL was loaded                         */
  1146.     SIGNAL ON SYNTAX NAME LoadRexxUtilError
  1147.  
  1148.     t = SysGetMessage( 1 )
  1149.   RETURN
  1150.  
  1151.   LoadREXXUtilError:
  1152.     call lineOut, "Error: Can not load the DLL REXXUTIL!"
  1153.   EXIT 255
  1154.  
  1155.  
  1156.