Sync usage with man page.
[netbsd-mini2440.git] / distrib / utils / libhack / getpwent.c
blob698ad90bcac70c77868ef9c917cfa38e8a8d923c
1 /* $NetBSD: getpwent.c,v 1.10 2008/11/28 19:39:00 sborrill Exp $ */
3 /*
4 * Copyright (c) 1987, 1988, 1989, 1993, 1994, 1995
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
33 * Copied from: lib/libc/gen/getpwent.c
34 * NetBSD: getpwent.c,v 1.48 2000/10/03 03:22:26 enami Exp
35 * and then gutted, leaving only /etc/master.passwd support.
38 #include <sys/cdefs.h>
40 #ifdef __weak_alias
41 #define endpwent _endpwent
42 #define getpwent _getpwent
43 #define getpwent_r _getpwent_r
44 #define getpwuid _getpwuid
45 #define getpwnam _getpwnam
46 #define setpwent _setpwent
47 #define setpassent _setpassent
48 #define getpwuid_r _getpwuid_r
49 #define getpwnam_r _getpwnam_r
51 __weak_alias(endpwent,_endpwent)
52 __weak_alias(getpwent,_getpwent)
53 __weak_alias(getpwent_r,_getpwent_r)
54 __weak_alias(getpwuid,_getpwuid)
55 __weak_alias(getpwnam,_getpwnam)
56 __weak_alias(setpwent,_setpwent)
57 __weak_alias(setpassent,_setpassent)
58 __weak_alias(getpwuid_r,_getpwuid_r)
59 __weak_alias(getpwnam_r,_getpwnam_r)
61 __weak_alias(__getpwent50,_getpwent)
62 __weak_alias(__getpwent_r50,_getpwent_r)
63 __weak_alias(__getpwuid50,_getpwuid)
64 __weak_alias(__getpwnam50,_getpwnam)
65 __weak_alias(__getpwuid_r50,_getpwuid_r)
66 __weak_alias(__getpwnam_r50,_getpwnam_r)
67 #endif
69 #include <sys/param.h>
71 #include <limits.h>
72 #include <pwd.h>
73 #include <stdlib.h>
74 #include <stdio.h>
75 #include <string.h>
77 static int pwstart(void);
78 static int pwscan(int, uid_t, const char *, struct passwd *,
79 char *, size_t);
80 static int pwmatchline(int, uid_t, const char *, struct passwd *,
81 char *);
83 static FILE *_pw_fp;
84 static struct passwd _pw_passwd; /* password structure */
85 static int _pw_stayopen; /* keep fd's open */
86 static int _pw_filesdone;
88 #define MAXLINELENGTH 1024
90 static char pwline[MAXLINELENGTH];
92 struct passwd *
93 getpwent(void)
96 if ((!_pw_fp && !pwstart()) ||
97 !pwscan(0, 0, NULL, &_pw_passwd, pwline, sizeof(pwline)))
98 return (NULL);
99 return (&_pw_passwd);
103 getpwent_r(struct passwd *pwres, char *buf, size_t bufsiz,
104 struct passwd **pwd)
106 int rval;
108 if (!_pw_fp && !pwstart())
109 return 1;
110 rval = !pwscan(0, 0, NULL, pwres, buf, bufsiz);
111 if (rval)
112 *pwd = NULL;
113 else
114 *pwd = pwres;
115 return rval;
118 struct passwd *
119 getpwnam(const char *name)
121 struct passwd *pwd;
122 return getpwnam_r(name, &_pw_passwd, pwline, sizeof(pwline),
123 &pwd) == 0 ? pwd : NULL;
127 getpwnam_r(const char *name, struct passwd *pwres, char *buf, size_t bufsiz,
128 struct passwd **pwd)
130 int rval;
132 if (!pwstart())
133 return 1;
134 rval = !pwscan(1, 0, name, pwres, buf, bufsiz);
135 if (!_pw_stayopen)
136 endpwent();
137 if (rval)
138 *pwd = NULL;
139 else
140 *pwd = pwres;
141 return rval;
144 struct passwd *
145 getpwuid(uid_t uid)
147 struct passwd *pwd;
148 return getpwuid_r(uid, &_pw_passwd, pwline, sizeof(pwline),
149 &pwd) == 0 ? pwd : NULL;
153 getpwuid_r(uid_t uid, struct passwd *pwres, char *buf, size_t bufsiz,
154 struct passwd **pwd)
156 int rval;
158 if (!pwstart())
159 return 1;
160 rval = !pwscan(1, uid, NULL, pwres, buf, bufsiz);
161 if (!_pw_stayopen)
162 endpwent();
163 if (rval)
164 *pwd = NULL;
165 else
166 *pwd = pwres;
167 return rval;
170 void
171 setpwent(void)
174 (void) setpassent(0);
178 setpassent(int stayopen)
181 if (!pwstart())
182 return 0;
183 _pw_stayopen = stayopen;
184 return 1;
187 void
188 endpwent(void)
191 _pw_filesdone = 0;
192 if (_pw_fp) {
193 (void)fclose(_pw_fp);
194 _pw_fp = NULL;
198 static int
199 pwstart(void)
202 _pw_filesdone = 0;
203 if (_pw_fp) {
204 rewind(_pw_fp);
205 return 1;
207 return (_pw_fp = fopen(_PATH_MASTERPASSWD, "r")) ? 1 : 0;
211 static int
212 pwscan(int search, uid_t uid, const char *name, struct passwd *pwd, char *buf,
213 size_t bufsiz)
216 if (_pw_filesdone)
217 return 0;
218 for (;;) {
219 if (!fgets(buf, bufsiz, _pw_fp)) {
220 if (!search)
221 _pw_filesdone = 1;
222 return 0;
224 /* skip lines that are too big */
225 if (!strchr(buf, '\n')) {
226 int ch;
228 while ((ch = getc(_pw_fp)) != '\n' && ch != EOF)
230 continue;
232 if (pwmatchline(search, uid, name, pwd, buf))
233 return 1;
235 /* NOTREACHED */
238 static int
239 pwmatchline(int search, uid_t uid, const char *name, struct passwd *pwd,
240 char *buf)
242 unsigned long id;
243 char *cp, *bp, *ep;
245 /* name may be NULL if search is nonzero */
247 bp = buf;
248 memset(pwd, 0, sizeof(*pwd));
249 pwd->pw_name = strsep(&bp, ":\n"); /* name */
250 if (search && name && strcmp(pwd->pw_name, name))
251 return 0;
253 pwd->pw_passwd = strsep(&bp, ":\n"); /* passwd */
255 if (!(cp = strsep(&bp, ":\n"))) /* uid */
256 return 0;
257 id = strtoul(cp, &ep, 10);
258 if (id > UID_MAX || *ep != '\0')
259 return 0;
260 pwd->pw_uid = (uid_t)id;
261 if (search && name == NULL && pwd->pw_uid != uid)
262 return 0;
264 if (!(cp = strsep(&bp, ":\n"))) /* gid */
265 return 0;
266 id = strtoul(cp, &ep, 10);
267 if (id > GID_MAX || *ep != '\0')
268 return 0;
269 pwd->pw_gid = (gid_t)id;
271 if (!(pwd->pw_class = strsep(&bp, ":"))) /* class */
272 return 0;
273 if (!(ep = strsep(&bp, ":"))) /* change */
274 return 0;
275 if (!(ep = strsep(&bp, ":"))) /* expire */
276 return 0;
278 if (!(pwd->pw_gecos = strsep(&bp, ":\n"))) /* gecos */
279 return 0;
280 if (!(pwd->pw_dir = strsep(&bp, ":\n"))) /* directory */
281 return 0;
282 if (!(pwd->pw_shell = strsep(&bp, ":\n"))) /* shell */
283 return 0;
285 if (strchr(bp, ':') != NULL)
286 return 0;
288 return 1;