Deleted Added
full compact
getusershell.c (52856) getusershell.c (65532)
1/* $NetBSD: getusershell.c,v 1.17 1999/01/25 01:09:34 lukem Exp $ */
2
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

--- 15 unchanged lines hidden (view full) ---

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.
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

--- 15 unchanged lines hidden (view full) ---

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.
32 *
33 * $FreeBSD: head/lib/libc/gen/getusershell.c 52856 1999-11-04 04:16:28Z ache $
34 */
35
34 */
35
36#include <sys/cdefs.h>
36#if defined(LIBC_SCCS) && !defined(lint)
37#if defined(LIBC_SCCS) && !defined(lint)
37static char sccsid[] = "@(#)getusershell.c 8.1 (Berkeley) 6/4/93";
38static char rcsid[] =
39 "$FreeBSD: head/lib/libc/gen/getusershell.c 65532 2000-09-06 18:16:48Z nectar $";
38#endif /* LIBC_SCCS and not lint */
39
40#include <sys/param.h>
41#include <sys/file.h>
40#endif /* LIBC_SCCS and not lint */
41
42#include <sys/param.h>
43#include <sys/file.h>
42#include <sys/stat.h>
43#include <stdio.h>
44
44#include <ctype.h>
45#include <ctype.h>
46#include <errno.h>
47#include <nsswitch.h>
48#include <paths.h>
49#include <stdio.h>
45#include <stdlib.h>
50#include <stdlib.h>
51#include <string.h>
52#include <stringlist.h>
46#include <unistd.h>
53#include <unistd.h>
47#include <paths.h>
48
54
55#ifdef HESIOD
56#include <hesiod.h>
57#endif
58#ifdef YP
59#include <rpc/rpc.h>
60#include <rpcsvc/ypclnt.h>
61#include <rpcsvc/yp_prot.h>
62#endif
63
49/*
50 * Local shells should NOT be added here. They should be added in
51 * /etc/shells.
52 */
53
64/*
65 * Local shells should NOT be added here. They should be added in
66 * /etc/shells.
67 */
68
54static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
55static char **curshell, **shells, *strings;
56static char **initshells __P((void));
69static const char *const okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
70static const char *const *curshell;
71static StringList *sl;
57
72
73static const char *const *initshells __P((void));
74
58/*
75/*
59 * Get a list of shells from _PATH_SHELLS, if it exists.
76 * Get a list of shells from "shells" nsswitch database
60 */
61char *
77 */
78char *
62getusershell()
79getusershell(void)
63{
64 char *ret;
65
66 if (curshell == NULL)
67 curshell = initshells();
80{
81 char *ret;
82
83 if (curshell == NULL)
84 curshell = initshells();
68 ret = *curshell;
85 /*LINTED*/
86 ret = (char *)*curshell;
69 if (ret != NULL)
70 curshell++;
71 return (ret);
72}
73
74void
87 if (ret != NULL)
88 curshell++;
89 return (ret);
90}
91
92void
75endusershell()
93endusershell(void)
76{
94{
77
78 if (shells != NULL)
79 free(shells);
80 shells = NULL;
81 if (strings != NULL)
82 free(strings);
83 strings = NULL;
95 if (sl)
96 sl_free(sl, 1);
97 sl = NULL;
84 curshell = NULL;
85}
86
87void
98 curshell = NULL;
99}
100
101void
88setusershell()
102setusershell(void)
89{
90
91 curshell = initshells();
92}
93
103{
104
105 curshell = initshells();
106}
107
94static char **
95initshells()
108
109static int _local_initshells __P((void *, void *, va_list));
110
111/*ARGSUSED*/
112static int
113_local_initshells(rv, cb_data, ap)
114 void *rv;
115 void *cb_data;
116 va_list ap;
96{
117{
97 register char **sp, *cp;
98 register FILE *fp;
99 struct stat statb;
118 char *sp, *cp;
119 FILE *fp;
120 char line[MAXPATHLEN + 2];
100
121
101 if (shells != NULL)
102 free(shells);
103 shells = NULL;
104 if (strings != NULL)
105 free(strings);
106 strings = NULL;
122 if (sl)
123 sl_free(sl, 1);
124 sl = sl_init();
125
107 if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
126 if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
108 return (okshells);
109 if (fstat(fileno(fp), &statb) == -1) {
110 (void)fclose(fp);
111 return (okshells);
112 }
113 if ((strings = malloc((u_int)statb.st_size)) == NULL) {
114 (void)fclose(fp);
115 return (okshells);
116 }
117 shells = calloc((unsigned)statb.st_size / 3, sizeof (char *));
118 if (shells == NULL) {
119 (void)fclose(fp);
120 free(strings);
121 strings = NULL;
122 return (okshells);
123 }
124 sp = shells;
125 cp = strings;
127 return NS_UNAVAIL;
128
129 sp = cp = line;
126 while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
127 while (*cp != '#' && *cp != '/' && *cp != '\0')
128 cp++;
129 if (*cp == '#' || *cp == '\0')
130 continue;
130 while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
131 while (*cp != '#' && *cp != '/' && *cp != '\0')
132 cp++;
133 if (*cp == '#' || *cp == '\0')
134 continue;
131 *sp++ = cp;
132 while (!isspace((unsigned char)*cp) && *cp != '#' && *cp != '\0')
135 sp = cp;
136 while (!isspace(*cp) && *cp != '#' && *cp != '\0')
133 cp++;
134 *cp++ = '\0';
137 cp++;
138 *cp++ = '\0';
139 sl_add(sl, strdup(sp));
135 }
140 }
136 *sp = NULL;
137 (void)fclose(fp);
141 (void)fclose(fp);
138 return (shells);
142 return NS_SUCCESS;
139}
143}
144
145#ifdef HESIOD
146static int _dns_initshells __P((void *, void *, va_list));
147
148/*ARGSUSED*/
149static int
150_dns_initshells(rv, cb_data, ap)
151 void *rv;
152 void *cb_data;
153 va_list ap;
154{
155 char shellname[] = "shells-XXXXX";
156 int hsindex, hpi, r;
157 char **hp;
158 void *context;
159
160 if (sl)
161 sl_free(sl, 1);
162 sl = sl_init();
163 r = NS_UNAVAIL;
164 if (hesiod_init(&context) == -1)
165 return (r);
166
167 for (hsindex = 0; ; hsindex++) {
168 snprintf(shellname, sizeof(shellname)-1, "shells-%d", hsindex);
169 hp = hesiod_resolve(context, shellname, "shells");
170 if (hp == NULL) {
171 if (errno == ENOENT) {
172 if (hsindex == 0)
173 r = NS_NOTFOUND;
174 else
175 r = NS_SUCCESS;
176 }
177 break;
178 } else {
179 for (hpi = 0; hp[hpi]; hpi++)
180 sl_add(sl, hp[hpi]);
181 free(hp);
182 }
183 }
184 hesiod_end(context);
185 return (r);
186}
187#endif /* HESIOD */
188
189#ifdef YP
190static int _nis_initshells __P((void *, void *, va_list));
191
192/*ARGSUSED*/
193static int
194_nis_initshells(rv, cb_data, ap)
195 void *rv;
196 void *cb_data;
197 va_list ap;
198{
199 static char *ypdomain;
200
201 if (sl)
202 sl_free(sl, 1);
203 sl = sl_init();
204
205 if (ypdomain == NULL) {
206 switch (yp_get_default_domain(&ypdomain)) {
207 case 0:
208 break;
209 case YPERR_RESRC:
210 return NS_TRYAGAIN;
211 default:
212 return NS_UNAVAIL;
213 }
214 }
215
216 for (;;) {
217 char *ypcur = NULL;
218 int ypcurlen = 0; /* XXX: GCC */
219 char *key, *data;
220 int keylen, datalen;
221 int r;
222
223 key = data = NULL;
224 if (ypcur) {
225 r = yp_next(ypdomain, "shells", ypcur, ypcurlen,
226 &key, &keylen, &data, &datalen);
227 free(ypcur);
228 switch (r) {
229 case 0:
230 break;
231 case YPERR_NOMORE:
232 free(key);
233 free(data);
234 return NS_SUCCESS;
235 default:
236 free(key);
237 free(data);
238 return NS_UNAVAIL;
239 }
240 ypcur = key;
241 ypcurlen = keylen;
242 } else {
243 if (yp_first(ypdomain, "shells", &ypcur,
244 &ypcurlen, &data, &datalen)) {
245 free(data);
246 return NS_UNAVAIL;
247 }
248 }
249 data[datalen] = '\0'; /* clear trailing \n */
250 sl_add(sl, data);
251 }
252}
253#endif /* YP */
254
255static const char *const *
256initshells()
257{
258 static const ns_dtab dtab[] = {
259 NS_FILES_CB(_local_initshells, NULL)
260 NS_DNS_CB(_dns_initshells, NULL)
261 NS_NIS_CB(_nis_initshells, NULL)
262 { 0 }
263 };
264 if (sl)
265 sl_free(sl, 1);
266 sl = sl_init();
267
268 if (nsdispatch(NULL, dtab, NSDB_SHELLS, "initshells", __nsdefaultsrc)
269 != NS_SUCCESS) {
270 if (sl)
271 sl_free(sl, 1);
272 sl = NULL;
273 return (okshells);
274 }
275 sl_add(sl, NULL);
276
277 return (const char *const *)(sl->sl_str);
278}