#!/bin/sh  
# \
exec oagtclsh "$0" "$@"

# $Log: not supported by cvs2svn $
# Revision 1.6  2000/11/20 14:45:39  borland
# Now shows the modification time as well as the age.
#
# Revision 1.5  1999/12/11 21:53:09  borland
# Fixed bug in -command option.
#
# Revision 1.4  1999/11/11 18:07:29  borland
# Added -invertAge and -command options.  Allows reversing age selection
# to pick old files and executing a command on each file.
#
# Revision 1.3  1999/02/13 23:11:08  borland
# Added -exclude, -excludeDir, and -filterDir options.  These options plus the
# existing -filter option accept lists of patterns.
#
# Revision 1.2  1999/02/12 03:11:41  borland
# Added -nocomplain to an instance of glob command.
#
# Revision 1.1  1999/02/11 18:20:30  borland
# First version.  Finds files that have recently been modified.  Has 1s
# resolution, unlike the unix find command which has 1 day resolution.
#

set auto_path [linsert $auto_path 0  /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]
APSStandardSetup

set usage {usage: findActiveFiles {-ageLimit <seconds> | -start YYYY-MM-DD@HH:MM:SS -end YYYY-MM-DD@HH:MM:SS} -filter <listOfPatterns> -filterDir <listOfPatterns> -levels <number> -sdds 1 -listDirsOnly 1 -exclude <listOfPatterns> -excludeDir <listOfPatterns> -invertAge 1 -command <string>}
set filter *
set start ""
set end ""
set ageLimit 10
set levels -1
set sdds 0
set listDirsOnly 0
set exclude ""
set excludeDir ""
set filterDir *
set command ""
set invertAge 0
set accessTime 0
set args $argv
if {[APSStrictParseArguments {ageLimit start end filter levels sdds listDirsOnly exclude excludeDir filterDir invertAge command accessTime}] || \
      $ageLimit<0 || ![llength $filter] || ![llength $filterDir]} {
    puts stderr $usage
    exit 1
}

set clockRef [clock seconds]

if [string length $end] {
    set dtList [split $end "@"]
    set dateList [split [lindex $dtList 0] -]
    set h [APSConvertTimeToHours [lindex $dtList 1]]
    set tEnd [exec timeconvert -breakdown=year=[lindex $dateList 0],month=[lindex $dateList 1],day=[lindex $dateList 2],hour=$h]
} else {
    set tEnd $clockRef
}

if [string length $start] {
    set dtList [split $start "@"]
    set dateList [split [lindex $dtList 0] -]
    set h [APSConvertTimeToHours [lindex $dtList 1]]
    set tStart [exec timeconvert -breakdown=year=[lindex $dateList 0],month=[lindex $dateList 1],day=[lindex $dateList 2],hour=$h]
} else {
    set tStart [expr $tEnd-$ageLimit]
}

proc CheckAndDescend {args} {
    set ageStart 0
    set ageEnd 0
    set filter *
    set levels -1
    set clockRef [clock seconds]
    set dirString .
    set listDirsOnly 0
    set exclude ""
    set excludeDir ""
    set filterDir *
    set invertAge 0
    set command ""
    set accessTime 0
    APSStrictParseArguments {ageStart ageEnd filter levels clockRef dirString listDirsOnly exclude excludeDir filterDir invertAge command accessTime}
    set mtimeCmd mtime
    if $accessTime {
        set mtimeCmd atime
    }
    foreach pattern $filter {
        foreach file [glob -nocomplain $pattern] {
            set doExclude 0
            foreach exPattern $exclude {
                if {[string length $exPattern] && [string match $exPattern $file]} {
                    set doExclude 1
                    break
                }
            }
            if $doExclude continue
            if [catch {file $mtimeCmd $file} mtime] continue
            set timeOfChange $mtime
            if {(!$invertAge && [expr $timeOfChange>$ageStart] && [expr $timeOfChange<$ageEnd]) || \
                  ($invertAge && ([expr $timeOfChange<=$ageStart] || [expr $timeOfChange>=$ageEnd]))} {
                if $listDirsOnly {
                    puts stdout "$dirString [expr $clockRef-$timeOfChange] \"[clock format $mtime]\""
                    flush stdout
                    break
                } else {
                    puts stdout "$dirString/$file [expr $clockRef-$timeOfChange] \"[clock format $mtime]\""
                    if [string length $command] {
                        catch {eval exec $command $file} result
                        if [llength $result] {
                            puts stdout "$result"
                        }
                    }
                    flush stdout
                }
            }
        }
    }
    if $levels==0 return
    incr levels -1
    foreach pattern $filterDir {
        foreach file [glob -nocomplain $pattern] {
            if [catch {file type $file} type] continue
            set doExclude 0
            foreach exPattern $excludeDir {
                if {[string length $exPattern] && [string match $exPattern $file]} {
                    set doExclude 1
                    break
                }
            }
            if $doExclude continue
            if [string compare $type directory]==0 {
                if [catch {cd $file}] continue
                CheckAndDescend -ageStart $ageStart -ageEnd $ageEnd -filter $filter -levels $levels \
                  -dirString $dirString/$file -listDirsOnly $listDirsOnly -exclude $exclude \
                  -excludeDir $excludeDir -invertAge $invertAge -command $command
                cd ..
            }
        }
    }
}

if $sdds {
    puts stdout "SDDS1\n&column name=Filename type=string &end"
    puts stdout "&column name=Age type=long units=seconds &end"
    puts stdout "&column name=TimeStamp type=string &end"
    puts stdout "&data mode=ascii no_row_counts=1 &end"
}
CheckAndDescend -ageStart $tStart -ageEnd $tEnd -clockRef $clockRef \
  -filter $filter -filterDir $filterDir -levels $levels \
  -listDirsOnly $listDirsOnly -exclude $exclude -excludeDir $excludeDir \
  -command $command -invertAge $invertAge -accessTime $accessTime

