2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2014 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from many
7 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 Bacula® is a registered trademark of Kern Sibbald.
17 * Written by Kern Sibbald, July 2007 to replace idcache.c
19 * Program to convert uid and gid into names, and cache the results
20 * for preformance reasons.
27 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
40 guid_list *new_guid_list()
44 list = (guid_list *)malloc(sizeof(guid_list));
45 list->uid_list = New(dlist(item, &item->link));
46 list->gid_list = New(dlist(item, &item->link));
50 void free_guid_list(guid_list *list)
53 foreach_dlist(item, list->uid_list) {
56 foreach_dlist(item, list->gid_list) {
59 delete list->uid_list;
60 delete list->gid_list;
64 static int uid_compare(void *item1, void *item2)
66 guitem *i1 = (guitem *)item1;
67 guitem *i2 = (guitem *)item2;
68 if (i1->uid < i2->uid) {
70 } else if (i1->uid > i2->uid) {
77 static int gid_compare(void *item1, void *item2)
79 guitem *i1 = (guitem *)item1;
80 guitem *i2 = (guitem *)item2;
81 if (i1->gid < i2->gid) {
83 } else if (i1->gid > i2->gid) {
91 static void get_uidname(uid_t uid, guitem *item)
96 pwbuf = getpwuid(uid);
97 if (pwbuf != NULL && strcmp(pwbuf->pw_name, "????????") != 0) {
98 item->name = bstrdup(pwbuf->pw_name);
104 static void get_gidname(gid_t gid, guitem *item)
109 grbuf = getgrgid(gid);
110 if (grbuf != NULL && strcmp(grbuf->gr_name, "????????") != 0) {
111 item->name = bstrdup(grbuf->gr_name);
118 char *guid_list::uid_to_name(uid_t uid, char *name, int maxlen)
120 guitem sitem, *item, *fitem;
124 item = (guitem *)uid_list->binary_search(&sitem, uid_compare);
125 Dmsg2(900, "uid=%d item=%p\n", uid, item);
127 item = (guitem *)malloc(sizeof(guitem));
130 get_uidname(uid, item);
132 item->name = bstrdup(edit_int64(uid, buf));
133 Dmsg2(900, "set uid=%d name=%s\n", uid, item->name);
135 fitem = (guitem *)uid_list->binary_insert(item, uid_compare);
136 if (fitem != item) { /* item already there this shouldn't happen */
142 bstrncpy(name, item->name, maxlen);
146 char *guid_list::gid_to_name(gid_t gid, char *name, int maxlen)
148 guitem sitem, *item, *fitem;
152 item = (guitem *)gid_list->binary_search(&sitem, gid_compare);
154 item = (guitem *)malloc(sizeof(guitem));
157 get_gidname(gid, item);
159 item->name = bstrdup(edit_int64(gid, buf));
161 fitem = (guitem *)gid_list->binary_insert(item, gid_compare);
162 if (fitem != item) { /* item already there this shouldn't happen */
169 bstrncpy(name, item->name, maxlen);
179 char ed1[50], ed2[50];
180 list = new_guid_list();
181 for (i=0; i<1001; i++) {
182 printf("uid=%d name=%s gid=%d name=%s\n", i, list->uid_to_name(i, ed1, sizeof(ed1)),
183 i, list->gid_to_name(i, ed2, sizeof(ed2)));
184 printf("uid=%d name=%s gid=%d name=%s\n", i, list->uid_to_name(i, ed1, sizeof(ed1)),
185 i, list->gid_to_name(i, ed2, sizeof(ed2)));
188 free_guid_list(list);
189 sm_dump(false); /* unit test */