Deleted Added
full compact
getusershell.c (90030) getusershell.c (90045)
1/* $NetBSD: getusershell.c,v 1.17 1999/01/25 01:09:34 lukem Exp $ */
2
3/*
4 * Copyright (c) 1985, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
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. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
1/*
2 * Copyright (c) 1985, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
36#if 0
37#if defined(LIBC_SCCS) && !defined(lint)
38static char sccsid[] = "@(#)getusershell.c 8.1 (Berkeley) 6/4/93";
39#endif /* LIBC_SCCS and not lint */
34#if defined(LIBC_SCCS) && !defined(lint)
35static char sccsid[] = "@(#)getusershell.c 8.1 (Berkeley) 6/4/93";
36#endif /* LIBC_SCCS and not lint */
40#endif
37/* $NetBSD: getusershell.c,v 1.17 1999/01/25 01:09:34 lukem Exp $ */
41#include <sys/cdefs.h>
38#include <sys/cdefs.h>
42__FBSDID("$FreeBSD: head/lib/libc/gen/getusershell.c 90030 2002-01-31 17:26:37Z obrien $");
39__FBSDID("$FreeBSD: head/lib/libc/gen/getusershell.c 90045 2002-02-01 01:32:19Z obrien $");
43
44#include <sys/param.h>
45#include <sys/file.h>
46
47#include <ctype.h>
48#include <errno.h>
49#include <nsswitch.h>
50#include <paths.h>
51#include <stdio.h>
52#include <stdlib.h>
53#include <string.h>
54#include <stringlist.h>
55#include <unistd.h>
56
57#ifdef HESIOD
58#include <hesiod.h>
59#endif
60#ifdef YP
61#include <rpc/rpc.h>
62#include <rpcsvc/ypclnt.h>
63#include <rpcsvc/yp_prot.h>
64#endif
65
66/*
67 * Local shells should NOT be added here. They should be added in
68 * /etc/shells.
69 */
70
71static const char *const okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
72static const char *const *curshell;
73static StringList *sl;
74
40
41#include <sys/param.h>
42#include <sys/file.h>
43
44#include <ctype.h>
45#include <errno.h>
46#include <nsswitch.h>
47#include <paths.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <stringlist.h>
52#include <unistd.h>
53
54#ifdef HESIOD
55#include <hesiod.h>
56#endif
57#ifdef YP
58#include <rpc/rpc.h>
59#include <rpcsvc/ypclnt.h>
60#include <rpcsvc/yp_prot.h>
61#endif
62
63/*
64 * Local shells should NOT be added here. They should be added in
65 * /etc/shells.
66 */
67
68static const char *const okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
69static const char *const *curshell;
70static StringList *sl;
71
75static const char *const *initshells __P((void));
72static const char *const *initshells(void);
76
77/*
78 * Get a list of shells from "shells" nsswitch database
79 */
80char *
81getusershell(void)
82{
83 char *ret;
84
85 if (curshell == NULL)
86 curshell = initshells();
87 /*LINTED*/
88 ret = (char *)*curshell;
89 if (ret != NULL)
90 curshell++;
91 return (ret);
92}
93
94void
95endusershell(void)
96{
97 if (sl)
98 sl_free(sl, 1);
99 sl = NULL;
100 curshell = NULL;
101}
102
103void
104setusershell(void)
105{
106
107 curshell = initshells();
108}
109
110
73
74/*
75 * Get a list of shells from "shells" nsswitch database
76 */
77char *
78getusershell(void)
79{
80 char *ret;
81
82 if (curshell == NULL)
83 curshell = initshells();
84 /*LINTED*/
85 ret = (char *)*curshell;
86 if (ret != NULL)
87 curshell++;
88 return (ret);
89}
90
91void
92endusershell(void)
93{
94 if (sl)
95 sl_free(sl, 1);
96 sl = NULL;
97 curshell = NULL;
98}
99
100void
101setusershell(void)
102{
103
104 curshell = initshells();
105}
106
107
111static int _local_initshells __P((void *, void *, va_list));
108static int _local_initshells(void *, void *, va_list);
112
113/*ARGSUSED*/
114static int
115_local_initshells(rv, cb_data, ap)
116 void *rv;
117 void *cb_data;
118 va_list ap;
119{
120 char *sp, *cp;
121 FILE *fp;
122 char line[MAXPATHLEN + 2];
123
124 if (sl)
125 sl_free(sl, 1);
126 sl = sl_init();
127
128 if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
129 return NS_UNAVAIL;
130
131 sp = cp = line;
132 while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
133 while (*cp != '#' && *cp != '/' && *cp != '\0')
134 cp++;
135 if (*cp == '#' || *cp == '\0')
136 continue;
137 sp = cp;
138 while (!isspace(*cp) && *cp != '#' && *cp != '\0')
139 cp++;
140 *cp++ = '\0';
141 sl_add(sl, strdup(sp));
142 }
143 (void)fclose(fp);
144 return NS_SUCCESS;
145}
146
147#ifdef HESIOD
109
110/*ARGSUSED*/
111static int
112_local_initshells(rv, cb_data, ap)
113 void *rv;
114 void *cb_data;
115 va_list ap;
116{
117 char *sp, *cp;
118 FILE *fp;
119 char line[MAXPATHLEN + 2];
120
121 if (sl)
122 sl_free(sl, 1);
123 sl = sl_init();
124
125 if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
126 return NS_UNAVAIL;
127
128 sp = cp = line;
129 while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
130 while (*cp != '#' && *cp != '/' && *cp != '\0')
131 cp++;
132 if (*cp == '#' || *cp == '\0')
133 continue;
134 sp = cp;
135 while (!isspace(*cp) && *cp != '#' && *cp != '\0')
136 cp++;
137 *cp++ = '\0';
138 sl_add(sl, strdup(sp));
139 }
140 (void)fclose(fp);
141 return NS_SUCCESS;
142}
143
144#ifdef HESIOD
148static int _dns_initshells __P((void *, void *, va_list));
145static int _dns_initshells(void *, void *, va_list);
149
150/*ARGSUSED*/
151static int
152_dns_initshells(rv, cb_data, ap)
153 void *rv;
154 void *cb_data;
155 va_list ap;
156{
157 char shellname[] = "shells-XXXXX";
158 int hsindex, hpi, r;
159 char **hp;
160 void *context;
161
162 if (sl)
163 sl_free(sl, 1);
164 sl = sl_init();
165 r = NS_UNAVAIL;
166 if (hesiod_init(&context) == -1)
167 return (r);
168
169 for (hsindex = 0; ; hsindex++) {
170 snprintf(shellname, sizeof(shellname)-1, "shells-%d", hsindex);
171 hp = hesiod_resolve(context, shellname, "shells");
172 if (hp == NULL) {
173 if (errno == ENOENT) {
174 if (hsindex == 0)
175 r = NS_NOTFOUND;
176 else
177 r = NS_SUCCESS;
178 }
179 break;
180 } else {
181 for (hpi = 0; hp[hpi]; hpi++)
182 sl_add(sl, hp[hpi]);
183 free(hp);
184 }
185 }
186 hesiod_end(context);
187 return (r);
188}
189#endif /* HESIOD */
190
191#ifdef YP
146
147/*ARGSUSED*/
148static int
149_dns_initshells(rv, cb_data, ap)
150 void *rv;
151 void *cb_data;
152 va_list ap;
153{
154 char shellname[] = "shells-XXXXX";
155 int hsindex, hpi, r;
156 char **hp;
157 void *context;
158
159 if (sl)
160 sl_free(sl, 1);
161 sl = sl_init();
162 r = NS_UNAVAIL;
163 if (hesiod_init(&context) == -1)
164 return (r);
165
166 for (hsindex = 0; ; hsindex++) {
167 snprintf(shellname, sizeof(shellname)-1, "shells-%d", hsindex);
168 hp = hesiod_resolve(context, shellname, "shells");
169 if (hp == NULL) {
170 if (errno == ENOENT) {
171 if (hsindex == 0)
172 r = NS_NOTFOUND;
173 else
174 r = NS_SUCCESS;
175 }
176 break;
177 } else {
178 for (hpi = 0; hp[hpi]; hpi++)
179 sl_add(sl, hp[hpi]);
180 free(hp);
181 }
182 }
183 hesiod_end(context);
184 return (r);
185}
186#endif /* HESIOD */
187
188#ifdef YP
192static int _nis_initshells __P((void *, void *, va_list));
189static int _nis_initshells(void *, void *, va_list);
193
194/*ARGSUSED*/
195static int
196_nis_initshells(rv, cb_data, ap)
197 void *rv;
198 void *cb_data;
199 va_list ap;
200{
201 static char *ypdomain;
202
203 if (sl)
204 sl_free(sl, 1);
205 sl = sl_init();
206
207 if (ypdomain == NULL) {
208 switch (yp_get_default_domain(&ypdomain)) {
209 case 0:
210 break;
211 case YPERR_RESRC:
212 return NS_TRYAGAIN;
213 default:
214 return NS_UNAVAIL;
215 }
216 }
217
218 for (;;) {
219 char *ypcur = NULL;
220 int ypcurlen = 0; /* XXX: GCC */
221 char *key, *data;
222 int keylen, datalen;
223 int r;
224
225 key = data = NULL;
226 if (ypcur) {
227 r = yp_next(ypdomain, "shells", ypcur, ypcurlen,
228 &key, &keylen, &data, &datalen);
229 free(ypcur);
230 switch (r) {
231 case 0:
232 break;
233 case YPERR_NOMORE:
234 free(key);
235 free(data);
236 return NS_SUCCESS;
237 default:
238 free(key);
239 free(data);
240 return NS_UNAVAIL;
241 }
242 ypcur = key;
243 ypcurlen = keylen;
244 } else {
245 if (yp_first(ypdomain, "shells", &ypcur,
246 &ypcurlen, &data, &datalen)) {
247 free(data);
248 return NS_UNAVAIL;
249 }
250 }
251 data[datalen] = '\0'; /* clear trailing \n */
252 sl_add(sl, data);
253 }
254}
255#endif /* YP */
256
257static const char *const *
258initshells()
259{
260 static const ns_dtab dtab[] = {
261 NS_FILES_CB(_local_initshells, NULL)
262 NS_DNS_CB(_dns_initshells, NULL)
263 NS_NIS_CB(_nis_initshells, NULL)
264 { 0 }
265 };
266 if (sl)
267 sl_free(sl, 1);
268 sl = sl_init();
269
270 if (nsdispatch(NULL, dtab, NSDB_SHELLS, "initshells", __nsdefaultsrc)
271 != NS_SUCCESS) {
272 if (sl)
273 sl_free(sl, 1);
274 sl = NULL;
275 return (okshells);
276 }
277 sl_add(sl, NULL);
278
279 return (const char *const *)(sl->sl_str);
280}
190
191/*ARGSUSED*/
192static int
193_nis_initshells(rv, cb_data, ap)
194 void *rv;
195 void *cb_data;
196 va_list ap;
197{
198 static char *ypdomain;
199
200 if (sl)
201 sl_free(sl, 1);
202 sl = sl_init();
203
204 if (ypdomain == NULL) {
205 switch (yp_get_default_domain(&ypdomain)) {
206 case 0:
207 break;
208 case YPERR_RESRC:
209 return NS_TRYAGAIN;
210 default:
211 return NS_UNAVAIL;
212 }
213 }
214
215 for (;;) {
216 char *ypcur = NULL;
217 int ypcurlen = 0; /* XXX: GCC */
218 char *key, *data;
219 int keylen, datalen;
220 int r;
221
222 key = data = NULL;
223 if (ypcur) {
224 r = yp_next(ypdomain, "shells", ypcur, ypcurlen,
225 &key, &keylen, &data, &datalen);
226 free(ypcur);
227 switch (r) {
228 case 0:
229 break;
230 case YPERR_NOMORE:
231 free(key);
232 free(data);
233 return NS_SUCCESS;
234 default:
235 free(key);
236 free(data);
237 return NS_UNAVAIL;
238 }
239 ypcur = key;
240 ypcurlen = keylen;
241 } else {
242 if (yp_first(ypdomain, "shells", &ypcur,
243 &ypcurlen, &data, &datalen)) {
244 free(data);
245 return NS_UNAVAIL;
246 }
247 }
248 data[datalen] = '\0'; /* clear trailing \n */
249 sl_add(sl, data);
250 }
251}
252#endif /* YP */
253
254static const char *const *
255initshells()
256{
257 static const ns_dtab dtab[] = {
258 NS_FILES_CB(_local_initshells, NULL)
259 NS_DNS_CB(_dns_initshells, NULL)
260 NS_NIS_CB(_nis_initshells, NULL)
261 { 0 }
262 };
263 if (sl)
264 sl_free(sl, 1);
265 sl = sl_init();
266
267 if (nsdispatch(NULL, dtab, NSDB_SHELLS, "initshells", __nsdefaultsrc)
268 != NS_SUCCESS) {
269 if (sl)
270 sl_free(sl, 1);
271 sl = NULL;
272 return (okshells);
273 }
274 sl_add(sl, NULL);
275
276 return (const char *const *)(sl->sl_str);
277}