8: #include <string.h>
9: #include <unistd.h>
10:
11: void usage (int die, char *error) {
12: fprintf(stderr, 'Использование: id [<имя_пользователя>]
') ;
13: if (error) fprintf(stderr, '%s
', error);
14: if (die) exit(die);
15: }
16:
17: void die(char *error) {
18: if (error) fprintf(stderr, '%s
', error);
19: exit(3);
20: }
21:
22: int main(int argc, const char *argv[]) {
23: struct passwd *pw;
24: struct group *gp;
25: int current_user = 0;
26: uid_t id;
27: int i;
28:
29: if (argc > 2)
30: usage(1, NULL);
31:
32: if (argc == 1) {
33: id = getuid();
34: current_user = 1;
35: if (!(pw = getpwuid(id)))
36: usage(1, 'Имя пользователя не существует');
37: } else {
38: if (!(pw = getpwnam(argv[1])))
39: usage(1, 'Имя пользователя не существует');
40: id = pw->pw_uid;
41: }
42:
43: printf('uid=%d(%s)', id, pw->pw_name);
44: if ((gp = getgrgid(pw->pw_gid)))
45: printf(' gid=%d(%s)', pw->pw_gid, gp->gr_name);
46:
47: if (current_user) {
48: gid_t *gid_list;
49: int gid_size;
50:
51: if (getuid() != geteuid()) {
52: id = geteuid();
53: if (!(pw = getpwuid(id)))
54: usage(1, 'Имя пользователя не существует');
55: printf(' euid=%d(%s)', id, pw->pw_name);
56: }
57:
58: if (getgid() != getegid()) {
59: id = getegid();
60: if (!(gp = getgrgid(id)))
61: usage(1, 'Группа не существует');
62: printf(' egid=%d(%s)', id, gp->gr_name);
63: }
64:
65: /* использование интерфейса getgroups для получения текущих групп */
66: gid_size = getgroups(0, NULL);
67: if (gid_size) {
68: gid_list = malloc(gid_size * sizeof(gid_t));
69: getgroups(gid_size, gid_list);
70:
71: for (i = 0; i < gid_size; i++) {
72: if (!(gp = getgrgid(gid_list[i])))
73: die('Группа не существует');
74: printf('%s%d(%s)', (i == 0) ? ' groups=' : ',',
75: gp->gr_gid, gp->gr_name);
76: }
77:
78: free(gid_list);
79: }
80: } else {
81: /* получение списка групп из базы данных групп */
82: i = 0;
83: while ((gp = getgrent())) {
84: char *c = * (gp->gr_mem);
85:
86: while (c && *c) {
87: if (!strncmp(c, pw->pw_name, 16)) {
88: printf('%s%d(%s)',
89: (i++ == 0) ? ' groups=' : ',',
90: gp->gr_gid, gp->gr_name);
91: с = NULL;
92: } else {
93: c++;
94: }
95: }
96: }
97: endgrent();
98: }
99:
100: printf('
');
101: exit(0);
102: }
Код обработки аргументов, который начинается в строке 29, обращается к нескольким важным функциям. При вызове без аргументов командной строки id
производит поиск информации, основанной на том, какую программу запустил пользователь, и сообщает об этом. Описание функции getuid()
можно найти в главе 10; она возвращает идентификатор пользователя процесса,