Perl для системного администрирования

Использование unpackQ



Использование unpackQ

В Perl существует функция unpack(), специально созданная для анализа двоичных данных и структур. Давайте посмотрим, как ее можно использовать для работы с файлами wtmp. Формат wtmp отличается в различных системах Unix. В следующем примере мы будем иметь дело с файлами wtmp из SunOS 4.1.4 и Digital Unix 4.0, поскольку они достаточно просты. Вот как выглядит текстовое представление первых трех записей в файле wtmp из SunOS 4.1.4.

Если вы еще не знакомы со структурой этого файла, подобный «ASCII-дамп» (так он называется) данных выглядит как некий полуслучайный мусор. Как же нам разобраться со структурой этого файла?

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

Все программы операционной системы, читающие и пишущие в файл wtmp, берут определение файла из одного коротенького включаемого файла С, который скорее всего расположен в /usr/include/utmp.h. Интересующая нас часть файла начинается с определения структуры данных С, которая будет использоваться для хранения информации. Если мы поищем struct utmp {, то найдем нужную нам часть. Строки, следующие за struct utmp {, определяют каждое поле этой структуры. Каждая из этих строк сопровождается комментарием в стиле /* се/ .

Чтобы почувствовать, насколько могут отличаться две различные версии wtmp, сравним отрывки из uimp.h для двух операционных систем:

SunOS 4.1.4:

struct utmp {

char ut_line[8]; /* tty name */

cnar ut_name[8]; /* user id «/

char ut__host[16]: /* nost name, if remote •/

long ut_tiine; /'* time on */ }:

Digital Unix 4.0:

slr.ict jT^ip !

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

Давайте построим шаблон по кусочкам, принимая за основу структуру на С из файла utmp.h в SunOS. Многие буквы разрешается использовать в шаблонах и здесь рассказывается именно о них, но вообще-то вы должны обратиться к разделу pack() из руководстваperlfunc за подробными разъяснениями. Создание шаблонов - не всегда простое занятие; периодически компиляторы С дополняют поля структуры для того, чтобы выровнять их по требуемой границе памяти. Команда pstruct, входящая в состав Perl, часто помогает справиться с подобными особенностями.

С нашим форматом данных таких сложностей не возникает. Посмотрите на анализ файла utmp.h (табл. 9.1).



Содержание раздела