home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / pmsw.zip / PMSW / PMSWALL.ZIP / OS2 / APPS / FINDDIR.CMD < prev    next >
OS/2 REXX Batch file  |  1994-06-16  |  14KB  |  496 lines

  1. /*
  2.    RxMP:  REXX Multiprocessing Package
  3.  
  4.    FindDir REXX to search all drives for a given directory name.
  5.    Version 1.0
  6.  
  7.    Copyright (C) 1994 Bruce E. Högman    All Rights Reserved.
  8.    1338 Avocado Isle
  9.    Fort Lauderdale, FL 33315 USA         1994-06-12
  10.  
  11.    See the .doc file for the RXMP package for license details.
  12. */
  13.  
  14. /*
  15.    Edit the next lines to suit your personal environment
  16. */
  17. ExitOnIdleSecs = 30      /* Prompt user to respond after n seconds */
  18.  
  19. /*
  20.    If you prefer a monochrome output, then comment out the call to
  21.    the ANSI_Define procedure.  Otherwise, the call will display
  22.    data using ANSI Color escape sequences.
  23. */
  24. Call ANSI_Null           /* Define null ANSI video strings */
  25. Call ANSI_Define         /* Define ANSI video strings */
  26. DisplayColor = White     /* This is the color in which to display data*/
  27. TimeOutColor = WhiteOnRed
  28. bTimeOutProcessing = 0
  29. bAdjustScreenSize = 1    /* 1: uses mode to increase screen to 33 lines*/
  30. MaxScreenSize = 33
  31.  
  32. ScreenLine.0=0           /* This is where we store lines to screen */
  33.  
  34. /*
  35.    Load REXXUTIL functions if not already
  36. */
  37. if 0 < RxFuncQuery('SysLoadFuncs') then
  38.    do;
  39.       Call rxfuncadd 'SysLoadFuncs','REXXUTIL','SysLoadFuncs';
  40.       Call SysLoadFuncs;
  41.    end;
  42. else nop
  43.  
  44. /*
  45.   Get our location in the file system
  46. */
  47. parse source OSName CmdName OurName
  48.  
  49. /*
  50.   Parse the input arguments into variables
  51. */
  52. parse upper arg DirName DriveList AdditionalArgs
  53. DirName = strip(DirName)
  54. DriveList = strip(DriveList)
  55. if DirName = '' then DirName = '/HELP'
  56. select
  57.    when DirName = '/?' | DirName = '/HELP' then
  58.       do
  59.          Call Syntax
  60.          Call charout ,RES
  61.          say 'Hit ENTER to end.'
  62.          pull reply
  63.          return 0
  64.       end
  65.    when DirName = '/S' then
  66.       do
  67.          Call SubProcessor AdditionalArgs
  68.          return 0
  69.       end
  70.    otherwise nop
  71. end
  72.  
  73. /*
  74.   Construct a drives list from user input or from all used drives
  75. */
  76. if DriveList='' then DriveList = SysDriveMap('C:','USED')
  77. else
  78.    do
  79.       xStr = DriveList; DriveList = ''
  80.       do i = 1 to length(xStr)
  81.          if DriveList \= '' then
  82.             if ' ' \= right(DriveList,1) then
  83.                DriveList = DriveList || ' '
  84.             else nop
  85.          else nop
  86.          DriveList = DriveList || substr(xStr,i,1) || ': '
  87.       end
  88.    end
  89.  
  90. /*
  91.   Compute the number of tasks we will launch using start command,
  92.   initialize each task entry with drive letter, and make boolean.
  93. */
  94. Task.0=(length(DriveList)+2)%3
  95. j=0;
  96. do i = 1 to length(DriveList) by 3
  97.    j = j+1;   Task.j = substr(DriveList,i,2)
  98.    TaskEnd.j = 0;
  99.    TaskFound.j=0;
  100. end
  101.  
  102. Call DisplayLineOnScreen DisplayColor||,
  103.    "Searching" Task.0 "drives:" DriveList
  104.  
  105. /*
  106.   Rexx will create a queuename for us
  107. */
  108. QName = RxQueue("Create")
  109. TName = RxQueue("Set",QName); TName = RxQueue("Get")
  110. if TName \= QName then
  111.    do
  112.       say 'Failure in RxQueue "Set"'
  113.       say 'Processing may be unsuccessful.'
  114.    end
  115. else nop
  116.  
  117. /*
  118.   Start a process for each drive letter in list
  119. */
  120. do i=1 to Task.0 by 1
  121.    CurrentDrive = Task.i
  122.    '@start "'CurrentDrive dirname'" /c /min' OurName ||,
  123.    ' /S X' QName CurrentDrive dirname
  124. end
  125.  
  126. /*
  127.   Counters for processing
  128. */
  129. EndTaskCount = 0
  130. DriveFoundCount = 0
  131. CountFound = 0
  132. DirList.0=0
  133. IdleSecondsCounter = ExitOnIdleSecs
  134.  
  135. bWeDeleteQueue = 1
  136. bMainLoop = 1
  137. do while bMainLoop
  138.    if 0 < queued() then Call QueuePull
  139.    else
  140.       do
  141.          IdleSecondsCounter = IdleSecondsCounter-1
  142.          Call SysSleep 1
  143.       end
  144.    if EndTaskCount = Task.0 then leave
  145.    else nop
  146.    if IdleSecondsCounter<1 then
  147.       do;
  148.          Call TimeOutProcessing
  149.          Call DisplayScreenData
  150.       end
  151. end
  152. Call DisplayLineOnScreen DisplayColor||,
  153.    'Found' CountFound 'directories on' DriveFoundCount 'drives.'
  154. if bWeDeleteQueue then Call RxQueue "Delete",QName
  155. else
  156.    do
  157.       Call DisplayLineOnScreen WhiteOnRed"Results may be incomplete."
  158.    end
  159. Call DisplayScreenData
  160. Call charout ,RES
  161. say 'Hit ENTER to end.'
  162. pull reply
  163. return 0
  164.  
  165. ANSI_Define:
  166.    ESC       =d2c(27)'['
  167.    RES       =ESC'0;1;37;40m'       /* Reset color to dull white */
  168.    TAB       =d2c(9)
  169.    Cyan      =ESC'0;1;36;40m'       /* Bright Cyan */
  170.    White     =ESC'0;1;37;40m'       /* Bright White */
  171.    Yellow    =ESC'0;1;33;40m'       /* Bright Yellow */
  172.    Pink      =ESC'0;1;35;40m'       /* Bright Pink */
  173.    Red       =ESC'0;1;31;40m'       /* Bright Red */
  174.    Hdr       =ESC'0;1;44;33m'
  175.    WhiteOnRed=ESC'0;1;5;41;37m'
  176.    return
  177.  
  178. ANSI_Null:
  179.    ESC=''
  180.    RES=''
  181.    TAB=d2c(9)
  182.    Cyan=''                   /* Bright Cyan */
  183.    White=''
  184.    Yellow=''
  185.    Pink=''
  186.    Red=''
  187.    Hdr=''
  188.    WhiteOnRed=''
  189.    return
  190.  
  191. DisplayLineOnScreen:
  192.    parse arg ScreenLineData
  193.    nSLine = ScreenLine.0; nSLine = NSLine+1; ScreenLine.0 = nSLine
  194.    ScreenLine.nSLine = ScreenLineData
  195.    if \bTimeOutProcessing then say ScreenLineData
  196.    return
  197.  
  198. DisplayScreenData:
  199.    parse value SysTextScreenSize() with ScrRows ScrCols
  200.    if ScreenLine.0 > ScrRows & ScrRows < MaxScreenSize & bAdjustScreenSize then
  201.       do
  202.          '@mode 80,'MaxScreenSize
  203.       end
  204.    call charout ,DisplayColor||d2c(27)'[2J'd2c(27)'[2;1H'
  205.    ScrRows = ScrRows-2
  206.    ScrLineCount = 0;
  207.    do sLine = 1 to ScreenLine.0
  208.       ScrLineCount = ScrLineCount+1
  209.       if ScrLineCount > ScrRows then
  210.          do
  211.             say d2c(27)'[sHit ENTER for next screen of data'
  212.             Call QueuePull; pull reply
  213.             ScrLineCount = 1
  214.             call charout ,d2c(27)'[u'd2c(27)'[K'
  215.          end
  216.       say ScreenLine.sLine
  217.    end
  218.    return
  219.  
  220. /*
  221.    QueuePull - pulls all data from queues while queued()>0.
  222.    This is called first by code that also pulls keyboard
  223.    input to empty active queue before attempting to read keyboard.
  224. */
  225. QueuePull:
  226.       do while 0 < queued()
  227.          parse upper pull queuemarker filespec VerbOrCount
  228.          select
  229.             when 0 < pos('\', filespec) then
  230.                do
  231.                   Call DisplayLineOnScreen TAB filespec
  232.                   DirList.0=(DirList.0)+1
  233.                end
  234.             when VerbOrCount = 'END' then
  235.                do
  236.                   bDrvLoop = 1
  237.                   do nDrv = 1 to Task.0 while bDrvLoop
  238.                      if filespec = Task.nDrv then
  239.                         do
  240.                            TaskEnd.nDrv = 1
  241.                            bDrvLoop = 0
  242.                            EndTaskCount = EndTaskCount+1
  243.                         end
  244.                   end
  245.                end
  246.             when DataType(VerbOrCount,'Whole Number') then
  247.                do
  248.                   CountFound = CountFound + VerbOrCount
  249.                   bDrvLoop = 1
  250.                   do nDrv = 1 to Task.0 while bDrvLoop
  251.                      if filespec = Task.nDrv then
  252.                         do
  253.                            TaskFound.nDrv = 1;
  254.                            bDrvLoop = 0
  255.                            DriveFoundCount = DriveFoundCount+1
  256.                         end
  257.                   end
  258.                end
  259.  
  260.       /*    when VerbOrCount = 'NONE' then
  261.                say filespec 'NO' 'directory   found'
  262.       */
  263.             otherwise nop
  264.          end
  265.       end
  266.    return
  267.  
  268. Syntax:
  269.    say d2c(27)'[2J'd2c(27)'[2;1H'
  270.    xstr = center('── RxMP FindDir ─ Find Directory on Drives ── '||,
  271.    '(C) 1994 Bruce E. Högman',80)
  272.    Call charout ,Hdr||xstr
  273.    call charout ,Cyan
  274.    say White'Syntax:'Cyan
  275.    say '         'Yellow||Ourname  '  directory_name ' Cyan'[ '||,
  276.        Yellow'drive_list 'Cyan']'
  277.    call charout ,Yellow
  278.    say ''
  279.    say 'directory_name:  'Cyan'simple name of directory'
  280.    say ''
  281.    call charout ,White
  282.    say '   This may be \dir1\dir2 as example, and only entries under \dir1 will be'
  283.    say '   found.  Name may contain usual wild-card characters.  In every case,'
  284.    say '   the search for directories starts at the root directory on each drive,'
  285.    say '   not at the current directory on that drive.  The program supplies a'
  286.    say '   leading "\" if not is present.'
  287.    say ''
  288.    call charout ,Yellow
  289.    say 'drive_list:      'Cyan'string of letters to include in search.'
  290.    say ''
  291.    call charout ,White
  292.    say '   If omitted, then all used drives, both local and remote will be searched.'
  293.    say ''
  294.    call charout ,Cyan
  295.    say 'Example:  finddir dll                   Example:  finddir os2\dll'
  296.    call charout ,White
  297.    say '   Finds all DLL directories.              Finds \os2\dll, \os2\apps\dll, etc.'
  298.    say ''
  299.    xstr = center(' ',80)
  300.    Call charout ,Hdr||xstr
  301.    call charout ,RES
  302.    return
  303.  
  304. /*
  305.    TimeOutProcessing is entered when no task has queued data for the
  306.    number of seconds specified by ExitOnIdleSecs
  307. */
  308. TimeOutProcessing:
  309.    RJ=d2c(27)'[80D'd2c(27)'[30C'
  310.    IdleSecondsCounter = ExitOnIdleSecs /* reset counter */
  311.    bTimeOutProcessing = 1
  312.    /*
  313.       Construct display box to overlay running display
  314.    */
  315.    TOP.1="Expired Timer Exit:"
  316.    TOP.2="Long tasks incomplete after "ExitOnIdleSecs" seconds."
  317.    TOP.3="These drive processes still running:"
  318.    TOP.4=''
  319.    do rDrv = 1 to Task.0
  320.       if \TaskEnd.rDrv then TOP.4 = TOP.4||Task.rDrv||' '
  321.    end
  322.    TOP.5="Reply Q to quit, else any other"
  323.    TOP.6="reply to continue processing."
  324.    TOP.0=6
  325.    mxTOP=0;
  326.    do mxi=1 to TOP.0
  327.       mxl=length(TOP.mxi)
  328.       if mxl > mxTOP then mxTOP = mxl
  329.    end
  330.    do mxi=1 to TOP.0
  331.       TOP.mxi=left(TOP.mxi||copies(' ',mxTOP),mxTOP)
  332.    end
  333.    parse value SysTextScreenSize() with sRows sCols
  334.    cRow = ((sRows+1) - TOP.0)%2
  335.    cCol = ((sCols+1) - mxl)%2
  336.    do mxi=1 to TOP.0
  337.       call charout ,TimeOutColor||d2c(27)'['cRow';'cCol'H'TOP.mxi
  338.       cRow=cRow+1
  339.    end
  340.    Call QueuePull; pull reply
  341.    if reply = 'Q' then
  342.       do
  343.          bWeDeleteQueue = 0
  344.          bMainLoop = 0
  345.          '@start "'QDelete||':'||QName'" /c /min '||,
  346.             SubFile QNAME '/D dummy'
  347.       end
  348.    bTimeOutProcessing = 0
  349.    return
  350.  
  351. /*
  352.    Subprocessor to FINDDIR.CMD
  353.  
  354.    Input:
  355.  
  356.       Identifier/queuename that identifies srch4dir task
  357.       Drive letter to search
  358.       Directory name to search for
  359.  
  360.       If Drive letter is "/D" this is a request to delete the queue
  361.       using RxQueue "Delete" call because the main program was ended
  362.       before the work of all subprocesses was complete.  This subprocess
  363.       will request deletion of the queue and wait until it can complete.
  364.       When /d is 2nd argument, a dummy 3rd argument is present.
  365.  
  366.    Returns:
  367.       queuename date time NONE             no entries found
  368.       queuename date time nnnn             number of entries following
  369.       queuename date time xxxxxxxxx        entries
  370. */
  371. SubProcessor: procedure
  372. parse upper arg QName DriveLtr DirName DebugOption
  373. if QName='' | DriveLtr='' | DirName='' then return 0
  374. if DriveLtr = '/D' then
  375.    do
  376.       Call QDelete QName
  377.       return 0
  378.    end
  379.  
  380. /*
  381.    Load REXXUTIL functions if not already
  382. */
  383. if 0 < RxFuncQuery('SysLoadFuncs') then
  384.    do;
  385.       Call rxfuncadd 'SysLoadFuncs','REXXUTIL','SysLoadFuncs';
  386.       Call SysLoadFuncs;
  387.    end;
  388.  
  389. /*
  390.   Set named queue as active queue
  391. */
  392.  
  393. TName = RxQueue("Set",QName); TName = RxQueue("Get")
  394. if TName \= QName then
  395.    do
  396.       say 'TName='TName 'QName='QName
  397.       say 'Failure in RxQueue Set queue named:' QName
  398.       return 1
  399.    end
  400.  
  401. /*
  402.   Adjust arguments as needed
  403. */
  404. if '\' \= left(DirName,1) then DirName='\'DirName
  405. if '\'  = right(DriveLtr,1) then
  406.    DriveLtr=substr(DriveLtr,1,length(DriveLtr)-1)
  407. if ':' \= right(DriveLtr,1) & length(DriveLtr)=1 then
  408.    DriveLtr=DriveLtr':'
  409.  
  410. /*
  411.   Get date & time for queue identifier and put on queue
  412. */
  413. queue QName'_'TimeStamp() DriveLtr 'START'
  414.  
  415. /*
  416.   Do real work of routine
  417. */
  418. Call SysFileTree DriveLtr||DirName,'DirStem','DSO'
  419.  
  420. /*
  421.   Return results as queue entries
  422. */
  423. queue QName'_'TimeStamp() DriveLtr 'READY'
  424. select
  425.    when DirStem.0=0 then queue QName'_'TimeStamp() DriveLtr 'NONE'
  426.    when DirStem.0>0 then queue QName'_'TimeStamp() DriveLtr DirStem.0
  427.    otherwise
  428.       do
  429.          say 'DirStem.0='DirStem.0
  430.          say 'REXX internal logic error in select.'; return 1
  431.       end
  432. end
  433. if DirStem.0>0 then
  434.    do i=1 to DirStem.0
  435.       queue QName'_'TimeStamp() DirStem.i
  436.    end
  437. queue QName'_'TimeStamp() DriveLtr 'END'
  438. return 0
  439.  
  440. /*
  441.    Input:  queuename to delete
  442.    Output: loops until queue is deleted
  443. */
  444. QDelete: procedure
  445.    say ''
  446.    say 'QDelete'
  447.    parse arg QName
  448.    bLoop = 1
  449.    do while bLoop
  450.       sRC = RxQueue("Delete",QName)
  451.       select
  452.          when sRC = 0 then
  453.             do
  454.                bLoop = 0
  455.                say 'Queue deleted:' QName
  456.             end
  457.          when sRC = 5 then
  458.             do
  459.                say "Not valid queue name:" QName
  460.                bLoop = 0
  461.             end
  462.          when sRC = 9 then
  463.             do
  464.                say "Queue does not exist:" QName
  465.                bLoop = 0
  466.             end
  467.          when sRC = 10 then
  468.             do
  469.                say "Queue is busy" QName
  470.                Call SysSleep 3
  471.             end
  472.          when sRC = 12 then
  473.             do
  474.                say "Memory failure has occurred"
  475.                bLoop = 0
  476.                pull reply
  477.             end
  478.          when sRC = 1000 then
  479.             do
  480.                say "Initialization error has occurred."
  481.                bLoop = 0
  482.                pull reply
  483.             end
  484.          otherwise
  485.             do
  486.                say "Unexpected return code from RxQueue of" sRC
  487.                pull reply
  488.                bLoop = 0
  489.             end
  490.       end
  491.    end
  492.    return
  493.  
  494. TimeStamp: procedure
  495.    return Date('s')||"_"Time('l')
  496.