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