| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- {
- Double Commander
- -------------------------------------------------------------------------
- This unit contains Haiku specific functions
- Copyright (C) 2022 Alexander Koblov ([email protected])
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- }
- unit DCHaiku;
- {$mode objfpc}{$H+}
- {$packrecords c}
- interface
- uses
- Classes, SysUtils, BaseUnix, Unix;
- // fcntl.h
- const
- O_NOTRAVERSE = $2000;
- // TypeConstants.h
- const
- B_STRING_TYPE = $43535452; // 'CSTR'
- // fs_attr.h
- type
- attr_info = record
- type_: cuint32;
- size: coff_t;
- end;
- Tattr_info = attr_info;
- Pattr_info = ^attr_info;
- function fs_remove_attr(fd: cint; attribute: PAnsiChar): cint; cdecl; external clib;
- function fs_stat_attr(fd: cint; attribute: pansichar; attrInfo: Pattr_info): cint; cdecl; external clib;
- function fs_open_attr(path: pansichar; attribute: pansichar;
- type_: cuint32; openMode: cint): cint; cdecl; external clib;
- function fs_fopen_attr(fd: cint; attribute: pansichar;
- type_: cuint32; openMode: cint): cint; cdecl; external clib;
- function fs_close_attr(fd: cint): cint; cdecl; external clib;
- function fs_open_attr_dir(path: pansichar): pDir; cdecl; external clib;
- function fs_lopen_attr_dir(path: pansichar): pDir; cdecl; external clib;
- function fs_fopen_attr_dir(fd: cint): pDir; cdecl; external clib;
- function fs_close_attr_dir(dir: pDir): cint; cdecl; external clib;
- function fs_read_attr_dir(dir: pDir): pDirent; cdecl; external clib;
- // OS.h
- const
- B_OS_NAME_LENGTH = 32;
- // StorageDefs.h
- const
- B_FILE_NAME_LENGTH = 256;
- // fs_info.h
- const
- B_FS_IS_READONLY = $00000001;
- B_FS_IS_REMOVABLE = $00000002;
- B_FS_IS_PERSISTENT = $00000004;
- B_FS_IS_SHARED = $00000008;
- type
- Tfs_info = record
- dev: dev_t;
- root: ino_t;
- flags: cuint32;
- block_size: coff_t;
- io_size: coff_t;
- total_blocks: coff_t;
- free_blocks: coff_t;
- total_nodes: coff_t;
- free_nodes: coff_t;
- device_name: array[0..127] of AnsiChar;
- volume_name: array[0..Pred(B_FILE_NAME_LENGTH)] of AnsiChar;
- fsh_name: array[0..Pred(B_OS_NAME_LENGTH)] of AnsiChar;
- end;
- Pfs_info = ^Tfs_info;
- function dev_for_path(path: PAnsiChar): dev_t; cdecl; external clib;
- function next_dev(pos: pcint32): dev_t; cdecl; external clib;
- function fs_stat_dev(dev: dev_t; info: Pfs_info): cint; cdecl; external clib;
- // FindDirectory.h
- const
- B_TRASH_DIRECTORY = 1;
- B_USER_DIRECTORY = 3000;
- B_USER_SETTINGS_DIRECTORY = 3006;
- B_USER_DATA_DIRECTORY = 3012;
- B_USER_CACHE_DIRECTORY = 3013;
- function find_directory(which: cuint32; volume: dev_t; createIt: cbool;
- pathString: PAnsiChar; length: cint32): status_t; cdecl; external clib;
- function mbFileCopyXattr(const Source, Target: String): Boolean;
- function mbFileWriteXattr(const FileName, AttrName, Value: String): Boolean;
- function mbFindDirectory(which: cuint32; volume: dev_t; createIt: cbool; out pathString: String): Boolean;
- implementation
- uses
- DCUnix, DCConvertEncoding;
- function mbFileOpen(const FileName: String; Flags: cInt): THandle;
- begin
- repeat
- Result:= fpOpen(FileName, Flags or O_CLOEXEC);
- until (Result <> -1) or (fpgeterrno <> ESysEINTR);
- end;
- function mbFileGetXattr(hFile: THandle): TStringArray;
- var
- DirPtr: pDir;
- PtrDirEnt: pDirent;
- Index: Integer = 0;
- begin
- Result:= Default(TStringArray);
- DirPtr:= fs_fopen_attr_dir(hFile);
- if Assigned(DirPtr) then
- try
- SetLength(Result, 512);
- PtrDirEnt:= fs_read_attr_dir(DirPtr);
- while PtrDirEnt <> nil do
- begin
- Result[Index]:= StrPas(PtrDirEnt^.d_name);
- Inc(Index);
- if (Index > High(Result)) then
- begin
- SetLength(Result, Length(Result) * 2);
- end;
- PtrDirEnt:= fs_read_attr_dir(DirPtr);
- end;
- finally
- fs_close_attr_dir(DirPtr);
- end;
- SetLength(Result, Index);
- end;
- function mbFileWriteXattr(const FileName, AttrName, Value: String): Boolean;
- var
- hAttr: cint;
- ALen: Integer;
- hTarget: THandle;
- begin
- hTarget:= mbFileOpen(FileName, O_RDWR or O_NOTRAVERSE);
- Result:= (hTarget <> feInvalidHandle);
- if Result then
- begin
- hAttr:= fs_fopen_attr(hTarget, PAnsiChar(AttrName),
- B_STRING_TYPE, O_CREAT or O_TRUNC or O_WRONLY);
- Result:= (hAttr <> feInvalidHandle);
- if Result then
- begin
- ALen:= Length(Value) + 1;
- Result:= (FileWrite(hAttr, PAnsiChar(Value)^, ALen) = ALen);
- fs_close_attr(hAttr);
- end;
- FileClose(hTarget);
- end;
- end;
- function mbFileCopyXattr(const Source, Target: String): Boolean;
- var
- AData: TBytes;
- Index: Integer;
- Names: TStringArray;
- AttrName: PAnsiChar;
- AttrInfo: Tattr_info;
- hSource, hTarget: THandle;
- function ReadAttr(hFile: cint; attribute: pansichar): Boolean;
- var
- hAttr: THandle;
- begin
- hAttr:= fs_fopen_attr(hFile, attribute, attrInfo.type_, O_RDONLY);
- Result:= (hAttr <> feInvalidHandle);
- if Result then
- begin
- Result:= (FileRead(hAttr, AData[0], attrInfo.size) = attrInfo.size);
- fs_close_attr(hAttr);
- end;
- end;
- function WriteAttr(hFile: cint; attribute: pansichar): Boolean;
- var
- hAttr: THandle;
- begin
- hAttr:= fs_fopen_attr(hFile, attribute, attrInfo.type_, O_CREAT or O_WRONLY);
- Result:= (hAttr <> feInvalidHandle);
- if Result then
- begin
- Result:= (FileWrite(hAttr, AData[0], attrInfo.size) = attrInfo.size);
- fs_close_attr(hAttr);
- end;
- end;
- begin
- hSource:= mbFileOpen(Source, O_RDONLY or O_NOTRAVERSE);
- Result:= (hSource <> feInvalidHandle);
- if Result then
- begin
- hTarget:= mbFileOpen(Target, O_RDWR or O_NOTRAVERSE);
- Result:= (hTarget <> feInvalidHandle);
- if Result then
- begin
- // Remove attributes from target
- Names:= mbFileGetXattr(hTarget);
- for Index:= 0 to High(Names) do
- begin
- fs_remove_attr(hTarget, PAnsiChar(Names[Index]));
- end;
- SetLength(AData, $FFFF);
- Names:= mbFileGetXattr(hSource);
- for Index:= 0 to High(Names) do
- begin
- AttrName:= PAnsiChar(Names[Index]);
- if (fs_stat_attr(hSource, AttrName, @AttrInfo) >= 0) then
- begin
- if (AttrInfo.size > Length(AData)) then
- begin
- SetLength(AData, AttrInfo.size);
- end;
- Result:= ReadAttr(hSource, AttrName);
- if Result then
- begin
- Result:= WriteAttr(hTarget, AttrName);
- if not Result then Break;
- end;
- end;
- end;
- FileClose(hTarget);
- end;
- FileClose(hSource);
- end;
- end;
- function mbFindDirectory(which: cuint32; volume: dev_t; createIt: cbool; out
- pathString: String): Boolean;
- var
- APath: array[0..MAX_PATH] of AnsiChar;
- begin
- Result:= find_directory(which, volume, createIt, APath, MAX_PATH) >= 0;
- if Result then begin
- pathString:= CeSysToUtf8(APath);
- end;
- end;
- end.
|