]>
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 | { | |
bcb40a76 TW |
37 | struct identry *ent; |
38 | ||
39 | if (!ic) | |
40 | return; | |
41 | ||
42 | ent = ic->ent; | |
04a5cb58 KZ |
43 | |
44 | while (ent) { | |
45 | struct identry *next = ent->next; | |
46 | free(ent->name); | |
47 | free(ent); | |
48 | ent = next; | |
49 | } | |
50 | ||
51 | free(ic); | |
52 | } | |
53 | ||
54 | static void add_id(struct idcache *ic, char *name, unsigned long int id) | |
55 | { | |
56 | struct identry *ent, *x; | |
57 | int w = 0; | |
58 | ||
bcb40a76 TW |
59 | if (!ic) |
60 | return; | |
61 | ||
04a5cb58 KZ |
62 | ent = calloc(1, sizeof(struct identry)); |
63 | if (!ent) | |
64 | return; | |
65 | ent->id = id; | |
66 | ||
67 | if (name) { | |
68 | #ifdef HAVE_WIDECHAR | |
69 | wchar_t wc[LOGIN_NAME_MAX + 1]; | |
70 | ||
71 | if (mbstowcs(wc, name, LOGIN_NAME_MAX) > 0) { | |
72 | wc[LOGIN_NAME_MAX] = '\0'; | |
73 | w = wcswidth(wc, LOGIN_NAME_MAX); | |
74 | } | |
75 | else | |
76 | #endif | |
77 | w = strlen(name); | |
78 | } | |
79 | ||
80 | /* note, we ignore names with non-printable widechars */ | |
81 | if (w > 0) { | |
82 | ent->name = strdup(name); | |
83 | if (!ent->name) { | |
84 | free(ent); | |
85 | return; | |
86 | } | |
87 | } else { | |
88 | if (asprintf(&ent->name, "%lu", id) < 0) { | |
89 | free(ent); | |
90 | return; | |
91 | } | |
92 | } | |
93 | ||
94 | for (x = ic->ent; x && x->next; x = x->next); | |
95 | ||
96 | if (x) | |
97 | x->next = ent; | |
98 | else | |
99 | ic->ent = ent; | |
100 | ||
101 | if (w <= 0) | |
102 | w = ent->name ? strlen(ent->name) : 0; | |
103 | ic->width = ic->width < w ? w : ic->width; | |
04a5cb58 KZ |
104 | } |
105 | ||
106 | void add_uid(struct idcache *cache, unsigned long int id) | |
107 | { | |
a938f9f0 | 108 | struct identry *ent = get_id(cache, id); |
04a5cb58 KZ |
109 | |
110 | if (!ent) { | |
111 | struct passwd *pw = getpwuid((uid_t) id); | |
112 | add_id(cache, pw ? pw->pw_name : NULL, id); | |
113 | } | |
114 | } | |
115 | ||
116 | void add_gid(struct idcache *cache, unsigned long int id) | |
117 | { | |
118 | struct identry *ent = get_id(cache, id); | |
119 | ||
120 | if (!ent) { | |
121 | struct group *gr = getgrgid((gid_t) id); | |
122 | add_id(cache, gr ? gr->gr_name : NULL, id); | |
123 | } | |
124 | } | |
125 |