(*
    Virtual File System support
     - prototypes functions and types
    draft version 25

    used in Seksi commander and Tux Commander

    Copyright (C) 2003 Radek Cervinka <radek.cervinka@centrum.cz>
    Copyright (C) 2005-2009 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

{$IFDEF FPC}
  {$PACKRECORDS C}
{$ENDIF}

const
      cVFSVersion = 5;    //  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;

      VFS_ASK_PASSWORD_NEED_PASSWORD = 1 shl 0;
      VFS_ASK_PASSWORD_NEED_USERNAME = 1 shl 1;
      VFS_ASK_PASSWORD_NEED_DOMAIN   = 1 shl 2;
      VFS_ASK_PASSWORD_SAVING_SUPPORTED = 1 shl 3;       //  Plugin reports if gnome-keyring is available
      VFS_ASK_PASSWORD_ANONYMOUS_SUPPORTED = 1 shl 4;
      VFS_ASK_PASSWORD_SAVE_INTERNAL = 1 shl 14;         //  Save password into internal Connection Manager
      VFS_ASK_PASSWORD_ARCHIVE_MODE = 1 shl 15;          //  Callback from archive, change the UI a little bit


type
     TVFSResult = longint;
     TVFSGlobs = Pointer;
     //  Plugin private data for each connection/instance

     //  File descriptor for Open, Read, Write, Close, Seek operations
     TVFSFileDes = Pointer;

     TVFSAskPasswordFlags = Longint;

     PVFSPasswordSave = ^TVFSPasswordSave;
     //  Let plugin save the password, usually to gnome-keyring
     TVFSPasswordSave = (VFS_PASSWORD_SAVE_NEVER,
                         VFS_PASSWORD_SAVE_FOR_SESSION,
                         VFS_PASSWORD_SAVE_PERMANENTLY);

     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}


    //* TODO: FName/FDisplayName: napsat presne pravidla pro absolutni/relativni cesty a opravit v modulech i v UVFSCore


     PVFSItem = ^TVFSItem;
     TVFSItem = record
{$IFNDEF CPU64}   //  32-bit platform
       FName: PChar;
       //  FDisplayName - plugins must ensure correct UTF-8 string
       FDisplayName: PChar;
       iSize: Int64;
       //  iPackedSize - set to -1 if plugin doesn't support this feature
       iPackedSize: Int64;
       m_time: DWORD;
       a_time: DWORD;
       c_time: DWORD;
       iMode: Integer;
       sLinkTo: PChar;
       iUID: Integer;
       iGID: Integer;
       ItemType: Integer;
{$ELSE}           //  64-bit platform
       FName: PChar;
       FDisplayName: PChar;
       iSize: Int64;
       iPackedSize: 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
     PVFSInfo = ^TVFSInfo;
     TVFSInfo = record
       ID: PChar;          //  unique identifier, not shown in GUI
       Name: PChar;        //  plugin name, GUI string (UTF-8)
       About: PChar;       //  GUI string (UTF-8)
       Copyright: PChar;   //  GUI string (UTF-8)
     end;

type
    //  Return index of the choice selected or negative number when dialog has been cancelled
    //    cancel_choice: index which represents the cancellation choice. Set to -1 (e.g.) to disable this feature
    PVFSAskQuestionCallback = ^TVFSAskQuestionCallback;
    TVFSAskQuestionCallback = procedure (const AMessage: PChar;
                                         const Choices: PPChar;
                                         choice: PInteger;
                                         cancel_choice: Integer;
                                         user_data: Pointer); cdecl;

    PVFSAskPasswordCallback = ^TVFSAskPasswordCallback;
    //  Remember to allocate passed strings separately (use strdup() when setting reply)
    //  Modules are eligible for keeping passwords during one session; calling callback again means the last password was wrong and user should enter new one
    //  Returns True (1) if succeeded or False (0) if cancelled
    TVFSAskPasswordCallback = function (const AMessage: PChar;
                                        const default_user: PChar;
                                        const default_domain: PChar;
                                        const default_password: PChar;
                                        flags: TVFSAskPasswordFlags;
                                        username: PPChar;
                                        password: PPChar;
                                        anonymous: PInteger;
                                        domain: PPChar;
                                        password_save: PVFSPasswordSave;
                                        user_data: Pointer): LongBool; cdecl;

    //  Return False to break the operation
    PVFSProgressCallback = ^TVFSProgressCallback;
    TVFSProgressCallback = function (position: Int64;
                                     max: Int64;
                                     user_data: Pointer): LongBool; cdecl;

type
    //  Log function for plugin debugging output - host application will print or save these messages
    PVFSLogFunc = ^TVFSLogFunc;
    TVFSLogFunc = procedure(const S: PChar); cdecl;

    TVFSNew = function (LogFunc: PVFSLogFunc): TVFSGlobs; cdecl;
    //  Allocates memory for the globs structure and performs intialization of the plugin
    TVFSFree = procedure (g: TVFSGlobs); cdecl;
    //  Performs cleanup and destroy all objects
    TVFSVersion = function: integer; cdecl;
    //  Returns VFS API Version; must match version hardcoded in the host program, otherwise the module is not loaded
    //  Please use the cVFSVersion constant as a return value
    TVFSGetInfo = function: PVFSInfo; cdecl;
    //  Returns module info struct, tuxcmd will take care of memory deallocation
    TVFSGetArchiveExts = function: PChar; cdecl;
    //  Returns the list of filename extensions which the module can handle separated by ';' (without a leading dots)
    //  Returning NULL or not defining the symbol at all means plugin can't handle archives
    //  tuxcmd will take care of memory deallocation
    TVFSGetNetworkServices = function: PChar; cdecl;
    //  Returns the list of supported remote protocols separated by ';' (without the '://')
    //  Returning NULL or not defining the symbol at all means plugin can't access network services
    //  tuxcmd will take care of memory deallocation
    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)


    TVFSOpenArchive = function (g:TVFSGlobs; const sName: PChar): TVFSResult; cdecl;
    //  Opens specified archive. This will also switch plugin (an instance) into archiving mode
    TVFSOpenURI = function (g:TVFSGlobs; const sURI: PChar): TVFSResult; cdecl;
    //  Opens specified network location. This will also switch plugin (an instance) into networking mode
    //  In case of URI, do not supply password encoded in the string; plugin will automatically spawn the TVFSAskPasswordCallback callback when needed
    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)
    //  tuxcmd will take care of memory deallocation
    TVFSGetPathURI = function (g:TVFSGlobs): PChar; cdecl;
    //  Returns the current working path in the URI form
    //  tuxcmd will take care of memory deallocation
    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, tuxcmd will take care of memory deallocation
    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)

    
    TVFSCopyToLocal = function (g:TVFSGlobs; const sSrcName, sDstName: PChar; 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)

    TVFSCopyFromLocal = function (g:TVFSGlobs; const sSrcName, sDstName: PChar; Append: LongBool): TVFSResult; cdecl;
    //  Performs the copy process from the local filesystem into the module 


    //  Prototype function for packing new files into archive
    TVFSPack = function (g:TVFSGlobs; const sSrcName, sDstName: PChar; CompressionLevel: integer; const Password: PChar): TVFSResult; cdecl;


    //  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;

    //* TODO: napsat presne pravidla pro absolutni/relativni cesty a opravit v modulech i v UVFSCore
    TVFSFileInfo = function (g:TVFSGlobs; AFileName: PChar; VFSItem: PVFSItem): TVFSResult; cdecl;
    //  Gets a single info item without need to list a whole directory

    TVFSGetPasswordRequired = function (g:TVFSGlobs): LongBool; cdecl;


    //  Reset stored session password in the plugin
    TVFSResetPassword = procedure (g: TVFSGlobs); cdecl;



    /// pridat neco jako set_loglevel ??

//// pridat typ pluginu - jestli archive nebo protocol - prip. jeste pridat ktery protokoly je to schopno handlovat



    TVFSSetCallbacks = procedure (g: TVFSGlobs; ask_question_callback: PVFSAskQuestionCallback;
                                                ask_password_callback: PVFSAskPasswordCallback;
                                                progress_func: PVFSProgressCallback;
                                                user_data: Pointer); cdecl;


    
//  TODO: some function to check the CRC of the archive - it should need also some progress feedback - the processed file and percentage progress

//  Prekopat error logging - asi neco na zpusob GError, stringy se budou vracet i z pluginu

implementation

end.
