]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/idcache.c
Fix since truncation bug; lock db during recycling; new update command line args...
[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 #define NEEDED 1
19 #ifdef NEEDED
20
21 #include <config.h>
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <pwd.h>
27 #include <grp.h>
28
29 #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
30 #include <string.h>
31 #else
32 #include <strings.h>
33 #endif
34
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38 #ifndef _POSIX_VERSION
39 struct passwd *getpwuid ();
40 struct passwd *getpwnam ();
41 struct group *getgrgid ();
42 struct group *getgrnam ();
43 #endif
44
45 #define xstrdup strdup
46 #define xmalloc malloc
47 //char *xmalloc ();
48 //char *xstrdup ();
49
50 struct userid
51 {
52   union
53     {
54       uid_t u;
55       gid_t g;
56     } id;
57   char *name;
58   struct userid *next;
59 };
60
61 static struct userid *user_alist;
62
63
64
65 /* The members of this list have names not in the local passwd file.  */
66 static struct userid *nouser_alist;
67
68 /* Translate UID to a login name or a stringified number,
69    with cache.  */
70
71 char *getuser (uid_t uid)
72 {
73   register struct userid *tail;
74   struct passwd *pwent;
75   char usernum_string[20];
76
77   for (tail = user_alist; tail; tail = tail->next)
78     if (tail->id.u == uid)
79       return tail->name;
80
81   pwent = getpwuid (uid);
82   tail = (struct userid *) xmalloc (sizeof (struct userid));
83   tail->id.u = uid;
84   if (pwent == 0) {
85       sprintf (usernum_string, "%u", (unsigned) uid);
86       tail->name = xstrdup (usernum_string);
87   } else {
88       tail->name = xstrdup (pwent->pw_name);
89   }
90
91   /* Add to the head of the list, so most recently used is first.  */
92   tail->next = user_alist;
93   user_alist = tail;
94   return tail->name;
95 }
96
97 /* Translate USER to a UID, with cache.
98    Return NULL if there is no such user.
99    (We also cache which user names have no passwd entry,
100    so we don't keep looking them up.)  */
101
102 uid_t *
103 getuidbyname (char *user)
104 {
105   register struct userid *tail;
106   struct passwd *pwent;
107
108   for (tail = user_alist; tail; tail = tail->next)
109     /* Avoid a function call for the most common case.  */
110     if (*tail->name == *user && !strcmp (tail->name, user))
111       return &tail->id.u;
112
113   for (tail = nouser_alist; tail; tail = tail->next)
114     /* Avoid a function call for the most common case.  */
115     if (*tail->name == *user && !strcmp (tail->name, user))
116       return 0;
117
118   pwent = getpwnam (user);
119
120   tail = (struct userid *) xmalloc (sizeof (struct userid));
121   tail->name = xstrdup (user);
122
123   /* Add to the head of the list, so most recently used is first.  */
124   if (pwent)
125     {
126       tail->id.u = pwent->pw_uid;
127       tail->next = user_alist;
128       user_alist = tail;
129       return &tail->id.u;
130     }
131
132   tail->next = nouser_alist;
133   nouser_alist = tail;
134   return 0;
135 }
136
137 /* Use the same struct as for userids.  */
138 static struct userid *group_alist;
139 static struct userid *nogroup_alist;
140
141 /* Translate GID to a group name or a stringified number,
142    with cache.  */
143
144 char *
145 getgroup (gid_t gid)
146 {
147   register struct userid *tail;
148   struct group *grent;
149   char groupnum_string[20];
150
151   for (tail = group_alist; tail; tail = tail->next)
152     if (tail->id.g == gid)
153       return tail->name;
154
155   grent = getgrgid (gid);
156   tail = (struct userid *) xmalloc (sizeof (struct userid));
157   tail->id.g = gid;
158   if (grent == 0)
159     {
160       sprintf (groupnum_string, "%u", (unsigned int) gid);
161       tail->name = xstrdup (groupnum_string);
162     }
163   else
164     tail->name = xstrdup (grent->gr_name);
165
166   /* Add to the head of the list, so most recently used is first.  */
167   tail->next = group_alist;
168   group_alist = tail;
169   return tail->name;
170 }
171
172 /* Translate GROUP to a UID, with cache.
173    Return NULL if there is no such group.
174    (We also cache which group names have no group entry,
175    so we don't keep looking them up.)  */
176
177 gid_t *
178 getgidbyname (char *group)
179 {
180   register struct userid *tail;
181   struct group *grent;
182
183   for (tail = group_alist; tail; tail = tail->next)
184     /* Avoid a function call for the most common case.  */
185     if (*tail->name == *group && !strcmp (tail->name, group))
186       return &tail->id.g;
187
188   for (tail = nogroup_alist; tail; tail = tail->next)
189     /* Avoid a function call for the most common case.  */
190     if (*tail->name == *group && !strcmp (tail->name, group))
191       return 0;
192
193   grent = getgrnam (group);
194
195   tail = (struct userid *) xmalloc (sizeof (struct userid));
196   tail->name = xstrdup (group);
197
198   /* Add to the head of the list, so most recently used is first.  */
199   if (grent)
200     {
201       tail->id.g = grent->gr_gid;
202       tail->next = group_alist;
203       group_alist = tail;
204       return &tail->id.g;
205     }
206
207   tail->next = nogroup_alist;
208   nogroup_alist = tail;
209   return 0;
210 }
211 #endif