Перейти к содержанию
Fire Monkey от А до Я
  • 0

Владелец файла и права доступа


AES

Вопрос

Народ, как правильно узнать кто владелец файла и права доступа к нему (то что выдает ls - l <filename>).

Пока только на ум приходит парсить вывод команды ls, но это не красивое решение.

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

Получить UID (идентификатор пользователя - владельца) можно с помошью функции stat (Описана в POSIX стандарте : https://pubs.opengroup.org/onlinepubs/9699919799/ ). Далее есть файл /etc/passwd где UID пользователей сопоставлены с их именами.

В Linux документацию на stat можно посмотреть командой man 2 stat (В случае если установлены средства разработки на языках C/C++).

Если не ошибаюсь, она находится в библиотеке libc. Значит задача состоит в том, чтобы загрузить "dll" библиотеку libc ( например /usr/lib64/libc.so.6 ) и вызвать функцию stat. Для загрузки динамических библиотек (разделяемых объектов - shared object - so) используется вызов dlopen.

Альтернативный способ состоит в том, чтобы напрямую (без библиотеки libc ) выполнить системный вызов stat, обратившись непосредственно к ядру ОС. Для этого, нужно, найти документацию на системный вызов stat, и вызвать его самому - вы по сути сами реализуете функционал библиотеки libc.

Второй способ, хоть и кажется сложнее, на самом деле реализуется буквально несколькими assembler'ными инструкциями.

Возможно в Delphi это уже сделали (не исключаю, что в какой-то библиотеке, уже есть функция Stat ).

В RAD Studio, в каталоге source\rtl\posix, есть файл SysStatAPI.inc - он включен в posix.sysstat.pas.

Значит просто: Uses Posix.SysStat и используйте функцию stat.

Изменено пользователем Billy Bones
Ссылка на комментарий
  • 0
В 27.03.2021 в 20:34, Billy Bones сказал:

Значит просто: Uses Posix.SysStat и используйте функцию stat.

Billy Bones

Здравствуйте.

Почему у меня при прописывании  Uses Posix.SysStat RAD Studio 10.3  "ругается" что cannot resolve unit filename Posix.SysStat at line...???? Хотя в библиотеке путь source\rtl\posix прописан.

Ссылка на комментарий
  • 0
В 29.03.2021 в 08:38, Олег Киреев сказал:

Почему у меня при прописывании  Uses Posix.SysStat RAD Studio 10.3  "ругается" что cannot resolve unit filename Posix.SysStat at line...???? Хотя в библиотеке путь source\rtl\posix прописан.

Компилировать самому модуль Posix.SysStat.pas не нужно, т.к. он уже откомпилирован и лежит в:

lib\linux64\debug - отладочная версия

lib\linux64\release - релизная версия

Компилятор его найдет, если путь к модулю указан в Tools | Options | Language | Delphi | Libraries | Library Path.

А он, по умолчанию, там указан: $(BDSLIB)\$(Platform)\release

Проверьте есть ли там откомпилированный модуль и прописан ли путь.

Если модуля нет, то его можно откомпилировать самому - в каталоге source\rtl лежит файл buildrtl.bat -  он собирает все библиотеки rtl. Процедура его использования не очень прозрачная. Где -то, в документации Embarcadero, написано как его правильно запустить.

Суть, состоит в том, что перед его запуском, должны быть, правильно, установлены, некоторые переменные, среды окружения.

Помню, что правил bin\rsvars.bat, и поменял там, все пути в стиле C:\Program Files (x86)\Embarcadero\Studio\21.0\XXXX на C:\RADStudio\XXX.  Где RADStudio получен с помощью mklink /J RADStudio "С:\Program Files (x86)\Embarcadero\Studio\21.0" . Это нужно, т.к. многие утилиты командной строки, например make, не понимают пути с пробелами. Без этого rtl библиотеки не соберутся ! (по крайней мере не собираются c++ rtl, где всё на make построено)

После того, как соберете rtl библиотеки, просто найдите Posix.SysStat.dcu (релизную версию, конечно :)), и положите его в lib\linux64\release.

Если, вдруг, модуль Posix.SysStat.dcu не соберется, то нужно будет искать, куда его нужно прописать, чтобы он собирался.

Ха, Ха, Ха - а rll для Linux не собирается с помощью buildrtl.bat :) - только для Win32, Win64, OSX32.

Значит нужно самому собрать. Создать свой проект, воткнуть туда исходники, прописать пути, если нужно, и откомпилировать. Изучите исходный код Posix.SysStat.pas - туда куча файлов включается includ'ом.

На самом деле, к себе в проект (например консольного приложения), нужно скопиповать эти файлы (сохраняя структуру каталогов):

source\rtl\posix в проекте как posix

    Posix.SysStat.pas

    Posix.SysStatAPI.inc

    Posix.Base.pas

    Posix.SysTypes.pas

source\rtl\posix\linux в проекте как posix\linux

    BaseTypes.inc

    SysStatTypes.inc

    SysTypesTypes.inc

Потом включить Posix.SysStat.pas, Posix.Base.pas, Posix.SysTypes.pas так:

Uses
	Posix.SysStat  in 'posix\Posix.SysStat.pas',
	Posix.Base     in 'posix\Posix.Base.pas',
	Posix.SysTypes in 'posix\Posix.SysTypes.pas';

Добавляем платформу Linux64 и компилируем - Дело в шляпе.

Выкладываем скомпилированный модуль в lib\linux64\release и дальше не паримся.

В RAD Studio 10.4.2 по умолчанию всё на месте. Uses Posix.SysStat прекрасно работает.

Изменено пользователем Billy Bones
Изменен список файлов для сборки модуля - так точнее.
Ссылка на комментарий
  • 0

Файл Posix.SysStat.dcu  у меня лежит в C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\iossimulator\debug. 

Файл  Posix.SysStat.pas у меня лежит в C:\Program Files (x86)\Embarcadero\Studio\20.0\source\rtl\posix.

Оба пути прописаны в библиотеке.

В коде  после implementation прописываю и так:  Uses Posix.SysStat и так  Uses Posix.SysStat in 'posix\Posix.SysStat.pas'; всё равно  "ругается" что cannot resolve unit filename Posix.SysStat at line... Что делать?

С Уважением. Олег.

Ссылка на комментарий
  • 0
6 минут назад, Олег Киреев сказал:

Файл Posix.SysStat.dcu  у меня лежит в C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\iossimulator\debug

Этот не подходит, т.к должен быть файл, конкретно, для платформы Linux: lib\linux64\release\Posix.SysStat.dcu.

В своем прошлом посте, Я, описал процедуру, как самому собрать модуль Posix.SysStat.dcu:

  1. Создать проект консольного приложения.
  2. Скопировать в каталог с проектом файлы (см. список файлов и их расположение в прошлом посте - я его менял добавляя информацию).
  3. Включить в проект файл Posix.SysStat.pas - он сам добавится в uses.
  4. Добавить платформу Linux64 и сделать её активной.
  5. Выбрать кофигурацию Release
  6. Собрать консольное приложение - автоматически будет собран Posix.SysStat.dcu - он лежит в подкаталоге проекта linux64\Release.
  7. Выложить Posix.SysStat.dcu в lib\linux64\release.

Всё.

Ссылка на комментарий
  • 0
В 27.03.2021 в 21:34, Billy Bones сказал:

Альтернативный способ состоит в том, чтобы напрямую (без библиотеки libc ) выполнить системный вызов stat, обратившись непосредственно к ядру ОС.

Коли хвастался, значит нужно показать как это делается:

Пишем такое консольное приложение:

Program ownof;

{$APPTYPE CONSOLE}

{$R *.res}

Type
	kernel_ulong_t = UInt64;
	kernel_long_t  =  Int64;

	TStat  = packed record
		st_dev        : kernel_ulong_t;
		st_ino        : kernel_ulong_t;
		st_nlink      : kernel_ulong_t;
		st_mode       : UInt32;
		st_uid        : UInt32;
		st_gid        : UInt32;
		__pad0        : UInt32;
		st_rdev       : kernel_ulong_t;
		st_size       : kernel_long_t;
		st_blksize    : kernel_long_t;
		st_blocks     : kernel_long_t;
		st_atime      : kernel_ulong_t;
		st_atime_nsec : kernel_ulong_t;
		st_mtime      : kernel_ulong_t;
		st_mtime_nsec : kernel_ulong_t;
		st_ctime      : kernel_ulong_t;
		st_ctime_nsec : kernel_ulong_t;
		__unused      : array[0..2] of kernel_long_t;
	end;

	(*
		Функция mystat реализована на ассемблере. Откомпилирована в Linux и
		объектный файл перенесен в проект.
	*)
	function mystat(path_to_file : PAnsiChar; var S : TStat) : NativeUInt;
		external 'mystat.o'

var
	S : TStat;

Begin
	// Файл a.txt создан руками в том-же каталоге, куда помещается исполняемый
	// модуль данной программы.
	mystat('a.txt', S);

	Writeln('Owner is ', S.st_uid);
End.

Исходный код для mystat.asm:

		.text

#	function mystat(path_to_file : PAnsiChar; var S : TStat) : NativeUInt;
#
#	Параметры:
#		rdi - path_to_file
#		rsi - @S
#
#	Параметры функции помещаются, в те-же регистры, что и требует интерфейс системных
#	вызовов - не делаем ничего лишнего !
#
#	После выхода из режима ядра в регистре rax будет содержаться рузультат работы
#	системного вызова. Наша функция тоже возвращает рузультат в rax - не делаем
#	ничего лишнего !

		.global	mystat
		.align	16
mystat:	
		movq	$4,	%rax	# поместим номер системного вызова в регистр rax
		syscall			# переходим в режим ядра			
		ret

Все данные для написания этой программы получены из исходных кодов ядра Linux 5.11.10.

Данная реализация привязана к нескольким вещам:

  1. К архитектуре процессора (т.к. mystat написана на x86_64 ассемблере )
  2. К ядру Linux (т.е. программа не будет работать на других Unix подобных ОС)
  3. К структуре с которой работает системный вызов sys_newstat (так называется, та процедура в ядре, что выполнает нужные нам действия).
  4. Способу выполнения системных вызовов (сам способ привязан к архитектуре процессора и к ядру ОС)

Пока ничего из этого не поменяется всё будет ОК. И никаких Вам libc.

PS:

  1. Номер системного вызова и его имя взято из файла arch/x86/entry/syscalls/syscall_64.tbl .
  2. Как делать системный вызов написано тут: arch/x86/entry/entry_64.S .
  3. Описание структуры взято из файла arch/x86/include/uapi/asm/stat.h

 

Изменено пользователем Billy Bones
Добавлены ссылки на исходники ядра.
Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...