328 lines
9.7 KiB
ObjectPascal
328 lines
9.7 KiB
ObjectPascal
{
|
|
Double Commander
|
|
-------------------------------------------------------------------------
|
|
Functions handling file attributes.
|
|
|
|
Copyright (C) 2012 Przemysław Nagay (cobines@gmail.com)
|
|
|
|
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 DCFileAttributes;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, DCBasicTypes;
|
|
|
|
const
|
|
// Windows attributes
|
|
FILE_ATTRIBUTE_READONLY = $0001;
|
|
FILE_ATTRIBUTE_HIDDEN = $0002;
|
|
FILE_ATTRIBUTE_SYSTEM = $0004;
|
|
FILE_ATTRIBUTE_DIRECTORY = $0010;
|
|
FILE_ATTRIBUTE_ARCHIVE = $0020;
|
|
FILE_ATTRIBUTE_NORMAL = $0080;
|
|
FILE_ATTRIBUTE_TEMPORARY = $0100;
|
|
FILE_ATTRIBUTE_SPARSE_FILE = $0200;
|
|
FILE_ATTRIBUTE_REPARSE_POINT = $0400;
|
|
FILE_ATTRIBUTE_COMPRESSED = $0800;
|
|
FILE_ATTRIBUTE_OFFLINE = $1000;
|
|
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = $2000;
|
|
FILE_ATTRIBUTE_ENCRYPTED = $4000;
|
|
FILE_ATTRIBUTE_VIRTUAL = $20000;
|
|
|
|
// Unix attributes
|
|
{ attributes mask }
|
|
S_IFMT = $F000;
|
|
{ first-in/first-out (FIFO/pipe) }
|
|
S_IFIFO = $1000;
|
|
{ character-special file (tty/console) }
|
|
S_IFCHR = $2000;
|
|
{ directory }
|
|
S_IFDIR = $4000;
|
|
{ blocking device (unused) }
|
|
S_IFBLK = $6000;
|
|
{ regular }
|
|
S_IFREG = $8000;
|
|
{ symbolic link (unused) }
|
|
S_IFLNK = $A000;
|
|
{ Berkeley socket }
|
|
S_IFSOCK = $C000;
|
|
|
|
{ mode_t possible values }
|
|
S_IRUSR = %0100000000; { Read permission for owner }
|
|
S_IWUSR = %0010000000; { Write permission for owner }
|
|
S_IXUSR = %0001000000; { Exec permission for owner }
|
|
S_IRGRP = %0000100000; { Read permission for group }
|
|
S_IWGRP = %0000010000; { Write permission for group }
|
|
S_IXGRP = %0000001000; { Exec permission for group }
|
|
S_IROTH = %0000000100; { Read permission for world }
|
|
S_IWOTH = %0000000010; { Write permission for world }
|
|
S_IXOTH = %0000000001; { Exec permission for world }
|
|
S_IRWXU = S_IRUSR or S_IWUSR or S_IXUSR;
|
|
S_IRWXG = S_IRGRP or S_IWGRP or S_IXGRP;
|
|
S_IRWXO = S_IROTH or S_IWOTH or S_IXOTH;
|
|
|
|
{ POSIX setuid(), setgid(), and sticky bit }
|
|
S_ISUID = $0800;
|
|
S_ISGID = $0400;
|
|
S_ISVTX = $0200;
|
|
|
|
function WinToUnixFileAttr(Attr: TFileAttrs): TFileAttrs;
|
|
function UnixToWinFileAttr(Attr: TFileAttrs): TFileAttrs;
|
|
function UnixToWinFileAttr(const FileName: String; Attr: TFileAttrs): TFileAttrs;
|
|
|
|
function SingleStrToFileAttr(sAttr: String): TFileAttrs;
|
|
function WinSingleStrToFileAttr(sAttr: String): TFileAttrs;
|
|
function UnixSingleStrToFileAttr(sAttr: String): TFileAttrs;
|
|
|
|
{en
|
|
Convert file attributes from string to number
|
|
@param(Attributes File attributes as string)
|
|
@returns(File attributes as number)
|
|
}
|
|
function StrToFileAttr(sAttr: String): TFileAttrs;
|
|
{en
|
|
Convert file attributes to string in the format of "attr1+attr2+attr3+".
|
|
@param(Attributes File attributes)
|
|
@returns(File attributes as string)
|
|
}
|
|
function FileAttrToStr(Attr: TFileAttrs): String;
|
|
{en
|
|
Convert Windows file attributes from string to number
|
|
@param(Attributes File attributes as string)
|
|
@returns(File attributes as number)
|
|
}
|
|
function WinStrToFileAttr(sAttr: String): TFileAttrs;
|
|
{en
|
|
Convert Unix file attributes from string to number
|
|
@param(Attributes File attributes as string)
|
|
@returns(File attributes as number)
|
|
}
|
|
function UnixStrToFileAttr(sAttr: String): TFileAttrs;
|
|
|
|
implementation
|
|
|
|
uses
|
|
DCStrUtils;
|
|
|
|
type
|
|
TAttrStrToFileAttr = record
|
|
Str: String;
|
|
Attr: TFileAttrs;
|
|
end;
|
|
|
|
const
|
|
WinAttrStrToFileAttr: array[0..9] of TAttrStrToFileAttr = (
|
|
(Str: 'r'; Attr: FILE_ATTRIBUTE_READONLY),
|
|
(Str: 'h'; Attr: FILE_ATTRIBUTE_HIDDEN),
|
|
(Str: 's'; Attr: FILE_ATTRIBUTE_SYSTEM),
|
|
(Str: 'd'; Attr: FILE_ATTRIBUTE_DIRECTORY),
|
|
(Str: 'a'; Attr: FILE_ATTRIBUTE_ARCHIVE),
|
|
(Str: 't'; Attr: FILE_ATTRIBUTE_TEMPORARY),
|
|
(Str: 'p'; Attr: FILE_ATTRIBUTE_SPARSE_FILE),
|
|
(Str: 'l'; Attr: FILE_ATTRIBUTE_REPARSE_POINT),
|
|
(Str: 'c'; Attr: FILE_ATTRIBUTE_COMPRESSED),
|
|
(Str: 'e'; Attr: FILE_ATTRIBUTE_ENCRYPTED));
|
|
|
|
UnixAttrStrToFileAttr: array[0..18] of TAttrStrToFileAttr = (
|
|
// Permissions
|
|
(Str: 'ur'; Attr: S_IRUSR),
|
|
(Str: 'uw'; Attr: S_IWUSR),
|
|
(Str: 'ux'; Attr: S_IXUSR),
|
|
(Str: 'gr'; Attr: S_IRGRP),
|
|
(Str: 'gw'; Attr: S_IWGRP),
|
|
(Str: 'gx'; Attr: S_IXGRP),
|
|
(Str: 'or'; Attr: S_IROTH),
|
|
(Str: 'ow'; Attr: S_IWOTH),
|
|
(Str: 'ox'; Attr: S_IXOTH),
|
|
(Str: 'us'; Attr: S_ISUID),
|
|
(Str: 'gs'; Attr: S_ISGID),
|
|
(Str: 'sb'; Attr: S_ISVTX),
|
|
// File types
|
|
(Str: 'f'; Attr: S_IFIFO),
|
|
(Str: 'c'; Attr: S_IFCHR),
|
|
(Str: 'd'; Attr: S_IFDIR),
|
|
(Str: 'b'; Attr: S_IFBLK),
|
|
(Str: 'r'; Attr: S_IFREG),
|
|
(Str: 'l'; Attr: S_IFLNK),
|
|
(Str: 's'; Attr: S_IFSOCK));
|
|
|
|
function WinToUnixFileAttr(Attr: TFileAttrs): TFileAttrs;
|
|
begin
|
|
Result := S_IRUSR or S_IRGRP or S_IROTH;
|
|
|
|
if (Attr and faReadOnly) = 0 then
|
|
Result := Result or S_IWUSR;
|
|
|
|
if (Attr and faDirectory) <> 0 then
|
|
Result := Result or S_IFDIR
|
|
else
|
|
Result := Result or S_IFREG;
|
|
end;
|
|
|
|
function UnixToWinFileAttr(Attr: TFileAttrs): TFileAttrs;
|
|
begin
|
|
Result := 0;
|
|
case (Attr and S_IFMT) of
|
|
0, S_IFREG:
|
|
Result := faArchive;
|
|
|
|
S_IFLNK:
|
|
Result := Result or faSymLink;
|
|
|
|
S_IFDIR:
|
|
Result := Result or faDirectory;
|
|
|
|
S_IFIFO, S_IFCHR, S_IFBLK, S_IFSOCK:
|
|
Result := Result or faSysFile;
|
|
end;
|
|
|
|
if (Attr and S_IWUSR) = 0 then
|
|
Result := Result or faReadOnly;
|
|
end;
|
|
|
|
function UnixToWinFileAttr(const FileName: String; Attr: TFileAttrs): TFileAttrs;
|
|
begin
|
|
Result := UnixToWinFileAttr(Attr);
|
|
if (Length(FileName) > 1) and (FileName[1] = '.') and (FileName[2] <> '.') then
|
|
Result := Result or faHidden;
|
|
end;
|
|
|
|
function SingleStrToFileAttr(sAttr: String): TFileAttrs;
|
|
begin
|
|
{$IF DEFINED(MSWINDOWS)}
|
|
Result := WinSingleStrToFileAttr(sAttr);
|
|
{$ELSEIF DEFINED(UNIX)}
|
|
Result := UnixSingleStrToFileAttr(sAttr);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function WinSingleStrToFileAttr(sAttr: String): TFileAttrs;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
for i := Low(WinAttrStrToFileAttr) to High(WinAttrStrToFileAttr) do
|
|
begin
|
|
if sAttr = WinAttrStrToFileAttr[i].Str then
|
|
Exit(WinAttrStrToFileAttr[i].Attr);
|
|
end;
|
|
Result := 0;
|
|
end;
|
|
|
|
function UnixSingleStrToFileAttr(sAttr: String): TFileAttrs;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if Length(sAttr) > 0 then
|
|
begin
|
|
if sAttr[1] in ['0'..'7'] then
|
|
begin
|
|
// Octal representation.
|
|
Exit(TFileAttrs(OctToDec(sAttr)));
|
|
end
|
|
else
|
|
begin
|
|
for i := Low(UnixAttrStrToFileAttr) to High(UnixAttrStrToFileAttr) do
|
|
begin
|
|
if sAttr = UnixAttrStrToFileAttr[i].Str then
|
|
Exit(UnixAttrStrToFileAttr[i].Attr);
|
|
end;
|
|
end;
|
|
end;
|
|
Result := 0;
|
|
end;
|
|
|
|
function StrToFileAttr(sAttr: String): TFileAttrs; inline;
|
|
begin
|
|
{$IF DEFINED(MSWINDOWS)}
|
|
Result := WinStrToFileAttr(sAttr);
|
|
{$ELSEIF DEFINED(UNIX)}
|
|
Result := UnixStrToFileAttr(sAttr);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function FileAttrToStr(Attr: TFileAttrs): String;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := '';
|
|
{$IF DEFINED(MSWINDOWS)}
|
|
for i := Low(WinAttrStrToFileAttr) to High(WinAttrStrToFileAttr) do
|
|
begin
|
|
if Attr and WinAttrStrToFileAttr[i].Attr <> 0 then
|
|
Result := Result + WinAttrStrToFileAttr[i].Str + '+';
|
|
end;
|
|
{$ELSEIF DEFINED(UNIX)}
|
|
for i := Low(UnixAttrStrToFileAttr) to High(UnixAttrStrToFileAttr) do
|
|
begin
|
|
if Attr and UnixAttrStrToFileAttr[i].Attr <> 0 then
|
|
Result := Result + UnixAttrStrToFileAttr[i].Str + '+';
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function WinStrToFileAttr(sAttr: String): TFileAttrs;
|
|
var
|
|
I: LongInt;
|
|
begin
|
|
Result:= 0;
|
|
sAttr:= LowerCase(sAttr);
|
|
|
|
for I:= 1 to Length(sAttr) do
|
|
case sAttr[I] of
|
|
'd': Result := Result or FILE_ATTRIBUTE_DIRECTORY;
|
|
'l': Result := Result or FILE_ATTRIBUTE_REPARSE_POINT;
|
|
'r': Result := Result or FILE_ATTRIBUTE_READONLY;
|
|
'a': Result := Result or FILE_ATTRIBUTE_ARCHIVE;
|
|
'h': Result := Result or FILE_ATTRIBUTE_HIDDEN;
|
|
's': Result := Result or FILE_ATTRIBUTE_SYSTEM;
|
|
end;
|
|
end;
|
|
|
|
function UnixStrToFileAttr(sAttr: String): TFileAttrs;
|
|
begin
|
|
Result:= 0;
|
|
if Length(sAttr) < 10 then Exit;
|
|
sAttr:= LowerCase(sAttr);
|
|
|
|
if sAttr[1]='d' then Result:= Result or S_IFDIR;
|
|
if sAttr[1]='l' then Result:= Result or S_IFLNK;
|
|
if sAttr[1]='s' then Result:= Result or S_IFSOCK;
|
|
if sAttr[1]='f' then Result:= Result or S_IFIFO;
|
|
if sAttr[1]='b' then Result:= Result or S_IFBLK;
|
|
if sAttr[1]='c' then Result:= Result or S_IFCHR;
|
|
|
|
|
|
if sAttr[2]='r' then Result:= Result or S_IRUSR;
|
|
if sAttr[3]='w' then Result:= Result or S_IWUSR;
|
|
if sAttr[4]='x' then Result:= Result or S_IXUSR;
|
|
if sAttr[5]='r' then Result:= Result or S_IRGRP;
|
|
if sAttr[6]='w' then Result:= Result or S_IWGRP;
|
|
if sAttr[7]='x' then Result:= Result or S_IXGRP;
|
|
if sAttr[8]='r' then Result:= Result or S_IROTH;
|
|
if sAttr[9]='w' then Result:= Result or S_IWOTH;
|
|
if sAttr[10]='x' then Result:= Result or S_IXOTH;
|
|
|
|
if sAttr[4]='s' then Result:= Result or S_ISUID;
|
|
if sAttr[7]='s' then Result:= Result or S_ISGID;
|
|
end;
|
|
|
|
end.
|
|
|