]> git.ipfire.org Git - thirdparty/util-linux.git/blob - lib/idcache.c
script: document SIGUSR1
[thirdparty/util-linux.git] / lib / idcache.c
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 */
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
30 struct idcache *new_idcache(void)
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