]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/idcache.c
kes Add dynamic dll entry point for SHGetFolderPath to Win32 code.
[bacula/bacula] / bacula / src / lib / idcache.c
1 /* idcache.c -- map user and group IDs, cached for speed
2    Copyright (C) 1985, 1988, 1989, 1990 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
17
18 #include "bacula.h"
19
20 struct userid {
21   union {
22       uid_t u;
23       gid_t g;
24   } id;
25   char *name;
26   struct userid *next;
27 };
28
29 static struct userid *user_alist = NULL;
30 /* Use the same struct as for userids.  */
31 static struct userid *group_alist = NULL;
32
33 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
34
35 /* Translate UID to a login name or a stringified number,
36    with cache.  */
37
38 char *getuser(uid_t uid, char *name, int len)
39 {
40    register struct userid *tail;
41    char usernum_string[20];
42
43    P(mutex);
44    for (tail = user_alist; tail; tail = tail->next) {
45       if (tail->id.u == uid) {
46          goto uid_done;
47       }
48    }
49
50    tail = (struct userid *)malloc(sizeof (struct userid));
51    tail->id.u = uid;
52    tail->name = NULL;
53
54 #if !defined(HAVE_WIN32)
55    {
56       struct passwd *pwent = getpwuid(uid);
57
58       if (pwent != NULL && strcmp(pwent->pw_name, "????????") != 0) {
59          tail->name = bstrdup(pwent->pw_name);
60       }
61    }
62 #endif
63
64    if (tail->name == NULL) {
65       sprintf(usernum_string, "%u", (uint32_t)uid);
66       tail->name = bstrdup(usernum_string);
67    }
68
69    /* Add to the head of the list, so most recently used is first.  */
70    tail->next = user_alist;
71    user_alist = tail;
72
73 uid_done:
74    bstrncpy(name, tail->name, len);
75    V(mutex);
76    return name;
77 }
78
79 void free_getuser_cache()
80 {
81   register struct userid *tail;
82
83   P(mutex);
84   for (tail = user_alist; tail; ) {
85      struct userid *otail = tail;
86      free(tail->name);
87      tail = tail->next;
88      free(otail);
89   }
90   user_alist = NULL;
91   V(mutex);
92 }
93
94
95
96 /* Translate GID to a group name or a stringified number,
97    with cache. */
98 char *getgroup(gid_t gid, char *name, int len)
99 {
100    register struct userid *tail;
101    char groupnum_string[20];
102
103    P(mutex);
104    for (tail = group_alist; tail; tail = tail->next) {
105       if (tail->id.g == gid) {
106          goto gid_done;
107       }
108    }
109
110    tail = (struct userid *)malloc(sizeof (struct userid));
111    tail->id.g = gid;
112    tail->name = NULL;
113
114 #if !defined(HAVE_WIN32)
115    {
116       struct group *grent = getgrgid(gid);
117
118       if (grent != NULL && strcmp(grent->gr_name, "????????") != 0) {
119          tail->name = bstrdup(grent->gr_name);
120       }
121    }
122 #endif
123
124    if (tail->name == NULL) {
125       sprintf (groupnum_string, "%u", (uint32_t)gid);
126       tail->name = bstrdup(groupnum_string);
127    }
128
129    /* Add to the head of the list, so most recently used is first. */
130    tail->next = group_alist;
131    group_alist = tail;
132
133 gid_done:
134    bstrncpy(name, tail->name, len);
135    V(mutex);
136    return name;
137 }
138
139 void free_getgroup_cache()
140 {
141   register struct userid *tail;
142
143   P(mutex);
144   for (tail = group_alist; tail; ) {
145      struct userid *otail = tail;
146      free(tail->name);
147      tail = tail->next;
148      free(otail);
149   }
150   group_alist = NULL;
151   V(mutex);
152 }