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