ЗАМЕЧАНИЕ. Указатели, возвращаемые 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++) /* Рассмотреть каждый член */