468x60comp.hardware.ani.


| Содержание | Предисловие | В

Глава 16

    В этой главе:


Доступ к системным базам данных

Получение информации о паролях и группах

Информация о вашем пользовательском имени и идентификаторе, кото-рая имеется в системе UNIX, практически открыта. По сути

name:pa3swd:uid:gid:gcos:dir:shell

Поля определены следующим образом:

name

Регистрационное имя пользователя

passwd

Зашифрованими пароль или что-нибудь простое, если используется теневой файл паролей

uid

Идентификатор пользователя (для пользователя root — 0, для обычных пользователей

gid

Регистрационная группа по умолчанию (группа 0 может быть привиле-гированной, но не обязательно)

gcos

Как правило, содержит полное имя пользователя, за которым через запятую следует и другая информация

dir

Начальний каталог (каталог, в который вы переходите, когда даєте команду cd без аргументов, и в котором хранится большинств

shell

Ваш регистрационный shell, как правило, /bin/sh или Типичные злементы файла паролей выглядят так:

fred:*:123:15:Fred Flintstone,,,:/home/fred:/bin/csh barney:*:125:15:Barney Rubble,,,:/home/barney:/bin/csh

Сейчас в Perl достаточно инструментов для того, чтобы можно было легко выполнить разбор такой строки (например, с помощью функции<

Например, программа getpwnam в Perl становится функцией getpwnam. Ее единственный аргумент

($name, $passwd, $uid, $gid, $quota, $cominent, $gcos, $dir, $shell)

Обратите внимание: здесь несколько больше значений, чем в файле паролей. Обычно в UNIX-системах, по крайней мере в тех, которые мы видели, поле $quota "*", 123, 15, "", "Fred Flintstone,,,", "Fred Flintstone,,,", "/home/gred"," /bin/csh")

посредством любого из следующих вызовов:

getpwuid(123) getpwnam("fred")

Отметим, что в качестве аргумента функция getpwuid принимает иден-тификатор пользователя, a getpwnam —<

При вьгзове в скалярном контексте функции getpwnam и getpwuid таюке имеют возвращаемое значение

$idnum = getpwuid("daemon");

$login °= getpwnam (25);

Возможно, вам захочется получить зти результаты по отдельности, ис-пользуя некоторые из уже знакомых вам операций, проводимых над списками. Один способ начальний каталог Фреда

Как просмотреть весь файл паролей? Для зтого можно бьгло бн поступить, к примеру, так:

for($id = 0; $id <= 10_000; $id++) f @stuff = getpwuid $id;

} ### не рекомендуется!

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

Функции getpwuid и getpwnam можно считать функциями произволь-ного доступа; они извлекают конкретний злемент по его ключу, поз

Программами последовательного доступа к файлу паролей являются функции setpwent, getpwent и endpwent. В совокупности зти три ф

Приведенное описание может сказаться не совсем понятным без приме-ра, позтому дадим его:

setpwent (); # инициализировать просмотр while (@list " getpwent ()) ( # выбрать след

($login,$home) = @list[0,7]; # получить регистрационное имя # и начальний каталог

print "Home directory for $login is $home\n"; # сообщить зто } endpwent(); # все сдела

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

setpwentf); # инициализировать просмотр while (@list = getpwentO) ( # вибрать следующ

($login,$home) = @list[0,7]; # долучить регистрационное имя # и начальний каталог

$home($login} = $home; # сохранить их )

endpwent(); # все сделано Skeys = sort ( $home($a( cmp $home($b) } keys %home;

foreach $login (Skeys) ( # пройти по рассортированньпл именам

print "home of $login is $home($login)\n";

}

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

В общем случае для просмотра небольшого количества значений реко-мендуется использовать программы произвольного доступа (getpwuid и getpwnam).Доступ к файлу /etc/group осуществляется аналогичным образом. После-довательный доступ обеспечивается вызовами функций setgrent, getgrent и endgrent. Вызов

<$name, $passwd, $gid, $members)

Зти четыре значення примерно соответствуют четырем полям файла /etc/group, позтому за подробной информацией обращайтесь к о

* Если у вас узел с большой NIS-картой, то по соображениям производительности такой способ предобработки файла паролей лучше не использовать.

Упаковка и распаковка двоичных данных

Данные о паролях и группах удобно использовать в текстовом виде. Информацию в других системных базах данных более естественно представлять иначе. Например, IP-адрес интерфейса обрабатыв

По зтой причино написанные на Perl сетевые программы, ожидающие или возвращающие IP-адрес, используют четырехбайтовую строку, одному символу которой соответстввует один байт

Функция pack по принципу работы немного похожа на функцию sprintf. Она получает строку, задающую формат, и спи

5buf = packf'CCCC", 140, 186, 65, 25);

Здесь строка формата pack — четыре буквы С. Каждая С соответствует отдельному значенню, взятому из приведенного следом списка (под

Аналогичным образом формат 1 генерирует длинное значение со знаком. На многих машинах зто четырехбайтовое число, хотя зтот формат зависит от конкретной машины. На четырехбай

$buf = packC'l",0х41424344) ;

генерирует четырехсимвольную строку, состоящую из символов abcd или dcba --

$buf = pack("ll", 0х41424344, 0х45464748);

создает восьмибайтовую строку, состоящую из букв abcdefgh или dcbahgfe, Полный перечень различных форматов, используемых для упаковки, приведен в справочной документации (perlfunc(l) или Programming Perl).Допустим, вам дали восьмибайтовую строку abcdefgh и сказали, что она является представлением хранящихся в памяти (один символ

Зто даст нам в переменной $vall нечто вроде 0х41424344, а может быт

Пробельные символы в строке, задающей формат, игнорируются и ис-пользуются лишь для удобочитаемости. Число в зтой строке, как правило, задает повторение предндущей спецификации соответствующее количество раз. Например, сссс можно записа

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

$bu£ ” pack("C*", 140, 186, 65, 25);

Здесь указанные четыре значення полностью обрабатываются одной спецификацией формата. Если бы вам требовались два коротких целых и "максимально возможное количество символов без знака", то можн

$buf = pack("s2 C*", 3141, 5926, 5, 3, 5, 8, 9, 7, 9, 3, 2);

Здесь мы получаем первые два значення как короткие (й генерируем, вероятно, четыре или восемь символов), а остальные девять как

Функция unpack co звездочкой в качестве спецификации может форми-ровать список злементов, длина которых заранее не определена. Например, при распаковке с использованием форм

@values = unpack("С*", "hello, world!\n");

позволяет сформировать список из 14 злементов, по одному для каждого символа строки.

Получение информации о сети

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

Один из параметров, который вам приходится часто определять,— зто IP-адрес, соответствующий сетевому имени (или наоборот). В С вы преоб-разуете сетевое имя в сетевой адрес с помощью программы gethostbyname(3). В Perl функция, преобразующая хост-имя в адрес, имеет то же имя, что и С-программа, и похожие параметры. Выглядит она так:

($name, $aliases, $addrtype, $length, @addrs) = gethostbyname($name);

# основная форма функций gethostbyname

Параметр зтой функций имя хоста, например, slate.bedrock.com, а в

Когда gethostbyname вызывается в скалярном контексте, возвращается только первый адрес.

Если gethostbyname завершается успешно, то переменной $name в качестве значення присваивается каноническое имя

Наиболее полезная часть возвращаемого значення массив @addrs. Каж

($addr) = (gethostbyname("slate.bedrock.com"))[4];

print "Slate's address is ",

join(".",unpack ("C4", $addr)), "\n";

Функция unpack получает четырехбайтовую строку и возвращает четыре числа. Оказывается, они стоят именно в том порядке, который нуж

Упражнение

Ответ см. в приложении А.

1. Напишите программу, которая создает таблицу соответствия идентифи-каторов пользователей и реальних имен из записей файла паролей, а затем с помощью зтой таблицы выводит с



|     Назад     | &n

| Содержание | Предисловие | В



Сайт создан в системе uCoz