|
@@ -303,50 +303,8 @@ begin
|
|
|
Result:=Result or faSymLink;
|
|
|
end;
|
|
|
|
|
|
-type
|
|
|
|
|
|
- pglob = ^tglob;
|
|
|
- tglob = record
|
|
|
- name : pchar;
|
|
|
- next : pglob;
|
|
|
- end;
|
|
|
-
|
|
|
-Function Dirname(Const path:pathstr):pathstr;
|
|
|
-{
|
|
|
- This function returns the directory part of a complete path.
|
|
|
- Unless the directory is root '/', The last character is not
|
|
|
- a slash.
|
|
|
-}
|
|
|
-var
|
|
|
- Dir : DirStr;
|
|
|
- Name : NameStr;
|
|
|
- Ext : ExtStr;
|
|
|
-begin
|
|
|
- FSplit(Path,Dir,Name,Ext);
|
|
|
- if length(Dir)>1 then
|
|
|
- Delete(Dir,length(Dir),1);
|
|
|
- DirName:=Dir;
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-Function Basename(Const path:pathstr;Const suf:pathstr):pathstr;
|
|
|
-{
|
|
|
- This function returns the filename part of a complete path. If suf is
|
|
|
- supplied, it is cut off the filename.
|
|
|
-}
|
|
|
-var
|
|
|
- Dir : DirStr;
|
|
|
- Name : NameStr;
|
|
|
- Ext : ExtStr;
|
|
|
-begin
|
|
|
- FSplit(Path,Dir,Name,Ext);
|
|
|
- if Suf<>Ext then
|
|
|
- Name:=Name+Ext;
|
|
|
- BaseName:=Name;
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-Function FNMatch(const Pattern,Name:shortstring):Boolean;
|
|
|
+Function FNMatch(const Pattern,Name:string):Boolean;
|
|
|
Var
|
|
|
LenPat,LenName : longint;
|
|
|
|
|
@@ -428,187 +386,144 @@ Begin {start FNMatch}
|
|
|
End;
|
|
|
|
|
|
|
|
|
-Procedure Globfree(var p : pglob);
|
|
|
-{
|
|
|
- Release memory occupied by pglob structure, and names in it.
|
|
|
- sets p to nil.
|
|
|
-}
|
|
|
+Type
|
|
|
+ TUnixFindData = Record
|
|
|
+ NamePos : LongInt; {to track which search this is}
|
|
|
+ DirPtr : Pointer; {directory pointer for reading directory}
|
|
|
+ SearchSpec : String;
|
|
|
+ SearchType : Byte; {0=normal, 1=open will close, 2=only 1 file}
|
|
|
+ SearchAttr : Byte; {attribute we are searching for}
|
|
|
+ End;
|
|
|
+ PUnixFindData = ^TUnixFindData;
|
|
|
+Var
|
|
|
+ CurrSearchNum : LongInt;
|
|
|
+
|
|
|
+Procedure FindClose(Var f: TSearchRec);
|
|
|
var
|
|
|
- temp : pglob;
|
|
|
-begin
|
|
|
- while assigned(p) do
|
|
|
- begin
|
|
|
- temp:=p^.next;
|
|
|
- if assigned(p^.name) then
|
|
|
- freemem(p^.name);
|
|
|
- dispose(p);
|
|
|
- p:=temp;
|
|
|
- end;
|
|
|
-end;
|
|
|
+ UnixFindData : PUnixFindData;
|
|
|
+Begin
|
|
|
+ UnixFindData:=PUnixFindData(f.FindHandle);
|
|
|
+ if UnixFindData=nil then
|
|
|
+ exit;
|
|
|
+ if UnixFindData^.SearchType=0 then
|
|
|
+ begin
|
|
|
+ if UnixFindData^.dirptr<>nil then
|
|
|
+ fpclosedir(pdir(UnixFindData^.dirptr)^);
|
|
|
+ end;
|
|
|
+ Dispose(UnixFindData);
|
|
|
+ f.FindHandle:=nil;
|
|
|
+End;
|
|
|
|
|
|
|
|
|
-Function Glob(Const path:pathstr):pglob;
|
|
|
-{
|
|
|
- Fills a tglob structure with entries matching path,
|
|
|
- and returns a pointer to it. Returns nil on error,
|
|
|
- linuxerror is set accordingly.
|
|
|
-}
|
|
|
+Function FindGetFileInfo(const s:string;var f:TSearchRec):boolean;
|
|
|
var
|
|
|
- temp,
|
|
|
- temp2 : string[255];
|
|
|
- thedir : pdir;
|
|
|
- buffer : pdirent;
|
|
|
- root,
|
|
|
- current : pglob;
|
|
|
+ st : baseunix.stat;
|
|
|
+ WinAttr : longint;
|
|
|
begin
|
|
|
-{ Get directory }
|
|
|
- temp:=dirname(path);
|
|
|
- if temp='' then
|
|
|
- temp:='.';
|
|
|
- temp:=temp+#0;
|
|
|
- thedir:=fpopendir(@temp[1]);
|
|
|
- if thedir=nil then
|
|
|
- exit(nil);
|
|
|
- temp:=basename(path,''); { get the pattern }
|
|
|
- if thedir^.dd_fd<0 then
|
|
|
- exit(nil);
|
|
|
-{get the entries}
|
|
|
- root:=nil;
|
|
|
- current:=nil;
|
|
|
- repeat
|
|
|
- buffer:=fpreaddir(thedir^);
|
|
|
- if buffer=nil then
|
|
|
- break;
|
|
|
- temp2:=strpas(@(buffer^.d_name[0]));
|
|
|
- if fnmatch(temp,temp2) then
|
|
|
- begin
|
|
|
- if root=nil then
|
|
|
- begin
|
|
|
- new(root);
|
|
|
- current:=root;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- new(current^.next);
|
|
|
- current:=current^.next;
|
|
|
- end;
|
|
|
- if current=nil then
|
|
|
- begin
|
|
|
- fpseterrno(ESysENOMEM);
|
|
|
- globfree(root);
|
|
|
- break;
|
|
|
- end;
|
|
|
- current^.next:=nil;
|
|
|
- getmem(current^.name,length(temp2)+1);
|
|
|
- if current^.name=nil then
|
|
|
- begin
|
|
|
- fpseterrno(ESysENOMEM);
|
|
|
- globfree(root);
|
|
|
- break;
|
|
|
- end;
|
|
|
- move(buffer^.d_name[0],current^.name^,length(temp2)+1);
|
|
|
- end;
|
|
|
- until false;
|
|
|
- fpclosedir(thedir^);
|
|
|
- glob:=root;
|
|
|
+ FindGetFileInfo:=false;
|
|
|
+ if not fpstat(s,st)>=0 then
|
|
|
+ exit;
|
|
|
+ WinAttr:=LinuxToWinAttr(PChar(s),st);
|
|
|
+ If ((WinAttr and Not(PUnixFindData(f.FindHandle)^.searchattr))=0) Then
|
|
|
+ Begin
|
|
|
+ f.Name:=Copy(s,PUnixFindData(f.FindHandle)^.NamePos+1,Length(s));
|
|
|
+ f.Attr:=WinAttr;
|
|
|
+ f.Size:=st.st_Size;
|
|
|
+ f.Mode:=st.st_mode;
|
|
|
+ f.Time:=UnixToWinAge(st.st_mtime);
|
|
|
+ result:=true;
|
|
|
+ End;
|
|
|
end;
|
|
|
|
|
|
|
|
|
+Function FindNext (Var Rslt : TSearchRec) : Longint;
|
|
|
{
|
|
|
- GlobToSearch takes a glob entry, stats the file.
|
|
|
- The glob entry is removed.
|
|
|
- If FileAttributes match, the entry is reused
|
|
|
+ re-opens dir if not already in array and calls FindWorkProc
|
|
|
}
|
|
|
-
|
|
|
-Type
|
|
|
- TGlobSearchRec = Record
|
|
|
- Path : shortString;
|
|
|
- GlobHandle : PGlob;
|
|
|
- end;
|
|
|
- PGlobSearchRec = ^TGlobSearchRec;
|
|
|
-
|
|
|
-Function GlobToTSearchRec (Var Info : TSearchRec) : Boolean;
|
|
|
-
|
|
|
-Var SInfo : Stat;
|
|
|
- p : Pglob;
|
|
|
- GlobSearchRec : PGlobSearchrec;
|
|
|
-
|
|
|
-begin
|
|
|
- GlobSearchRec:=Info.FindHandle;
|
|
|
- P:=GlobSearchRec^.GlobHandle;
|
|
|
- Result:=P<>Nil;
|
|
|
- If Result then
|
|
|
- begin
|
|
|
- GlobSearchRec^.GlobHandle:=P^.Next;
|
|
|
- Result:=Fpstat(GlobSearchRec^.Path+StrPas(p^.name),SInfo)>=0;
|
|
|
- Info.PathOnly:=GlobSearchRec^.Path;
|
|
|
- If Result then
|
|
|
- begin
|
|
|
- Info.Attr:=LinuxToWinAttr(p^.name,SInfo);
|
|
|
- Result:=(Info.ExcludeAttr and Info.Attr)=0;
|
|
|
- If Result Then
|
|
|
- With Info do
|
|
|
- begin
|
|
|
- Attr:=Info.Attr;
|
|
|
- If P^.Name<>Nil then
|
|
|
- Name:=strpas(p^.name);
|
|
|
- Time:=UnixToWinAge(Sinfo.st_mtime);
|
|
|
- Size:=Sinfo.st_Size;
|
|
|
- Mode:=Sinfo.st_mode;
|
|
|
- end;
|
|
|
- end;
|
|
|
- P^.Next:=Nil;
|
|
|
- GlobFree(P);
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-Function DoFind(Var Rslt : TSearchRec) : Longint;
|
|
|
-
|
|
|
Var
|
|
|
- GlobSearchRec : PGlobSearchRec;
|
|
|
-
|
|
|
-begin
|
|
|
+ DirName : String;
|
|
|
+ i,
|
|
|
+ ArrayPos : Longint;
|
|
|
+ FName,
|
|
|
+ SName : string;
|
|
|
+ Found,
|
|
|
+ Finished : boolean;
|
|
|
+ p : pdirent;
|
|
|
+ UnixFindData : PUnixFindData;
|
|
|
+Begin
|
|
|
Result:=-1;
|
|
|
- GlobSearchRec:=Rslt.FindHandle;
|
|
|
- If (GlobSearchRec^.GlobHandle<>Nil) then
|
|
|
- While (GlobSearchRec^.GlobHandle<>Nil) and not (Result=0) do
|
|
|
- If GlobToTSearchRec(Rslt) Then Result:=0;
|
|
|
-end;
|
|
|
-
|
|
|
+ UnixFindData:=PUnixFindData(Rslt.FindHandle);
|
|
|
+ if UnixFindData=nil then
|
|
|
+ exit;
|
|
|
+ if (UnixFindData^.SearchType=0) and
|
|
|
+ (UnixFindData^.Dirptr=nil) then
|
|
|
+ begin
|
|
|
+ If UnixFindData^.NamePos = 0 Then
|
|
|
+ DirName:='./'
|
|
|
+ Else
|
|
|
+ DirName:=Copy(UnixFindData^.SearchSpec,1,UnixFindData^.NamePos);
|
|
|
+ UnixFindData^.DirPtr := fpopendir(Pchar(DirName));
|
|
|
+ end;
|
|
|
+ SName:=Copy(UnixFindData^.SearchSpec,UnixFindData^.NamePos+1,Length(UnixFindData^.SearchSpec));
|
|
|
+ Found:=False;
|
|
|
+ Finished:=(UnixFindData^.dirptr=nil);
|
|
|
+ While Not Finished Do
|
|
|
+ Begin
|
|
|
+ p:=fpreaddir(pdir(UnixFindData^.dirptr)^);
|
|
|
+ if p=nil then
|
|
|
+ FName:=''
|
|
|
+ else
|
|
|
+ FName:=p^.d_name;
|
|
|
+ If FName='' Then
|
|
|
+ Finished:=True
|
|
|
+ Else
|
|
|
+ Begin
|
|
|
+ If FNMatch(SName,FName) Then
|
|
|
+ Begin
|
|
|
+ Found:=FindGetFileInfo(Copy(UnixFindData^.SearchSpec,1,UnixFindData^.NamePos)+FName,Rslt);
|
|
|
+ if Found then
|
|
|
+ begin
|
|
|
+ Result:=0;
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ End;
|
|
|
+ End;
|
|
|
+ End;
|
|
|
+End;
|
|
|
|
|
|
|
|
|
Function FindFirst (Const Path : String; Attr : Longint; out Rslt : TSearchRec) : Longint;
|
|
|
-
|
|
|
-Var
|
|
|
- GlobSearchRec : PGlobSearchRec;
|
|
|
-
|
|
|
-begin
|
|
|
- New(GlobSearchRec);
|
|
|
- GlobSearchRec^.Path:=ExpandFileName(ExtractFilePath(Path));
|
|
|
- GlobSearchRec^.GlobHandle:=Glob(Path);
|
|
|
- Rslt.ExcludeAttr:=Not Attr and (faHidden or faSysFile or faVolumeID or faDirectory); //!! Not correct !!
|
|
|
- Rslt.FindHandle:=GlobSearchRec;
|
|
|
- Result:=DoFind (Rslt);
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-Function FindNext (Var Rslt : TSearchRec) : Longint;
|
|
|
-
|
|
|
-begin
|
|
|
- Result:=DoFind (Rslt);
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-Procedure FindClose (Var F : TSearchrec);
|
|
|
-
|
|
|
-Var
|
|
|
- GlobSearchRec : PGlobSearchRec;
|
|
|
-
|
|
|
-begin
|
|
|
- GlobSearchRec:=F.FindHandle;
|
|
|
- GlobFree (GlobSearchRec^.GlobHandle);
|
|
|
- Dispose(GlobSearchRec);
|
|
|
-end;
|
|
|
+{
|
|
|
+ opens dir and calls FindWorkProc
|
|
|
+}
|
|
|
+var
|
|
|
+ UnixFindData : PUnixFindData;
|
|
|
+Begin
|
|
|
+ Result:=-1;
|
|
|
+ fillchar(Rslt,sizeof(Rslt),0);
|
|
|
+ if Path='' then
|
|
|
+ exit;
|
|
|
+ { Allocate UnixFindData }
|
|
|
+ New(UnixFindData);
|
|
|
+ FillChar(UnixFindData^,sizeof(UnixFindData),0);
|
|
|
+ Rslt.FindHandle:=UnixFindData;
|
|
|
+ {Create Info}
|
|
|
+ UnixFindData^.SearchSpec := Path;
|
|
|
+ {We always also search for readonly and archive, regardless of Attr:}
|
|
|
+ UnixFindData^.SearchAttr := Attr or faarchive or fareadonly;
|
|
|
+ UnixFindData^.NamePos := Length(UnixFindData^.SearchSpec);
|
|
|
+ while (UnixFindData^.NamePos>0) and (UnixFindData^.SearchSpec[UnixFindData^.NamePos]<>'/') do
|
|
|
+ dec(UnixFindData^.NamePos);
|
|
|
+ {Wildcards?}
|
|
|
+ if (Pos('?',Path)=0) and (Pos('*',Path)=0) then
|
|
|
+ begin
|
|
|
+ if FindGetFileInfo(Path,Rslt) then
|
|
|
+ Result:=0;
|
|
|
+ UnixFindData^.SearchType:=1;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ Result:=FindNext(Rslt);
|
|
|
+End;
|
|
|
|
|
|
|
|
|
Function FileGetDate (Handle : Longint) : Longint;
|
|
@@ -718,7 +633,7 @@ begin
|
|
|
inc(Drives);
|
|
|
if Drives>26 then
|
|
|
Drives:=4;
|
|
|
- Result:=Drives;
|
|
|
+ Result:=Drives;
|
|
|
end;
|
|
|
|
|
|
|