]> git.ipfire.org Git - thirdparty/util-linux.git/blame - lib/idcache.c
all_errnos/all_syscalls: fail if any step fails
[thirdparty/util-linux.git] / lib / idcache.c
CommitLineData
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
15struct 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 30struct idcache *new_idcache(void)
04a5cb58
KZ
31{
32 return calloc(1, sizeof(struct idcache));
33}
34
35void 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
54static 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
106void 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
116void 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