]> git.saurik.com Git - apple/libinfo.git/blame - gen.subproj/getpwent.c
Libinfo-222.4.9.tar.gz
[apple/libinfo.git] / gen.subproj / getpwent.c
CommitLineData
03fb6eb0
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
ad21edcc
A
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
03fb6eb0
A
13 *
14 * The Original Code and all software distributed under the License are
ad21edcc 15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
03fb6eb0
A
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
ad21edcc
A
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
03fb6eb0
A
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * Copyright 1997 Apple Computer, Inc. (unpublished)
26 *
27 * /etc/passwd file access routines.
28 * Just read from the /etc/passwd file and skip the dbm database, since
29 * lookupd does all flat file lookups when the system is multi-user.
30 * These routines are only used in single-user mode.
31 *
32 * 17 Apr 1997 file created - Marc Majka
33 */
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <pwd.h>
a0865d63 39#include <unistd.h>
03fb6eb0
A
40
41#define forever for (;;)
42
43#define _PWENT_ 0
44#define _PWNAM_ 1
45#define _PWUID_ 2
46
47static struct passwd _pw = { 0 };
48static FILE *_pfp;
49static int _pwStayOpen;
a0865d63 50static int _pwFileFormat = 1;
03fb6eb0
A
51
52static void
53free_pw()
54{
55 if (_pw.pw_name != NULL) free(_pw.pw_name);
56 if (_pw.pw_passwd != NULL) free(_pw.pw_passwd);
57 if (_pw.pw_class != NULL) free(_pw.pw_class);
58 if (_pw.pw_gecos != NULL) free(_pw.pw_gecos);
59 if (_pw.pw_dir != NULL) free(_pw.pw_dir);
60 if (_pw.pw_shell != NULL) free(_pw.pw_shell);
61
62 _pw.pw_name = NULL;
63 _pw.pw_passwd = NULL;
64 _pw.pw_class = NULL;
65 _pw.pw_gecos = NULL;
66 _pw.pw_dir = NULL;
67 _pw.pw_shell = NULL;
68}
69
70static void
71freeList(char **l)
72{
73 int i;
74
75 if (l == NULL) return;
76 for (i = 0; l[i] != NULL; i++)
77 {
78 if (l[i] != NULL) free(l[i]);
79 l[i] = NULL;
80 }
81 if (l != NULL) free(l);
82}
83
84static unsigned int
85listLength(char **l)
86{
87 int i;
88
89 if (l == NULL) return 0;
90 for (i = 0; l[i] != NULL; i++);
91 return i;
92}
93
94static char *
95copyString(char *s)
96{
97 int len;
98 char *t;
99
100 if (s == NULL) return NULL;
101
102 len = strlen(s) + 1;
103 t = malloc(len);
104 bcopy(s, t, len);
105 return t;
106}
107
108
109static char **
110insertString(char *s, char **l, unsigned int x)
111{
112 int i, len;
113
114 if (s == NULL) return l;
115 if (l == NULL)
116 {
117 l = (char **)malloc(2 * sizeof(char *));
118 l[0] = copyString(s);
119 l[1] = NULL;
120 return l;
121 }
122
123 for (i = 0; l[i] != NULL; i++);
124 len = i + 1; /* count the NULL on the end of the list too! */
125
126 l = (char **)realloc(l, (len + 1) * sizeof(char *));
127
128 if ((x >= (len - 1)) || (x == (unsigned int)-1))
129 {
130 l[len - 1] = copyString(s);
131 l[len] = NULL;
132 return l;
133 }
134
135 for (i = len; i > x; i--) l[i] = l[i - 1];
136 l[x] = copyString(s);
137 return l;
138}
139
140static char **
141appendString(char *s, char **l)
142{
143 return insertString(s, l, (unsigned int)-1);
144}
145
146
147static char **
148tokenize(const char *data, const char *sep)
149{
150 char **tokens = NULL;
151 const char *p;
152 int i, j, len;
153 char buf[4096];
154 int scanning;
155
156 if (data == NULL) return NULL;
157 if (sep == NULL)
158 {
159 tokens = appendString((char *)data, tokens);
160 return tokens;
161 }
162
163 len = strlen(sep);
164
165 p = data;
166
167 while (p[0] != '\0')
168 {
169 /* skip leading white space */
170 while ((p[0] == ' ') || (p[0] == '\t') || (p[0] == '\n')) p++;
171
172 /* check for end of line */
173 if (p[0] == '\0') break;
174
175 /* copy data */
176 i = 0;
177 scanning = 1;
178 for (j = 0; (j < len) && (scanning == 1); j++)
179 {
180 if (p[0] == sep[j] || (p[0] == '\0')) scanning = 0;
181 }
182
183 while (scanning == 1)
184 {
185 buf[i++] = p[0];
186 p++;
187 for (j = 0; (j < len) && (scanning == 1); j++)
188 {
189 if (p[0] == sep[j] || (p[0] == '\0')) scanning = 0;
190 }
191 }
192
193 /* back over trailing whitespace */
194 i--;
ccd4a120
A
195 if (i > -1) { /* did we actually copy anything? */
196 while ((buf[i] == ' ') || (buf[i] == '\t') || (buf[i] == '\n')) i--;
197 }
03fb6eb0
A
198 buf[++i] = '\0';
199
200 tokens = appendString(buf, tokens);
201
202 /* check for end of line */
203 if (p[0] == '\0') break;
204
205 /* skip separator */
206 scanning = 1;
207 for (j = 0; (j < len) && (scanning == 1); j++)
208 {
209 if (p[0] == sep[j])
210 {
211 p++;
212 scanning = 0;
213 }
214 }
215
216 if ((scanning == 0) && p[0] == '\0')
217 {
218 /* line ended at a separator - add a null member */
219 tokens = appendString("", tokens);
220 return tokens;
221 }
222 }
223 return tokens;
224}
225
226struct passwd *
227parseUser(char *data)
228{
229 char **tokens;
a0865d63 230 int ntokens;
03fb6eb0
A
231
232 if (data == NULL) return NULL;
233
234 tokens = tokenize(data, ":");
a0865d63
A
235 ntokens = listLength(tokens);
236 if (( _pwFileFormat && (ntokens != 10)) ||
237 (!_pwFileFormat && (ntokens != 7)))
03fb6eb0
A
238 {
239 freeList(tokens);
240 return NULL;
241 }
242
243 free_pw();
244
245 _pw.pw_name = tokens[0];
246 _pw.pw_passwd = tokens[1];
247 _pw.pw_uid = atoi(tokens[2]);
248 free(tokens[2]);
249 _pw.pw_gid = atoi(tokens[3]);
250 free(tokens[3]);
a0865d63
A
251
252 if (_pwFileFormat)
253 {
254 _pw.pw_class = tokens[4];
255 _pw.pw_change = atoi(tokens[5]);
256 free(tokens[5]);
257 _pw.pw_expire = atoi(tokens[6]);
258 free(tokens[6]);
259 _pw.pw_gecos = tokens[7];
260 _pw.pw_dir = tokens[8];
261 _pw.pw_shell = tokens[9];
262 }
263 else
264 {
265 _pw.pw_class = copyString("");
266 _pw.pw_change = 0;
267 _pw.pw_expire = 0;
268 _pw.pw_gecos = tokens[4];
269 _pw.pw_dir = tokens[5];
270 _pw.pw_shell = tokens[6];
271 }
03fb6eb0
A
272
273 free(tokens);
274
275 return &_pw;
276}
277
278static char *
279getLine(FILE *fp)
280{
281 char s[1024];
282 char *out;
283
284 s[0] = '\0';
285
286 fgets(s, 1024, fp);
287 if (s == NULL || s[0] == '\0') return NULL;
288
289 if (s[0] != '#') s[strlen(s) - 1] = '\0';
290
291 out = copyString(s);
292 return out;
293}
294
295int
296setpassent(int stayopen)
297{
298 _pwStayOpen = stayopen;
299 return(1);
300}
301
302int
303setpwent()
304{
305 if (_pfp == NULL)
306 {
a0865d63
A
307 char *pwFile;
308 if (geteuid() == 0)
309 {
310 pwFile = _PATH_MASTERPASSWD;
311 }
312 else
313 {
314 pwFile = _PATH_PASSWD;
315 _pwFileFormat = 0;
316 }
317 _pfp = fopen(pwFile, "r");
03fb6eb0
A
318 if (_pfp == NULL)
319 {
a0865d63 320 perror(pwFile);
03fb6eb0
A
321 return(0);
322 }
323 }
324 else rewind(_pfp);
325 _pwStayOpen = 0;
326 return(1);
327}
328
329void
330endpwent()
331{
332 if (_pfp != NULL)
333 {
334 fclose(_pfp);
335 _pfp = NULL;
336 }
337}
338
339static struct passwd *
340getpw(const char *nam, uid_t uid, int which)
341{
342 char *line;
343 struct passwd *pw;
344
345 if (which != 0)
346 {
347 if (setpwent() == 0) return NULL;
348 }
349
350 forever
351 {
352 line = getLine(_pfp);
353 if (line == NULL) break;
354
355 if (line[0] == '#')
356 {
357 free(line);
358 line = NULL;
359 continue;
360 }
361
362 pw = parseUser(line);
363 free(line);
364 line = NULL;
365
366 if ((pw == NULL) || (which == _PWENT_))
367 {
368 if (_pwStayOpen == 0) endpwent();
369 return pw;
370 }
371
372 if (((which == _PWNAM_) && (!strcmp(nam, pw->pw_name))) ||
373 ((which == _PWUID_) && (uid == pw->pw_uid)))
374 {
375 if (_pwStayOpen == 0) endpwent();
376 return pw;
377 }
378 }
379
380 if (_pwStayOpen == 0) endpwent();
381 return NULL;
382}
383
384struct passwd *
385getpwent()
386{
387 return getpw(NULL, 0, _PWENT_);
388}
389
390struct passwd *
391getpwnam(const char *nam)
392{
393 return getpw(nam, 0, _PWNAM_);
394}
395
396struct passwd *
397getpwuid(uid_t uid)
398{
399 return getpw(NULL, uid, _PWUID_);
400}