summaryrefslogtreecommitdiff
path: root/vfs
diff options
context:
space:
mode:
Diffstat (limited to 'vfs')
-rw-r--r--vfs/ModuleLoader.pas156
-rw-r--r--vfs/UVFSCore.pas1075
-rw-r--r--vfs/common/vfs_types.h114
-rw-r--r--vfs/null_plugin/COPYING339
-rw-r--r--vfs/null_plugin/Makefile22
-rw-r--r--vfs/null_plugin/README15
-rw-r--r--vfs/null_plugin/null_plugin.c357
l---------vfs/null_plugin/vfs_types.h1
-rw-r--r--vfs/uVFSprototypes.pas246
9 files changed, 2325 insertions, 0 deletions
diff --git a/vfs/ModuleLoader.pas b/vfs/ModuleLoader.pas
new file mode 100644
index 0000000..51351dd
--- /dev/null
+++ b/vfs/ModuleLoader.pas
@@ -0,0 +1,156 @@
+{******************************************************************}
+{ }
+{ Project JEDI }
+{ OS independent Dynamic Loading Helpers }
+{ }
+{ The initial developer of the this code is }
+{ Robert Marquardt <robert_marquardt@gmx.de) }
+{ }
+{ Copyright (C) 2000, 2001 Robert Marquardt. }
+{ }
+{ Obtained through: }
+{ Joint Endeavour of Delphi Innovators (Project JEDI) }
+{ }
+{ You may retrieve the latest version of this file at the Project }
+{ JEDI home page, located at http://delphi-jedi.org }
+{ }
+{ The contents of this file are used with permission, subject to }
+{ the Mozilla Public License Version 1.1 (the "License"); you may }
+{ not use this file except in compliance with the License. You may }
+{ obtain a copy of the License at }
+{ http://www.mozilla.org/NPL/NPL-1_1Final.html }
+{ }
+{ Software distributed under the License is distributed on an }
+{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
+{ implied. See the License for the specific language governing }
+{ rights and limitations under the License. }
+{ }
+{******************************************************************}
+
+unit ModuleLoader;
+
+interface
+{$WEAKPACKAGEUNIT ON}
+
+
+uses
+ Libc;
+type
+ // Handle to a loaded .so
+ TModuleHandle = Pointer;
+
+const
+ // Value designating an unassigned TModuleHandle od a failed loading
+ INVALID_MODULEHANDLE_VALUE = TModuleHandle(nil);
+
+function LoadModule(var Module: TModuleHandle; FileName: string): Boolean;
+function LoadModuleEx(var Module: TModuleHandle; FileName: string; Flags: Cardinal): Boolean;
+procedure UnloadModule(var Module: TModuleHandle);
+function GetModuleSymbol(Module: TModuleHandle; SymbolName: string): Pointer;
+function GetModuleSymbolEx(Module: TModuleHandle; SymbolName: string; var Accu: Boolean): Pointer;
+function ReadModuleData(Module: TModuleHandle; SymbolName: string; var Buffer; Size: Cardinal): Boolean;
+function WriteModuleData(Module: TModuleHandle; SymbolName: string; var Buffer; Size: Cardinal): Boolean;
+
+implementation
+
+// load the .so file FileName
+// the rules for FileName are those of dlopen()
+// Returns: True = success, False = failure to load
+// Assigns: the handle of the loaded .so to Module
+// Warning: if Module has any other value than INVALID_MODULEHANDLE_VALUE
+// on entry the function will do nothing but returning success.
+
+function LoadModule(var Module: TModuleHandle; FileName: string): Boolean;
+begin
+ Module := dlopen(PChar(FileName), RTLD_LAZY);
+ Result := Module <> INVALID_MODULEHANDLE_VALUE;
+end;
+
+// load the .so file FileName
+// dlopen() with flags is used to get better control of the loading
+// for the allowed values for flags see "man dlopen".
+
+function LoadModuleEx(var Module: TModuleHandle; FileName: string; Flags: Cardinal): Boolean;
+begin
+ Module := dlopen(PChar(FileName), Flags);
+ Result := Module <> INVALID_MODULEHANDLE_VALUE;
+end;
+
+// unload a .so loaded with LoadModule or LoadModuleEx
+// The procedure will not try to unload a handle with
+// value INVALID_MODULEHANDLE_VALUE and assigns this value
+// to Module after unload.
+
+procedure UnloadModule(var Module: TModuleHandle);
+begin
+ if Module <> INVALID_MODULEHANDLE_VALUE then
+ dlclose(Module);
+ Module := INVALID_MODULEHANDLE_VALUE;
+end;
+
+// returns the pointer to the symbol named SymbolName
+// if it is exported from the .so Module
+// nil is returned if the symbol is not available
+
+function GetModuleSymbol(Module: TModuleHandle; SymbolName: string): Pointer;
+begin
+ Result := nil;
+ if Module <> INVALID_MODULEHANDLE_VALUE then
+ Result := dlsym(Module, PChar(SymbolName));
+end;
+
+// returns the pointer to the symbol named SymbolName
+// if it is exported from the .so Module
+// nil is returned if the symbol is not available.
+// as an extra the boolean variable Accu is updated
+// by anding in the success of the function.
+// This is very handy for rendering a global result
+// when accessing a long list of symbols.
+
+function GetModuleSymbolEx(Module: TModuleHandle; SymbolName: string; var Accu: Boolean): Pointer;
+begin
+ Result := nil;
+ if Module <> INVALID_MODULEHANDLE_VALUE then
+ Result := dlsym(Module, PChar(SymbolName));
+ Accu := Accu and (Result <> nil);
+end;
+
+// get the value of variables exported from a .so Module
+// Delphi cannot access variables in a .so directly, so
+// this function allows to copy the data from the .so.
+// Beware! You are accessing the .so memory image directly.
+// Be sure to access a variable not a function and be sure
+// to read the correct amount of data.
+
+function ReadModuleData(Module: TModuleHandle; SymbolName: string; var Buffer; Size: Cardinal): Boolean;
+var
+ Sym: Pointer;
+begin
+ Result := True;
+ Sym := GetModuleSymbolEx(Module, SymbolName, Result);
+ if Result then
+ Move(Sym^, Buffer, Size);
+end;
+
+// set the value of variables exported from a .so Module
+// Delphi cannot access variables in a .so directly, so
+// this function allows to copy the data to the .so!
+// BEWARE! You are accessing the .so memory image directly.
+// Be sure to access a variable not a function and be sure
+// to write the correct amount of data.
+// The changes are not persistent. They get lost when the
+// .so is unloaded.
+
+function WriteModuleData(Module: TModuleHandle; SymbolName: string; var Buffer; Size: Cardinal): Boolean;
+var
+ Sym: Pointer;
+begin
+ Result := True;
+ Sym := GetModuleSymbolEx(Module, SymbolName, Result);
+ if Result then
+ Move(Buffer, Sym^, Size);
+end;
+end.
+
+
+
diff --git a/vfs/UVFSCore.pas b/vfs/UVFSCore.pas
new file mode 100644
index 0000000..21fc21b
--- /dev/null
+++ b/vfs/UVFSCore.pas
@@ -0,0 +1,1075 @@
+(*
+ Tux Commander - UVFSCore - VFS Core utilities and management
+ Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ Check for updates on tuxcmd.sourceforge.net
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*)
+unit UVFSCore;
+
+{$IFDEF __FPC__}
+ {$M+}
+{$ENDIF}
+
+interface
+
+uses GTKForms, Libc, {$IFDEF KYLIX}UGlibC_compat,{$ENDIF} Classes, uVFSprototypes, UEngines, UCoreUtils;
+
+
+type
+ TVFSPlugin = class
+ private
+ FVFSAllocNeeded: TVFSAllocNeeded;
+ FVFSInit: TVFSInit;
+ FVFSDestroy: TVFSDestroy;
+ FVFSVersion: TVFSVersion;
+ FVFSGetInfo: TVFSGetInfo;
+ FVFSOpen: TVFSOpen;
+ FVFSClose: TVFSClose;
+ FVFSListFirst: TVFSListFirst;
+ FVFSListNext: TVFSListNext;
+ FVFSListClose: TVFSListClose;
+ FVFSChangeDir: TVFSChangeDir;
+ FVFSGetPath: TVFSGetPath;
+ FVFSGetPrefix: TVFSGetPrefix;
+ FVFSGetFileSystemSize: TVFSGetFileSystemSize;
+ FVFSGetFileSystemFree: TVFSGetFileSystemFree;
+ FVFSLogin: TVFSLogin;
+ FVFSFileExists: TVFSFileExists;
+ FVFSFileInfo: TVFSFileInfo;
+ FVFSMkDir: TVFSMkDir;
+ FVFSRemove: TVFSRemove;
+ FVFSRename: TVFSRename;
+ FVFSMakeSymLink: TVFSMakeSymLink;
+ FVFSChmod: TVFSChmod;
+ FVFSChown: TVFSChown;
+ FVFSChangeTimes: TVFSChangeTimes;
+ FVFSGetDirSize: TVFSGetDirSize;
+ FVFSBreakGetDirSize: TVFSBreakGetDirSize;
+ FVFSOpenFile: TVFSOpenFile;
+ FVFSReadFile: TVFSReadFile;
+ FVFSWriteFile: TVFSWriteFile;
+ FVFSCloseFile: TVFSCloseFile;
+ FVFSFileSeek: TVFSFileSeek;
+ FVFSSetBlockSize: TVFSSetBlockSize;
+ FVFSCopyOut: TVFSCopyOut;
+ FVFSCopyIn: TVFSCopyIn;
+ FVFSIsOnSameFS: TVFSIsOnSameFS;
+ FVFSTwoSameFiles: TVFSTwoSameFiles;
+ FVFSGetExts: TVFSGetExts;
+ FVFSGetServices: TVFSGetServices;
+ FVFSSetPassword: TVFSSetPassword;
+ FVFSGetPasswordRequired: TVFSGetPasswordRequired;
+ public
+ ModuleHandle: Pointer;
+ FullPath: string; // module path
+ Extensions, Services: TOpenStringArray; // the list of the extensions plugin can handle
+ constructor Create(PluginHandle: Pointer);
+ destructor Destroy; override;
+ published
+ function VFSVersion: integer;
+ function VFSName: PChar;
+ function VFSDescription: PChar;
+ function VFSAbout: PChar;
+ function VFSCopyright: PChar;
+ end;
+
+
+ TVFSEngine = class(TPanelEngine)
+ private
+ FGlobs: Pointer;
+ FSourcePlugin: TVFSPlugin;
+ FBlockSize: Cardinal;
+ FProgressFunc: TEngineProgressFunc;
+ FSenderThread: Pointer;
+ BreakProcessingKind: integer;
+ FPassword: string;
+ procedure SetFPassword(Value: string);
+ public
+ ArchiveMode: boolean;
+ constructor Create(SourcePlugin: TVFSPlugin);
+ function VFSOpenURI(OpenFile: string): boolean;
+ function VFSOpenEx(OpenFile: string): TVFSResult;
+ function VFSClose: boolean;
+
+ 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 ChangeDir(const NewPath: string; const ShowProgress: boolean = True): 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;
+ procedure BreakProcessing(ProcessingKind: integer); override;
+ function RenameFile(SourceFile, DestFile: string): integer; override;
+ function ChangeTimes(APath: string; mtime, atime: Int64): integer; 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 GetPrefix: string; override;
+ function Login(Username, Password: string): integer; override;
+
+ function GetBlockSize: Cardinal; override;
+ procedure SetBlockSize(Value: Cardinal); 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 IsOnSameFS(const Path1, Path2: string): boolean; override;
+ function TwoSameFiles(const Path1, Path2: string): boolean; override;
+
+ function SetPassword(Password: string): integer;
+ function GetPasswordRequired: boolean;
+ published
+ property Path: string read GetPath write SetPath;
+ property BlockSize: Cardinal read GetBlockSize write SetBlockSize;
+ property Password: string read FPassword write SetFPassword;
+ end;
+
+
+
+procedure DoInitPlugins;
+
+var PluginList: TList;
+
+implementation
+
+uses SysUtils, ModuleLoader, UConfig, ULocale;
+
+
+const ConstGlobalModulePath1 = '/usr/lib/tuxcmd';
+ ConstGlobalModulePath2 = '/usr/local/lib/tuxcmd';
+ ConstLocalModulePath1 = '~/.tuxcmd/plugins';
+ ConstLocalModulePath2 = './plugins';
+ ConstLocalModulePath3 = '../lib/tuxcmd';
+
+ ConstVFSVersionRequired = 2;
+
+var BinaryPath: string;
+
+
+procedure VFSLogFunc(s: PChar); cdecl;
+begin
+ DebugMsg([' ### VFS ###: ', s]);
+end;
+
+(********************************************************************************************************************************)
+constructor TVFSPlugin.Create(PluginHandle: Pointer);
+begin
+ inherited Create;
+ ModuleHandle := PluginHandle;
+
+ // Find the symbols
+ @FVFSAllocNeeded := GetModuleSymbol(ModuleHandle, 'VFSAllocNeeded');
+ @FVFSInit := GetModuleSymbol(ModuleHandle, 'VFSInit');
+ @FVFSDestroy := GetModuleSymbol(ModuleHandle, 'VFSDestroy');
+ @FVFSVersion := GetModuleSymbol(ModuleHandle, 'VFSVersion');
+ @FVFSGetInfo := GetModuleSymbol(ModuleHandle, 'VFSGetInfo');
+ @FVFSOpen := GetModuleSymbol(ModuleHandle, 'VFSOpen');
+ @FVFSClose := GetModuleSymbol(ModuleHandle, 'VFSClose');
+ @FVFSListFirst := GetModuleSymbol(ModuleHandle, 'VFSListFirst');
+ @FVFSListNext := GetModuleSymbol(ModuleHandle, 'VFSListNext');
+ @FVFSListClose := GetModuleSymbol(ModuleHandle, 'VFSListClose');
+ @FVFSGetPath := GetModuleSymbol(ModuleHandle, 'VFSGetPath');
+ @FVFSChangeDir := GetModuleSymbol(ModuleHandle, 'VFSChangeDir');
+ @FVFSGetPrefix := GetModuleSymbol(ModuleHandle, 'VFSGetPrefix');
+ @FVFSGetFileSystemSize := GetModuleSymbol(ModuleHandle, 'VFSGetFileSystemSize');
+ @FVFSGetFileSystemFree := GetModuleSymbol(ModuleHandle, 'VFSGetFileSystemFree');
+ @FVFSLogin := GetModuleSymbol(ModuleHandle, 'VFSLogin');
+ @FVFSFileExists := GetModuleSymbol(ModuleHandle, 'VFSFileExists');
+ @FVFSFileInfo := GetModuleSymbol(ModuleHandle, 'VFSFileInfo');
+ @FVFSMkDir := GetModuleSymbol(ModuleHandle, 'VFSMkDir');
+ @FVFSRemove := GetModuleSymbol(ModuleHandle, 'VFSRemove');
+ @FVFSRename := GetModuleSymbol(ModuleHandle, 'VFSRename');
+ @FVFSMakeSymLink := GetModuleSymbol(ModuleHandle, 'VFSMakeSymLink');
+ @FVFSChmod := GetModuleSymbol(ModuleHandle, 'VFSChmod');
+ @FVFSChown := GetModuleSymbol(ModuleHandle, 'VFSChown');
+ @FVFSChangeTimes := GetModuleSymbol(ModuleHandle, 'VFSChangeTimes');
+ @FVFSGetDirSize := GetModuleSymbol(ModuleHandle, 'VFSGetDirSize');
+ @FVFSBreakGetDirSize := GetModuleSymbol(ModuleHandle, 'VFSBreakGetDirSize');
+ @FVFSCopyOut := GetModuleSymbol(ModuleHandle, 'VFSCopyOut');
+ @FVFSCopyIn := GetModuleSymbol(ModuleHandle, 'VFSCopyIn');
+ @FVFSOpenFile := GetModuleSymbol(ModuleHandle, 'VFSOpenFile');
+ @FVFSReadFile := GetModuleSymbol(ModuleHandle, 'VFSReadFile');
+ @FVFSWriteFile := GetModuleSymbol(ModuleHandle, 'VFSWriteFile');
+ @FVFSCloseFile := GetModuleSymbol(ModuleHandle, 'VFSCloseFile');
+ @FVFSFileSeek := GetModuleSymbol(ModuleHandle, 'VFSFileSeek');
+ @FVFSSetBlockSize := GetModuleSymbol(ModuleHandle, 'VFSSetBlockSize');
+ @FVFSIsOnSameFS := GetModuleSymbol(ModuleHandle, 'VFSIsOnSameFS');
+ @FVFSTwoSameFiles := GetModuleSymbol(ModuleHandle, 'VFSTwoSameFiles');
+ @FVFSGetExts := GetModuleSymbol(ModuleHandle, 'VFSGetExts');
+ @FVFSGetServices := GetModuleSymbol(ModuleHandle, 'VFSGetServices');
+ @FVFSSetPassword := GetModuleSymbol(ModuleHandle, 'VFSSetPassword');
+ @FVFSGetPasswordRequired := GetModuleSymbol(ModuleHandle, 'VFSGetPasswordRequired');
+ // Initialize the extensions list
+ SetLength(Extensions, 0);
+ SetLength(Services, 0);
+ if @FVFSGetExts <> nil then ParseString(FVFSGetExts, ';', Extensions);
+ if @FVFSGetServices <> nil then ParseString(FVFSGetServices, ';', Services);
+end;
+
+destructor TVFSPlugin.Destroy;
+begin
+ if ModuleHandle <> nil then UnloadModule(ModuleHandle);
+ inherited Destroy;
+end;
+
+(********************************************************************************************************************************)
+function TVFSPlugin.VFSVersion: integer;
+begin
+ if @FVFSVersion <> nil then Result := FVFSVersion
+ else Result := -1;
+end;
+
+function TVFSPlugin.VFSName: PChar;
+var Info: TVFSInfo;
+begin
+ if @FVFSGetInfo <> nil then begin
+ Info := FVFSGetInfo;
+ Result := Info.Name;
+ end else Result := nil;
+end;
+
+function TVFSPlugin.VFSDescription: PChar;
+var Info: TVFSInfo;
+begin
+ if @FVFSGetInfo <> nil then begin
+ Info := FVFSGetInfo;
+ Result := Info.Description;
+ end else Result := nil;
+end;
+
+function TVFSPlugin.VFSAbout: PChar;
+var Info: TVFSInfo;
+begin
+ if @FVFSGetInfo <> nil then begin
+ Info := FVFSGetInfo;
+ Result := Info.About;
+ end else Result := nil;
+end;
+
+function TVFSPlugin.VFSCopyright: PChar;
+var Info: TVFSInfo;
+begin
+ if @FVFSGetInfo <> nil then begin
+ Info := FVFSGetInfo;
+ Result := Info.Copyright;
+ end else Result := nil;
+end;
+
+(********************************************************************************************************************************)
+(********************************************************************************************************************************)
+constructor TVFSEngine.Create(SourcePlugin: TVFSPlugin);
+begin
+ inherited Create;
+ FSourcePlugin := SourcePlugin;
+ FBlockSize := 65536;
+ ArchiveMode := False;
+ BreakProcessingKind := 0;
+ if @FSourcePlugin.FVFSAllocNeeded <> nil then begin
+ FGlobs := Libc.malloc(FSourcePlugin.FVFSAllocNeeded);
+ Libc.memset(FGlobs, 0, FSourcePlugin.FVFSAllocNeeded);
+ end else begin
+ FGlobs := Libc.malloc(SizeOf(FGlobs));
+ Libc.memset(FGlobs, 0, SizeOf(FGlobs));
+ end;
+
+{$IFNDEF KYLIX}
+ DebugMsg(['sizeof(TVFSItem) = ', sizeof(TVFSItem)]);
+ DebugMsg(['sizeof(TVFSItem.sFileName) = ', sizeof(TVFSItem.sFileName)]);
+ DebugMsg(['sizeof(TVFSItem.iSize) = ', sizeof(TVFSItem.iSize)]);
+ DebugMsg(['sizeof(TVFSItem.m_time) = ', sizeof(TVFSItem.m_time)]);
+ DebugMsg(['sizeof(TVFSItem.a_time) = ', sizeof(TVFSItem.a_time)]);
+ DebugMsg(['sizeof(TVFSItem.c_time) = ', sizeof(TVFSItem.c_time)]);
+ DebugMsg(['sizeof(TVFSItem.iMode) = ', sizeof(TVFSItem.iMode)]);
+ DebugMsg(['sizeof(TVFSItem.sLinkTo) = ', sizeof(TVFSItem.sLinkTo)]);
+ DebugMsg(['sizeof(TVFSItem.iUID) = ', sizeof(TVFSItem.iUID)]);
+ DebugMsg(['sizeof(TVFSItem.iGID) = ', sizeof(TVFSItem.iGID)]);
+ DebugMsg(['sizeof(TVFSItem.ItemType) = ', sizeof(TVFSItem.ItemType)]);
+{$ENDIF}
+
+ if @FSourcePlugin.FVFSInit <> nil then FSourcePlugin.FVFSInit(FGlobs, @VFSLogFunc);
+ FPassword := '';
+end;
+
+function TVFSEngine.VFSOpenURI(OpenFile: string): boolean;
+begin
+ Result := False;
+ if @FSourcePlugin.FVFSOpen <> nil then Result := FSourcePlugin.FVFSOpen(FGlobs, PChar(OpenFile)) = cVFS_OK;
+end;
+
+function TVFSEngine.VFSOpenEx(OpenFile: string): TVFSResult;
+begin
+ Result := cVFS_OK;
+ if @FSourcePlugin.FVFSOpen <> nil then Result := FSourcePlugin.FVFSOpen(FGlobs, PChar(OpenFile));
+end;
+
+function TVFSEngine.VFSClose: boolean;
+begin
+ Result := False;
+ if @FSourcePlugin.FVFSClose <> nil then Result := FSourcePlugin.FVFSClose(FGlobs) = cVFS_OK;
+end;
+
+destructor TVFSEngine.Destroy;
+begin
+ try
+ if @FSourcePlugin.FVFSDestroy <> nil then FSourcePlugin.FVFSDestroy(FGlobs);
+ libc.free(FGlobs);
+ except
+ on E: Exception do DebugMsg(['*** TVFSEngine.Destroy() -Exception: ', E.Message]);
+ end;
+end;
+
+function TVFSEngine.GetListing(var List: TList; const AddDotFiles: boolean; APath: string): integer;
+var P: PVFSItem;
+ Item: PDataItem;
+ i, Res: integer;
+begin
+ DebugMsg(['^^VFS (II): GetListing begin']);
+ Result := 0;
+ try
+ if @FSourcePlugin.FVFSListFirst = nil then Exit;
+ P := Libc.malloc(SizeOf(TVFSItem));
+ Libc.memset(P, 0, SizeOf(TVFSItem));
+// DebugMsg(['Item = ', Int64(P)]);
+// DebugMsg(['FVFSListFirst']);
+ Res := FSourcePlugin.FVFSListFirst(FGlobs, PChar(APath), P);
+ if Res <> cVFS_OK then begin
+ FSourcePlugin.FVFSListClose(FGlobs);
+ if Res = cVFS_Not_More_Files then Result := 0
+ else Result := Res;
+ Libc.free(P);
+ Exit;
+ end;
+
+ repeat
+// DebugMsg(['begin--']);
+ if AddDotFiles or (not ((Length(P^.sFileName) > 1) and (P^.sFileName[0] = '.') and (P^.sFileName[1] <> '.'))) then begin
+// DebugMsg(['Checkpoint 1']);
+ Item := Libc.malloc(SizeOf(TDataItem));
+ Libc.memset(Item, 0, SizeOf(TDataItem));
+// DebugMsg(['Checkpoint 2']);
+ for i := 0 to Length(Item^.ColumnData) - 1 do Item^.ColumnData[i] := nil;
+// DebugMsg(['Checkpoint 3']);
+ with Item^ do
+ try
+ AName := strdup(P^.sFileName);
+ if P^.sLinkTo <> nil
+ then begin
+ LnkPointTo := strdup(P^.sLinkTo);
+ DebugMsg(['LnkPointTo = ', P^.sLinkTo]);
+ end else LnkPointTo := nil;
+ Mode := P^.iMode;
+// DebugMsg(['Checkpoint 4']);
+ IsDotFile := (Length(AName) > 1) and (AName[0] = '.') and (AName[1] <> '.');
+ IsDir := TVFSItemType(P^.ItemType) = vDirectory;
+ IsLnk := TVFSItemType(P^.ItemType) = vSymlink;
+ IsBlk := TVFSItemType(P^.ItemType) = vBlockdev;
+ IsChr := TVFSItemType(P^.ItemType) = vChardev;
+ IsFIFO := TVFSItemType(P^.ItemType) = vFifo;
+ IsSock := TVFSItemType(P^.ItemType) = vSock;
+// DebugMsg(['Checkpoint 5']);
+ ModifyTime := UnixTimeToTDateTime(P^.m_time);
+// DebugMsg(['Returned datetime: ', Longword(P^.m_time)]);
+// DebugMsg(['Checkpoint 6']);
+ UID := P^.iUID;
+// DebugMsg(['Checkpoint 7']);
+ GID := P^.iGID;
+// DebugMsg(['Checkpoint 8']);
+ UpDir := False;
+// DebugMsg(['Checkpoint 9']);
+ Selected := False;
+// DebugMsg(['Checkpoint 10']);
+ Size := P^.iSize;
+// DebugMsg(['Checkpoint 11']);
+ List.Add(Item);
+// DebugMsg(['Checkpoint 12']);
+ except
+ on E: Exception do
+ DebugMsg(['^^VFS (EE): GetListing: Item-Exception: ', E.Message]);
+ end;
+ end; // of if AddDotFiles
+ Libc.free(P); // Not needed - just zero-erase the memory
+// DebugMsg(['Checkpoint 13']);
+ P := Libc.malloc(SizeOf(TVFSItem));
+ Libc.memset(P, 0, SizeOf(TVFSItem));
+// DebugMsg(['Item = ', Int64(P)]);
+// DebugMsg(['Checkpoint 14']);
+// DebugMsg(['FVFSListNext --begin']);
+ Res := FSourcePlugin.FVFSListNext(FGlobs, PChar(APath), P);
+// DebugMsg(['FVFSListNext --end']);
+// Sleep(500);
+ until (Res <> cVFS_OK) or (BreakProcessingKind = 2);
+ if BreakProcessingKind <> 0 then DebugMsg(['^^VFS (WW): GetListing: stopped by BreakProcessing']);
+
+ Libc.free(P);
+ FSourcePlugin.FVFSListClose(FGlobs);
+ if Res <> cVFS_Not_More_Files then Result := Res;
+ except
+ on E: Exception do
+ DebugMsg(['^^VFS (EE): GetListing: Exception: ', E.Message]);
+ end;
+ BreakProcessingKind := 0;
+ DebugMsg(['^^VFS (II): GetListing end.']);
+end;
+
+function TVFSEngine.GetListing(var List: TList; const AddDotFiles: boolean): integer;
+begin
+ Result := GetListing(List, AddDotFiles, GetPath);
+end;
+
+function TVFSEngine.ExplicitChDir(const NewPath: string): integer;
+begin
+ Result := __chdir(PChar(NewPath));
+ if Result <> 0 then Result := errno;
+end;
+
+function TVFSEngine.GetFileSystemSize: Int64;
+begin
+ Result := GetFileSystemSize(GetPath);
+end;
+
+function TVFSEngine.GetFileSystemSize(const APath: string): Int64;
+begin
+ if @FSourcePlugin.FVFSGetFileSystemSize <> nil
+ then Result := FSourcePlugin.FVFSGetFileSystemSize(FGlobs, PChar(APath))
+ else Result := 0;
+end;
+
+function TVFSEngine.GetFileSystemFree: Int64;
+begin
+ Result := GetFileSystemFree(GetPath);
+end;
+
+function TVFSEngine.GetFileSystemFree(const APath: string): Int64;
+begin
+ if @FSourcePlugin.FVFSGetFileSystemFree <> nil
+ then Result := FSourcePlugin.FVFSGetFileSystemFree(FGlobs, PChar(APath))
+ else Result := 0;
+end;
+
+procedure TVFSEngine.GetFileSystemInfo(const APath: string; var FSSize, FSFree: Int64; var FSName: string);
+begin
+ FSSize := GetFileSystemSize(APath);
+ FSFree := GetFileSystemFree(APath);
+ FSName := 'plugin';
+end;
+
+function TVFSEngine.IsOnROMedium(const FileName: string): boolean;
+begin
+ Result := True;
+end;
+
+function TVFSEngine.FileCanRun(const FileName: string): boolean;
+var Item: PDataItemSL;
+begin
+ Item := GetFileInfoSL(FileName);
+ Result := Assigned(Item) and Item^.IsExecutable;
+ FreeDataItem(Item);
+end;
+
+function TVFSEngine.GetPrefix: string;
+begin
+ if @FSourcePlugin.FVFSGetPrefix <> nil then Result := URIHidePassword(FSourcePlugin.FVFSGetPrefix(FGlobs))
+ else Result := 'VFS';
+end;
+
+function TVFSEngine.GetPath: string;
+begin
+ if @FSourcePlugin.FVFSGetPath <> nil then Result := FSourcePlugin.FVFSGetPath(FGlobs)
+ else Result := '/';
+end;
+
+function TVFSEngine.ChangeDir(const NewPath: string; const ShowProgress: boolean = True): integer;
+begin
+ DebugMsg(['^^VFS (II): ChangeDir begin']);
+ Result := 0;
+ try
+ Result := FSourcePlugin.FVFSChangeDir(FGlobs, PChar(NewPath));
+// Sleep(3000);
+ except
+ on E: Exception do DebugMsg(['^^VFS (EE): ChangeDir: Exception: ', E.Message]);
+ end;
+ DebugMsg(['^^VFS (II): ChangeDir end.']);
+end;
+
+procedure TVFSEngine.SetPath(Value: string);
+begin
+ ChangeDir(Value);
+end;
+
+function TVFSEngine.Login(Username, Password: string): integer;
+begin
+ if @FSourcePlugin.FVFSLogin <> nil then Result := FSourcePlugin.FVFSLogin(FGlobs, PChar(Username), PChar(Password))
+ else Result := cVFS_OK;
+end;
+
+function TVFSEngine.FileExists(const FileName: string; const Use_lstat: boolean = False): Boolean;
+begin
+ if @FSourcePlugin.FVFSFileExists <> nil then Result := FSourcePlugin.FVFSFileExists(FGlobs, PChar(FileName), Use_lstat)
+ else Result := False;
+end;
+
+function TVFSEngine.DirectoryExists(const FileName: string; const Use_lstat: boolean = False): Boolean;
+var P: PVFSItem;
+ Res: integer;
+begin
+ if @FSourcePlugin.FVFSFileExists <> nil then begin
+ Result := FSourcePlugin.FVFSFileExists(FGlobs, PChar(FileName), Use_lstat);
+ if Result and (@FSourcePlugin.FVFSFileInfo <> nil) then begin
+ P := Libc.malloc(SizeOf(TVFSItem));
+ Libc.memset(P, 0, SizeOf(TVFSItem));
+ Res := FSourcePlugin.FVFSFileInfo(FGlobs, PChar(FileName), P);
+ if (Res <> cVFS_OK) or (P = nil) or (TVFSItemType(P^.ItemType) <> vDirectory) then Result := False;
+ Libc.free(P);
+ end;
+ end else Result := False;
+end;
+
+function TVFSEngine.GetFileInfoSL(APath: string): PDataItemSL;
+var P: PVFSItem;
+ Item: PDataItemSL;
+ Res: integer;
+begin
+ Result := nil;
+ if @FSourcePlugin.FVFSFileInfo = nil then Exit;
+ P := Libc.malloc(SizeOf(TVFSItem));
+ Libc.memset(P, 0, SizeOf(TVFSItem));
+
+ Res := FSourcePlugin.FVFSFileInfo(FGlobs, PChar(APath), P);
+ if Res <> cVFS_OK then begin
+ DebugMsg(['*** VFSFileInfo(', APath, ') failed. Code = ', Res]);
+ Exit;
+ end;
+
+ try
+ Item := Libc.malloc(SizeOf(TDataItemSL));
+ Libc.memset(Item, 0, SizeOf(TDataItemSL));
+ with Item^ do begin
+ AName := strdup(P^.sFileName);
+ if P^.sLinkTo <> nil then LnkPointTo := strdup(P^.sLinkTo)
+ else LnkPointTo := nil;
+ ADestination := nil;
+ Stage1 := True;
+ Level := 0;
+ IsDir := TVFSItemType(P^.ItemType) = vDirectory;
+ IsLnk := TVFSItemType(P^.ItemType) = vSymlink;
+ ForceMove := False;
+{***} IsOnRO := True;
+ IsExecutable := P^.iMode and S_IXUSR = S_IXUSR;
+ Mode := P^.iMode;
+ ModifyTime := UnixTimeToTDateTime(P^.m_time);
+ mtime := P^.m_time;
+ atime := P^.a_time;
+ UID := P^.iUID;
+ GID := P^.iGID;
+ Size := P^.iSize;
+ Libc.free(P);
+ end;
+ Result := Item;
+ except
+ on E: Exception do DebugMsg(['*** TVFSEngine.GetFileInfoSL(APath=', APath, ') -Exception: ', E.Message]);
+ end;
+end;
+
+function TVFSEngine.MakeDir(const NewDir: string): integer;
+begin
+ if @FSourcePlugin.FVFSMkDir <> nil then Result := FSourcePlugin.FVFSMkDir(FGlobs, PChar(NewDir))
+ else Result := cVFS_Failed;
+end;
+
+function TVFSEngine.Remove(APath: string): integer;
+begin
+ if @FSourcePlugin.FVFSRemove <> nil then Result := FSourcePlugin.FVFSRemove(FGlobs, PChar(APath))
+ else Result := cVFS_Failed;
+end;
+
+function TVFSEngine.RenameFile(SourceFile, DestFile: string): integer;
+begin
+ if @FSourcePlugin.FVFSRename <> nil then Result := FSourcePlugin.FVFSRename(FGlobs, PChar(SourceFile), PChar(DestFile))
+ else Result := cVFS_Failed;
+end;
+
+procedure TVFSEngine.FillDirFiles(APath: string; List: TList; ALevel: word);
+var Item: PDataItemSL;
+ i, Res: integer;
+ FilesList: TList;
+ LocalList: TStringList;
+ P: PVFSItem;
+
+
+ procedure AddEntry(FPath: string; AddCurrDirStage, AStage1: boolean);
+ begin
+ Item := Libc.malloc(SizeOf(TDataItemSL));
+ Libc.memset(Item, 0, SizeOf(TDataItemSL));
+ with Item^ do begin
+// AName := Libc.malloc(Length(FPath) + 1);
+// Libc.memset(AName, 0, Length(FPath) + 1);
+ AName := strdup(PChar(FPath));
+ if P^.sLinkTo <> nil then LnkPointTo := strdup(P^.sLinkTo)
+ else LnkPointTo := nil;
+ ADestination := nil;
+ Stage1 := AStage1;
+ IsDir := TVFSItemType(P^.ItemType) = vDirectory;
+ IsLnk := TVFSItemType(P^.ItemType) = vSymlink;
+ if IsLnk and AddCurrDirStage then DebugMsg(['*** Assertion failed AddEntry: Item^.IsLnk = True']);
+ ForceMove := False;
+{***} IsOnRO := True;
+ IsExecutable := AddCurrDirStage or (P^.iMode and S_IXUSR = S_IXUSR);
+ Mode := P^.iMode;
+ ModifyTime := UnixTimeToTDateTime(P^.m_time);
+ mtime := P^.m_time;
+ atime := P^.a_time;
+ UID := P^.iUID;
+ GID := P^.iGID;
+ Size := P^.iSize;
+ {$WARNINGS OFF}
+ Level := ALevel + Ord(not AddCurrDirStage);
+ {$WARNINGS ON}
+ end;
+ if AddCurrDirStage then List.Add(Item)
+ else FilesList.Add(Item);
+ end;
+
+begin
+ if not Assigned(List) then Exit;
+ FilesList := TList.Create;
+ LocalList := TStringList.Create;
+ try
+ try
+ P := Libc.malloc(SizeOf(TVFSItem));
+ Libc.memset(P, 0, SizeOf(TVFSItem));
+ Res := FSourcePlugin.FVFSFileInfo(FGlobs, PChar(APath), P);
+ if Res <> cVFS_OK then DebugMsg(['*** FillDirFiles - VFSFileInfo(', APath, ') failed. Code = ', Res]);
+ AddEntry(APath, True, True);
+ Libc.free(P);
+
+ APath := IncludeTrailingPathDelimiter(APath);
+ if @FSourcePlugin.FVFSChangeDir <> nil then Res := FSourcePlugin.FVFSChangeDir(FGlobs, PChar(APath))
+ else Exit;
+ if Res <> 0 then Exit;
+
+ if @FSourcePlugin.FVFSListFirst = nil then Exit;
+ P := Libc.malloc(SizeOf(TVFSItem));
+ Libc.memset(P, 0, SizeOf(TVFSItem));
+ Res := FSourcePlugin.FVFSListFirst(FGlobs, PChar(APath), P);
+ if Res <> cVFS_OK then begin
+ FSourcePlugin.FVFSListClose(FGlobs);
+ Libc.free(P);
+ Exit;
+ end;
+
+ repeat
+ if TVFSItemType(P^.ItemType) = vDirectory
+ then LocalList.Add(APath + String(P^.sFileName))
+ else AddEntry(APath + String(P^.sFileName), False, True);
+ Libc.free(P);
+ P := Libc.malloc(SizeOf(TVFSItem));
+ Libc.memset(P, 0, SizeOf(TVFSItem));
+ Res := FSourcePlugin.FVFSListNext(FGlobs, PChar(GetPath), P);
+ until (Res <> cVFS_OK);
+
+ Libc.free(P);
+ FSourcePlugin.FVFSListClose(FGlobs);
+
+ {$WARNINGS OFF}
+ if LocalList.Count > 0 then
+ for i := 0 to LocalList.Count - 1 do
+ FillDirFiles(LocalList[i], List, ALevel + 1);
+ {$WARNINGS ON}
+
+ if FilesList.Count > 0 then
+ for i := 0 to FilesList.Count - 1 do
+ List.Add(FilesList[i]);
+ except
+ on E: Exception do DebugMsg(['*** TVFSEngine.FillDirFiles(APath=', APath, ', Level=', ALevel, ') -Exception: ', E.Message]);
+ end;
+ finally
+ P := Libc.malloc(SizeOf(TVFSItem));
+ Libc.memset(P, 0, SizeOf(TVFSItem));
+ Res := FSourcePlugin.FVFSFileInfo(FGlobs, PChar(APath), P);
+ if Res <> cVFS_OK then DebugMsg(['*** FillDirFiles - VFSFileInfo(', APath, ') failed. Code = ', Res]);
+ AddEntry(APath, True, False);
+ Libc.free(P);
+
+ LocalList.Free;
+ FilesList.Free;
+ end;
+end;
+
+function TVFSEngine.MakeSymLink(const NewFileName, PointTo: string): integer;
+begin
+ if @FSourcePlugin.FVFSMakeSymLink <> nil then Result := FSourcePlugin.FVFSMakeSymLink(FGlobs, PChar(NewFileName), PChar(PointTo))
+ else Result := cVFS_Failed;
+end;
+
+function TVFSEngine.Chmod(const FileName: string; const Mode: integer): integer;
+begin
+ if @FSourcePlugin.FVFSChmod <> nil then Result := FSourcePlugin.FVFSChmod(FGlobs, PChar(FileName), Mode)
+ else Result := cVFS_Failed;
+end;
+
+function TVFSEngine.Chown(const FileName: string; const UID, GID: integer): integer;
+begin
+ if @FSourcePlugin.FVFSChown <> nil then Result := FSourcePlugin.FVFSChown(FGlobs, PChar(FileName), UID, GID)
+ else Result := cVFS_Failed;
+end;
+
+function TVFSEngine.ChangeTimes(APath: string; mtime, atime: Int64): integer;
+begin
+ if @FSourcePlugin.FVFSChangeTimes <> nil then Result := FSourcePlugin.FVFSChangeTimes(FGlobs, PChar(APath), mtime, atime)
+ else Result := cVFS_Failed;
+end;
+
+function TVFSEngine.GetDirSize(APath: string): Int64;
+begin
+ if @FSourcePlugin.FVFSGetDirSize <> nil then Result := FSourcePlugin.FVFSGetDirSize(FGlobs, PChar(APath))
+ else Result := 0;
+end;
+
+procedure TVFSEngine.BreakProcessing(ProcessingKind: integer);
+begin
+ case ProcessingKind of
+ 1: if @FSourcePlugin.FVFSBreakGetDirSize <> nil then FSourcePlugin.FVFSBreakGetDirSize(FGlobs);
+ end;
+end;
+
+function TVFSEngine.GetBlockSize: Cardinal;
+begin
+ Result := FBlockSize;
+end;
+
+procedure TVFSEngine.SetBlockSize(Value: Cardinal);
+begin
+ if @FSourcePlugin.FVFSSetBlockSize <> nil then FSourcePlugin.FVFSSetBlockSize(FGlobs, Value);
+end;
+
+
+
+(********************************************************************************************************************************)
+function TVFSEngine.IsOnSameFS(const Path1, Path2: string): boolean;
+begin
+ if @FSourcePlugin.FVFSIsOnSameFS <> nil then Result := FSourcePlugin.FVFSIsOnSameFS(FGlobs, PChar(Path1), PChar(Path2))
+ else Result := True;
+end;
+
+function TVFSEngine.OpenFile(const APath: string; Mode: integer; var Error: integer): TEngineFileDes;
+var i: integer;
+begin
+ if @FSourcePlugin.FVFSOpenFile <> nil then begin
+ Result := FSourcePlugin.FVFSOpenFile(FGlobs, PChar(APath), Mode, @i);
+ Error := i;
+ end else Result := nil;
+end;
+
+function TVFSEngine.ReadFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; ABlockSize: integer; var Error: integer): integer;
+var i: integer;
+begin
+ if @FSourcePlugin.FVFSReadFile <> nil then begin
+ Result := FSourcePlugin.FVFSReadFile(FGlobs, FileDescriptor, Buffer, ABlockSize, @i);
+ Error := i;
+ end else Result := -1;
+end;
+
+function TVFSEngine.WriteFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; BytesCount: integer; var Error: integer): integer;
+var i: integer;
+begin
+ if @FSourcePlugin.FVFSWriteFile <> nil then begin
+ Result := FSourcePlugin.FVFSWriteFile(FGlobs, FileDescriptor, Buffer, BytesCount, @i);
+ Error := i;
+ end else Result := -1;
+end;
+
+function TVFSEngine.CloseFile(const FileDescriptor: TEngineFileDes): integer;
+begin
+ if @FSourcePlugin.FVFSCloseFile <> nil then Result := FSourcePlugin.FVFSCloseFile(FGlobs, FileDescriptor)
+ else Result := 0;
+end;
+
+function TVFSEngine.FileSeek(const FileDescriptor: TEngineFileDes; const AbsoluteOffset: Int64; var Error: integer): Int64;
+var i: integer;
+begin
+ if @FSourcePlugin.FVFSFileSeek <> nil then begin
+ Result := FSourcePlugin.FVFSFileSeek(FGlobs, FileDescriptor, AbsoluteOffset, @i);
+ Error := i;
+ end else Result := -1;
+end;
+
+function TVFSEngine.TwoSameFiles(const Path1, Path2: string): boolean;
+begin
+ if @FSourcePlugin.FVFSTwoSameFiles <> nil then Result := FSourcePlugin.FVFSTwoSameFiles(FGlobs, PChar(Path1), PChar(Path2))
+ else Result := False;
+end;
+
+
+
+(********************************************************************************************************************************)
+
+function VFSCopyCallBackFunc(iPos, iMax:Int64; data: Pointer): LongBool; cdecl;
+begin
+// DebugMsg(['VFSCopyCallBackFunc called (iPos = ', iPos, ', iMax = ', iMax, ')']);
+ Result := True;
+ if not Assigned(data) then Exit;
+ if Assigned(TVFSEngine(data).FProgressFunc) then
+ try
+ Result := TVFSEngine(data).FProgressFunc(TVFSEngine(data).FSenderThread, iPos);
+ except
+ on E: Exception do DebugMsg(['*** Exception raised in VFSCopyCallBackFunc(iPos=', iPos, ', iMax=', iMax, ', data=', data, '): (', E.ClassName, '): ', E.Message]);
+ end;
+end;
+
+function TVFSEngine.CopyFileOut(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
+var Res: TVFSResult;
+begin
+ try
+ if @FSourcePlugin.FVFSCopyOut <> nil then begin
+ FSenderThread := Sender;
+ FProgressFunc := ProgressFunc;
+// DebugMsg(['0 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$']);
+// DebugMsg([' Pointer(FGlobs) = 0x', IntToHex(Int64(FGlobs), 16), ', Pointer(@NewVFSCopyCallBackFunc) = 0x', IntToHex(Int64(@NewVFSCopyCallBackFunc), 16), ', Pointer(Self) = 0x', IntToHex(Int64(Self), 16)]);
+ try
+ Res := FSourcePlugin.FVFSCopyOut(FGlobs, PChar(SourceFile), PChar(DestFile), @VFSCopyCallBackFunc, Self, Append);
+ except
+ on E: Exception do begin
+ DebugMsg(['*** Exception raised in TVFSEngine.CopyFileOut(Sender=', QWord(Sender), ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]);
+ Res := cVFS_WriteErr;
+ end;
+ end;
+// DebugMsg(['1 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$']);
+ Result := Res = cVFS_OK;
+ if (Res <> cVFS_OK) and Assigned(ErrorFunc) then
+ case Res of
+ cVFS_ReadErr: Result := ErrorFunc(Sender, 6, 0, SourceFile);
+ cVFS_WriteErr: Result := ErrorFunc(Sender, 7, 0, DestFile);
+ cVFS_mallocFailed: ErrorFunc(Sender, 1, 0, SourceFile);
+ cVFS_Cancelled: Result := False;
+ end;
+ end else Result := False;
+ except
+ on E: Exception do DebugMsg(['*** Exception raised in TVFSEngine.CopyFileOut(Sender=', QWord(Sender), ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]);
+ end;
+end;
+
+function TVFSEngine.CopyFileIn(Sender: Pointer; SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
+var Res: TVFSResult;
+begin
+ try
+ if @FSourcePlugin.FVFSCopyIn <> nil then begin
+ FSenderThread := Sender;
+ FProgressFunc := ProgressFunc;
+ try
+ Res := FSourcePlugin.FVFSCopyIn(FGlobs, PChar(SourceFile), PChar(DestFile), @VFSCopyCallBackFunc, Self, Append);
+ except
+ on E: Exception do begin
+ DebugMsg(['*** Exception raised in TVFSEngine.CopyFileIn(Sender=', QWord(Sender), ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]);
+ Res := cVFS_WriteErr;
+ end;
+ end;
+ Result := Res = cVFS_OK;
+ if (Res <> cVFS_OK) and Assigned(ErrorFunc) then
+ case Res of
+ cVFS_ReadErr: Result := ErrorFunc(Sender, 6, 0, SourceFile);
+ cVFS_WriteErr: Result := ErrorFunc(Sender, 7, 0, DestFile);
+ cVFS_mallocFailed: ErrorFunc(Sender, 1, 0, SourceFile);
+ cVFS_Cancelled: Result := False;
+ end;
+ end else Result := False;
+ except
+ on E: Exception do DebugMsg(['*** Exception raised in TVFSEngine.CopyFileIn(Sender=', QWord(Sender), ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]);
+ end;
+end;
+
+
+(********************************************************************************************************************************)
+(********************************************************************************************************************************)
+function TVFSEngine.SetPassword(Password: string): integer;
+begin
+ if @FSourcePlugin.FVFSSetPassword <> nil then Result := FSourcePlugin.FVFSSetPassword(FGlobs, PChar(Password))
+ else Result := 0;
+ FPassword := Password;
+end;
+
+function TVFSEngine.GetPasswordRequired: boolean;
+begin
+ if @FSourcePlugin.FVFSGetPasswordRequired <> nil then Result := FSourcePlugin.FVFSGetPasswordRequired(FGlobs)
+ else Result := False;
+end;
+
+procedure TVFSEngine.SetFPassword(Value: string);
+begin
+ SetPassword(Value);
+end;
+
+
+(********************************************************************************************************************************)
+(********************************************************************************************************************************)
+function GetBinaryPath: string;
+var i: integer;
+ Buf: array[0..1024] of char;
+begin
+ Result := ParamStr(0); // Fallback
+ try
+ DebugMsg(['Trying to determine binary path...']);
+ DebugMsg(['Fallback path = ', Result]);
+ Buf[0] := #0;
+ FillChar(Buf, 1025, 0);
+ i := readlink(PChar(Format('/proc/%d/exe', [getpid])), @Buf, 1024);
+ if i < 1 then begin
+ DebugMsg(['Something went wrong during readlink: ', string(strerror(errno))]);
+ Exit;
+ end;
+ Buf[i] := #0;
+ Result := string(PChar(@Buf));
+ DebugMsg(['Path to executable = ', Result]);
+ except
+ on E: Exception do DebugMsg(['*** Exception raised in GetBinaryPath: (', E.ClassName, '): ', E.Message]);
+ end;
+end;
+
+
+procedure QueryModules(APath: string);
+var Handle: PDirectoryStream;
+ DirEnt: PDirent64;
+ s: string;
+ PluginItem: TVFSPlugin;
+ ModuleHandler: TModuleHandle;
+ VFSVersionFunc: TVFSVersion;
+ i: integer;
+ Buf: PChar;
+ b: boolean;
+begin
+ if Length(APath) < 1 then Exit;
+ try
+ try
+ APath := ReplaceStr(APath, '~', GetHomePath);
+ DebugMsg(['------------------ Querying modules in ', APath, ' ---']);
+
+ // First change to the program starting directory
+ if APath[1] <> '/' then begin
+ s := ExtractFilePath(BinaryPath);
+ DebugMsg(['----> Changing dir to ', s]);
+ i := __chdir(PChar(s));
+ if i <> 0 then DebugMsg(['Something went wrong during chdir: ', string(strerror(errno))]);
+ s := get_current_dir_name;
+ DebugMsg([' [II] Changed dir to ', s]);
+ end;
+
+ // Change to the required directory
+ s := APath;
+ DebugMsg(['----> Changing dir to ', s]);
+ i := __chdir(PChar(s));
+ if i <> 0 then begin
+ DebugMsg(['Something went wrong during chdir: ', string(strerror(errno))]);
+ Exit;
+ end;
+ s := get_current_dir_name;
+ DebugMsg([' [II] Changed dir to ', s, ', trying to list the files...']);
+
+ // Going to read the directory and search for the files...
+ Handle := opendir(PChar(s));
+ if not Assigned(Handle) then begin
+ DebugMsg(['Something went wrong during opendir: ', string(strerror(errno))]);
+ Exit;
+ end;
+ repeat
+ DirEnt := readdir64(Handle);
+ if Assigned(DirEnt) then begin
+ Buf := PChar(@DirEnt^.d_name[0]);
+ if Assigned(Buf) and (strcmp(Buf, '.') <> 0) and (strcmp(Buf, '..') <> 0) then
+ begin
+ DebugMsg(['$$$ Found ', Buf, ', trying to load...']);
+
+ // Try to find the plugin in the plugin list to prevent multiple plugin loading
+ b := False;
+ if PluginList.Count > 0 then
+ for i := 0 to PluginList.Count - 1 do
+ if CompareStr(TVFSPlugin(PluginList[i]).FullPath, IncludeTrailingPathDelimiter(s) + Buf) = 0 then begin
+ b := True;
+ Break;
+ end;
+
+ ModuleHandler := nil;
+ if b then DebugMsg(['Module ', s, ' is already loaded --> skipping...']) else
+ if not LoadModule(ModuleHandler, IncludeTrailingPathDelimiter(s) + Buf) then DebugMsg([' XXX Error loading module: ', dlerror])
+ else try
+ @VFSVersionFunc := GetModuleSymbol(ModuleHandler, 'VFSVersion');
+ if (@VFSVersionFunc <> nil) and (VFSVersionFunc >= ConstVFSVersionRequired) then begin
+ PluginItem := TVFSPlugin.Create(ModuleHandler);
+ PluginItem.FullPath := IncludeTrailingPathDelimiter(s) + Buf;
+ PluginList.Add(PluginItem);
+ end else DebugMsg([' $XXX: Error getting version info or version mismatch']);
+ except end;
+ end;
+ end;
+ until DirEnt = nil;
+ closedir(Handle);
+ except
+ on E: Exception do DebugMsg(['*** Exception raised in QueryModules(APath = ', APath, '): (', E.ClassName, '): ', E.Message]);
+ end;
+ finally
+ DebugMsg(['------------------ Done querying modules ---------------']);
+ end;
+end;
+
+
+procedure UnloadModules;
+var i: integer;
+begin
+ if Assigned(PluginList) and (PluginList.Count > 0) then
+ for i := PluginList.Count - 1 downto 0 do
+ try
+ UnloadModule(TVFSPlugin(PluginList[i]).ModuleHandle);
+ TVFSPlugin(PluginList[i]).Free;
+ PluginList.Delete(i);
+ except
+ on E: Exception do DebugMsg(['*** Exception raised in UnloadModules(i = ', i, '): (', E.ClassName, '): ', E.Message]);
+ end;
+end;
+
+
+procedure DoInitPlugins;
+begin
+ PluginList := TList.Create;
+ if not ParamDisablePlugins then begin
+ BinaryPath := GetBinaryPath;
+ QueryModules(ConstGlobalModulePath1);
+ QueryModules(ConstGlobalModulePath2);
+ QueryModules(ConstLocalModulePath1);
+ QueryModules(ConstLocalModulePath2);
+ QueryModules(ConstLocalModulePath3);
+ end;
+end;
+
+initialization
+finalization
+ UnloadModules;
+ PluginList.Free;
+end.
diff --git a/vfs/common/vfs_types.h b/vfs/common/vfs_types.h
new file mode 100644
index 0000000..609a78b
--- /dev/null
+++ b/vfs/common/vfs_types.h
@@ -0,0 +1,114 @@
+/* Tux Commander VFS: Virtual File System types and definitions
+ * - prototypes functions and types
+ * draft version 3
+ *
+ * Copyright (C) 2003 Radek Cervinka <radek.cervinka@centrum.cz>
+ * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __VFS_TYPES_H__
+#define __VFS_TYPES_H__
+
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+typedef int TVFSResult;
+
+
+typedef void (* TVFSLogFunc)(char *s);
+typedef int (* TVFSCopyCallBackFunc)(u_int64_t iPos, u_int64_t iMax, void *data);
+typedef void *TVFSFileDes;
+
+static const int cVFSVersion = 3; // current version of the VFS API
+
+// Capabilities
+static const int capVFS_nil = 0;
+static const int capVFS_List = 1 << 0;
+static const int capVFS_CopyOut = 1 << 1;
+static const int capVFS_CopyIn = 1 << 2;
+static const int capVFS_MkDir = 1 << 3;
+static const int capVFS_RmDir = 1 << 4;
+static const int capVFS_Multiple = 1 << 5; // support multiple files = background copy & thread safe
+static const int capVFS_Delete = 1 << 6;
+static const int capVFS_Rename = 1 << 7;
+static const int capVFS_Execute = 1 << 8;
+static const int capVFS_Append = 1 << 9;
+
+// Error codes (TVFSResult)
+enum {
+ cVFS_OK = 0,
+ cVFS_Failed = 1, // also No such file
+ cVFS_Cancelled = 2,
+ cVFS_Not_Supported = 3,
+ cVFS_No_More_Files = 4,
+ cVFS_ReadErr = 5,
+ cVFS_WriteErr = 6, // also Readonly FileSystem
+ cVFS_LoginFailed = 7,
+ cVFS_PermissionDenied = 8,
+ cVFS_NoSpaceLeft = 9,
+ cVFS_mallocFailed = 10,
+ cVFS_BadPassword = 11,
+ cVFS_MissingVolume = 12,
+ cVFS_CorruptedArchive = 13
+};
+
+
+// Open modes
+enum {
+ cVFS_OpenRead,
+ cVFS_OpenWrite,
+ cVFS_OpenAppend
+};
+
+
+// Item Type enum
+enum TVFSItemType {
+ vRegular = 0,
+ vSymlink = 1,
+ vChardev = 2,
+ vBlockdev = 3,
+ vDirectory = 4,
+ vFifo = 5,
+ vSock = 6,
+ vOther = 7
+};
+
+
+struct TVFSItem {
+ char *sFileName;
+ u_int64_t iSize;
+ __time_t m_time; // numbers should be located before the other variables (bug?)
+ __time_t a_time;
+ __time_t c_time;
+ __mode_t iMode;
+ char *sLinkTo;
+ __uid_t iUID;
+ __gid_t iGID;
+ enum TVFSItemType ItemType;
+};
+
+struct TVFSInfo {
+ const char *Name;
+ const char *Description;
+ const char *About;
+ const char *Copyright;
+};
+
+
+#endif /* __VFS_TYPES_H__ */
diff --git a/vfs/null_plugin/COPYING b/vfs/null_plugin/COPYING
new file mode 100644
index 0000000..d511905
--- /dev/null
+++ b/vfs/null_plugin/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/vfs/null_plugin/Makefile b/vfs/null_plugin/Makefile
new file mode 100644
index 0000000..f2c6e7e
--- /dev/null
+++ b/vfs/null_plugin/Makefile
@@ -0,0 +1,22 @@
+# path definitions
+DESTDIR = /usr
+INSTALL=install -c
+INSTALL_DATA = ${INSTALL} -m 644
+LIB_SUFFIX=`if test \`uname -m\` = x86_64; then echo 64; fi`
+
+# compiler options
+CC = gcc
+CFLAGS = -Wall -O2 -g
+
+
+all shared static: null_plugin
+
+null_plugin: null_plugin.c
+ $(CC) -c null_plugin.c -I. -fPIC -I/usr/include $(CFLAGS)
+ $(CC) -shared -Wall -o libnull_plugin.so null_plugin.o
+
+install::
+ $(INSTALL) ./libnull_plugin.so $(DESTDIR)/lib$(LIB_SUFFIX)/tuxcmd/
+
+clean:
+ rm -f *.o libnull_plugin.so
diff --git a/vfs/null_plugin/README b/vfs/null_plugin/README
new file mode 100644
index 0000000..7123ad0
--- /dev/null
+++ b/vfs/null_plugin/README
@@ -0,0 +1,15 @@
+null plugin for Tux Commander
+Plugin API version 2
+
+
+Copyright (c) 2005 Tomas Bzatek <tbzatek@users.sourceforge.net>
+http://tuxcmd.sourceforge.net
+
+
+
+This is the null VFS module for Tux Commander. It is intended as a basic
+skeleton structure for writing new plugins. It contains all functions required
+for successful access to the fake directory structure it creates.
+
+Please see vfs/uVFSprototypes.pas file for a brief documentation of the VFS API
+and description of each function.
diff --git a/vfs/null_plugin/null_plugin.c b/vfs/null_plugin/null_plugin.c
new file mode 100644
index 0000000..0d24765
--- /dev/null
+++ b/vfs/null_plugin/null_plugin.c
@@ -0,0 +1,357 @@
+/* null plugin for Tux Commander
+ * Copyright (C) 2005 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ * Check for updates on tuxcmd.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <time.h>
+#include "vfs_types.h"
+
+
+// Declaration of the global plugin object
+struct TVFSGlobs {
+ TVFSLogFunc log_func;
+ int list_item_id;
+ char *curr_dir;
+};
+
+
+
+// Basic initialization functions
+int VFSAllocNeeded()
+{
+ return sizeof(struct TVFSGlobs);
+}
+
+void VFSInit(struct TVFSGlobs *globs, TVFSLogFunc log_func)
+{
+
+ globs->log_func = log_func;
+ globs->log_func("null plugin: VFSInit");
+ globs->curr_dir = NULL;
+
+}
+
+void VFSDestroy(struct TVFSGlobs *globs)
+{
+
+ globs->log_func("null plugin: VFSDestroy");
+
+}
+
+int VFSVersion()
+{
+ return cVFSVersion;
+}
+
+struct TVFSInfo VFSGetInfo()
+{
+
+ static const struct TVFSInfo info =
+ {
+ "Null plugin",
+ "null testing plugin",
+ "Plugin API version 2",
+ "Copyright © 2007 Tomáš Bžatek"
+ };
+
+ return info;
+}
+
+char *VFSGetPrefix(struct TVFSGlobs *globs)
+{
+ return "null";
+}
+
+TVFSResult VFSOpen(struct TVFSGlobs *globs, char *sName)
+{
+ return cVFS_OK;
+}
+
+TVFSResult VFSClose(struct TVFSGlobs *globs)
+{
+ return cVFS_OK;
+}
+
+char *VFSGetPath(struct TVFSGlobs *globs)
+{
+ return globs->curr_dir;
+}
+
+u_int64_t VFSGetFileSystemFree(struct TVFSGlobs *globs, char *APath)
+{
+ return 0;
+}
+
+u_int64_t VFSGetFileSystemSize(struct TVFSGlobs *globs, char *APath)
+{
+ return 0;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////
+
+TVFSResult VFSChangeDir(struct TVFSGlobs *globs, char *NewPath)
+{
+ if (globs->curr_dir != NULL) free(globs->curr_dir);
+ globs->curr_dir = strdup(NewPath);
+ return cVFS_OK;
+}
+
+int VFSLogin(struct TVFSGlobs *globs, char *user, char *pass)
+{
+ return cVFS_OK;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////
+
+static char *items[] =
+{
+ "This is the first item",
+ "This is the second item",
+ "This is the third item",
+ "This is the fourth item",
+ "This is the fifth item",
+ "This is the sixth item",
+ "This is the seventh item",
+ "This is the eight item",
+ "This is the nineth item",
+ "This is the tenth item",
+ "This is the eleventh item",
+ "This is the twelveth item",
+ "This is the thirteenth item",
+ "This is the fourteenth item",
+ "This is the fifteenth item",
+ "This is the sixteeth item",
+ "This is the seventeenth item",
+ "This is the eighteenth item",
+};
+
+
+TVFSResult VFSListFirst(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item)
+{
+ globs->list_item_id = 0;
+ printf("C Item = %lu \n", (long int)Item);
+
+ Item->sFileName = strdup(items[globs->list_item_id]);
+// Item->iSize = rand();
+ Item->iSize = globs->list_item_id + 1;
+ Item->iMode = S_IRWXO + S_IRWXG + S_IRWXU;
+ Item->sLinkTo = "/tmp";
+ Item->ItemType = vSymlink;
+ Item->iUID = 100;
+ Item->iGID = 1000;
+ Item->m_time = time(NULL) + globs->list_item_id;
+ printf("C sizeof(TVFSItem) = %ld \n", sizeof(struct TVFSItem));
+ printf("C sizeof(Item->sFileName) = %ld \n", sizeof(Item->sFileName));
+ printf("C sizeof(Item->iSize) = %ld \n", sizeof(Item->iSize));
+ printf("C sizeof(Item->m_time) = %ld \n", sizeof(Item->m_time));
+ printf("C sizeof(Item->a_time) = %ld \n", sizeof(Item->a_time));
+ printf("C sizeof(Item->c_time) = %ld \n", sizeof(Item->c_time));
+ printf("C sizeof(Item->iMode) = %ld \n", sizeof(Item->iMode));
+ printf("C sizeof(Item->sLinkTo) = %ld \n", sizeof(Item->sLinkTo));
+ printf("C sizeof(Item->iUID) = %ld \n", sizeof(Item->iUID));
+ printf("C sizeof(Item->iGID) = %ld \n", sizeof(Item->iGID));
+ printf("C sizeof(Item->ItemType) = %ld \n", sizeof(Item->ItemType));
+
+ static struct TVFSItem x;
+ printf("C sizeof(x.sFileName) = %ld \n", sizeof(x.sFileName));
+ printf("C sizeof(x.iSize) = %ld \n", sizeof(x.iSize));
+ printf("C sizeof(x.m_time) = %ld \n", sizeof(x.m_time));
+ printf("C sizeof(x.a_time) = %ld \n", sizeof(x.a_time));
+ printf("C sizeof(x.c_time) = %ld \n", sizeof(x.c_time));
+ printf("C sizeof(x.iMode) = %ld \n", sizeof(x.iMode));
+ printf("C sizeof(x.sLinkTo) = %ld \n", sizeof(x.sLinkTo));
+ printf("C sizeof(x.iUID) = %ld \n", sizeof(x.iUID));
+ printf("C sizeof(x.iGID) = %ld \n", sizeof(x.iGID));
+ printf("C sizeof(x.ItemType) = %ld \n", sizeof(x.ItemType));
+
+ return cVFS_OK;
+}
+
+TVFSResult VFSListNext(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item)
+{
+ globs->list_item_id++;
+ printf("C Item = %lu \n", (long int)Item);
+
+ if (globs->list_item_id >= (sizeof(items) / sizeof(items[0]))) {
+ Item = NULL;
+ return cVFS_No_More_Files;
+ }
+
+ Item->sFileName = strdup(items[globs->list_item_id]);
+
+ Item->iSize = globs->list_item_id + 1;
+ Item->iMode = S_IRWXO + /* S_IRWXG + */ S_IRWXU;
+ Item->sLinkTo = NULL;
+ Item->iUID = 100;
+ Item->iGID = 1000;
+ Item->m_time = time(NULL) + globs->list_item_id;
+
+ if (globs->list_item_id < 4) Item->ItemType = vDirectory;
+ else Item->ItemType = vRegular;
+
+ return cVFS_OK;
+}
+
+TVFSResult VFSListClose(struct TVFSGlobs *globs)
+{
+ return cVFS_OK;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////
+long VFSFileExists(struct TVFSGlobs *globs, const char *FileName, const long Use_lstat)
+{
+ return 0;
+}
+
+TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item)
+{
+ return cVFS_OK;
+}
+
+TVFSResult VFSMkDir(struct TVFSGlobs *globs, const char *sDirName)
+{
+ return cVFS_OK;
+}
+
+TVFSResult VFSRemove(struct TVFSGlobs *globs, const char *APath)
+{
+ return cVFS_OK;
+}
+
+TVFSResult VFSRename(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName)
+{
+ return cVFS_OK;
+}
+
+TVFSResult VFSMakeSymLink(struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo)
+{
+ return cVFS_OK;
+}
+
+TVFSResult VFSChmod(struct TVFSGlobs *globs, const char *FileName, const uint Mode)
+{
+ return cVFS_OK;
+}
+
+TVFSResult VFSChown(struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID)
+{
+ return cVFS_OK;
+}
+
+TVFSResult VFSChangeTimes(struct TVFSGlobs *globs, char *APath, long mtime, long atime)
+{
+ return cVFS_OK;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////
+
+u_int64_t VFSGetDirSize(struct TVFSGlobs *globs, char *APath)
+{
+ return 0;
+}
+
+
+void VFSBreakGetDirSize(struct TVFSGlobs *globs)
+{
+
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////
+
+TVFSFileDes VFSOpenFile(struct TVFSGlobs *globs, const char *APath, int Mode, int *Error)
+{
+ *Error = 0;
+ return (TVFSFileDes)0;
+}
+
+TVFSResult VFSCloseFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor)
+{
+ return cVFS_OK;
+}
+
+u_int64_t VFSFileSeek(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, u_int64_t AbsoluteOffset, int *Error)
+{
+ *Error = 0;
+ return 0;
+}
+
+int VFSReadFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buffer, int ABlockSize, int *Error)
+{
+ *Error = 0;
+ return 0;
+}
+
+int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buffer, int BytesCount, int *Error)
+{
+ *Error = 0;
+ return 0;
+}
+
+void VFSSetBlockSize(struct TVFSGlobs *globs, int Value)
+{
+
+}
+
+int VFSIsOnSameFS(struct TVFSGlobs *globs, const char *Path1, const char *Path2)
+{
+ return 0;
+}
+
+int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path2)
+{
+ return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////
+
+TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, TVFSCopyCallBackFunc pCallBackProgress, void *data, int Append)
+{
+ return cVFS_OK;
+}
+
+TVFSResult VFSCopyIn(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, TVFSCopyCallBackFunc pCallBackProgress, void *data, int Append)
+{
+ return cVFS_OK;
+}
+
+////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
diff --git a/vfs/null_plugin/vfs_types.h b/vfs/null_plugin/vfs_types.h
new file mode 120000
index 0000000..c2235a2
--- /dev/null
+++ b/vfs/null_plugin/vfs_types.h
@@ -0,0 +1 @@
+../common/vfs_types.h \ No newline at end of file
diff --git a/vfs/uVFSprototypes.pas b/vfs/uVFSprototypes.pas
new file mode 100644
index 0000000..7a87aa0
--- /dev/null
+++ b/vfs/uVFSprototypes.pas
@@ -0,0 +1,246 @@
+(*
+ Virtual File System support
+ - prototypes functions and types
+ draft version 24
+
+ used in Seksi commander and Tux Commander
+
+ Copyright (C) 2003 Radek Cervinka <radek.cervinka@centrum.cz>
+ Copyright (C) 2005-2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*)
+
+unit uVFSprototypes;
+
+interface
+
+const
+ cVFSVersion = 3; // current version of the VFS API
+
+ // Capabilities
+ capVFS_nil = 0;
+ capVFS_List = 1;
+ capVFS_CopyOut = 2;
+ capVFS_CopyIn = 4;
+ capVFS_NeedsTemp = 8; // if not set, the seek operation is available
+ capVFS_Multiple = 16; // support multiple files - ?
+ capVFS_Execute = 32;
+ capVFS_Writable = 64;
+ capVFS_NeedsLogin = 128; // Anonymous is login operation too
+
+
+ // Error codes (TVFSResult)
+ cVFS_OK = 0;
+ cVFS_Failed = 1; // also No such file
+ cVFS_Cancelled = 2;
+ cVFS_Not_Supported = 3;
+ cVFS_Not_More_Files = 4; // returned while directory listing
+ cVFS_ReadErr = 5;
+ cVFS_WriteErr = 6; // also ReadOnlyFileSystem
+ cVFS_LoginFailed = 7;
+ cVFS_PermissionDenied = 8;
+ cVFS_NoSpaceLeft = 9;
+ cVFS_mallocFailed = 10;
+ cVFS_BadPassword = 11;
+ cVFS_MissingVolume = 12;
+ cVFS_CorruptedArchive = 13;
+
+
+ // Open modes (for VFSOpenFile function)
+ cVFS_OpenRead = 0;
+ cVFS_OpenWrite = 1;
+ cVFS_OpenAppend = 2;
+
+
+
+type
+ TVFSResult = longint;
+ TVFSGlobs = Pointer;
+ // The plugin can store some data into this object for identify the object instances
+ // It is allocated in the application side with the size returned by VFSAllocNeeded()
+ // Generally, it is required for correct cooperation of thread in the module
+
+ // File descriptor for Open, Read, Write, Close, Seek operations
+ TVFSFileDes = Pointer;
+
+ TVFSItemType = (vRegular=0, vSymlink=1, vChardev=2, vBlockdev=3, vDirectory=4, vFifo=5, vSock=6, vOther=7);
+
+{$IFDEF KYLIX}
+ DWORD = Cardinal;
+// ShortBool = boolean;
+{$ENDIF}
+{$IFNDEF CPU64}
+ ShortBool = boolean;
+{$ENDIF}
+
+ PVFSItem = ^TVFSItem;
+ TVFSItem = packed record
+{$IFNDEF CPU64} // 32-bit platform
+ sFileName: PChar;
+ iSize: Int64;
+ m_time: DWORD;
+ a_time: DWORD;
+ c_time: DWORD;
+ iMode: Integer;
+ sLinkTo: PChar;
+ iUID: Integer;
+ iGID: Integer;
+ ItemType: TVFSItemType;
+{$ELSE} // 64-bit platform
+ sFileName: PChar;
+ iSize: Int64;
+ m_time: QWORD;
+ a_time: QWORD;
+ c_time: QWORD;
+ iMode: Longint;
+ __padding1: array[1..4] of byte;
+ sLinkTo: PChar;
+ iUID: Longint;
+ iGID: Longint;
+ ItemType: Longint;
+ __padding: array[1..4] of byte;
+{$ENDIF}
+ end;
+
+ // This structure contains basic informations about the plugin (Name is used to identify the module in the application)
+ TVFSInfo = packed record
+ Name: PChar;
+ Description: PChar;
+ About: PChar;
+ Copyright: PChar;
+ end;
+
+type
+ // Log function which could plugin call - the application must handle the messages (e.g. write them to the stdout)
+ PVFSLogFunc = ^TVFSLogFunc;
+ TVFSLogFunc = procedure(S: PChar); cdecl;
+
+ TVFSAllocNeeded = function: integer; cdecl;
+ // Returns sizeof internal structure of TVFSGlobs in the plugin - host application will then allocate corresponding amount of memory
+ TVFSInit = procedure (g:TVFSGlobs; LogFunc: PVFSLogFunc); cdecl;
+ // Performs intialization of the plugin and sets the log function for the module (assume allocated memory for TVFSGlobs)
+ TVFSDestroy = procedure (g:TVFSGlobs); cdecl;
+ // Performs cleanup and destroy all objects
+ TVFSVersion = function: integer; cdecl;
+ // Returns API Version; the host application checks for this number and if the returned number is less than a value required by the host application, the module is not loaded
+ // The current version for this API is '3' - please use the constant declared above as return value
+ TVFSGetInfo = function: TVFSInfo; cdecl;
+ // Returns the structure with module info
+ TVFSGetPrefix = function (g:TVFSGlobs): PChar; cdecl;
+ // Returns prefix used in the application to show difference between local and VFS filesystems (e.g. "ftp" or "smb")
+ TVFSGetCharset = function (g:TVFSGlobs): PChar; cdecl;
+ // TODO: Returns charset which the plugin uses
+ TVFSGetExts = function: PChar; cdecl;
+ // Returns the list of filename extensions which the module can handle separated by ';' (without a leading dots)
+ TVFSGetServices = function: PChar; cdecl;
+ // Returns the list of supported remote protocols separated by ';' (without the '://')
+ TVFSCaps = function (const sExt: PChar): Integer; cdecl;
+ // TODO: Returns a bit mask of plugin capabilities
+ TVFSSetProtocolLogFunc = procedure (g:TVFSGlobs; ProtocolLogFunc: TVFSLogFunc); cdecl;
+ // TODO: Sets the protocol log function (unlike module debug log func this is intended only for server messages (FTP mainly))
+ TVFSSetBlockSize = procedure (g:TVFSGlobs; Value: Cardinal); cdecl;
+ // Sets the block size for I/O operations (not all modules supports this)
+
+
+ TVFSOpen = function (g:TVFSGlobs; const sName: PChar): TVFSResult; cdecl;
+ // TODO: Opens the location (file or URI/URL)
+ TVFSLogin = function (g:TVFSGlobs; const User, Pass: PChar): TVFSResult; cdecl;
+ // TODO: Performs login to the server
+ TVFSClose = function (g:TVFSGlobs): TVFSResult; cdecl;
+ // Closes the file or connection to the server
+ TVFSMkDir = function (g:TVFSGlobs; const sDirName: PChar): TVFSResult; cdecl;
+ TVFSRename = function (g:TVFSGlobs; const sSrcName, sDstName: PChar): TVFSResult; cdecl;
+ // Only rename/move in this function, the two files/directories have to be on the same filesystem - otherway it needs to be copied and deleted manually
+ TVFSRemove = function (g:TVFSGlobs; const APath: PChar): TVFSResult; cdecl;
+ // Removes the file/directory (empty only!)
+ TVFSFileExists = function (g:TVFSGlobs; const FileName: PChar; const Use_lstat: LongBool): LongBool; cdecl;
+ // This function checks for existing location; the Use_lstat parameter specifies to not follow the symlinks (default false = follow symlinks)
+ TVFSMakeSymLink = function (g:TVFSGlobs; const NewFileName, PointTo: PChar): TVFSResult; cdecl;
+ TVFSChmod = function (g:TVFSGlobs; const FileName: PChar; const Mode: integer): TVFSResult; cdecl;
+ // The parameter for this function is in classic unix format (glibc) - a bit mask
+ TVFSChown = function (g:TVFSGlobs; const FileName: PChar; const UID, GID: integer): TVFSResult; cdecl;
+ TVFSChangeTimes = function (g:TVFSGlobs; APath: PChar; mtime, atime: Longint): TVFSResult; cdecl;
+ // Changes times for the file/directory - mtime and atime are __time_t parameters (glibc)
+ TVFSChangeDir = function (g:TVFSGlobs; const NewPath: PChar): TVFSResult; cdecl;
+ // Try to change the directory when correct permissions
+ TVFSGetPath = function (g:TVFSGlobs): PChar; cdecl;
+ // Returns the current working path (not all plugins can support this; just return '/' in this case)
+ TVFSGetFileSystemSize = function (g:TVFSGlobs; const APath: PChar): Int64; cdecl;
+ // Gets the size of filesystem; the path is optional, specified to recognize various mounted filesystems in the tree
+ TVFSGetFileSystemFree = function (g:TVFSGlobs; const APath: PChar): Int64; cdecl;
+ TVFSGetFSLabel = function (g:TVFSGlobs; const APath: PChar): PChar; cdecl;
+ // Gets the filesystem label
+ TVFSIsOnSameFS = function (g:TVFSGlobs; const Path1, Path2: PChar): boolean; cdecl;
+ TVFSTwoSameFiles = function (g:TVFSGlobs; const Path1, Path2: PChar): boolean; cdecl;
+ // Checks if the two files are simmilar (used to test the case-insensitive filesystem - or hardlinks)
+ TVFSGetDirSize = function (g:TVFSGlobs; APath: PChar): Int64; cdecl;
+ // Calculates recursively the size of the tree specified under the path APath
+ TVFSBreakGetDirSize = procedure (g:TVFSGlobs); cdecl;
+ // Call this function to break the calculation performed by VFSGetDirSize
+ TVFSRun = function (g:TVFSGlobs; const sName: PChar): TVFSResult; cdecl;
+ // TODO: Runs the command read from inside the archive (typically installing the rpm package)
+
+
+ TVFSCopyCallBackFunc = function (iPos, iMax: Int64; data: Pointer):LongBool; cdecl;
+ // Callback function used during the copy process; return False to break the copy process
+
+ TVFSCopyOut = function (g:TVFSGlobs; const sSrcName, sDstName: PChar; pCallBackProgress: TVFSCopyCallBackFunc; data: Pointer; Append: LongBool): TVFSResult; cdecl;
+ // Performs the copy process from inside of module to the file in the local system
+ // (thus sSrcName is a path from inside of module and sDstName is path in the local filesystem where the file should be copied)
+ // The data pointer is then used to call the callback function in
+ // Note: if you need to transfer a file between two VFS modules, you need to do it manually - either first copy to local FS or use the Open, Read, Write functions of the module (NOTE: both VFS modules have to support these functions)
+
+ TVFSCopyIn = function (g:TVFSGlobs; const sSrcName, sDstName: PChar; pCallBackProgress: TVFSCopyCallBackFunc; data: Pointer; Append: LongBool): TVFSResult; cdecl;
+ // Performs the copy process from the local filesystem into the module
+
+
+ // This is the set of basic functions which can manipulate with the data
+ // There is a TVFSFileDes object which identifies the processed file (filedescriptor)
+ // All these functions needs a pointer to an int variable to store the error code
+ // NOTE: not all modules could support this set of functions due to its design (unable to set a solid block size)
+ TVFSOpenFile = function (g:TVFSGlobs; const APath: PChar; Mode: integer; Error: Pinteger): TVFSFileDes; cdecl;
+ // Opens a file or creates new (the values for the Mode parameter are described above) and returns the assigned filedescriptor
+ TVFSReadFile = function (g:TVFSGlobs; const FileDescriptor: TVFSFileDes; Buffer: Pointer; ABlockSize: integer; Error: Pinteger): integer; cdecl;
+ // Returns number of bytes read; the buffer needs to be allocated by a blocksize (set it by VFSSetBlockSize function)
+ TVFSWriteFile = function (g:TVFSGlobs; const FileDescriptor: TVFSFileDes; Buffer: Pointer; BytesCount: integer; Error: Pinteger): integer; cdecl;
+ // Returns number of bytes written
+ TVFSCloseFile = function (g:TVFSGlobs; const FileDescriptor: TVFSFileDes): TVFSResult; cdecl;
+ TVFSFileSeek = function (g:TVFSGlobs; const FileDescriptor: TVFSFileDes; const AbsoluteOffset: Int64; Error: Pinteger): Int64; cdecl;
+ // Sets the position in the file from the start and returns real current position
+
+
+ // These are the functions used to list the contents of the directory
+ // First call the VFSListFirst function and then repeat call of VFSListNext until it returns NULL.
+ // Then call VFSListClose to make cleanup
+ TVFSListFirst = function (g:TVFSGlobs; const sDir: PChar; VFSItem: PVFSItem): TVFSResult; cdecl;
+ TVFSListNext = function (g:TVFSGlobs; const sDir: PChar; VFSItem: PVFSItem): TVFSResult; cdecl;
+ TVFSListClose = function (g:TVFSGlobs): TVFSResult; cdecl;
+ TVFSFileInfo = function (g:TVFSGlobs; AFileName: PChar; VFSItem: PVFSItem): TVFSResult; cdecl;
+ // Gets a single info item without need to list a whole directory
+
+ TVFSSetPassword = function (g:TVFSGlobs; pass: PChar): TVFSResult; cdecl;
+ TVFSGetPasswordRequired = function (g:TVFSGlobs): LongBool; cdecl;
+
+ /// pridat neco jako set_loglevel ??
+
+//// pridat typ pluginu - jestli archive nebo protocol - prip. jeste pridat ktery protokoly je to schopno handlovat
+
+
+// TODO: some function to check the CRC of the archive - it should need also some progress feedback - the processed file and percentage progress
+
+implementation
+
+end.