]>
Commit | Line | Data |
---|---|---|
8fb94518 KZ |
1 | /* |
2 | * No copyright is claimed. This code is in the public domain; do with | |
3 | * it what you wish. | |
4 | * | |
5 | * Written by Karel Zak <kzak@redhat.com> | |
6 | */ | |
04a5cb58 KZ |
7 | #include <wchar.h> |
8 | #include <pwd.h> | |
9 | #include <grp.h> | |
10 | #include <sys/types.h> | |
11 | ||
12 | #include "c.h" | |
13 | #include "idcache.h" | |
14 | ||
15 | struct identry *get_id(struct idcache *ic, unsigned long int id) | |
16 | { | |
17 | struct identry *ent; | |
18 | ||
19 | if (!ic) | |
20 | return NULL; | |
21 | ||
22 | for (ent = ic->ent; ent; ent = ent->next) { | |
23 | if (ent->id == id) | |
24 | return ent; | |
25 | } | |
26 | ||
27 | return NULL; | |
28 | } | |
29 | ||
a2c8c533 | 30 | struct idcache *new_idcache(void) |
04a5cb58 KZ |
31 | { |
32 | return calloc(1, sizeof(struct idcache)); | |
33 | } | |
34 | ||
35 | void free_idcache(struct idcache *ic) | |
36 | { | |
37 | struct identry *ent = ic->ent; | |
38 | ||
39 | while (ent) { | |
40 | struct identry *next = ent->next; | |
41 | free(ent->name); | |
42 | free(ent); | |
43 | ent = next; | |
44 | } | |
45 | ||
46 | free(ic); | |
47 | } | |
48 | ||
49 | static void add_id(struct idcache *ic, char *name, unsigned long int id) | |
50 | { | |
51 | struct identry *ent, *x; | |
52 | int w = 0; | |
53 | ||
54 | ent = calloc(1, sizeof(struct identry)); | |
55 | if (!ent) | |
56 | return; | |
57 | ent->id = id; | |
58 | ||
59 | if (name) { | |
60 | #ifdef HAVE_WIDECHAR | |
61 | wchar_t wc[LOGIN_NAME_MAX + 1]; | |
62 | ||
63 | if (mbstowcs(wc, name, LOGIN_NAME_MAX) > 0) { | |
64 | wc[LOGIN_NAME_MAX] = '\0'; | |
65 | w = wcswidth(wc, LOGIN_NAME_MAX); | |
66 | } | |
67 | else | |
68 | #endif | |
69 | w = strlen(name); | |
70 | } | |
71 | ||
72 | /* note, we ignore names with non-printable widechars */ | |
73 | if (w > 0) { | |
74 | ent->name = strdup(name); | |
75 | if (!ent->name) { | |
76 | free(ent); | |
77 | return; | |
78 | } | |
79 | } else { | |
80 | if (asprintf(&ent->name, "%lu", id) < 0) { | |
81 | free(ent); | |
82 | return; | |
83 | } | |
84 | } | |
85 | ||
86 | for (x = ic->ent; x && x->next; x = x->next); | |
87 | ||
88 | if (x) | |
89 | x->next = ent; | |
90 | else | |
91 | ic->ent = ent; | |
92 | ||
93 | if (w <= 0) | |
94 | w = ent->name ? strlen(ent->name) : 0; | |
95 | ic->width = ic->width < w ? w : ic->width; | |
96 | return; | |
97 | } | |
98 | ||
99 | void add_uid(struct idcache *cache, unsigned long int id) | |
100 | { | |
101 | struct identry *ent= get_id(cache, id); | |
102 | ||
103 | if (!ent) { | |
104 | struct passwd *pw = getpwuid((uid_t) id); | |
105 | add_id(cache, pw ? pw->pw_name : NULL, id); | |
106 | } | |
107 | } | |
108 | ||
109 | void add_gid(struct idcache *cache, unsigned long int id) | |
110 | { | |
111 | struct identry *ent = get_id(cache, id); | |
112 | ||
113 | if (!ent) { | |
114 | struct group *gr = getgrgid((gid_t) id); | |
115 | add_id(cache, gr ? gr->gr_name : NULL, id); | |
116 | } | |
117 | } | |
118 |