1 /* @(#)getpwent.c	1.1 11/07/12 Copyright 2011 J. Schilling */
2 /*
3  *	Passwd functions for platforms (like MINGW) that do not have them.
4  *
5  *	Copyright (c) 2011 J. Schilling
6  */
7 /*
8  * The contents of this file are subject to the terms of the
9  * Common Development and Distribution License, Version 1.0 only
10  * (the "License").  You may not use this file except in compliance
11  * with the License.
12  *
13  * See the file CDDL.Schily.txt in this distribution for details.
14  * A copy of the CDDL is also available via the Internet at
15  * http://www.opensource.org/licenses/cddl1.txt
16  *
17  * When distributing Covered Code, include this CDDL HEADER in each
18  * file and include the License file CDDL.Schily.txt from this distribution.
19  */
20 
21 #include <schily/stdio.h>
22 #include <schily/pwd.h>
23 #include <schily/standard.h>
24 #include <schily/utypes.h>
25 #include <schily/schily.h>
26 
27 #if !defined(HAVE_GETPWNAM) && !defined(HAVE_GETPWENT) && \
28 	!defined(HAVE_GETPWUID) && !defined(HAVE_SETPWENT) && \
29 	!defined(HAVE_ENDPWENT)
30 
31 
32 LOCAL	FILE		*pwdf;
33 LOCAL	struct passwd	pwd;
34 LOCAL	struct passwd	rootpwd = { "root", "*", 0, 0, "", "/", "" };
35 LOCAL	char		pwdbuf[128];
36 
37 LOCAL	struct passwd *mkpwd	__PR((char *arr[]));
38 LOCAL	struct passwd *findpwent __PR((const char *string, int field));
39 
40 EXPORT struct passwd *
getpwent()41 getpwent()
42 {
43 	char	*arr[7];
44 
45 	if (pwdf == (FILE *)NULL) {
46 		pwdf = fileopen("/etc/passwd", "r");
47 		if (pwdf == (FILE *)NULL)
48 			return ((struct passwd *)0);
49 	}
50 	if (fgetline(pwdf, pwdbuf, sizeof (pwdbuf)) == EOF)
51 		return ((struct passwd *)0);
52 	breakline(pwdbuf, ':', arr, 7);
53 	return (mkpwd(arr));
54 }
55 
56 EXPORT void
setpwent()57 setpwent()
58 {
59 	if (pwdf == (FILE *)NULL) {
60 		pwdf = fileopen("/etc/passwd", "r");
61 		if (pwdf == (FILE *)NULL)
62 			return;
63 	}
64 	fileseek(pwdf, (off_t)0);
65 }
66 
67 EXPORT void
endpwent()68 endpwent()
69 {
70 	if (pwdf != (FILE *)NULL) {
71 		fclose(pwdf);
72 		pwdf = (FILE *)NULL;
73 	}
74 }
75 
76 EXPORT struct passwd *
getpwnam(name)77 getpwnam(name)
78 	const char	*name;
79 {
80 	setpwent();
81 	if (pwdf == (FILE *)NULL) {
82 		if (streql(rootpwd.pw_name, name))
83 			return (&rootpwd);
84 		return ((struct passwd *)0);
85 	}
86 	return (findpwent(name, 0));
87 }
88 
89 EXPORT struct passwd *
getpwuid(uid)90 getpwuid(uid)
91 	uid_t	uid;
92 {
93 	char	suid[32];
94 
95 	setpwent();
96 	if (pwdf == (FILE *)NULL) {
97 		if (uid == 0)
98 			return (&rootpwd);
99 		return ((struct passwd *)0);
100 	}
101 	js_snprintf(suid, sizeof (suid), "%lld", (Llong)uid);
102 	return (findpwent(suid, 2));
103 }
104 
105 LOCAL struct passwd *
mkpwd(arr)106 mkpwd(arr)
107 	char	*arr[];
108 {
109 	long	l;
110 
111 	pwd.pw_name = arr[0];
112 	pwd.pw_passwd = arr[1];
113 	(void) astolb(arr[2], &l, 10);
114 	pwd.pw_uid = l;
115 	(void) astolb(arr[3], &l, 10);
116 	pwd.pw_gid = l;
117 	pwd.pw_gecos = arr[4];
118 	pwd.pw_dir = arr[5];
119 	pwd.pw_shell = arr[6];
120 
121 	return (&pwd);
122 }
123 
124 LOCAL struct passwd *
findpwent(string,field)125 findpwent(string, field)
126 	const char	*string;
127 	int		field;
128 {
129 	char	*arr[7];
130 
131 	for (;;) {
132 		if (fgetline(pwdf, pwdbuf, sizeof (pwdbuf)) == EOF)
133 			return ((struct passwd *)0);
134 		breakline(pwdbuf, ':', arr, 7);
135 		if (streql(string, arr[field]))
136 			return (mkpwd(arr));
137 	}
138 }
139 
140 #endif
141