ЗАМЕЧАНИЕ. Указатели, возвращаемые getpwent()
, getpwnam()
и getpwuid()
, все указывают на внутренние static
данные. Поэтому следует сделать копию их содержимого, если нужно сохранить сведения.
Хорошенько рассмотрите определение struct passwd
. Члены, представляющие символьные строки, являются указателями, они также указывают на внутренние static
данные, и если вы собираетесь скопировать структуру, не забудьте также скопировать и данные, на которые указывает каждый член структуры.
6.3.2. База данных групп
Формат базы данных групп /etc/group
подобен формату /etc/passwd
, но с меньшим числом полей.
$ grep arnold /etc/group
mail:x:12:mail,postfix,arnold
uucp:x:14:uucp,arnold
floppy:x:19:arnold
devel:x:42:miriam,arnold
arnold:x:2076:arnold
Опять-таки на одну группу отводится одна строка, с полями, разделенными двоеточием. Поля следующие.
Это имя группы, как оно отображается в 'ls -l
' или в любом другом контексте, когда требуется имя группы.
Историческое поле. Оно больше не используется.
Как и для ID пользователя, должен быть уникальным для каждой группы.
Разделенный запятыми список пользователей, являющихся членами группы.
В предыдущем примере мы видели, что пользователь arnold
является членом нескольких групп. Это членство на практике отражается в том, что называют
API базы данных групп сходна с API для базы данных пользователей. Следующие функции определены в
:
#include
#include
struct group *getgrent(void);
void setgrent(void);
void endgrent(void);
struct group *getgrnam(const char *name);
struct group *getgrgid(gid_t gid);
struct group соответствует записям в /etc/group:
struct group {
char *gr_name; /* имя группы */
char *gr_passwd; /* пароль группы */
gid_t gr_gid; /* id группы */
char **gr_mem; /* члены группы */
};
Поле gr_mem
требует некоторого объяснения. Хотя оно объявлено в виде указателя на указатель (char**
), лучше представить его как массив строк (наподобие argv
). Последний элемент в массиве устанавливается в NULL
. Когда в списке нет членов, первый элемент массива равен NULL
.
ch06-groupinfo.с
демонстрирует, как использовать struct group
и поле gr_mem
. Программа принимает в командной строке имя единственного пользователя и печатает все записи групп, в которых появляется этот пользователь:
1 /* ch06-groupinfo.с --- Демонстрация getgrent() и struct group */
2
3 #include
4 #include
5 #include
6
7 extern void print_group(const struct group *gr);
8
9 /* main --- вывести строки групп для пользователя в argv[1] */
10
11 int
12 main(int argc, char **argv)
13 {
14 struct group *gr;
15 int i;
16
17 if (argc != 2) { /* Проверка аргументов */
18 fprintf(stderr, "usage: %s user\n", argv[0]);
19 exit(1);
20 }
21
22 while ((gr = getgrent()) != NULL) /* Получить запись каждой группы: */
23 for (i = 0; gr->gr_mem[i] != NULL; i++) /* Рассмотреть каждый член */