Mercurial > hg > octave-nkf > gnulib-hg
annotate lib/idcache.c @ 9148:71cb6e488d75
New file: lib/idcache.h
* NEWS: Mention the addition.
* modules/idcache (Files): Add lib/idcache.h
* lib/idcache.c: Include "idcache.h".
Don't include <sys/types.h>.
Add a FIXME comment.
Move file-scoped "static" declarations to the top.
* lib/idcache.h: New file. Include <sys/types.h> here, instead.
author | Jim Meyering <jim@meyering.net> |
---|---|
date | Sat, 18 Aug 2007 07:16:52 +0000 |
parents | 476857ef4611 |
children | bbbbbf4cd1c5 |
rev | line source |
---|---|
5 | 1 /* idcache.c -- map user and group IDs, cached for speed |
5907 | 2 |
9148 | 3 Copyright (C) 1985, 1988, 1989, 1990, 1997, 1998, 2003, 2005-2007 |
7302
8a1a9361108c
* _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents:
6275
diff
changeset
|
4 Free Software Foundation, Inc. |
5 | 5 |
6 This program is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 2, or (at your option) | |
9 any later version. | |
10 | |
11 This program is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
650
b4ef1c1a0171
update FSF address in copyright
Jim Meyering <jim@meyering.net>
parents:
5
diff
changeset
|
17 along with this program; if not, write to the Free Software Foundation, |
5848
a48fb0e98c8c
*** empty log message ***
Paul Eggert <eggert@cs.ucla.edu>
parents:
4662
diff
changeset
|
18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
650
b4ef1c1a0171
update FSF address in copyright
Jim Meyering <jim@meyering.net>
parents:
5
diff
changeset
|
19 |
7302
8a1a9361108c
* _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents:
6275
diff
changeset
|
20 #include <config.h> |
5 | 21 |
9148 | 22 #include "idcache.h" |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
23 #include <stddef.h> |
5 | 24 #include <stdio.h> |
4662 | 25 #include <string.h> |
5 | 26 #include <pwd.h> |
27 #include <grp.h> | |
28 | |
6275 | 29 #include <unistd.h> |
967
029c8dd12d60
(getuser): Return NULL (rather than stringified uid) upon lookup failure.
Jim Meyering <jim@meyering.net>
parents:
650
diff
changeset
|
30 |
4544 | 31 #include "xalloc.h" |
32 | |
1261
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
33 #ifdef __DJGPP__ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
34 static char digits[] = "0123456789"; |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
35 #endif |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
36 |
5 | 37 struct userid |
38 { | |
39 union | |
40 { | |
41 uid_t u; | |
42 gid_t g; | |
43 } id; | |
44 struct userid *next; | |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
45 char name[FLEXIBLE_ARRAY_MEMBER]; |
5 | 46 }; |
47 | |
9148 | 48 /* FIXME: provide a function to free any malloc'd storage and reset lists, |
49 so that an application can use code like this just before exiting: | |
50 #ifdef lint | |
51 idcache_clear (); | |
52 #endif | |
53 */ | |
54 | |
5 | 55 static struct userid *user_alist; |
56 | |
7675
476857ef4611
* lib/idcache.c: Adjust comments in user- and group- portions to
Jim Meyering <jim@meyering.net>
parents:
7673
diff
changeset
|
57 /* Each entry on list is a user name for which the first lookup failed. */ |
5 | 58 static struct userid *nouser_alist; |
59 | |
9148 | 60 /* Use the same struct as for userids. */ |
61 static struct userid *group_alist; | |
62 | |
63 /* Each entry on list is a group name for which the first lookup failed. */ | |
64 static struct userid *nogroup_alist; | |
65 | |
1253 | 66 /* Translate UID to a login name, with cache, or NULL if unresolved. */ |
5 | 67 |
68 char * | |
1253 | 69 getuser (uid_t uid) |
5 | 70 { |
7672
d2c7e0fe0b94
* lib/idcache.c (getuser): Remove all uses of the register keyword.
Jim Meyering <jim@meyering.net>
parents:
7671
diff
changeset
|
71 struct userid *tail; |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
72 struct userid *match = NULL; |
5 | 73 |
74 for (tail = user_alist; tail; tail = tail->next) | |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
75 { |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
76 if (tail->id.u == uid) |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
77 { |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
78 match = tail; |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
79 break; |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
80 } |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
81 } |
5 | 82 |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
83 if (match == NULL) |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
84 { |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
85 struct passwd *pwent = getpwuid (uid); |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
86 char const *name = pwent ? pwent->pw_name : ""; |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
87 match = xmalloc (offsetof (struct userid, name) + strlen (name) + 1); |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
88 match->id.u = uid; |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
89 strcpy (match->name, name); |
5 | 90 |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
91 /* Add to the head of the list, so most recently used is first. */ |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
92 match->next = user_alist; |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
93 user_alist = match; |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
94 } |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
95 |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
96 return match->name[0] ? match->name : NULL; |
5 | 97 } |
98 | |
99 /* Translate USER to a UID, with cache. | |
100 Return NULL if there is no such user. | |
101 (We also cache which user names have no passwd entry, | |
102 so we don't keep looking them up.) */ | |
103 | |
104 uid_t * | |
1253 | 105 getuidbyname (const char *user) |
5 | 106 { |
7672
d2c7e0fe0b94
* lib/idcache.c (getuser): Remove all uses of the register keyword.
Jim Meyering <jim@meyering.net>
parents:
7671
diff
changeset
|
107 struct userid *tail; |
5 | 108 struct passwd *pwent; |
109 | |
110 for (tail = user_alist; tail; tail = tail->next) | |
111 /* Avoid a function call for the most common case. */ | |
1253 | 112 if (*tail->name == *user && !strcmp (tail->name, user)) |
5 | 113 return &tail->id.u; |
114 | |
115 for (tail = nouser_alist; tail; tail = tail->next) | |
116 /* Avoid a function call for the most common case. */ | |
117 if (*tail->name == *user && !strcmp (tail->name, user)) | |
7671
0e4c9d56db95
Use cleaner syntax: NULL rather than 0.
Jim Meyering <jim@meyering.net>
parents:
7670
diff
changeset
|
118 return NULL; |
5 | 119 |
120 pwent = getpwnam (user); | |
1261
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
121 #ifdef __DJGPP__ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
122 /* We need to pretend to be the user USER, to make |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
123 pwd functions know about an arbitrary user name. */ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
124 if (!pwent && strspn (user, digits) < strlen (user)) |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
125 { |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
126 setenv ("USER", user, 1); |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
127 pwent = getpwnam (user); /* now it will succeed */ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
128 } |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
129 #endif |
5 | 130 |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
131 tail = xmalloc (offsetof (struct userid, name) + strlen (user) + 1); |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
132 strcpy (tail->name, user); |
5 | 133 |
1253 | 134 /* Add to the head of the list, so most recently used is first. */ |
5 | 135 if (pwent) |
136 { | |
137 tail->id.u = pwent->pw_uid; | |
138 tail->next = user_alist; | |
139 user_alist = tail; | |
140 return &tail->id.u; | |
141 } | |
142 | |
143 tail->next = nouser_alist; | |
144 nouser_alist = tail; | |
7671
0e4c9d56db95
Use cleaner syntax: NULL rather than 0.
Jim Meyering <jim@meyering.net>
parents:
7670
diff
changeset
|
145 return NULL; |
5 | 146 } |
147 | |
1253 | 148 /* Translate GID to a group name, with cache, or NULL if unresolved. */ |
5 | 149 |
150 char * | |
1253 | 151 getgroup (gid_t gid) |
5 | 152 { |
7672
d2c7e0fe0b94
* lib/idcache.c (getuser): Remove all uses of the register keyword.
Jim Meyering <jim@meyering.net>
parents:
7671
diff
changeset
|
153 struct userid *tail; |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
154 struct userid *match = NULL; |
5 | 155 |
156 for (tail = group_alist; tail; tail = tail->next) | |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
157 { |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
158 if (tail->id.g == gid) |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
159 { |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
160 match = tail; |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
161 break; |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
162 } |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
163 } |
5 | 164 |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
165 if (match == NULL) |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
166 { |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
167 struct group *grent = getgrgid (gid); |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
168 char const *name = grent ? grent->gr_name : ""; |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
169 match = xmalloc (offsetof (struct userid, name) + strlen (name) + 1); |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
170 match->id.g = gid; |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
171 strcpy (match->name, name); |
5 | 172 |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
173 /* Add to the head of the list, so most recently used is first. */ |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
174 match->next = group_alist; |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
175 group_alist = match; |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
176 } |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
177 |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
178 return match->name[0] ? match->name : NULL; |
5 | 179 } |
180 | |
967
029c8dd12d60
(getuser): Return NULL (rather than stringified uid) upon lookup failure.
Jim Meyering <jim@meyering.net>
parents:
650
diff
changeset
|
181 /* Translate GROUP to a GID, with cache. |
5 | 182 Return NULL if there is no such group. |
183 (We also cache which group names have no group entry, | |
184 so we don't keep looking them up.) */ | |
185 | |
186 gid_t * | |
1253 | 187 getgidbyname (const char *group) |
5 | 188 { |
7672
d2c7e0fe0b94
* lib/idcache.c (getuser): Remove all uses of the register keyword.
Jim Meyering <jim@meyering.net>
parents:
7671
diff
changeset
|
189 struct userid *tail; |
5 | 190 struct group *grent; |
191 | |
192 for (tail = group_alist; tail; tail = tail->next) | |
193 /* Avoid a function call for the most common case. */ | |
1253 | 194 if (*tail->name == *group && !strcmp (tail->name, group)) |
5 | 195 return &tail->id.g; |
196 | |
197 for (tail = nogroup_alist; tail; tail = tail->next) | |
198 /* Avoid a function call for the most common case. */ | |
199 if (*tail->name == *group && !strcmp (tail->name, group)) | |
7671
0e4c9d56db95
Use cleaner syntax: NULL rather than 0.
Jim Meyering <jim@meyering.net>
parents:
7670
diff
changeset
|
200 return NULL; |
5 | 201 |
202 grent = getgrnam (group); | |
1261
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
203 #ifdef __DJGPP__ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
204 /* We need to pretend to belong to group GROUP, to make |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
205 grp functions know about an arbitrary group name. */ |
1261
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
206 if (!grent && strspn (group, digits) < strlen (group)) |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
207 { |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
208 setenv ("GROUP", group, 1); |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
209 grent = getgrnam (group); /* now it will succeed */ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
210 } |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
211 #endif |
5 | 212 |
7673
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
213 tail = xmalloc (offsetof (struct userid, name) + strlen (group) + 1); |
a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
Jim Meyering <jim@meyering.net>
parents:
7672
diff
changeset
|
214 strcpy (tail->name, group); |
5 | 215 |
216 /* Add to the head of the list, so most recently used is first. */ | |
217 if (grent) | |
218 { | |
219 tail->id.g = grent->gr_gid; | |
220 tail->next = group_alist; | |
221 group_alist = tail; | |
222 return &tail->id.g; | |
223 } | |
650
b4ef1c1a0171
update FSF address in copyright
Jim Meyering <jim@meyering.net>
parents:
5
diff
changeset
|
224 |
5 | 225 tail->next = nogroup_alist; |
226 nogroup_alist = tail; | |
7671
0e4c9d56db95
Use cleaner syntax: NULL rather than 0.
Jim Meyering <jim@meyering.net>
parents:
7670
diff
changeset
|
227 return NULL; |
5 | 228 } |