FileFind eXtended Ver 1.10
Posted: Fri Oct 12, 2007 10:06 pm
Some time ago I released to forum a filefind routine. Well, here is a utility based on that routing. For you DOS lovers
I only wrote it in the past 24 hours, and haven't found any bugs
I hope you guys find it useful
cheers
I only wrote it in the past 24 hours, and haven't found any bugs
I hope you guys find it useful
cheers
Code: Select all
; Dynamic recursive file finder with stored results and with filters
; KingLestat
; June/2007
; PB v4.02
;
; Thanks akj / blueznl for x_matchpattern routine
Macro FixTime ( mytime, tflag )
i = Len ( mytime )
If i = 2
mytime + "0000"
ElseIf i = 4
mytime + "00"
Else
tflag = #False
EndIf
EndMacro
Macro AssignDate ( datemin, datemax, dflag )
dflag = #True
szDate = FormatDate ( gszDateMask, today )
If FindString ( param1, "-", 1 ) > 0
temp = PeekS ( @param1 + 3 )
datemin = Trim ( StringField ( temp, 1, "-" ) )
datemax = Trim ( StringField ( temp, 2, "-" ) )
If Len ( datemin ) <> 8 Or Len ( datemax ) <> 8
dflag = #False
EndIf
Else
temp = Trim ( PeekS ( @param1 + 3 ) )
If Len ( temp ) <> 8
dflag = #False
Else
If szDate > temp
datemin = temp
datemax = szDate
Else
datemin = szDate
datemax = temp
EndIf
EndIf
EndIf
EndMacro
Macro AssignTime ( timemin, timemax, tflag )
tflag = #True
szTime = FormatDate ( "%hh%ii%ss", today )
If FindString ( param1, "-", 1 ) > 0
temp = PeekS ( @param1 + 3 )
timemin = Trim ( StringField ( temp, 1, "-" ) )
timemax = Trim ( StringField ( temp, 2, "-" ) )
FixTime ( timemin, tflag )
FixTime ( timemax, tflag )
Else
temp = Trim ( PeekS ( @param1 + 3 ) )
FixTime ( temp, tflag )
If szTime > temp
timemin = temp
timemax = szTime
Else
timemin = szTime
timemax = temp
EndIf
EndIf
EndMacro
Macro CheckFDate ( tflag, pbmacro, fdate, fmin, fmax )
If tflag = #True
fdate = GetFileDate ( filename, pbmacro )
temp = FormatDate ( gszDateMask, fdate )
If temp < fmin Or temp > fmax
ProcedureReturn
EndIf
EndIf
EndMacro
Macro CheckFTime ( tflag, pbmacro, fdate, fmin, fmax )
If tflag = #True
If Not fdate
fdate = GetFileDate ( filename, pbmacro )
EndIf
temp = FormatDate ( gszTimeMask, fdate )
If temp < fmin Or temp > fmax
ProcedureReturn
EndIf
EndIf
EndMacro
Macro SizeAdjuster ( num, nresult )
mult = Right ( num, 1 )
If mult = "K"
i = 1024
ElseIf mult = "M"
i = 1024 * 1024
ElseIf mult = "G"
i = 1024 * 1024 * 1024
Else
i = 1
EndIf
nresult = Val ( num ) * i
EndMacro
#FILE_BUFFER = 8192
Global szContent.s = ""
Global szMask.s = "*.*"
Global szXMask.s = ""
Global szShort.s = ""
Global gszDateMask.s = "%yyyy%mm%dd"
Global gszTimeMask.s = "%hh%ii%ss"
Global szaDateMin.s
Global szaDateMax.s
Global szaTimeMin.s
Global szaTimeMax.s
Global szmDateMin.s
Global szmDateMax.s
Global szmTimeMin.s
Global szmTimeMax.s
Global szcDateMin.s
Global szcDateMax.s
Global szcTimeMin.s
Global szcTimeMax.s
Global szDirLine.s = "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ"
Global gSizeMin.l = 0
Global gSizeMax.l
Global gFound.l = 0
Global Dim szLevel.s(128)
Global gLen.l = 8
Global gRealLen.l
Global *memBuffer.l
Global bSize.l = #False
Global bXclude.l = #False
Global bContent.l = #False
Global bShort.l = #False
Global bcTime.l = #False
Global bcDate.l = #False
Global baTime.l = #False
Global baDate.l = #False
Global bmTime.l = #False
Global bmDate.l = #False
Global NewList xllmask.s()
Structure stInfo
name.s
Size.l
dir.l
EndStructure
Global NewList infolist.stInfo()
Procedure.l x_matchpattern ( String.s, pattern.s, ulcase.l )
; check if a string matches one or more patterns (wildcards *? separator |)
;
; *** check if string matches one or more patters using * and ? as wildcards
;
; in: string.s - string to check
; pattern.s - pattern including wildcards * and ? and multiple patterns seperated by |
; ulcase.l = 0 (#x_parse_matchcase) - check case
; = 1 (#x_parse_anycase) - don't care about case
; retval: 0 or #False - no match
; 1 or #True - match
;
; notes:
;
; - ? must be filled by a character, this is different in windows / dos where it can be empty
; - note that an 'empty' pattern will matches an empty original
; - rewrite number three, and it's still horrible
;
If ulcase = 1
pattern = LCase(pattern)
String = LCase(String)
EndIf
;
p_p = 0
p_l = Len(pattern)
s_l = Len(String)
;
If s_l = 0 ; 2265 handle emtpy strings
If p_l = 0
match = #True
ElseIf FindString(pattern,"||",1) > 0
match = #True
ElseIf Right(pattern,1) = "|"
match = #True
Else
match = #False
EndIf
Else
Repeat
s_p = 1
;
Repeat
ff_max = 0
ff_min = 0
p_sub.s = ""
p_char.s = ""
done = #False
match = #False
Repeat
p_p = p_p+1
p_char = Mid(pattern,p_p,1)
If p_char = "*"
ff_max = s_l
ElseIf p_char = "?"
ff_min = ff_min+1
If ff_min > ff_max
ff_max = ff_min
EndIf
ElseIf p_char = "|"
done = #True
Else
p_sub = p_sub+p_char
Repeat
p_char = Mid(pattern,p_p+1,1)
If p_char = "*" Or p_char = "?"
done = #True
ElseIf p_char = "|"
done = #True
; p_p = p_p+1 ; 2265 small quickfix... hope it works
Else
p_sub = p_sub+p_char
If p_p < p_l
p_p = p_p+1
Else
done = #True
EndIf
EndIf
Until done = #True
EndIf
If p_p >= p_l
done = #True
EndIf
Until done = #True
;
If p_sub = ""
If s_l-s_p+1 <= ff_max And s_l-s_p+1 >= ff_min
match = #True
Else
EndIf
s_p = s_l+1
Else
x = FindString(String,p_sub,s_p)
If x > 0
If x-s_p > ff_max
ElseIf x-s_p < ff_min
Else
match = #True
EndIf
s_p = x+Len(p_sub)
Else
s_p = s_l+1
EndIf
EndIf
Until match = #False Or s_p = s_l+1
;
If p_p < p_l
If match = #False
While p_p < p_l And p_char <> "|"
p_p = p_p+1
p_char = Mid(pattern,p_p,1)
Wend
Else
While p_p < p_l And p_char <> "|"
p_p = p_p+1
p_char = Mid(pattern,p_p,1)
If p_char = "|"
ElseIf p_char <> "*"
match = #False
EndIf
Wend
EndIf
EndIf
Until match = #True Or p_p >= p_l
EndIf
;
ProcedureReturn match
EndProcedure
EnableExplicit
Procedure InfoPath ( filename.s )
Protected Size.l
Protected fn.l
Protected mdaytime.l, adaytime.l, cdaytime.l
Protected Bytes.l
Protected dirpart.s
Protected filepart.s
Protected fdate.s, ftime.s
Protected temp.s
Static LastDir.s = ""
If bXclude = #True
ForEach xllmask()
If x_matchpattern ( filename, xllmask(), #True )
ProcedureReturn
EndIf
Next
EndIf
Size & 0
mdaytime & 0
adaytime & 0
cdaytime & 0
If bSize = #True
Size = FileSize ( filename )
If Size < gSizeMin Or Size > gSizeMax
ProcedureReturn
EndIf
EndIf
If bContent = #True
Protected flag.l
Protected i.l, j.l, k.l
fn = ReadFile ( #PB_Any, filename )
flag = #True
If fn > 0
fn = ReadFile ( #PB_Any, filename )
FileBuffersSize ( fn, 0 )
i = 0
k = 0
While Eof ( fn ) = 0
Bytes = ReadData ( fn, *memBuffer + k, #FILE_BUFFER )
j = Bytes + k
While i < j
If CompareMemoryString ( *memBuffer + i, @szShort, 1, gLen ) = 0
If bShort = #True
If CompareMemoryString ( *memBuffer + i, @szContent, 1, gRealLen ) = 0
flag = #False
Break
EndIf
Else
flag = #False
Break
EndIf
EndIf
i + 1
Wend
If Not flag Or Bytes < #FILE_BUFFER
Break
EndIf
MoveMemory ( *memBuffer + i, *memBuffer, gRealLen )
k = gRealLen
Wend
CloseFile ( fn )
Else
PrintN ("....cant open [" + filename + "]" )
flag = #False
EndIf
If flag = #True
ProcedureReturn
EndIf
EndIf
CheckFDate ( bmDate, #PB_Date_Modified, mdaytime, szmDateMin, szmDateMax )
CheckFDate ( baDate, #PB_Date_Accessed, adaytime, szaDateMin, szaDateMax )
CheckFDate ( bcDate, #PB_Date_Created, cdaytime, szcDateMin, szcDateMax )
CheckFTime ( bmTime, #PB_Date_Modified, mdaytime, szmTimeMin, szmTimeMax )
CheckFTime ( bcTime, #PB_Date_Created, cdaytime, szcTimeMin, szcTimeMax )
CheckFTime ( baTime, #PB_Date_Accessed, adaytime, szaTimeMin, szaTimeMax )
filepart = GetFilePart ( filename )
dirpart = GetPathPart ( filename )
If CompareMemoryString ( @dirpart, @LastDir, 1 )
AddElement ( infolist() )
infolist()\name = dirpart
infolist()\dir = #True
LastDir = dirpart
EndIf
AddElement ( infolist() )
infolist()\name = filepart
infolist()\dir = #False
If Size
infolist()\Size = Size
Else
infolist()\Size = FileSize ( filename )
EndIf
gFound + 1
EndProcedure
Procedure FindFileEx ( mask.l, root.s, func.l )
Protected temp.s
Protected df.l
Protected skip.l
Static NewList llmask.s()
If mask
Protected i.l, j.l
Protected filemask.s
ClearList ( llmask() )
filemask = PeekS ( mask )
i = 1
Repeat
temp = StringField ( filemask, i, ";" )
If temp > ""
AddElement ( llmask() )
llmask() = temp
i + 1
Else
Break
EndIf
ForEver
EndIf
ForEach llmask()
df = ExamineDirectory ( #PB_Any, root, llmask() )
If df > 0
While NextDirectoryEntry ( df )
If DirectoryEntryType ( df ) = #PB_DirectoryEntry_File
CallFunctionFast ( func, root + "\" + DirectoryEntryName ( df ) )
EndIf
Wend
EndIf
Next
df = ExamineDirectory ( #PB_Any, root, "" )
If df > 0
skip & 0
While NextDirectoryEntry ( df )
If DirectoryEntryType ( df ) = #PB_DirectoryEntry_Directory
skip + 1
If skip > 2
temp = DirectoryEntryName ( df )
FindFileEx ( 0, root + "\" + temp, func )
EndIf
EndIf
Wend
EndIf
EndProcedure
OpenConsole()
PrintN ( "FFX - File Finder eXtra - V1.10.............(c) Terence Agius, 2007" )
PrintN ( "" )
If CountProgramParameters () > 0
Define.s param1
Define.s temp, temp2
Define.s dir
Define.s mult
Define.s Path
Define.l i, j, k, l
Define.l today, day, start
Define.s szDate, szTime
Define.f fsize
param1 = ProgramParameter()
temp = UCase ( Left ( param1, 2 ) )
If temp = "-?" Or temp = "-H"
PrintN ( "Usage:" )
PrintN ( "" )
PrintN ( "FFX is a DOS based recursive search facility with the ability to exclude files" )
PrintN ( "and also look inside the files" )
PrintN ( "" )
PrintN ( "FFX {-h or -?} for help" )
PrintN ( "FFX path i={include list} x={exclude list} s={min-max} f={content To find in file} ...." )
PrintN ( "da=yyyymmdd-yyyymmdd, ta=hhmmss-hhmmss" )
PrintN ( "dm=yyyymmdd-yyyymmdd, tm=hhmmss-hhmmss" )
PrintN ( "dc=yyyymmdd-yyyymmdd, tc=hhmmss-hhmmss" )
PrintN ( "....include and exclude lists can have multiple selection seperated by (;)")
PrintN ( "....if only 1 number is specified with (s=) option, a min of 0 is assumed" )
PrintN ( "....parameter (s=) can have k/m/g modifiers to specify size in KB, MB, GB respectively" )
PrintN ( "....the parameters have no specific order, mix and match at will" )
PrintN ( "....if i= is not specified (i=*.* is assumed)" )
PrintN ( "....the search inside the file (if specified) is case insensitive" )
PrintN ( "....the date (d=) and time (t=) can be use seperately or together" )
PrintN ( "....the time format is 24 hrs (000000 to 235959")
PrintN ( "....if only 1 date or time is enterred, FFX will use the current date/time" )
PrintN ( " if time/date enterred is later than current, it will use your values for max" )
PrintN ( " while if they are less, it will use them as minimum vales." )
PrintN ( " in date and time (a) = last accessed (m) = last modified and (c) created" )
PrintN ( "" )
PrintN ( "Examples:" )
PrintN ( "" )
PrintN ( "FFX c:\ i=*.exe;*.dll x=w*.exe --> Find all exe and dll files on c: and exclude w*.exe" )
End
EndIf
Path = param1
k = Len ( Path )
While Right ( Path, 1 ) = "\"
k - 1
Path = Left ( param1, k )
Wend
today = Date()
Repeat
param1 = ProgramParameter()
If param1 > ""
temp = UCase ( Left ( param1, 2 ) )
If temp = "S="
bSize = #True
param1 = UCase ( param1 )
If FindString ( param1, "-", 1 ) > 0
temp = PeekS ( @param1 + 2 )
temp2 = StringField ( temp, 1, "-" )
SizeAdjuster ( temp2, gSizeMin )
temp2 = StringField ( temp, 2, "-" )
SizeAdjuster ( temp2, gSizeMax )
Else
temp = Trim ( PeekS ( @param1 + 2 ) )
SizeAdjuster ( temp, gSizeMax )
EndIf
ElseIf temp = "I="
szMask = Trim ( PeekS ( @param1 + 2 ) )
ElseIf temp = "X="
bXclude = #True
szXMask = Trim ( PeekS ( @param1 + 2 ) )
i = 1
Repeat
temp = StringField ( szXMask, i, ";" )
If temp > ""
AddElement ( xllmask() )
xllmask() = temp
i + 1
Else
Break
EndIf
ForEver
ElseIf temp = "DM"
AssignDate ( szmDateMin, szmDateMax, bmDate )
ElseIf temp = "DA"
AssignDate ( szaDateMin, szaDateMax, baDate )
ElseIf temp = "DC"
AssignDate ( szcDateMin, szcDateMax, bcDate )
ElseIf temp = "TM"
AssignTime ( szmTimeMin, szmTimeMax, bmTime )
ElseIf temp = "TA"
AssignTime ( szaTimeMin, szaTimeMax, baTime )
ElseIf temp = "TC"
AssignTime ( szcTimeMin, szcTimeMax, bcTime )
ElseIf temp = "F="
bContent = #True
szContent = LCase ( Trim ( PeekS ( @param1 + 2 ) ) )
*memBuffer = AllocateMemory ( #FILE_BUFFER + 32 )
i = Len ( szContent )
gRealLen = i
If i > 16
bShort = #True
szShort = Left ( szContent, 8 )
Else
gLen = i
szShort = szContent
EndIf
EndIf
Else
Break
EndIf
ForEver
start = ElapsedMilliseconds ()
FindFileEx ( @szMask, Path, @InfoPath() )
If gFound
PrintN ( "" )
PrintN ( "<" + Path + ">" )
j = 0
k + 1
ForEach infolist()
If infolist()\dir
dir = PeekS ( @infolist()\name + k )
i = CountString ( dir, "\" )
If j > 0
j = 0
For l = 0 To i
If szLevel ( l ) = StringField ( dir, l + 1, "\" )
j + 1
Else
Break
EndIf
Next
EndIf
While j < i
temp = StringField ( dir, j + 1, "\" )
szLevel ( j ) = temp
PrintN ( Chr(195) + Left ( szDirLine, j + 1 ) + "<" + temp + ">" )
j + 1
Wend
Else
temp = " bytes"
fsize = infolist()\Size
If fsize > ( 1024 * 1024 * 1024 )
fsize / 1024
fsize / 1024
fsize / 1024
temp = " Gb"
ElseIf fsize > ( 1024 * 1024 )
fsize / 1024
fsize / 1024
temp = "Mb"
ElseIf fsize > 1024
fsize / 1024
temp = " kb"
EndIf
PrintN ( Chr(195) + Left ( szDirLine, j + 1 ) + "[" + infolist()\name + " --> " + StrF ( fsize, 2 ) + temp + " ]" )
EndIf
Next
PrintN ( "" )
temp = " milliseconds"
fsize = ElapsedMilliseconds () - start
If fsize > 2000
fsize / 1000
temp = " seconds"
EndIf
PrintN ( "Found " + Str ( gFound ) + " file(s) in " + StrF ( fsize, 2 ) + temp )
Else
PrintN ( "No files found matching your search criteria." )
EndIf
Else
PrintN ( "Insufficient parameters" )
PrintN ( "" )
PrintN ( "Use -h or -? for usage" )
PrintN ( "" )
PrintN ( "Program Aborted." )
EndIf
End
/code