summaryrefslogtreecommitdiff
path: root/UEngines.pas
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2009-11-28 16:00:34 +0100
committerTomas Bzatek <tbzatek@users.sourceforge.net>2009-11-28 16:00:34 +0100
commit6132c2ef3066e813acb1237afeca266f32c53a21 (patch)
treeb880a4eeb74e07f0e94c9767f9aba0873194d903 /UEngines.pas
parent9e4a6521a9ea3310437962d6708cf814fafc70d1 (diff)
downloadtuxcmd-6132c2ef3066e813acb1237afeca266f32c53a21.tar.xz
Engine and VFS API cleanupv0.6.72
* also split threaded operations into UCoreWorkers.pas * symlinks should be properly resolved now, even in archives * no more relative/absolute path confusion * moved FillDirFiles outside engines, made it more universal
Diffstat (limited to 'UEngines.pas')
-rw-r--r--UEngines.pas765
1 files changed, 272 insertions, 493 deletions
diff --git a/UEngines.pas b/UEngines.pas
index dd35d44..5e3909c 100644
--- a/UEngines.pas
+++ b/UEngines.pas
@@ -45,28 +45,24 @@ type
FDisplayName: PChar; // always-valid UTF-8
LnkPointTo: PChar; // ANSI
ColumnData: array[0..9] of PChar;
- Size: Int64;
+ Size: cuLongLong;
+ PackedSize: Int64;
UpDir: boolean;
- Mode, UID, GID: Cardinal;
- IsDir, IsLnk, IsBlk, IsChr, IsFIFO, IsSock, Selected, IsDotFile: boolean;
- ModifyTime: time_t;
+ Mode, UID, GID: cuLong;
+ IsDir, IsLnk, IsBlk, IsChr, IsFIFO, IsSock: boolean;
+ Selected, IsDotFile, IsExecutable: boolean;
+ atime, mtime, ctime: time_t;
Icon: Pointer;
ItemColor: PGdkColor;
end;
PDataItemSL = ^TDataItemSL;
TDataItemSL = record
+ DataItem: PDataItem;
Stage1: boolean;
- FName: PChar; // ANSI
- FDisplayName: PChar; // always-valid UTF-8
- LnkPointTo: PChar; // ANSI
- ADestination: PChar;
- Size, PackedSize: Int64;
- Mode, UID, GID: Cardinal;
- IsDir, IsLnk, ForceMove, IsOnRO, IsExecutable: boolean;
- ModifyTime: time_t;
Level: word;
- atime, mtime: Int64;
+ ADestination: PChar;
+ ForceMove, IsOnRO: boolean;
end;
TEngineProgressFunc = function (Sender: Pointer; BytesDone: Int64): boolean; cdecl; // Return False to break the copy process
@@ -81,45 +77,45 @@ type
LastHighlightItem, SavePath: string;
constructor Create;
destructor Destroy; override;
- function GetListing(var List: TList; const AddDotFiles: boolean): integer; overload; virtual; abstract; // Returns errorcode
- function GetListing(var List: TList; const AddDotFiles: boolean; APath: string): integer; overload; virtual; abstract; // Returns errorcode
+
+ function GetListing(List: TList; const APath: string; AddDotFiles, FollowSymlinks, AddFullPath: boolean): integer; virtual; abstract; // Returns errorcode
+ function GetFileInfo(const APath: string; FollowSymlinks, AddFullPath: boolean): PDataItem; virtual; abstract;
+
function ChangeDir(const NewPath: string): integer; virtual; abstract; // Returns errorcode
- function ExplicitChDir(const NewPath: string): integer; virtual; abstract; // Returns errorcode
- function GetFileSystemSize: Int64; overload; virtual; abstract;
- function GetFileSystemSize(const APath: string): Int64; overload; virtual; abstract;
- function GetFileSystemFree: Int64; overload; virtual; abstract;
- function GetFileSystemFree(const APath: string): Int64; overload; virtual; abstract;
- function MakeDir(const NewDir: string): integer; virtual; abstract; // Returns errorcode
- function GetDirSize(APath: string): Int64; virtual; abstract; // Returns size or 0 if fails
- function Remove(APath: string): integer; virtual; abstract; // Returns errorcode
- procedure FillDirFiles(APath: string; List: TList; ALevel: word); virtual; abstract;
- function GetFileInfoSL(APath: string): PDataItemSL; virtual; abstract;
- function FileExists(const FileName: string; const Use_lstat: boolean = False): Boolean; virtual; abstract;
- function DirectoryExists(const FileName: string; const Use_lstat: boolean = False): Boolean; virtual; abstract;
- function MakeSymLink(const NewFileName, PointTo: string): integer; virtual; abstract; // Returns errorcode
- function Chmod(const FileName: string; const Mode: integer): integer; virtual; abstract; // Returns errorcode
- function Chown(const FileName: string; const UID, GID: integer): integer; virtual; abstract; // Returns errorcode
+ function GetPath: string; virtual; abstract;
+ procedure SetPath(Value: string); virtual; abstract;
+
+ function GetDirSize(const APath: string): Int64; virtual; abstract; // Returns size or 0 if fails
procedure BreakProcessing(ProcessingKind: integer); virtual; abstract; // 1 = GetDirSize, 2 = GetListing
- function RenameFile(SourceFile, DestFile: string): integer; virtual; abstract; // Returns errorcode
- function ChangeTimes(APath: string; mtime, atime: Int64): integer; virtual; abstract; // Returns errorcode
+ function FileExists(const FileName: string; FollowSymlinks: boolean): boolean; virtual; abstract;
+ function DirectoryExists(const FileName: string; FollowSymlinks: boolean): boolean; virtual; abstract;
procedure GetFileSystemInfo(const APath: string; var FSSize, FSFree: Int64; var FSName: string); virtual; abstract;
- function OpenFile(const APath: string; Mode: integer; var Error: integer): TEngineFileDes; virtual; abstract; // Returns filedescriptor
- function ReadFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; ABlockSize: integer; var Error: integer): integer; virtual; abstract; // Returns number of bytes read
- function WriteFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; BytesCount: integer; var Error: integer): integer; virtual; abstract; // Returns number of bytes written
- function CloseFile(const FileDescriptor: TEngineFileDes): integer; virtual; abstract; // Returns errorcode
- function FileSeek(const FileDescriptor: TEngineFileDes; const AbsoluteOffset: Int64; var Error: integer): Int64; virtual; abstract; // Returns errorcode
function IsOnROMedium(const FileName: string): boolean; virtual; abstract;
function FileCanRun(const FileName: string): boolean; virtual; abstract;
- function GetPath: string; virtual; abstract;
- procedure SetPath(Value: string); virtual; abstract;
+
+ // Operations
+ function MakeDir(const NewDir: string): integer; virtual; abstract; // Returns errorcode
+ function Remove(const APath: string): integer; virtual; abstract; // Returns errorcode
+ function MakeSymLink(const NewFileName, PointTo: string): integer; virtual; abstract; // Returns errorcode
+ function Chmod(const FileName: string; Mode: cuLong): integer; virtual; abstract; // Returns errorcode
+ function Chown(const FileName: string; UID, GID: cuLong): integer; virtual; abstract; // Returns errorcode
+ function RenameFile(const SourceFile, DestFile: string): integer; virtual; abstract; // Returns errorcode
+ function ChangeTimes(const APath: string; mtime, atime: time_t): integer; virtual; abstract; // Returns errorcode
// Copy-related routines
function GetBlockSize: guint32; virtual; abstract;
procedure SetBlockSize(Value: guint32); virtual; abstract;
- function CopyFileIn(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; virtual; abstract; // returns True if file is successfully copied
- function CopyFileOut(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; virtual; abstract; // returns True if file is successfully copied
- function IsOnSameFS(const Path1, Path2: string): boolean; virtual; abstract;
- function TwoSameFiles(const Path1, Path2: string): boolean; virtual; abstract;
+ function CopyFileIn(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; virtual; abstract; // returns True if file is successfully copied
+ function CopyFileOut(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; virtual; abstract; // returns True if file is successfully copied
+ function IsOnSameFS(const Path1, Path2: string; FollowSymlinks: boolean): boolean; virtual; abstract;
+ function TwoSameFiles(const Path1, Path2: string; FollowSymlinks: boolean): boolean; virtual; abstract;
+
+ // Separate file read/write routines, not supported on most backends
+ function OpenFile(const APath: string; Mode: integer; var Error: integer): TEngineFileDes; virtual; abstract; // Returns filedescriptor
+ function ReadFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; ABlockSize: integer; var Error: integer): integer; virtual; abstract; // Returns number of bytes read
+ function WriteFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; BytesCount: integer; var Error: integer): integer; virtual; abstract; // Returns number of bytes written
+ function CloseFile(const FileDescriptor: TEngineFileDes): integer; virtual; abstract; // Returns errorcode
+ function FileSeek(const FileDescriptor: TEngineFileDes; const AbsoluteOffset: Int64; var Error: integer): Int64; virtual; abstract; // Returns errorcode
published
property Path: string read GetPath write SetPath;
property BlockSize: guint32 read GetBlockSize write SetBlockSize;
@@ -132,45 +128,45 @@ type
public
constructor Create;
destructor Destroy; override;
- function GetListing(var List: TList; const AddDotFiles: boolean): integer; override;
- function GetListing(var List: TList; const AddDotFiles: boolean; APath: string): integer; override;
+
+ function GetListing(List: TList; const APath: string; AddDotFiles, FollowSymlinks, AddFullPath: boolean): integer; override;
+ function GetFileInfo(const APath: string; FollowSymlinks, AddFullPath: boolean): PDataItem; override;
+
function ChangeDir(const NewPath: string): integer; override;
- function ExplicitChDir(const NewPath: string): integer; override;
- function GetFileSystemSize: Int64; override;
- function GetFileSystemSize(const APath: string): Int64; override;
- function GetFileSystemFree: Int64; override;
- function GetFileSystemFree(const APath: string): Int64; override;
- function MakeDir(const NewDir: string): integer; override;
- function GetDirSize(APath: string): Int64; override;
- function Remove(APath: string): integer; override;
- procedure FillDirFiles(APath: string; List: TList; ALevel: word); override;
- function GetFileInfoSL(APath: string): PDataItemSL; override;
- function FileExists(const FileName: string; const Use_lstat: boolean = False): Boolean; override;
- function DirectoryExists(const FileName: string; const Use_lstat: boolean = False): Boolean; override;
- function MakeSymLink(const NewFileName, PointTo: string): integer; override;
- function Chmod(const FileName: string; const Mode: integer): integer; override;
- function Chown(const FileName: string; const UID, GID: integer): integer; override;
+ function GetPath: string; override;
+ procedure SetPath(Value: string); override;
+
+ function GetDirSize(const APath: string): Int64; override;
procedure BreakProcessing(ProcessingKind: integer); override;
- function RenameFile(SourceFile, DestFile: string): integer; override;
- function ChangeTimes(APath: string; mtime, atime: Int64): integer; override;
+ function FileExists(const FileName: string; FollowSymlinks: boolean): boolean; override;
+ function DirectoryExists(const FileName: string; FollowSymlinks: boolean): boolean; override;
procedure GetFileSystemInfo(const APath: string; var FSSize, FSFree: Int64; var FSName: string); override;
- function OpenFile(const APath: string; Mode: integer; var Error: integer): TEngineFileDes; override;
- function ReadFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; ABlockSize: integer; var Error: integer): integer; override;
- function WriteFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; BytesCount: integer; var Error: integer): integer; override;
- function CloseFile(const FileDescriptor: TEngineFileDes): integer; override;
- function FileSeek(const FileDescriptor: TEngineFileDes; const AbsoluteOffset: Int64; var Error: integer): Int64; override;
function IsOnROMedium(const FileName: string): boolean; override;
function FileCanRun(const FileName: string): boolean; override;
- function GetPath: string; override;
- procedure SetPath(Value: string); override;
+
+ function MakeDir(const NewDir: string): integer; override;
+ function Remove(const APath: string): integer; override;
+ function MakeSymLink(const NewFileName, PointTo: string): integer; override;
+ function Chmod(const FileName: string; Mode: cuLong): integer; override;
+ function Chown(const FileName: string; UID, GID: cuLong): integer; override;
+ function RenameFile(const SourceFile, DestFile: string): integer; override;
+ function ChangeTimes(const APath: string; mtime, atime: time_t): integer; override;
function GetBlockSize: guint32; override;
procedure SetBlockSize(Value: guint32); override;
- function CopyFileIn(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; override;
- function CopyFileOut(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; override;
- function CopyFile(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
- function IsOnSameFS(const Path1, Path2: string): boolean; override;
- function TwoSameFiles(const Path1, Path2: string): boolean; override;
+ function CopyFileIn(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; override;
+ function CopyFileOut(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; override;
+ function IsOnSameFS(const Path1, Path2: string; FollowSymlinks: boolean): boolean; override;
+ function TwoSameFiles(const Path1, Path2: string; FollowSymlinks: boolean): boolean; override;
+
+ function OpenFile(const APath: string; Mode: integer; var Error: integer): TEngineFileDes; override;
+ function ReadFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; ABlockSize: integer; var Error: integer): integer; override;
+ function WriteFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; BytesCount: integer; var Error: integer): integer; override;
+ function CloseFile(const FileDescriptor: TEngineFileDes): integer; override;
+ function FileSeek(const FileDescriptor: TEngineFileDes; const AbsoluteOffset: Int64; var Error: integer): Int64; override;
+
+ // Local extra functions
+ function CopyFile(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
published
property Path;
property BlockSize;
@@ -179,6 +175,8 @@ type
procedure FreeDataItem(DataItem: PDataItemSL); overload;
procedure FreeDataItem(DataItem: PDataItem); overload;
+function DuplicateDataItem(DataItem: PDataItem): PDataItem; overload;
+function DuplicateDataItem(DataItem: PDataItemSL): PDataItemSL; overload;
implementation
@@ -236,112 +234,40 @@ begin
end;
end;
-function TLocalTreeEngine.GetListing(var List: TList; const AddDotFiles: boolean; APath: string): integer;
-var Item : PDataItem;
- Handle : PDIR;
- DirEnt : PDirent64;
- Buf : PChar;
-// StatBuf : TStatBuf64;
- StatBuf : Pstat64;
- i: integer;
- LnkBuf : array[0..1000] of char;
+function TLocalTreeEngine.GetListing(List: TList; const APath: string; AddDotFiles, FollowSymlinks, AddFullPath: boolean): integer;
+var Item: PDataItem;
+ Handle: PDIR;
+ DirEnt: PDirent64;
+ Buf: PChar;
begin
Result := 0;
try
- APath := IncludeTrailingPathDelimiter(APath);
- if libc_chdir(PChar(APath)) <> 0 then begin
- Result := errno;
- DebugMsg(['*** TLocalTreeEngine.GetListing(APath=', APath, '): chdir error: ', strerror(Result)]);
- Exit;
- end;
- Handle := opendir(PChar(APath));
- if not Assigned(Handle) then begin
- DebugMsg(['*** TLocalTreeEngine.GetListing(APath=', APath, '): opendir() handle == NULL: ', strerror(errno)]);
- Result := ERRNoAccess;
- Exit;
- end;
- repeat
-// DebugMsg(['x1']);
- DirEnt := readdir64(Handle);
-// DebugMsg(['x2']);
- if Assigned(DirEnt) and Assigned(PChar(@DirEnt^.d_name[0])) then begin
-// DebugMsg(['x3']);
- Buf := Pchar(@DirEnt^.d_name[0]);
-// DebugMsg(['x4']);
- if (Buf <> '.') and (Buf <> '..') and (DirEnt^.d_name[0] <> #0) and
- (AddDotFiles or (Length(Buf) = 1) or ((Length(Buf) > 1) and (not ((Buf[0] = '.') and (Buf[1] <> '.'))))) then
- begin
-// DebugMsg(['x5']);
- Item := malloc(SizeOf(TDataItem));
-// DebugMsg(['x6']);
- memset(Item, 0, SizeOf(TDataItem));
-// DebugMsg(['x7']);
- with Item^ do begin
-// DebugMsg(['x8']);
- FName := nil;
- FDisplayName := nil;
- LnkPointTo := nil;
- for i := 0 to Length(ColumnData) - 1 do ColumnData[i] := nil;
- FName := strdup(Buf);
- FDisplayName := StrToUTF8(Buf);
-// FDisplayName := strdup(Buf);
-// DebugMsg(['x']);
- StatBuf := malloc(sizeof(Tstat64));
- memset(StatBuf, 0, sizeof(Tstat64));
-// DebugMsg(['(II) TLocalTreeEngine.GetListing(APath=', APath, '): lstat(Buf = ', Buf, ')']);
- if lstat64(Buf, StatBuf) <> 0 then begin
- DebugMsg(['*** TLocalTreeEngine.GetListing(APath=', APath, '): Error reading file via lstat64: ', strerror(errno)]);
- Continue;
- end;
- Mode := StatBuf^.st_mode;
- IsDotFile := (Length(Buf) > 1) and (Buf[0] = '.') and (Buf[1] <> '.');
- IsDir := __S_ISTYPE(StatBuf^.st_mode, __S_IFDIR);
- IsLnk := __S_ISTYPE(StatBuf^.st_mode, __S_IFLNK);
- IsBlk := __S_ISTYPE(StatBuf^.st_mode, __S_IFBLK);
- IsChr := __S_ISTYPE(StatBuf^.st_mode, __S_IFCHR);
- IsFIFO := __S_ISTYPE(StatBuf^.st_mode, __S_IFIFO);
- IsSock := __S_ISTYPE(StatBuf^.st_mode, __S_IFSOCK);
- ModifyTime := StatBuf^.st_mtime;
- if StatBuf^.st_uid = 4294967295 then UID := getuid
- else UID := StatBuf^.st_uid;
- if StatBuf^.st_gid = 4294967295 then GID := getgid
- else GID := StatBuf^.st_gid;
- UpDir := False;
- Selected := False;
-// DebugMsg(['(II) TLocalTreeEngine.GetListing(APath=', APath, '): freeing StatBuf...']);
- libc_free(StatBuf);
-// DebugMsg([' done.']);
- if IsLnk then begin
-// DebugMsg(['aaaax']);
- i := readlink(PChar(APath + String(Buf)), LnkBuf, SizeOf(LnkBuf));
- if i > 0 then begin
- LnkBuf[i] := #0;
- LnkPointTo := malloc(i + 1);
- memset(LnkPointTo, 0, i + 1);
- LnkPointTo := strncpy(LnkPointTo, @LnkBuf[0], i);
- end;
+ if libc_chdir(PChar(APath)) <> 0 then begin
+ Result := errno;
+ DebugMsg(['*** TLocalTreeEngine.GetListing(APath=', APath, '): chdir error: ', strerror(Result)]);
+ Exit;
+ end;
+ Handle := opendir(PChar(APath));
+ if Handle = nil then begin
+ DebugMsg(['*** TLocalTreeEngine.GetListing(APath=', APath, '): opendir() handle == NULL: ', strerror(errno)]);
+ Result := ERRNoAccess;
+ Exit;
+ end;
- StatBuf := malloc(sizeof(Tstat64));
- memset(StatBuf, 0, sizeof(Tstat64));
- if stat64(Buf, StatBuf) = 0 then begin
- IsDir := __S_ISTYPE(StatBuf^.st_mode, __S_IFDIR);
- Mode := StatBuf^.st_mode;
- end;
-// DebugMsg(['(II) TLocalTreeEngine.GetListing(APath=', APath, '): freeing StatBuf...']);
- libc_free(StatBuf);
-// DebugMsg([' done.']);
- end;
-// DebugMsg(['xdffffffff']);
- if not IsDir then Size := StatBuf^.st_size
- else Size := -1;
-// DebugMsg(['xxsdfsf']);
+ repeat
+ DirEnt := readdir64(Handle);
+ if (DirEnt <> nil) and (DirEnt^.d_name[0] <> #0) then begin
+ Buf := PChar(@DirEnt^.d_name[0]);
+ if (Buf <> '.') and (Buf <> '..') and (strlen(Buf) > 0) and
+ (AddDotFiles or (Buf[0] <> '.')) then
+ begin
+ Item := GetFileInfo(IncludeTrailingPathDelimiter(APath) + string(Buf), FollowSymlinks, AddFullPath);
List.Add(Item);
-// DebugMsg(['x1123']);
end;
end;
- end;
- until DirEnt = nil;
- closedir(Handle);
+ until DirEnt = nil;
+ // TODO: check errno?
+ closedir(Handle);
except
on E: Exception do begin
Result := ERRException;
@@ -351,9 +277,66 @@ begin
end;
end;
-function TLocalTreeEngine.GetListing(var List: TList; const AddDotFiles: boolean): integer;
+function TLocalTreeEngine.GetFileInfo(const APath: string; FollowSymlinks, AddFullPath: boolean): PDataItem;
+var Item: PDataItem;
+ StatBuf: Pstat64;
+ LnkBuf: array[0..65535] of char;
+ i: integer;
begin
- Result := GetListing(List, AddDotFiles, FPath);
+ StatBuf := malloc(sizeof(Tstat64));
+ memset(StatBuf, 0, sizeof(Tstat64));
+ if lstat64(PChar(APath), StatBuf) <> 0 then begin
+ DebugMsg(['*** TLocalTreeEngine.GetFileInfo(APath=', APath, '): Error reading file via lstat64: ', strerror(errno)]);
+ libc_free(StatBuf);
+ Result := nil;
+ Exit;
+ end;
+
+ Item := malloc(sizeof(TDataItem));
+ memset(Item, 0, sizeof(TDataItem));
+ Item^.UpDir := False;
+ Item^.LnkPointTo := nil;
+ Item^.Selected := False;
+
+ if AddFullPath then Item^.FName := strdup(PChar(APath))
+ else Item^.FName := strdup(PChar(ExtractFileName(APath)));
+ Item^.FDisplayName := StrToUTF8(Item^.FName);
+
+ Item^.Mode := StatBuf^.st_mode;
+ Item^.IsDotFile := (Length(ExtractFileName(APath)) > 0) and (ExtractFileName(APath)[1] = '.');
+ Item^.IsExecutable := (StatBuf^.st_mode and S_IXUSR) = S_IXUSR;
+ Item^.IsDir := __S_ISTYPE(StatBuf^.st_mode, __S_IFDIR);
+ Item^.IsLnk := __S_ISTYPE(StatBuf^.st_mode, __S_IFLNK);
+ Item^.IsBlk := __S_ISTYPE(StatBuf^.st_mode, __S_IFBLK);
+ Item^.IsChr := __S_ISTYPE(StatBuf^.st_mode, __S_IFCHR);
+ Item^.IsFIFO := __S_ISTYPE(StatBuf^.st_mode, __S_IFIFO);
+ Item^.IsSock := __S_ISTYPE(StatBuf^.st_mode, __S_IFSOCK);
+ Item^.mtime := StatBuf^.st_mtime;
+ Item^.atime := StatBuf^.st_atime;
+ Item^.ctime := StatBuf^.st_ctime;
+ Item^.UID := StatBuf^.st_uid;
+ Item^.GID := StatBuf^.st_gid;
+ Item^.Size := StatBuf^.st_size;
+ Item^.PackedSize := -1;
+ libc_free(StatBuf);
+
+ if Item^.IsLnk then begin
+ i := readlink(PChar(APath), LnkBuf, sizeof(LnkBuf));
+ if i >= 0 then
+ Item^.LnkPointTo := g_strdup(@LnkBuf[0]);
+ if FollowSymlinks then begin
+ StatBuf := malloc(sizeof(Tstat64));
+ memset(StatBuf, 0, sizeof(Tstat64));
+ if stat64(PChar(APath), StatBuf) = 0 then begin
+ Item^.IsDir := __S_ISTYPE(StatBuf^.st_mode, __S_IFDIR);
+ Item^.Mode := StatBuf^.st_mode;
+ Item^.Size := StatBuf^.st_size;
+ end;
+ libc_free(StatBuf);
+ end;
+ end;
+
+ Result := Item;
end;
function TLocalTreeEngine.ChangeDir(const NewPath: string): integer;
@@ -390,55 +373,6 @@ begin
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.ExplicitChDir(const NewPath: string): integer;
-begin
- Result := libc_chdir(PChar(NewPath));
- if Result <> 0 then Result := errno;
-end;
-
-(********************************************************************************************************************************)
-function TLocalTreeEngine.GetFileSystemSize(const APath: string): Int64;
-var Stat: Pstatfs64;
-begin
- Result := 0;
- try
- Stat := malloc(sizeof(Tstatfs64));
- memset(Stat, 0, sizeof(Tstatfs64));
- if statfs64(PChar(APath), Stat) <> 0 then Exit;
- Result := Stat^.f_bsize * Stat^.f_blocks;
- libc_free(Stat);
- except
- on E: Exception do DebugMsg(['*** TLocalTreeEngine.GetFileSystemSize(APath=', APath, ') -Exception: ', E.Message]);
- end;
-end;
-
-function TLocalTreeEngine.GetFileSystemSize: Int64;
-begin
- Result := GetFileSystemSize(FPath);
-end;
-
-(********************************************************************************************************************************)
-function TLocalTreeEngine.GetFileSystemFree(const APath: string): Int64;
-var Stat: Pstatfs64;
-begin
- Result := 0;
- try
- Stat := malloc(sizeof(Tstatfs64));
- memset(Stat, 0, sizeof(Tstatfs64));
- if statfs64(PChar(APath), Stat) <> 0 then Exit;
- Result := Stat^.f_bsize * Stat^.f_bavail;
- libc_free(Stat);
- except
- on E: Exception do DebugMsg(['*** TLocalTreeEngine.GetFileSystemFree(APath=', APath, ') -Exception: ', E.Message]);
- end;
-end;
-
-function TLocalTreeEngine.GetFileSystemFree: Int64;
-begin
- Result := GetFileSystemFree(FPath);
-end;
-
-(********************************************************************************************************************************)
function TLocalTreeEngine.MakeDir(const NewDir: string): integer;
begin
// DebugMsg(['(II) TLocalTreeEngine.MakeDir: begin']);
@@ -447,7 +381,7 @@ begin
// if Result <> 0 then Result := errno;
if Result <> 0 then try
- if Self.DirectoryExists(NewDir) or (g_mkdir_with_parents(PChar(NewDir), OctalToAttr(ConfDefaultDirCreationMask)) <> 0) {ForceDirectories(NewDir))}
+ if Self.DirectoryExists(NewDir, False) or (g_mkdir_with_parents(PChar(NewDir), OctalToAttr(ConfDefaultDirCreationMask)) <> 0) {ForceDirectories(NewDir))}
then Result := errno
else Result := 0;
except
@@ -459,40 +393,36 @@ begin
end;
(********************************************************************************************************************************)
-
-function TLocalTreeEngine.GetDirSize(APath: string): Int64;
+function TLocalTreeEngine.GetDirSize(const APath: string): Int64;
function InternalGetDirSize(APath: string): Int64;
- var Handle : PDIR;
- DirEnt : PDirent64;
- StatBuf : Pstat64;
+ var Handle: PDIR;
+ DirEnt: PDirent64;
+ StatBuf: Pstat64;
+ Buf: PChar;
begin
Result := 0;
try
if BreakProcessingType = 1 then Exit;
APath := IncludeTrailingPathDelimiter(APath);
- if libc_chdir(PChar(APath)) <> 0 then begin
- Result := 0;
- Exit;
- end;
- Handle := OpenDir(PChar(APath));
- if not Assigned(Handle) then begin
- Result := 0;
- Exit;
- end;
+ if libc_chdir(PChar(APath)) <> 0 then Exit;
+ Handle := opendir(PChar(APath));
+ if not Assigned(Handle) then Exit;
repeat
DirEnt := readdir64(Handle);
- if Assigned(DirEnt) and Assigned(PChar(@DirEnt^.d_name[0])) and (PChar(@DirEnt^.d_name[0]) <> '.') and
- (PChar(@DirEnt^.d_name[0]) <> '..') and (DirEnt^.d_name[0] <> #0) then
- begin
- StatBuf := malloc(sizeof(Tstat64));
- memset(StatBuf, 0, sizeof(Tstat64));
- if lstat64(PChar(@DirEnt^.d_name[0]), StatBuf) <> 0 then Continue;
- if __S_ISTYPE(StatBuf^.st_mode, __S_IFDIR) then begin
- Inc(Result, InternalGetDirSize(APath + String(PChar(@DirEnt^.d_name[0]))));
- libc_chdir(PChar(APath));
- end else Inc(Result, StatBuf^.st_size);
- libc_free(StatBuf);
+ if DirEnt <> nil then begin
+ Buf := PChar(@DirEnt^.d_name[0]);
+ if (strlen(Buf) > 0) and (Buf <> '.') and (Buf <> '..') then begin
+ StatBuf := malloc(sizeof(Tstat64));
+ memset(StatBuf, 0, sizeof(Tstat64));
+ if lstat64(Buf, StatBuf) = 0 then begin
+ if __S_ISTYPE(StatBuf^.st_mode, __S_IFDIR) then begin
+ Inc(Result, InternalGetDirSize(APath + string(Buf)));
+ libc_chdir(PChar(APath));
+ end else Inc(Result, StatBuf^.st_size);
+ end;
+ libc_free(StatBuf);
+ end;
end;
until DirEnt = nil;
closedir(Handle);
@@ -514,206 +444,25 @@ begin
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.Remove(APath: string): integer;
+function TLocalTreeEngine.Remove(const APath: string): integer;
begin
- APath := ExcludeTrailingPathDelimiter(APath);
- Result := libc_remove(PChar(APath));
+ Result := libc_remove(PChar(ExcludeTrailingPathDelimiter(APath)));
if Result <> 0 then Result := errno;
end;
(********************************************************************************************************************************)
-procedure TLocalTreeEngine.FillDirFiles(APath: string; List: TList; ALevel: word);
-var Handle : PDIR;
- DirEnt : PDirent64;
- StatBuf_global : Pstat64;
- Item: PDataItemSL;
- i: integer;
- LnkBuf : array[0..1000] of char;
- FilesList: TList;
-
-
- procedure AddEntry(FPath: string; AddCurrDirStage, AStage1: boolean);
- var StatBuf_local : Pstat64;
- begin
-// DebugMsg(['TLocalTreeEngine.FillDirFiles: addding "', FPath, '"']);
- FPath := ExcludeTrailingPathDelimiter(FPath);
- StatBuf_local := malloc(sizeof(Tstat64));
- memset(StatBuf_local, 0, sizeof(Tstat64));
- if lstat64(PChar(FPath), StatBuf_local) <> 0 then begin
- DebugMsg(['*** TLocalTreeEngine.FillDirFiles: Error reading file stat AddEntry("', FPath, '"): ', strerror(errno)]);
- Exit;
- end;
- Item := malloc(SizeOf(TDataItemSL));
- memset(Item, 0, SizeOf(TDataItemSL));
- with Item^ do begin
- FName := nil;
- FDisplayName := nil;
- LnkPointTo := nil;
- ADestination := nil;
- Stage1 := AStage1;
- FName := strdup(PChar(FPath));
- FDisplayName := StrToUTF8(PChar(FPath));
- Size := StatBuf_local^.st_size;
- PackedSize := -1;
- Mode := StatBuf_local^.st_mode;
- IsDir := __S_ISTYPE(StatBuf_local^.st_mode, __S_IFDIR);
- IsLnk := __S_ISTYPE(StatBuf_local^.st_mode, __S_IFLNK);
- IsExecutable := AddCurrDirStage or (StatBuf_local^.st_mode and S_IXUSR = S_IXUSR);
- IsOnRO := IsOnROMedium(FPath);
- ForceMove := False;
- if StatBuf_local^.st_uid = 4294967295 then UID := getuid
- else UID := StatBuf_local^.st_uid;
- if StatBuf_local^.st_gid = 4294967295 then GID := getgid
- else GID := StatBuf_local^.st_gid;
- atime := StatBuf_local^.st_atime;
- mtime := StatBuf_local^.st_mtime;
- if IsLnk and AddCurrDirStage then DebugMsg(['*** Assertion failed AddEntry: Item^.IsLnk = True']);
- if IsLnk and (not AddCurrDirStage) then begin
- i := readlink(PChar(APath + String(PChar(@DirEnt^.d_name[0]))), LnkBuf, SizeOf(LnkBuf));
- if i > 0 then begin
- LnkBuf[i] := #0;
- LnkPointTo := malloc(i + 1);
- memset(LnkPointTo, 0, i + 1);
- LnkPointTo := strncpy(LnkPointTo, @LnkBuf[0], i);
-// StrLCopy(LnkPointTo, @LnkBuf[0], i);
- end;
- end;
- ModifyTime := StatBuf_local^.st_mtime;
-// DebugMsg([FormatDateTime('c', ModifyTime)]);
- Level := ALevel + Ord(not AddCurrDirStage);
- libc_free(StatBuf_local);
- end;
- if AddCurrDirStage then List.Add(Item)
- else FilesList.Add(Item);
- end;
-
-begin
- if not Assigned(List) then Exit;
- try
- AddEntry(APath, True, True);
- FilesList := TList.Create;
- APath := IncludeTrailingPathDelimiter(APath);
- if libc_chdir(PChar(APath)) <> 0 then begin
- DebugMsg(['*** TLocalTreeEngine.FillDirFiles: chdir to "', APath, '" failed: ', strerror(errno)]);
- Exit;
- end;
- Handle := OpenDir(PChar(APath));
- if Assigned(Handle) then
- repeat
- DirEnt := readdir64(Handle);
- if Assigned(DirEnt) and Assigned(PChar(@DirEnt^.d_name[0])) and (PChar(@DirEnt^.d_name[0]) <> '.') and (PChar(@DirEnt^.d_name[0]) <> '..') then begin
- StatBuf_global := malloc(sizeof(Tstat64));
- memset(StatBuf_global, 0, sizeof(Tstat64));
- if lstat64(PChar(@DirEnt^.d_name[0]), StatBuf_global) <> 0 then begin
- DebugMsg(['*** TLocalTreeEngine.FillDirFiles: Error lstat-ing ("', PChar(@DirEnt^.d_name[0]), '"): ', strerror(errno)]);
- Continue;
- end;
- if __S_ISTYPE(StatBuf_global^.st_mode, __S_IFDIR) then begin
- FillDirFiles(APath + String(PChar(@DirEnt^.d_name[0])), List, ALevel + 1);
- libc_chdir(PChar(APath));
- end else AddEntry(APath + String(PChar(@DirEnt^.d_name[0])), False, True);
- libc_free(StatBuf_global);
- end;
- until DirEnt = nil;
- CloseDir(Handle);
- if FilesList.Count > 0 then
- for i := 0 to FilesList.Count - 1 do
- List.Add(FilesList[i]);
- FilesList.Free;
- AddEntry(APath, True, False);
- except
- on E: Exception do DebugMsg(['*** TLocalTreeEngine.FillDirFiles(APath=', APath, ', Level=', ALevel, ') -Exception: ', E.Message]);
- end;
-end;
-
-(********************************************************************************************************************************)
-function TLocalTreeEngine.GetFileInfoSL(APath: string): PDataItemSL;
-var StatBuf : Pstat64;
- i : integer;
- LnkBuf : array[0..1000] of char;
-begin
- Result := nil;
- try
- StatBuf := malloc(sizeof(Tstat64));
- memset(StatBuf, 0, sizeof(Tstat64));
- if lstat64(PChar(APath), StatBuf) <> 0 then begin
- DebugMsg(['*** Error reading file stat GetFileInfoSL(lstat): ', strerror(errno)]);
- Exit;
- end;
-// DebugMsg(['x1']);
- Result := malloc(SizeOf(TDataItemSL));
- memset(Result, 0, SizeOf(TDataItemSL));
-// DebugMsg(['x1']);
- with Result^ do begin
- FName := nil;
- FDisplayName := nil;
- LnkPointTo := nil;
- ADestination := nil;
- Stage1 := True;
-// DebugMsg(['x1']);
- FName := strdup(PChar(APath));
- FDisplayName := StrToUTF8(PChar(APath));
- Size := StatBuf^.st_size;
- PackedSize := -1;
- Mode := StatBuf^.st_mode;
- IsDir := __S_ISTYPE(StatBuf^.st_mode, __S_IFDIR);
- IsLnk := __S_ISTYPE(StatBuf^.st_mode, __S_IFLNK);
-// DebugMsg(['x1']);
- IsExecutable := StatBuf^.st_mode and S_IXUSR = S_IXUSR;
-// DebugMsg(['x2']);
- IsOnRO := IsOnROMedium(APath);
-// DebugMsg(['x2']);
- ForceMove := False;
-// DebugMsg(['x2']);
- ModifyTime := StatBuf^.st_mtime;
-// DebugMsg(['x2']);
- if StatBuf^.st_uid = 4294967295 then UID := getuid
- else UID := StatBuf^.st_uid;
- if StatBuf^.st_gid = 4294967295 then GID := getgid
- else GID := StatBuf^.st_gid;
- atime := StatBuf^.st_atime;
- mtime := StatBuf^.st_mtime;
-// DebugMsg(['x1']);
- libc_free(StatBuf);
-// DebugMsg(['x1']);
- Level := 1;
-// DebugMsg(['x1']);
- if IsLnk then begin
- i := readlink(PChar(APath), LnkBuf, SizeOf(LnkBuf));
- if i > 0 then begin
- LnkBuf[i] := #0;
- LnkPointTo := malloc(i + 1);
- memset(LnkPointTo, 0, i + 1);
-// StrLCopy(LnkPointTo, @LnkBuf[0], i);
- LnkPointTo := strncpy(LnkPointTo, @LnkBuf[0], i);
- end;
- StatBuf := malloc(sizeof(Tstat64));
- memset(StatBuf, 0, sizeof(Tstat64));
- if stat64(PChar(APath), StatBuf) = 0 then begin
- IsDir := __S_ISTYPE(StatBuf^.st_mode, __S_IFDIR);
- Mode := StatBuf^.st_mode;
- end;
- libc_free(StatBuf);
- end;
- end;
-// DebugMsg(['x1']);
- except
- on E: Exception do DebugMsg(['*** TLocalTreeEngine.GetFileInfoSL(APath=', APath, ') -Exception: ', E.Message]);
- end;
-end;
-(********************************************************************************************************************************)
-function TLocalTreeEngine.CopyFileIn(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
+function TLocalTreeEngine.CopyFileIn(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
begin
Result := CopyFile(Sender, SourceFile, DestFile, ProgressFunc, ErrorFunc, Append);
end;
-function TLocalTreeEngine.CopyFileOut(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
+function TLocalTreeEngine.CopyFileOut(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
begin
Result := CopyFile(Sender, SourceFile, DestFile, ProgressFunc, ErrorFunc, Append);
end;
-function TLocalTreeEngine.CopyFile(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
+function TLocalTreeEngine.CopyFile(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
var fsrc, fdest: PFILE;
BytesDone, BytesRead: Int64;
// offset: __off_t;
@@ -849,26 +598,25 @@ begin
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.FileExists(const FileName: string; const Use_lstat: boolean = False): Boolean;
+function TLocalTreeEngine.FileExists(const FileName: string; FollowSymlinks: boolean): boolean;
var st: Pstat64;
begin
st := malloc(sizeof(Tstat64));
memset(st, 0, sizeof(Tstat64));
- if Use_lstat then Result := lstat64(PChar(FileName), st) = 0
- else Result := stat64(PChar(FileName), st) = 0;
+ if not FollowSymlinks then Result := lstat64(PChar(FileName), st) = 0
+ else Result := stat64(PChar(FileName), st) = 0;
libc_free(st);
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.DirectoryExists(const FileName: string; const Use_lstat: boolean = False): Boolean;
+function TLocalTreeEngine.DirectoryExists(const FileName: string; FollowSymlinks: boolean): boolean;
var st: Pstat64;
begin
st := malloc(sizeof(Tstat64));
memset(st, 0, sizeof(Tstat64));
- if Use_lstat then Result := lstat64(PChar(FileName), st) = 0 else
- if stat64(PChar(FileName), st) = 0
- then Result := S_ISDIR(st^.st_mode)
- else Result := False;
+ if not FollowSymlinks then Result := lstat64(PChar(FileName), st) = 0
+ else Result := stat64(PChar(FileName), st) = 0;
+ Result := Result and S_ISDIR(st^.st_mode);
libc_free(st);
end;
@@ -881,14 +629,14 @@ begin
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.Chmod(const FileName: string; const Mode: integer): integer;
+function TLocalTreeEngine.Chmod(const FileName: string; Mode: cuLong): integer;
begin
Result := libc_chmod(PChar(FileName), Mode);
if Result <> 0 then Result := errno;
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.Chown(const FileName: string; const UID, GID: integer): integer;
+function TLocalTreeEngine.Chown(const FileName: string; UID, GID: cuLong): integer;
begin
Result := libc_chown(PChar(FileName), UID, GID);
if Result <> 0 then Result := errno;
@@ -901,8 +649,9 @@ begin
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.IsOnSameFS(const Path1, Path2: string): boolean;
+function TLocalTreeEngine.IsOnSameFS(const Path1, Path2: string; FollowSymlinks: boolean): boolean;
var FStat1, FStat2: Pstat64;
+ Res1, Res2: integer;
begin
// DebugMsg(['** TLocalTreeEngine.IsOnSameFS("', Path1, '", "', Path2, '")']);
Result := False; // Default fallback result (forces copy + delete)
@@ -910,29 +659,50 @@ begin
FStat2 := malloc(sizeof(Tstat64));
memset(FStat1, 0, sizeof(Tstat64));
memset(FStat2, 0, sizeof(Tstat64));
- if lstat64(PChar(Path1), FStat1) <> 0 then begin
- DebugMsg(['** TLocalTreeEngine.IsOnSameFS: stat(', Path1, ') error: ', strerror(errno)]);
- Exit;
- end;
- if lstat64(PChar(Path2), FStat2) <> 0 then begin
- DebugMsg(['** TLocalTreeEngine.IsOnSameFS: stat(', Path2, ') error: ', strerror(errno)]);
- Exit;
- end;
- Result := FStat1^.st_dev = FStat2^.st_dev;
+ if FollowSymlinks then Res1 := stat64(PChar(Path1), FStat1)
+ else Res1 := lstat64(PChar(Path1), FStat1);
+ if Res1 <> 0 then DebugMsg(['** TLocalTreeEngine.IsOnSameFS: stat(', Path1, ') error: ', strerror(errno)]);
+ if FollowSymlinks then Res2 := stat64(PChar(Path2), FStat2)
+ else Res2 := lstat64(PChar(Path2), FStat2);
+ if Res2 <> 0 then DebugMsg(['** TLocalTreeEngine.IsOnSameFS: stat(', Path2, ') error: ', strerror(errno)]);
+ if (Res1 = 0) and (Res2 = 0) then
+ Result := FStat1^.st_dev = FStat2^.st_dev;
libc_free(FStat1);
libc_free(FStat2);
// DebugMsg(['** TLocalTreeEngine.IsOnSameFS("', Path1, '", "', Path2, '") Result = ', Result]);
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.RenameFile(SourceFile, DestFile: string): integer;
+function TLocalTreeEngine.TwoSameFiles(const Path1, Path2: string; FollowSymlinks: boolean): boolean;
+var FStat1, FStat2: Pstat64;
+ Res1, Res2: integer;
+begin
+ Result := False;
+ FStat1 := malloc(sizeof(Tstat64));
+ FStat2 := malloc(sizeof(Tstat64));
+ memset(FStat1, 0, sizeof(Tstat64));
+ memset(FStat2, 0, sizeof(Tstat64));
+ if FollowSymlinks then Res1 := stat64(PChar(Path1), FStat1)
+ else Res1 := lstat64(PChar(Path1), FStat1);
+ if Res1 <> 0 then DebugMsg(['** TLocalTreeEngine.TwoSameFiles: stat(', Path1, ') error: ', strerror(errno)]);
+ if FollowSymlinks then Res2 := stat64(PChar(Path2), FStat2)
+ else Res2 := lstat64(PChar(Path2), FStat2);
+ if Res2 <> 0 then DebugMsg(['** TLocalTreeEngine.TwoSameFiles: stat(', Path2, ') error: ', strerror(errno)]);
+ if (Res1 = 0) and (Res2 = 0) then
+ Result := FStat1^.st_ino = FStat2^.st_ino;
+ libc_free(FStat1);
+ libc_free(FStat2);
+end;
+
+(********************************************************************************************************************************)
+function TLocalTreeEngine.RenameFile(const SourceFile, DestFile: string): integer;
begin
Result := libc_rename(PChar(SourceFile), PChar(DestFile));
if Result <> 0 then Result := errno;
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.ChangeTimes(APath: string; mtime, atime: Int64): integer;
+function TLocalTreeEngine.ChangeTimes(const APath: string; mtime, atime: time_t): integer;
var timebuf: Putimbuf;
begin
Result := errno;
@@ -966,7 +736,7 @@ begin
memset(Stat, 0, sizeof(Tstatfs64));
if statfs64(PChar(APath), Stat) <> 0 then Exit;
FSSize := Stat^.f_bsize * Stat^.f_blocks;
- FSFree := Stat^.f_bsize * Stat^.f_bavail;
+ FSFree := Stat^.f_bsize * Stat^.f_bfree;
fd := setmntent(_PATH_MOUNTED, 'r');
if fd = nil then Exit;
// Get mount name
@@ -986,10 +756,12 @@ begin
if Stat^.f_type = $9660 then begin { ISOFS_SUPER_MAGIC }
if Assigned(mntdev) and (mntdev <> '') then begin
fd := fopen(mntdev, 'r');
- if fd = nil then Exit;
- if fseek(fd, 32808, SEEK_SET) <> 0 then Exit;
- if fread(@Buffer[0], 1, 32, fd) <> 0 then FSName := Trim(String(Buffer));
- fclose(fd);
+ if fd <> nil then begin
+ if fseek(fd, 32808, SEEK_SET) = 0 then
+ if fread(@Buffer[0], 1, 32, fd) <> 0 then
+ FSName := Trim(String(Buffer));
+ fclose(fd);
+ end;
end;
end;
libc_free(Stat);
@@ -1054,8 +826,8 @@ begin
try
Stat := malloc(sizeof(Tstatfs64));
memset(Stat, 0, sizeof(Tstatfs64));
- if statfs64(PChar(FileName), Stat) <> 0 then Exit;
- Result := (Stat^.f_type = $9660); { ISOFS_SUPER_MAGIC }
+ if statfs64(PChar(FileName), Stat) = 0 then
+ Result := (Stat^.f_type = $9660); { ISOFS_SUPER_MAGIC }
libc_free(Stat);
except
on E: Exception do DebugMsg(['*** TLocalTreeEngine.IsOnROMedium(FileName=', FileName, ') -Exception: ', E.Message]);
@@ -1068,59 +840,66 @@ begin
Result := access(PChar(FileName), R_OK or X_OK) = 0;
end;
-(********************************************************************************************************************************)
-function TLocalTreeEngine.TwoSameFiles(const Path1, Path2: string): boolean;
-var st1, st2: Pstat64;
-begin
- Result := False;
- st1 := malloc(sizeof(Tstat64));
- st2 := malloc(sizeof(Tstat64));
- memset(st1, 0, sizeof(Tstat64));
- memset(st2, 0, sizeof(Tstat64));
- if lstat64(PChar(Path1), st1) <> 0 then Exit;
- if lstat64(PChar(Path2), st2) <> 0 then Exit;
-// DebugMsg(['*** TLocalTreeEngine.TwoSameFiles: ', st1^.st_ino, ' ', st2^.st_ino]);
- Result := st1^.st_ino = st2^.st_ino;
- libc_free(st1);
- libc_free(st2);
-end;
-
(********************************************************************************************************************************)
(********************************************************************************************************************************)
-procedure FreeDataItem(DataItem: PDataItemSL);
+procedure FreeDataItem(DataItem: PDataItem);
+var i : integer;
begin
try
- if Assigned(DataItem) then begin
+ if DataItem <> nil then begin
with DataItem^ do begin
if FName <> nil then libc_free(FName);
if FDisplayName <> nil then libc_free(FDisplayName);
-// if Assigned(ADestination) then Dispose(ADestination);
if LnkPointTo <> nil then libc_free(LnkPointTo);
+ for i := 0 to Length(ColumnData) - 1 do
+ if ColumnData[i] <> nil then libc_free(ColumnData[i]);
end;
libc_free(DataItem);
end;
except
+ on E: Exception do DebugMsg(['*** FreeDataItem: Exception: ', E.Message]);
end;
end;
-procedure FreeDataItem(DataItem: PDataItem);
-var i : integer;
+procedure FreeDataItem(DataItem: PDataItemSL);
begin
try
- if Assigned(DataItem) then begin
+ if DataItem <> nil then begin
with DataItem^ do begin
- if FName <> nil then libc_free(FName);
- if FDisplayName <> nil then libc_free(FDisplayName);
- if LnkPointTo <> nil then libc_free(LnkPointTo);
- for i := 0 to Length(ColumnData) - 1 do
- if ColumnData[i] <> nil then libc_free(ColumnData[i]);
+ if ADestination <> nil then libc_free(ADestination);
+ FreeDataItem(DataItem);
end;
libc_free(DataItem);
end;
except
+ on E: Exception do DebugMsg(['*** FreeDataItem: Exception: ', E.Message]);
end;
end;
+function DuplicateDataItem(DataItem: PDataItem): PDataItem;
+var NewDataItem: PDataItem;
+ i: integer;
+begin
+ NewDataItem := malloc(sizeof(TDataItem));
+ memcpy(NewDataItem, DataItem, sizeof(TDataItem));
+ NewDataItem^.FName := g_strdup(DataItem^.FName);
+ NewDataItem^.FDisplayName := g_strdup(DataItem^.FDisplayName);
+ NewDataItem^.LnkPointTo := g_strdup(DataItem^.LnkPointTo);
+ for i := 0 to Length(DataItem^.ColumnData) - 1 do
+ NewDataItem^.ColumnData[i] := g_strdup(DataItem^.ColumnData[i]);
+ Result := NewDataItem;
+end;
+
+function DuplicateDataItem(DataItem: PDataItemSL): PDataItemSL;
+var NewDataItem: PDataItemSL;
+begin
+ NewDataItem := malloc(sizeof(TDataItemSL));
+ memcpy(NewDataItem, DataItem, sizeof(TDataItemSL));
+ NewDataItem^.ADestination := g_strdup(DataItem^.ADestination);
+ NewDataItem^.DataItem := DuplicateDataItem(DataItem^.DataItem);
+ Result := NewDataItem;
+end;
+
end.