home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / DHRGCD.ZIP / DHRGCD.CMD next >
OS/2 REXX Batch file  |  1992-07-01  |  19KB  |  480 lines

  1. /* This is a REXX Exec */
  2. /*
  3. ** DHR Global Change Directory Version 1.01
  4. ** Created 06/09/92 by Dennis H. Rosenthal
  5. ** for OS/2 Version 2.0.
  6. ** Released to the public domain.
  7. ** No warranty expressed or implied.
  8. ** Enter DHRGCD /h for View help or ? for
  9. **  help info at end of this file
  10. */
  11. trace
  12. /* Reference #1 */
  13. parse upper source opsys cmdtype exname1
  14. exname = filespec('NAME',exname1)                        /* name of this file */
  15. parse var exname exname '.' .
  16. '@ECHO OFF'                              /* Turn off display of OS/2 commands */
  17. signal on halt name gcd_halt                       /* Trap control break keys */
  18.  
  19. /*
  20. ** Set Options Next
  21. */
  22.  
  23. /* Reference #2 */
  24. use_current_disk_index = 'N'           /* Set to 'Y' to always check current  */
  25.                                        /*  disk first for directory index     */
  26. use_boot_disk_index = 'Y'              /* Set to 'N' to use first local       */
  27.                                        /*  disk for directory index           */
  28. use_ansi_colors = 'Y'                  /* Set to 'N' to skip colors           */
  29.  
  30. use_all_disks = 'Y'                   /* Set to 'N' to index only local disks */
  31.                                       /* Set to 'Y' to index local & network  */
  32.  
  33. /*
  34. ** End of Options
  35. */
  36.  
  37.  
  38. /*
  39. ** Extract command line parms
  40. ** Provide both OS/2 method - command / option or / option command
  41. ** and VM/CMS method - command ( option
  42. */
  43. /*
  44. ** Allow spaces in directory name ("  ")
  45. ** Place directory desired into variable named target
  46. ** Place option into variable named opt
  47. */
  48. /* Reference #3 */
  49. parse upper arg target1 '/' opt1 target2 .
  50. parse upper arg . '"'target3'"' .
  51. parse upper arg target4 '(' opt2 ')' .
  52. target1 = strip(target1)
  53. target2 = strip(target2)
  54. target3 = strip(target3,T)                     /* remove only trailing blanks */
  55. target4 = strip(target4)
  56. if target3 <> '' then target = target3
  57. else if opt2 <> '' then target = target4
  58. else if target1 <> '' then target = target1
  59. else target = target2
  60. if opt2 <> '' then opt = opt2
  61. else opt = opt1
  62. opt = strip(opt)
  63. if target = '?' then opt = target
  64.  
  65. /*
  66. ** Verify allowable options here
  67. */
  68. /* Reference #4 */
  69. if opt = '?' | opt = 'H' then do
  70.     call disp_help
  71.     exit 4                                                /* exit immediately */
  72. end
  73. else if target = '' then do
  74.     if opt = 'L' | opt = '' then do
  75.         say ''
  76.         say 'Cmd requires destination directory as parameter'
  77.         say 'For more information, use /? as parm'
  78.         exit 12                                           /* exit immediately */
  79.     end
  80.     else if opt <> 'R' & opt <> 'RQ' then do
  81.         say ''
  82.         say 'Error - Invalid option ('opt') entered'
  83.         exit 16                                           /* exit immediately */
  84.     end
  85. end
  86. else if opt <> '' then do
  87.     if opt <> 'L' & opt <> 'R' & opt <> 'RQ' then do
  88.         say ''
  89.         say 'Error - Invalid option ('opt') entered'
  90.         exit 16                                           /* exit immediately */
  91.     end
  92. end
  93.  
  94. /*
  95. ** Define some constants
  96. */
  97. /* Reference #5 */
  98. index_file = 'DIRINFO.GCD'                      /* Identify Global Index File */
  99. if use_ansi_colors = 'Y' then do                          /* test option flag */
  100.     esc_char        = '1B'x
  101.     ansi_red        = esc_char'[0;31;40m'       /* red foreground, black back */
  102.     ansi_boldred    = esc_char'[1;31;40m'   /* bold red foreground,black back */
  103.     ansi_green      = esc_char'[0;32;40m'     /* green foreground, black back */
  104.     ansi_boldgreen  = esc_char'[1;32;40m'     /* green foreground, black back */
  105.     ansi_yellow     = esc_char'[0;33;40m'    /* yellow foreground, black back */
  106.     ansi_boldyellow = esc_char'[1;33;40m'    /* yellow foreground, black back */
  107.     ansi_blue       = esc_char'[0;34;40m'      /* blue foreground, black back */
  108.     ansi_boldblue   = esc_char'[1;34;40m'      /* blue foreground, black back */
  109.     ansi_white      = esc_char'[0;40m'               /* normal white on black */
  110.     ansi_erase      = esc_char'[2J'              /* erase screen, home cursor */
  111. end
  112. else do
  113.     ansi_red        = ''
  114.     ansi_boldred    = ''
  115.     ansi_green      = ''
  116.     ansi_boldgreen  = ''
  117.     ansi_yellow     = ''
  118.     ansi_boldyellow = ''
  119.     ansi_blue       = ''
  120.     ansi_boldblue   = ''
  121.     ansi_white      = ''
  122.     ansi_erase      = ''
  123. end
  124. gcd_rc = 0
  125. result = 0
  126. building_index = 0
  127. cur_dir = directory()                               /* save current directory */
  128. /* Load Rexx System Utility Functions if not already loaded */
  129. if RxFuncQuery('SysLoadFuncs') then do
  130.     call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  131.     call SysLoadFuncs                                    /* RexxUtil function */
  132. end
  133.  
  134.  
  135. /*
  136. ** Identify boot disk if option selected
  137. */
  138. /* Reference #6 */
  139. boot_disk = ''                                          /* init value to null */
  140. if use_boot_disk_index = 'Y' then do                           /* test option */
  141.     /*
  142.     ** Find Boot Disk
  143.     ** Use custom DLL to issue DosQuerySysInfo
  144.     */
  145.     if RxFuncQuery('DHRSysInfo') then
  146.         call RxFuncAdd 'DHRSysInfo','DHRRU100','DHRSysInfo'
  147.     if result > 1 then do
  148.         say ''
  149.         say 'Unable to Add Function DHRSysInfo from DLL DHRRU100'
  150.             '(rc ='result')'
  151.         say 'Please insure that the DHRRU100.DLL exists in a'
  152.             'subdirectory contained'
  153.         say 'in the LIBPATH statement in your CONFIG.SYS file.'
  154.         exit 32                                           /* exit immediately */
  155.     end
  156.     call 'DHRSysInfo' OS2info                     /* Extract OS/2 System Info */
  157.     if result <> 0 then do
  158.         say ''
  159.         say 'Error' result 'processing DHRSysInfo request'
  160.         exit 36                                           /* exit immediately */
  161.     end
  162.     call RxFuncDrop 'DHRSysInfo'
  163.     /*
  164.     ** Set boot_disk to disk letter if not floppy
  165.     ** OS2info.5 = boot disk number, 1=A, 3=C, etc.
  166.     */
  167.     if OS2info.5 > 2 then
  168.         boot_disk = substr('ABCDEFGHIJKLMNOPQRSTUVWXYZ',OS2info.5,1)':'
  169. end
  170.  
  171.  
  172. /*
  173. ** Check if index file already exists.
  174. ** If use_current_disk_index option is set to 'Y' then check only current
  175. ** disk.
  176. ** If use_boot_disk_index is set to 'Y' then check boot disk.
  177. ** If not found, check first local disk.
  178. */
  179. /* Reference #7 */
  180. index_disk = ''                                         /* init value to null */
  181. if use_current_disk_index = 'Y' then do                        /* test option */
  182.     index_disk = left(cur_dir,2)
  183.     rc = SysFileTree(index_disk'\'index_file,dirstem,'FO')   /* RexxUtil call */
  184.     if dirstem.0 < 1 then index_disk = ''                        /* not found */
  185. end
  186. else do
  187.     if use_boot_disk_index = 'Y' & boot_disk <> '' then do     /* test option */
  188.         index_disk = boot_disk                       /* always use boot disk! */
  189.         /* Uncomment the following to search for the index on */
  190.         /* all other disks if it is not currently on the boot disk */
  191.         /* rc = SysFileTree(boot_disk'\'index_file,dirstem,'FO') */
  192.         /* if dirstem.0 < 1 then index_disk = '' */              /* not found */
  193.         /* else index_disk = boot_disk */                    /* use boot disk */
  194.     end
  195.     if index_disk = '' then do         /* search local disks if not yet found */
  196.         local_list = SysDriveMap('C:','LOCAL')           /* RexxUtil function */
  197.         do while local_list <> ''
  198.             parse var local_list test_drive local_list
  199.             rc = SysFileTree(test_drive'\'index_file,dirstem,'FO')  /*RexxUtil*/
  200.             if dirstem.0 > 0 then do
  201.                 index_disk = test_drive              /* found on a local disk */
  202.                 leave
  203.             end
  204.         end
  205.     end
  206. end
  207. /*
  208. ** if index file has not been found, set index_disk based on options set
  209. */
  210. /* Reference #8 */
  211. if index_disk = '' then do
  212.     if use_current_disk_index = 'Y' then index_disk = left(cur_dir,2)
  213.     else if use_boot_disk_index = 'Y' & boot_disk <> '' then
  214.         index_disk = boot_disk
  215.     else do
  216.         local_list = SysDriveMap('C:','LOCAL')           /* RexxUtil function */
  217.         if local_list <> '' then index_disk = left(local_list,2)
  218.         else do
  219.             say ''
  220.             say 'Error - Directory Index not found and no local disks'
  221.             say 'found to store index!'
  222.             exit 44                                       /* exit immediately */
  223.         end
  224.     end
  225. end
  226.  
  227.  
  228. /*
  229. ** Process request
  230. */
  231. /* Reference #9 */
  232. if opt = 'R' | opt = 'RQ' then do                  /* Rebuild Directory Index */
  233.     'DEL' index_disk'\'index_file' 2> NUL'            /* Delete Previous File */
  234.     if opt = 'R' then say 'Index File will be placed on disk' index_disk
  235.     dir_count = 0
  236.     drive_list = ''
  237.     building_index = 1                               /* set flag for gcd_halt */
  238.     if target = '' then do
  239.         if use_all_disks = 'Y' then                              /* test flag */
  240.             drive_list = SysDriveMap('C:','USED')        /* RexxUtil function */
  241.         else
  242.             drive_list = SysDriveMap('C:','LOCAL')       /* RexxUtil function */
  243.     end
  244.     else do while target <> ''
  245.         drive_list = drive_list||left(target,1)': '      /* Use supplied list */
  246.         target = substr(target,2)
  247.     end
  248.     if opt = 'R' then say 'Now Process Drives ' drive_list
  249.     do while drive_list <> ''
  250.         parse var drive_list test_drive drive_list
  251.         if opt = 'R' then say 'Examine Disk' test_drive
  252.         /* rc = SysFileTree(test_drive'\*.*',dirstem,'SDO') */
  253.         call sysfiletree_work_around
  254.         if dirstem.0 = 0 then do
  255.             say 'Warning - No Directories On Drive' test_drive
  256.         end
  257.         else do dir_ctr = 1 to dirstem.0
  258.             call write_dir dirstem.dir_ctr
  259.         end
  260.         dir_count = dir_count + dirstem.0
  261.     end
  262.     if dir_count = 0 then do
  263.         say ''
  264.         say 'Error - No Directories Found, Index File Not Created'
  265.         exit 24                                           /* exit immediately */
  266.     end
  267.     else do
  268.         say dir_count 'Directories Indexed'
  269.         rc = lineout(index_disk'\'index_file)                   /* Close File */
  270.     end
  271.     building_index = 0                             /* reset flag for gcd_halt */
  272. end
  273. else do
  274.     /*
  275.     ** Extract info from directory file
  276.     */
  277.     /* Reference #10 */
  278.     call SysFileSearch target,index_disk'\'index_file,'searchstem'  /*RexxUtil*/
  279.     if result <> 0 then do
  280.         say ansi_red
  281.         say 'Error - Index File -' index_disk'\'index_file' - Not Found'
  282.         say 'Execute' exname '/r to Build Index'
  283.         gcd_rc = 28
  284.         signal exit_gcd                                         /* go to exit */
  285.     end
  286.     match_ctr = 0
  287.     match_val. = ''
  288.     best_match = ''
  289.     do s_ctr = 1 to searchstem.0
  290.         if opt = 'L' then
  291.             if left(cur_dir,2) <> left(searchstem.s_ctr,2) then iterate
  292.         last_sub = filespec('NAME',searchstem.s_ctr)
  293.         if pos(target,last_sub) > 0 then do
  294.             match_ctr = match_ctr + 1
  295.             match_val.match_ctr = searchstem.s_ctr
  296.             if left(cur_dir,2) = left(match_val.match_ctr,2) & ,
  297.                 cur_dir <> match_val.match_ctr & ,
  298.                 target = last_sub then best_match = match_ctr   /* best match */
  299.         end
  300.     end
  301.     ans1 = ''
  302.     if match_ctr = 1 then do
  303.         say ansi_green'Now Switching to' match_val.1
  304.         call directory match_val.1
  305.         if result = '' then do
  306.             say ansi_red'Error changing to directory' match_val.1
  307.             gcd_rc = 20
  308.         end
  309.     end
  310.     /* Reference #11 */
  311.     else if match_ctr > 1 then do while ans1 = ''
  312.         say ansi_green'There are multiple possibilities -'
  313.         /*y ansi_green'1...+....1....+....2....+....3....+....4....+....5' */
  314.         parse value SysTextScreenSize() with screen_rows screen_cols  /*RexxUt*/
  315.         if match_ctr > screen_rows - 5 then do
  316.             do temp_ctr = 1 to match_ctr by 2
  317.                 temp_ctr2 = temp_ctr + 1
  318.                 if match_val.temp_ctr2 <> '' then
  319.                     disp2 = right(temp_ctr2,3) match_val.temp_ctr2
  320.                 else disp2 = ''
  321.                 if length(match_val.temp_ctr) < 36 & ,
  322.                    length(match_val.temp_ctr2) < 36 then do
  323.                     say ansi_boldgreen||right(temp_ctr,3),
  324.                         left(match_val.temp_ctr,35),
  325.                         disp2
  326.                 end
  327.                 else do
  328.                     say ansi_boldgreen||right(temp_ctr,3) match_val.temp_ctr
  329.                     say ansi_boldgreen||disp2
  330.                 end
  331.             end
  332.         end
  333.         else do
  334.             do temp_ctr = 1 to match_ctr
  335.                 say ansi_boldgreen||right(temp_ctr,3) match_val.temp_ctr
  336.             end
  337.         end
  338.         if best_match = '' then
  339.             say ansi_boldyellow'Enter Selection Number or 0 for No Change'
  340.         else
  341.             say ansi_boldyellow'Enter Selection Number, 0 for No Change,',
  342.                 'or Just Press Enter for Item' best_match
  343.         ans1 = get_ans(match_ctr)                   /* function defined below */
  344.         if ans1 = 0 then do
  345.             say ansi_yellow||exname 'will terminate with no change'
  346.             signal exit_gcd                                     /* go to exit */
  347.         end
  348.         if best_match <> '' then if ans1 = '' then ans1 = best_match
  349.         destdir = match_val.ans1
  350.         if destdir <> '' then do
  351.             say ansi_green'Now Switching to' destdir
  352.             call directory destdir
  353.             if result = '' then do
  354.                 say ansi_red'Error changing to directory' match_val.1
  355.                 gcd_rc = 20
  356.             end
  357.         end
  358.         else do
  359.             say ansi_erase||ansi_boldred'Invalid Response ('ans1'),',
  360.                 'Enter again'
  361.             ans1 = ''
  362.         end
  363.     end
  364.     else do
  365.         say ansi_red'Error - Directory' target 'not found'
  366.         gcd_rc = 8
  367.     end
  368. end
  369. /* Reference #12 */
  370. exit_gcd:                                                 /* go to exit label */
  371. call CHAROUT 'CON:', ansi_white                       /* restore screen color */
  372. exit gcd_rc                       /* exit main procedure with variable gcd_rc */
  373.  
  374.  
  375.  
  376. /*
  377. ** Arrive here if control break or control C due to
  378. ** 'signal on halt name gcd_halt' statement at the beginning
  379. */
  380. /* Reference #13 */
  381. gcd_halt:
  382. if building_index = 1 then do
  383.     rc = lineout(index_disk'\'index_file)                       /* Close File */
  384.     'DEL' index_disk'\'index_file' 2> NUL'     /* Delete Current Partial File */
  385. end
  386. say ''
  387. say exname 'will terminate' ansi_white                /* restore screen color */
  388. exit -1                                                   /* exit immediately */
  389.  
  390.  
  391. /*
  392. ** Following subroutine required because SysFileTree
  393. ** does not return directories with leading spaces!
  394. */
  395. /* Reference #14 */
  396. sysfiletree_work_around:
  397. 'DIR' test_drive'\ /A:D /B /F /S | RXQUEUE'
  398. dirstem.0 = queued()
  399. do dir_ctr = 1 to dirstem.0
  400.     pull dirstem.dir_ctr
  401. end
  402. return                                                    /* return to caller */
  403.  
  404.  
  405. /*
  406. ** Function to Process Keyboard Input function
  407. */
  408. /* Reference #15 */
  409. get_ans:
  410. parse arg max_numb
  411. max_digits = length(max_numb)
  412. key_string = ''
  413. key_count = 0
  414. do forever
  415.     key = SysGetKey('NOECHO')                            /* RexxUtil function */
  416.     if key = '00'x | key = 'E0' then key = SysGetKey('NOECHO')
  417.     if key = '1B'x then do                             /* Esc key = no change */
  418.         key_string = 0
  419.         leave
  420.     end
  421.     if key = '0D'x then leave                             /* Enter key = exit */
  422.     if key < '0' | key > '9' then iterate             /* Process only numbers */
  423.     key_string = key_string||key                                /* Save input */
  424.     call CHAROUT 'CON:', key                               /* Echo to display */
  425.     if key = '0' & key_string = '0' then leave           /* Exit if leading 0 */
  426.     key_count = key_count + 1
  427.     if key_count >= max_digits then leave       /* Exit if max digits entered */
  428. end
  429. call CHAROUT 'CON:', '  '                                  /* Add some spaces */
  430. return key_string                           /* Return to caller with numerics */
  431.  
  432.  
  433. /*
  434. ** Subroutine to Write Directory Info to File
  435. */
  436. /* Reference #16 */
  437. write_dir:
  438. parse upper arg save_dir
  439. if opt = 'R' then say save_dir
  440. rc = lineout(index_disk'\'index_file, save_dir)
  441. if rc <> 0 then do
  442.     say 'Error' rc 'writing' index_file 'to disk' index_disk
  443.     say exname 'will terminate immediately'
  444.     gcd_rc = 40
  445.     signal exit_gcd
  446. end
  447. return                                                    /* return to caller */
  448.  
  449.  
  450. /*
  451. ** Subroutine to Display Help Information
  452. */
  453. /* Reference #17 */
  454. disp_help:
  455. if opt = 'H' then do
  456.     'VIEW ' exname
  457.     if rc = 0 then return                       /* unfortunately, rc always 0 */
  458. end
  459. say '                     ' exname 'Version 1.01 Help'
  460. say 'This cmd will jump to another directory on the current disk or any other'
  461. say 'hard disk known to your PC. Format is -'
  462. say exname 'new-directory-name'
  463. say 'If multiple destinations are possible, a selection list will be presented.'
  464. say 'Use the /r or /rq option to initialize a list of directories available on your'
  465. say 'PC. This should be rerun when directories change. Format is -'
  466. say exname '/r optional-drive-list'
  467. say 'where an optional string of drive letters may be supplied (ex. DFH). If not'
  468. say 'supplied, all local drives starting with drive C will be examined for'
  469. say 'directories. The option /rq will do the same but without the display of each'
  470. say 'directory found.'
  471. say 'The option /l may be used to restrict selection to directories only on the'
  472. say 'current disk. The option /h may be used to display more help information.'
  473. say 'The search for new-directory-name will only be successful if it appears as'
  474. say 'part of the last qualifier of a directory in whole or part.'
  475. say 'The destination of where the index file will be placed may be customized.'
  476. say ' '
  477. say 'Please refer to the' exname'.DOC file or' exname'.INF (with VIEW) file for'
  478. say 'more information'.
  479. return                                                    /* return to caller */
  480.