Mercurial > hg > octave-kai > gnulib-hg
annotate lib/idcache.c @ 7296:33903d90fa2b
(argp_doc): Make sure NULL is not passed to dgettext
author | Sergey Poznyakoff <gray@gnu.org.ua> |
---|---|
date | Tue, 12 Sep 2006 09:06:40 +0000 |
parents | fd0ccce602e4 |
children | 8a1a9361108c |
rev | line source |
---|---|
5 | 1 /* idcache.c -- map user and group IDs, cached for speed |
5907 | 2 |
3 Copyright (C) 1985, 1988, 1989, 1990, 1997, 1998, 2003, 2005 Free | |
4 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 |
6259
96c32553b4c6
Use a consistent style for including <config.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5949
diff
changeset
|
20 #ifdef HAVE_CONFIG_H |
967
029c8dd12d60
(getuser): Return NULL (rather than stringified uid) upon lookup failure.
Jim Meyering <jim@meyering.net>
parents:
650
diff
changeset
|
21 # include <config.h> |
650
b4ef1c1a0171
update FSF address in copyright
Jim Meyering <jim@meyering.net>
parents:
5
diff
changeset
|
22 #endif |
5 | 23 |
24 #include <stdio.h> | |
4662 | 25 #include <string.h> |
5 | 26 #include <sys/types.h> |
27 #include <pwd.h> | |
28 #include <grp.h> | |
29 | |
6275 | 30 #include <unistd.h> |
967
029c8dd12d60
(getuser): Return NULL (rather than stringified uid) upon lookup failure.
Jim Meyering <jim@meyering.net>
parents:
650
diff
changeset
|
31 |
4544 | 32 #include "xalloc.h" |
33 | |
1261
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
34 #ifdef __DJGPP__ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
35 static char digits[] = "0123456789"; |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
36 #endif |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
37 |
5 | 38 struct userid |
39 { | |
40 union | |
41 { | |
42 uid_t u; | |
43 gid_t g; | |
44 } id; | |
45 char *name; | |
46 struct userid *next; | |
47 }; | |
48 | |
49 static struct userid *user_alist; | |
50 | |
1253 | 51 /* The members of this list have names not in the local passwd file. */ |
5 | 52 static struct userid *nouser_alist; |
53 | |
1253 | 54 /* Translate UID to a login name, with cache, or NULL if unresolved. */ |
5 | 55 |
56 char * | |
1253 | 57 getuser (uid_t uid) |
5 | 58 { |
59 register struct userid *tail; | |
60 struct passwd *pwent; | |
61 | |
62 for (tail = user_alist; tail; tail = tail->next) | |
63 if (tail->id.u == uid) | |
64 return tail->name; | |
65 | |
66 pwent = getpwuid (uid); | |
5949
9300a4e513e9
(getuser, getuidbyname, getgroup, getgidbyname):
Jim Meyering <jim@meyering.net>
parents:
5907
diff
changeset
|
67 tail = xmalloc (sizeof *tail); |
5 | 68 tail->id.u = uid; |
1253 | 69 tail->name = pwent ? xstrdup (pwent->pw_name) : NULL; |
5 | 70 |
1253 | 71 /* Add to the head of the list, so most recently used is first. */ |
5 | 72 tail->next = user_alist; |
73 user_alist = tail; | |
74 return tail->name; | |
75 } | |
76 | |
77 /* Translate USER to a UID, with cache. | |
78 Return NULL if there is no such user. | |
79 (We also cache which user names have no passwd entry, | |
80 so we don't keep looking them up.) */ | |
81 | |
82 uid_t * | |
1253 | 83 getuidbyname (const char *user) |
5 | 84 { |
85 register struct userid *tail; | |
86 struct passwd *pwent; | |
87 | |
88 for (tail = user_alist; tail; tail = tail->next) | |
89 /* Avoid a function call for the most common case. */ | |
1253 | 90 if (*tail->name == *user && !strcmp (tail->name, user)) |
5 | 91 return &tail->id.u; |
92 | |
93 for (tail = nouser_alist; tail; tail = tail->next) | |
94 /* Avoid a function call for the most common case. */ | |
95 if (*tail->name == *user && !strcmp (tail->name, user)) | |
96 return 0; | |
97 | |
98 pwent = getpwnam (user); | |
1261
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
99 #ifdef __DJGPP__ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
100 /* 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
|
101 pwd functions know about an arbitrary user name. */ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
102 if (!pwent && strspn (user, digits) < strlen (user)) |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
103 { |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
104 setenv ("USER", user, 1); |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
105 pwent = getpwnam (user); /* now it will succeed */ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
106 } |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
107 #endif |
5 | 108 |
5949
9300a4e513e9
(getuser, getuidbyname, getgroup, getgidbyname):
Jim Meyering <jim@meyering.net>
parents:
5907
diff
changeset
|
109 tail = xmalloc (sizeof *tail); |
5 | 110 tail->name = xstrdup (user); |
111 | |
1253 | 112 /* Add to the head of the list, so most recently used is first. */ |
5 | 113 if (pwent) |
114 { | |
115 tail->id.u = pwent->pw_uid; | |
116 tail->next = user_alist; | |
117 user_alist = tail; | |
118 return &tail->id.u; | |
119 } | |
120 | |
121 tail->next = nouser_alist; | |
122 nouser_alist = tail; | |
123 return 0; | |
124 } | |
125 | |
126 /* Use the same struct as for userids. */ | |
127 static struct userid *group_alist; | |
128 static struct userid *nogroup_alist; | |
129 | |
1253 | 130 /* Translate GID to a group name, with cache, or NULL if unresolved. */ |
5 | 131 |
132 char * | |
1253 | 133 getgroup (gid_t gid) |
5 | 134 { |
135 register struct userid *tail; | |
136 struct group *grent; | |
137 | |
138 for (tail = group_alist; tail; tail = tail->next) | |
139 if (tail->id.g == gid) | |
140 return tail->name; | |
141 | |
142 grent = getgrgid (gid); | |
5949
9300a4e513e9
(getuser, getuidbyname, getgroup, getgidbyname):
Jim Meyering <jim@meyering.net>
parents:
5907
diff
changeset
|
143 tail = xmalloc (sizeof *tail); |
5 | 144 tail->id.g = gid; |
1253 | 145 tail->name = grent ? xstrdup (grent->gr_name) : NULL; |
5 | 146 |
147 /* Add to the head of the list, so most recently used is first. */ | |
148 tail->next = group_alist; | |
149 group_alist = tail; | |
150 return tail->name; | |
151 } | |
152 | |
967
029c8dd12d60
(getuser): Return NULL (rather than stringified uid) upon lookup failure.
Jim Meyering <jim@meyering.net>
parents:
650
diff
changeset
|
153 /* Translate GROUP to a GID, with cache. |
5 | 154 Return NULL if there is no such group. |
155 (We also cache which group names have no group entry, | |
156 so we don't keep looking them up.) */ | |
157 | |
158 gid_t * | |
1253 | 159 getgidbyname (const char *group) |
5 | 160 { |
161 register struct userid *tail; | |
162 struct group *grent; | |
163 | |
164 for (tail = group_alist; tail; tail = tail->next) | |
165 /* Avoid a function call for the most common case. */ | |
1253 | 166 if (*tail->name == *group && !strcmp (tail->name, group)) |
5 | 167 return &tail->id.g; |
168 | |
169 for (tail = nogroup_alist; tail; tail = tail->next) | |
170 /* Avoid a function call for the most common case. */ | |
171 if (*tail->name == *group && !strcmp (tail->name, group)) | |
172 return 0; | |
173 | |
174 grent = getgrnam (group); | |
1261
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
175 #ifdef __DJGPP__ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
176 /* We need to pretend to belong to group GROUP, to make |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
177 grp functions know about any arbitrary group name. */ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
178 if (!grent && strspn (group, digits) < strlen (group)) |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
179 { |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
180 setenv ("GROUP", group, 1); |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
181 grent = getgrnam (group); /* now it will succeed */ |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
182 } |
67cadf165f7f
(getuidbyname) [__DJGPP__]: Make function know about
Jim Meyering <jim@meyering.net>
parents:
1253
diff
changeset
|
183 #endif |
5 | 184 |
5949
9300a4e513e9
(getuser, getuidbyname, getgroup, getgidbyname):
Jim Meyering <jim@meyering.net>
parents:
5907
diff
changeset
|
185 tail = xmalloc (sizeof *tail); |
5 | 186 tail->name = xstrdup (group); |
187 | |
188 /* Add to the head of the list, so most recently used is first. */ | |
189 if (grent) | |
190 { | |
191 tail->id.g = grent->gr_gid; | |
192 tail->next = group_alist; | |
193 group_alist = tail; | |
194 return &tail->id.g; | |
195 } | |
650
b4ef1c1a0171
update FSF address in copyright
Jim Meyering <jim@meyering.net>
parents:
5
diff
changeset
|
196 |
5 | 197 tail->next = nogroup_alist; |
198 nogroup_alist = tail; | |
199 return 0; | |
200 } |