2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright 1997 Apple Computer, Inc. (unpublished)
28 * /etc/passwd file access routines.
29 * Just read from the /etc/passwd file and skip the dbm database, since
30 * lookupd does all flat file lookups when the system is multi-user.
31 * These routines are only used in single-user mode.
33 * 17 Apr 1997 file created - Marc Majka
42 #define forever for (;;)
48 static struct passwd _pw
= { 0 };
50 static int _pwStayOpen
;
51 static int _pwFileFormat
= 1;
56 if (_pw
.pw_name
!= NULL
) free(_pw
.pw_name
);
57 if (_pw
.pw_passwd
!= NULL
) free(_pw
.pw_passwd
);
58 if (_pw
.pw_class
!= NULL
) free(_pw
.pw_class
);
59 if (_pw
.pw_gecos
!= NULL
) free(_pw
.pw_gecos
);
60 if (_pw
.pw_dir
!= NULL
) free(_pw
.pw_dir
);
61 if (_pw
.pw_shell
!= NULL
) free(_pw
.pw_shell
);
76 if (l
== NULL
) return;
77 for (i
= 0; l
[i
] != NULL
; i
++)
79 if (l
[i
] != NULL
) free(l
[i
]);
82 if (l
!= NULL
) free(l
);
90 if (l
== NULL
) return 0;
91 for (i
= 0; l
[i
] != NULL
; i
++);
101 if (s
== NULL
) return NULL
;
111 insertString(char *s
, char **l
, unsigned int x
)
115 if (s
== NULL
) return l
;
118 l
= (char **)malloc(2 * sizeof(char *));
119 l
[0] = copyString(s
);
124 for (i
= 0; l
[i
] != NULL
; i
++);
125 len
= i
+ 1; /* count the NULL on the end of the list too! */
127 l
= (char **)realloc(l
, (len
+ 1) * sizeof(char *));
129 if ((x
>= (len
- 1)) || (x
== (unsigned int)-1))
131 l
[len
- 1] = copyString(s
);
136 for (i
= len
; i
> x
; i
--) l
[i
] = l
[i
- 1];
137 l
[x
] = copyString(s
);
142 appendString(char *s
, char **l
)
144 return insertString(s
, l
, (unsigned int)-1);
149 tokenize(const char *data
, const char *sep
)
151 char **tokens
= NULL
;
157 if (data
== NULL
) return NULL
;
160 tokens
= appendString((char *)data
, tokens
);
170 /* skip leading white space */
171 while ((p
[0] == ' ') || (p
[0] == '\t') || (p
[0] == '\n')) p
++;
173 /* check for end of line */
174 if (p
[0] == '\0') break;
179 for (j
= 0; (j
< len
) && (scanning
== 1); j
++)
181 if (p
[0] == sep
[j
] || (p
[0] == '\0')) scanning
= 0;
184 while (scanning
== 1)
188 for (j
= 0; (j
< len
) && (scanning
== 1); j
++)
190 if (p
[0] == sep
[j
] || (p
[0] == '\0')) scanning
= 0;
194 /* back over trailing whitespace */
196 if (i
> -1) { /* did we actually copy anything? */
197 while ((buf
[i
] == ' ') || (buf
[i
] == '\t') || (buf
[i
] == '\n')) i
--;
201 tokens
= appendString(buf
, tokens
);
203 /* check for end of line */
204 if (p
[0] == '\0') break;
208 for (j
= 0; (j
< len
) && (scanning
== 1); j
++)
217 if ((scanning
== 0) && p
[0] == '\0')
219 /* line ended at a separator - add a null member */
220 tokens
= appendString("", tokens
);
228 parseUser(char *data
)
233 if (data
== NULL
) return NULL
;
235 tokens
= tokenize(data
, ":");
236 ntokens
= listLength(tokens
);
237 if (( _pwFileFormat
&& (ntokens
!= 10)) ||
238 (!_pwFileFormat
&& (ntokens
!= 7)))
246 _pw
.pw_name
= tokens
[0];
247 _pw
.pw_passwd
= tokens
[1];
248 _pw
.pw_uid
= atoi(tokens
[2]);
250 _pw
.pw_gid
= atoi(tokens
[3]);
255 _pw
.pw_class
= tokens
[4];
256 _pw
.pw_change
= atoi(tokens
[5]);
258 _pw
.pw_expire
= atoi(tokens
[6]);
260 _pw
.pw_gecos
= tokens
[7];
261 _pw
.pw_dir
= tokens
[8];
262 _pw
.pw_shell
= tokens
[9];
266 _pw
.pw_class
= copyString("");
269 _pw
.pw_gecos
= tokens
[4];
270 _pw
.pw_dir
= tokens
[5];
271 _pw
.pw_shell
= tokens
[6];
288 if (s
== NULL
|| s
[0] == '\0') return NULL
;
290 if (s
[0] != '#') s
[strlen(s
) - 1] = '\0';
297 setpassent(int stayopen
)
299 _pwStayOpen
= stayopen
;
311 pwFile
= _PATH_MASTERPASSWD
;
315 pwFile
= _PATH_PASSWD
;
318 _pfp
= fopen(pwFile
, "r");
340 static struct passwd
*
341 getpw(const char *nam
, uid_t uid
, int which
)
348 if (setpwent() == 0) return NULL
;
353 line
= getLine(_pfp
);
354 if (line
== NULL
) break;
363 pw
= parseUser(line
);
367 if ((pw
== NULL
) || (which
== _PWENT_
))
369 if (_pwStayOpen
== 0) endpwent();
373 if (((which
== _PWNAM_
) && (!strcmp(nam
, pw
->pw_name
))) ||
374 ((which
== _PWUID_
) && (uid
== pw
->pw_uid
)))
376 if (_pwStayOpen
== 0) endpwent();
381 if (_pwStayOpen
== 0) endpwent();
388 return getpw(NULL
, 0, _PWENT_
);
392 getpwnam(const char *nam
)
394 return getpw(nam
, 0, _PWNAM_
);
400 return getpw(NULL
, uid
, _PWUID_
);