Kniga-Online.club
» » » » Арнольд Роббинс - Linux программирование в примерах

Арнольд Роббинс - Linux программирование в примерах

Читать бесплатно Арнольд Роббинс - Linux программирование в примерах. Жанр: Программное обеспечение издательство -, год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:

Функция rpl_utime() (строки 75–82) является «заместителем utime()». Если второй аргумент не равен NULL, она вызывает настоящую utime(). В противном случае она вызывает utime_null().

5.5.4. Использование fchown() и fchmod() для обеспечения безопасности

В исходных системах Unix были только системные вызовы chown() и chmod(). Однако, на сильно загруженных системах эти системные вызовы попадают в условия состязания, посредством чего злоумышленник может организовать замещение другим файлом файла, у которого изменяется владелец или права доступа.

Однако, после открытия файла условие состязания больше не представляет проблему. Программа может использовать stat() с именем файла для получения информации о файле. Если получены сведения, которые ожидались, после открытия файла fstat() может проверить, что файл тот же самый (сравнив поля st_dev и st_ino структур struct stat «до» и «после»).

Когда программа знает, что файлы те же самые, владение или права доступа могут быть изменены с помощью fchown() или fchmod().

Эти системные вызовы, также как lchown(), сравнительно недавние;[63] в старых системах Unix их не было, хотя в современных совместимых с POSIX системах они есть.

Соответствующих функций futime() или lutime() нет. В случае futime() это (очевидно) потому, что временные отметки не являются критическими для безопасности системы в том же отношении, что для владения и прав доступа, lutime() отсутствует потому, что временные отметки неуместны для символических ссылок.

5.6. Резюме

• Иерархия файлов и каталогов, как она видится пользователю, является одним логическим деревом, корень которого находится в /. Оно составлено из одного или более разделов, каждый из которых содержит файловую систему. Внутри файловой системы в индексах хранятся данные о файлах (метаданные), включая размещение блоков данных.

• Каталоги осуществляют связь между именами файлов и индексами. Концептуально содержимое каталога, которое является просто последовательностью пар (индекс, имя). Каждый элемент каталога для файла называется (прямой) ссылкой, а файлы могут иметь множество ссылок. Прямые ссылки, поскольку они работают лишь по номеру индекса, все должны находиться в одной файловой системе. Символические ссылки являются указателями на файлы или каталоги и работают на основе имени файла, а не номера индекса, поэтому их использование не ограничено одной и той же файловой системой.

• Прямые ссылки создаются с помощью link(), символические ссылки создаются с помощью symlink(), ссылки удаляются с помощью unlink(), а переименовываются файлы (с возможным перемещением в другой каталог) с помощью rename(). Блоки данных файла не освобождаются до тех пор, пока счетчик ссылок не достигнет нуля и не закроется последний открытый дескриптор файла.

• Каталоги создаются с помощью mkdir(), а удаляются с помощью rmdir(); перед удалением каталог должен быть пустым (не оставлено ничего, кроме '.' и '..'). GNU/Linux версия функции ISO С remove() вызывает соответствующие функции unlink() или rmdir().

• Каталоги обрабатываются с помощью функций opendir(), readdir(), rewinddir() и closedir(). struct dirent содержит номер индекса и имя файла. Максимально переносимый код использует в члене d_name только имя файла. Функции BSD telldir() и seekdir() для сохранения и восстановления текущего положения в каталоге широко доступны, но не полностью переносимы, как другие функции работы с каталогами.

• Вспомогательные данные получаются с помощью семейства системных вызовов stat(), структура struct stat содержит всю информацию о файле за исключением имени файла. (В самом деле, поскольку у файла может быть множество имен или он может совсем не иметь ссылок, невозможно сделать имя доступным.)

• Макрос S_ISxxx() в <sys/stat.h> дает возможность определить тип файла. Функции major() и minor() из <sys/sysmacros.h> дают возможность расшифровки значений dev_t, представляющих блочные и символьные устройства.

• Символические ссылки можно проверить, использовав lstat(), а поле st_size структуры struct stat для символической ссылки возвращает число байтов, необходимых для размещения имени указываемого файла. Содержимое символической ссылки читают с помощью readlink(). Нужно позаботиться о том, чтобы размер буфера был правильным и чтобы завершить полученное имя файла нулевым байтом, чтобы можно было его использовать в качестве строки С.

• Несколько разнообразных системных вызовов обновляют другие данные: семейство chown() используется для смены владельца и группы, процедуры chmod() для прав доступа к файлу, a utime() для изменения значений времени доступа и изменения файла.

Упражнения

1. Напишите программу 'const char *fmt_mode(mode_t mode)'. Ввод представляет собой значение mode_t, полученное из поля st_mode структуры struct stat; т.е. оно содержит как биты прав доступа, так и типа файла.

Вывод должен представлять строку в 10 символов, идентичную первому полю вывода 'ls -l'. Другими словами, первый символ обозначает тип файла, а остальные девять — права доступа.

Когда установлены биты S_ISUID и S_IXUSR, используйте s вместо x; если установлен лишь бит I_ISUID, используйте S. То же относится к битам S_ISGID и S_IXGRP. Если установлены оба бита S_ISVTX и S_IXOTH, используйте t; для одного S_ISVTX используйте T.

Для простоты можете использовать статический (static) буфер, содержимое которого перезаписывается при каждом вызове процедуры.

2. Доработайте ch05-catdir.c, чтобы она вызывала stat() для каждого найденного имени файла. Затем выведите номер индекса, результат вызова fmt_mode(), число ссылок и имя файла.

3. Доработайте ch05-catdir.c так, что если файл является символической ссылкой, программа будет также выводить имя указываемого файла.

4. Добавьте такую опцию, что если имя файла является именем подкаталога, программа рекурсивно входит в него и отображает сведения о файлах (и каталогах) этого подкаталога. Необходим лишь один уровень рекурсии.

5. Если вы не работаете на системе GNU/Linux, запустите ch05-trymkdir (см. раздел 5.2 «Создание и удаление каталогов») на своей системе и сравните результаты с приведенными нами.

6. Напишите программу mkdir. Посмотрите свою локальную справочную страницу для mkdir(1) и реализуйте все ее опции.

7. В корневом каталоге, /, как номер устройства, так и номер индекса для '.' и '..' совпадают. Используя эту информацию, напишите программу pwd.

Вначале программа должна найти имя текущего каталога, прочитав содержимое родительского каталога. Затем она должна продолжить собирать сведения о иерархии файловой системы, пока не достигнет корневого каталога.

Отображение имени каталога в обратном порядке, от текущего каталога до корневого, легко. Как будет справляться ваша версия pwd с выводом имени каталога правильным образом, от корневого каталога вниз?

8. Если вы написали pwd, использовав рекурсию, напишите ее снова, использовав итерацию. Если вы использовали итерацию, напишите ее с использованием рекурсии. Что лучше? (Подсказка: рассмотрите очень глубоко вложенные деревья каталогов.)

9. Тщательно исследуйте функцию rpl_utime() (см. раздел 5.5.3.1 «Подделка utime(file, NULL)»). Какой ресурс не восстанавливается, если одна из проверок в середине if не выполняется? (Спасибо Джеффу Колье (Geoff Collyer).)

10. (Трудное) Прочтите страницу справки для chmod(1). Напишите код для анализа аргумента символических опций, который позволяет добавлять, удалять и устанавливать права доступа на основе владельца, группы, других и «всех».

Когда вы решите, что это работает, напишите свою собственную версию chmod, которая применяет назначенные права доступа к каждому файлу или каталогу, указанному в командной строке. Какую функцию вы использовали, chmod() — или open() и fchmod() — и почему?

Глава 6

Общие библиотечные интерфейсы — часть 1

В главе 5 «Каталоги и служебные данные файлов» мы видели, что непосредственное чтение каталога возвращает имена файлов в том порядке, в каком они хранятся в каталоге. Мы также видели, что struct stat содержит всю информацию о файле за исключением его имени. Однако, некоторые компоненты этой структуры не могут использоваться непосредственно; они являются просто числовыми значениями.

Перейти на страницу:

Арнольд Роббинс читать все книги автора по порядку

Арнольд Роббинс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


Linux программирование в примерах отзывы

Отзывы читателей о книге Linux программирование в примерах, автор: Арнольд Роббинс. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*