Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
методичка ПО ОСРВ заочники.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
8.72 Mб
Скачать

3.6.5. Чего мы достигли?

Мы достигли того, что правильно отображаются такие атрибуты, как ссылки, размер, имя Вывод значения времени модификации представлен в формате time_t. Мы можем исполн зовать ctime, чтобы конвертировать это значение в строку, где будет содержаться месяц,] день, время или год. В поле mode в нашем выводе выводится значение режима в числовой виде, а при работе Is вывод будет символьным:

-rw-rw-r--

Вывод в полях user и group представлен в числовом виде, а в команде Is в этих полях вы­водятся символьные имена собственника и имя группы. Для окончания работы над нашим вариантом по написанию Is -I нам необходимо еще ознакомиться, как конвертировать! числовые значения полей mode, user и group в символьные представления значений.

3.6.6. Преобразование числового значения поля mode в символьное значение

Каким образом представлены разряды, соотнесенные типу файла и правам доступа, в поле I st_mode? Как нам выбрать эти атрибуты и представить их как последовательность из I 10 символов? Какая связь между восьмеричным числом 100664 и строкой rw-rw-r-? Ответ: поле st mode шестнадцатиразрядное. Отдельные атрибуты закодированы в соответствующих подстроках в этом 16-разрядном поле. На рисунке 3.4 показано назначение пяти таких подстрок.

Рисунок 3.4

Представление кодов типа файла и прав доступа

Подстрока из первых четырех разрядов предназначена для представления типа файла. В четырехразрядном поле можно хранить 16 возможных комбинаций из 1 и 0. Каждый из этих двоичных кодов может служить для представления отдельного типа файла. В настоя-1 шее время используется семь типов файлов.

Следующая подстрока из трех разрядов предназначена для хранения специальных атрибутов файла. Каждый разряд в этой подстроке соответствует специальному атрибуту. Если любой разряд установлен в ' 1', то соответствующий ему атрибут установлен. Если разряд установлен в '0', то соответствующий ему атрибут не установлен. Эти специальные атрибуты называются set-user-ID, set-group-ID и sticky bits. Они будут рассмотрены позже. Наконец, далее расположены три последовательности трехразрядных подстрок для представления прав доступа к файлу. Первая подстрока - для хранения прав доступа собственника, вторая подстрока - для хранения прав доступа группы и последняя подстрока – для хранения прав доступа всех остальных пользователей. Для каждого класса пользователей в подстроке из трех разрядов можно задать наличие или отсутствие прав на чтение, запись и исполнение. Значение какого-либо разряда в любой из подстрок, равное “1”, означает, что соответствующий вид доступа разрешен. Значение какого-либо разряда в любой из подстрок, равное '0', означает, что соответствующий вид доступа запрещен.

Секреты кодировки подполей

Весьма распространенным приемом является упаковка специальных значений в подполя больших строк. Эта идея иллюстрируется на таких примерах:

Примеры кодирования подстрок

617-495-4204

Область, коммутатор, линия

027-93-1111

Личный социальный номер

128.103.33.100

IP - адрес

Как читать подполя: Маскирование

Как можно определить - принадлежит ли телефонный номер 212-333-4444 кодовой облас ти212? Очень просто. Вы берете три первых числа из номера и сравниваете их подстрокой 212. Другой подход будет заключаться в том, что вы обнуляете все цифры в телефонном номере, кроме первых трех, и затем сравниваете результат с 212-000-0000.

Техника обнуления указанных подполей называется маскированием. Подход напоминает о маске на лице, которая все скрывает, за исключением ваших глаз и, возможно, ушей и рта. Мы можем использовать набор масок для преобразования значения поля st_mode в символьную строку, которая выводится стандартной командой Is -I.

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

Первый момент: Концепция маскирования

Маскирование значения - это обнуление установленных значений разрядов в числе при | условии, что остальные разряды остаются неизменяемыми.

Второй момент: Целое число - это битовая строка

Целые числа хранятся в компьютере как последовательность двоичных разрядов. На рисунке 3.5 показано, как десятичное значение числа 215 выражается как последовательность единиц и нулей, используя двоичную нотацию (основание 2) Каково будет деся­тичное значение, которое соответствует двоичному значению 00011010?

Рисунок 3.5 Преобразования десятичного представления в двоичное

Третий момент: Техника маскирования

Операция поразрядного "И"(т. е. &) дает возможность маскировать одно значение с по­мощью другого значения. На рисунке 3.6 показано восьмеричное значение 100664 (осно­вание 8), которое маскируется кодом, составленным пользователем. Отметьте, как неко­торые единичные разряды в исходном числе будут преобразованы в 0 с помощью определенных разрядов маски.

Рисунок 3.6

Использование двоичной маски

Четвертый момент: Использование восьмеричного основания

Использование масок в двоичном формате является достаточно утомительным, особенно! для слов длиной в 16 или 32 разряда. Поэтому произведем группировку больших десятичных чисел в трехсимвольные "связки" (например, 23,234,456,022) для более простого прочтения значения числа, а также сгруппируем двоичные представления больших чисел в трехсимвольные "'связки" и преобразуем каждую "связку" в одно восьмеричное число (значение от 0 до 7).

Например, мы можем произвести группировку по связкам в двоичном числе 1000000110110100 и получить такое представление: 1,000,000,110,110,100. После чего пре­образуем каждую связку и получим такое представление числа: 0100664, которое легче воспринимается.

Использование маскирования для декодирования значения типа файла

Тип файла кодируется в первом четырехразрядном поле mode. Для декодирования ин­формации в этом поле мы можем использовать маскирование. Прежде всего, мы исполь­зуем маску для обнуления всех разрядов, кроме первых четырех разрядов. Затем сравним полученный результат с кодами для каждого из типов:

Определения этих кодов находятся в заголовочном файле <sys/stat.h>:

#define

SIFMT 0170000

/* тип файла 7

#define

SJFREG 0100000

Г обычный */

#define

SJFDIR 0040000

Г каталог */

«define

SIFBLK 0060000

/* специальный блочный */

«define

S IFCHR 0020000

/*специальный символьный */

«define

S.IFIFO 0010000

Г программный канал fifo */

«define

SIFLNK 0120000

/* символическая ссылка */

«define

SIFSOCK 0140000

/* сокет */

Символьная константа S_IFMT - это маска, с помощью которой выбираются первые че­тыре разряда. Значением маски является число 0170000. Убедитесь в том, что эта маска вы­бирает правильный набор разрядов с помощью обратного преобразования каждого вось­меричного представления цифры в трехразрядный двоичный эквивалент. Код типа для обычного файла (SJFREG) равен 0100000. Значение кода типа для каталога равно 0040000.

Например, во фрагменте кода:

if ((info.st.mode & 0170000) ==0040000)

printf("this is a directory.");

будет проводиться проверка на тип каталога, что делается с помощью маскирования всех полей, кроме поля типа, и последующего сравнении результата с кодом типа каталога.

Если вы пожелаете написать код для маскирования и проверки, вы можете использовать при этом макросы из заголовочного файла <sys/stat.h>:

/*

* Макросы для типов файла

*/

#define

S ISHFO(m) (((m)&(0170000)) == (0010000))

«define

S ISDIR(m) (((m)&(0170000)) == (0040000))

«define

SJSCHR(m) (((m)&(0170000)) == (0020000))

#define

SJSBLK(m) (((m)&(0170000)) == (0060000))

«define

SJSREG(m) (((m)&(0170000)) == (0100000))

С помощью этих макросов можно так написать наш код:

if(SJSDIR(info.st_mode))

printf("this is a directory.");

Использование маскирования для декодирования разрядов прав доступа

Последние девять разрядов в mode предназначены для представления прав доступа на вы­полнение операций чтения, записи и исполнения с файлом для каждого класса пользова­телей. В стандартной версии команды Is производится преобразование этих девяти дво­ичных разрядов, каждый из которых установлен в 1 или 0, в строку, которая состоит из по­следовательности символов и прочерков.

Назначение каждого разряда маски можно посмотреть в файле <sys/stat.h>. Следующая программа представляет собой простое, читабельное приложение, которое проверяет отдельно каждый разряд:

/*

* В этой функции извлекается значение mode и формируется символьный массив.

* В символьный массив помещается значение типа файла и

* девять символов для представления прав доступа.

* ЗАМЕЧАНИЕ: Коды setuid, setgid sticky

* не рассматриваются

*/

void mode to_letters(int mode, char str[])

{

strcpy(str,"-......—");

/* по умолчанию - отсутствие всех прав */

if(SJSDIR(mode))str[0] = 'd';

/* каталог */

if(SJSCHR(mode))sir[0] = 'c';

/* символьные устройства */

if(SISBLK(mode))str[0] = 'b';

/* блочное устройство */

if(mode&SJRUSR)str[1] = 'r';

/* 3 разряда для собственника */

if(mode&S_IWUSR)str[2] = 'w';

if(mode&SJXUSR)str[3] = Y;

if(mode&SIRGRP)str[4] = 'r';

/* 3 разряда для группы */

if(mode&SJWGRP)str[5] = 'w,;

if(mode&SJXGRP)str[6] = Y;

if (mode & SJROTH) str[7] = V;

/* 3 разряда для всех остальных */

if (mode& S.IWOTH) str[8] ='w'.-if (mode & S IXOTH) str[9] = V; }

if (mode& S.IWOTH) str[8] ='w';

if (mode & S IXOTH) str[9] = V;

}

Декодирование разрядов и написание версии Is

У нас накопилось достаточно знаний для написания версии команды Is, которая может правильно работать с длинным форматом вывода. Мы можем правильно выводить значе­ния таких атрибутов файла, как размер, ссылки и имя файла. Мы имеем возможность взять значение поля mode и преобразовать его значение в стандартную последовательность из символов и прочерков. Можно преобразовать с помощью ctime значение времени из формата time_t в строковый формат. А каковы соображения по строчному представлению имен собственника и группы?