2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2016 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Written by Kern Sibbald, July 2007 to replace idcache.c
22 * Program to convert uid and gid into names, and cache the results
23 * for preformance reasons.
30 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
43 guid_list *new_guid_list()
47 list = (guid_list *)malloc(sizeof(guid_list));
48 list->uid_list = New(dlist(item, &item->link));
49 list->gid_list = New(dlist(item, &item->link));
53 void free_guid_list(guid_list *list)
56 foreach_dlist(item, list->uid_list) {
59 foreach_dlist(item, list->gid_list) {
62 delete list->uid_list;
63 delete list->gid_list;
67 static int uid_compare(void *item1, void *item2)
69 guitem *i1 = (guitem *)item1;
70 guitem *i2 = (guitem *)item2;
71 if (i1->uid < i2->uid) {
73 } else if (i1->uid > i2->uid) {
80 static int gid_compare(void *item1, void *item2)
82 guitem *i1 = (guitem *)item1;
83 guitem *i2 = (guitem *)item2;
84 if (i1->gid < i2->gid) {
86 } else if (i1->gid > i2->gid) {
94 static void get_uidname(uid_t uid, guitem *item)
99 pwbuf = getpwuid(uid);
100 if (pwbuf != NULL && strcmp(pwbuf->pw_name, "????????") != 0) {
101 item->name = bstrdup(pwbuf->pw_name);
107 static void get_gidname(gid_t gid, guitem *item)
112 grbuf = getgrgid(gid);
113 if (grbuf != NULL && strcmp(grbuf->gr_name, "????????") != 0) {
114 item->name = bstrdup(grbuf->gr_name);
121 char *guid_list::uid_to_name(uid_t uid, char *name, int maxlen)
123 guitem sitem, *item, *fitem;
127 item = (guitem *)uid_list->binary_search(&sitem, uid_compare);
128 Dmsg2(900, "uid=%d item=%p\n", uid, item);
130 item = (guitem *)malloc(sizeof(guitem));
133 get_uidname(uid, item);
135 item->name = bstrdup(edit_int64(uid, buf));
136 Dmsg2(900, "set uid=%d name=%s\n", uid, item->name);
138 fitem = (guitem *)uid_list->binary_insert(item, uid_compare);
139 if (fitem != item) { /* item already there this shouldn't happen */
145 bstrncpy(name, item->name, maxlen);
149 char *guid_list::gid_to_name(gid_t gid, char *name, int maxlen)
151 guitem sitem, *item, *fitem;
155 item = (guitem *)gid_list->binary_search(&sitem, gid_compare);
157 item = (guitem *)malloc(sizeof(guitem));
160 get_gidname(gid, item);
162 item->name = bstrdup(edit_int64(gid, buf));
164 fitem = (guitem *)gid_list->binary_insert(item, gid_compare);
165 if (fitem != item) { /* item already there this shouldn't happen */
172 bstrncpy(name, item->name, maxlen);
182 char ed1[50], ed2[50];
183 list = new_guid_list();
184 for (i=0; i<1001; i++) {
185 printf("uid=%d name=%s gid=%d name=%s\n", i, list->uid_to_name(i, ed1, sizeof(ed1)),
186 i, list->gid_to_name(i, ed2, sizeof(ed2)));
187 printf("uid=%d name=%s gid=%d name=%s\n", i, list->uid_to_name(i, ed1, sizeof(ed1)),
188 i, list->gid_to_name(i, ed2, sizeof(ed2)));
191 free_guid_list(list);
192 sm_dump(false); /* unit test */