6811333 Remove prom_printf() message in emlxs driver
[opensolaris.git] / usr / src / lib / libc / port / gen / getusershell.c
blob368fa72a614cc1afcc225f47ce748326f8980eee
1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
6 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
9 /*
10 * Copyright (c) 1985 Regents of the University of California.
11 * All rights reserved. The Berkeley software License Agreement
12 * specifies the terms and conditions for redistribution.
15 #pragma ident "%Z%%M% %I% %E% SMI"
17 #include "lint.h"
18 #include <sys/types.h>
19 #include <sys/param.h>
20 #include <sys/stat.h>
21 #include <ctype.h>
22 #include <stdio.h>
23 #include <limits.h>
24 #include <stdlib.h>
25 #include <sys/file.h>
26 #include "libc.h"
27 #include <unistd.h>
29 #define SHELLS "/etc/shells"
32 * Do not add local shells here. They should be added in /etc/shells
34 * Do not add restricted shells:
35 * Shells returned by getusershell traditionally allow:
36 * - users to change away from (i.e., if you have an rksh in
37 * getusershell(), then users can change their shell to ksh)
38 * - by default, ftp in is allowed only for shells returned by
39 * getusershell(); since FTP has no restrictions on directory
40 * movement, adding rksh to getusershell() would defeat that
41 * protection.
43 const char *okshells[] = {
44 "/usr/bin/sh",
45 "/usr/bin/csh",
46 "/usr/bin/ksh",
47 "/usr/bin/ksh93",
48 "/usr/bin/jsh",
49 "/bin/sh",
50 "/bin/csh",
51 "/bin/ksh",
52 "/bin/ksh93",
53 "/bin/jsh",
54 "/sbin/sh",
55 "/sbin/jsh",
56 "/usr/bin/pfsh",
57 "/usr/bin/pfcsh",
58 "/usr/bin/pfksh",
59 "/usr/bin/bash",
60 "/usr/bin/tcsh",
61 "/usr/bin/zsh",
62 "/bin/pfsh",
63 "/bin/pfcsh",
64 "/bin/pfksh",
65 "/bin/bash",
66 "/bin/tcsh",
67 "/bin/zsh",
68 "/usr/xpg4/bin/sh",
69 "/sbin/pfsh",
70 "/usr/sfw/bin/zsh",
71 NULL
74 static char **shells, *strings;
75 static char **curshell;
76 static char **initshells(void);
79 * Get a list of shells from SHELLS, if it exists.
81 char *
82 getusershell(void)
84 char *ret;
86 if (curshell == NULL)
87 curshell = initshells();
88 ret = *curshell;
89 if (ret != NULL)
90 curshell++;
91 return (ret);
94 void
95 endusershell(void)
98 if (shells != NULL)
99 (void) free((char *)shells);
100 shells = NULL;
101 if (strings != NULL)
102 (void) free(strings);
103 strings = NULL;
104 curshell = NULL;
107 void
108 setusershell(void)
111 curshell = initshells();
114 static char **
115 initshells(void)
117 char **sp, *cp;
118 FILE *fp;
119 struct stat statb;
121 if (shells != NULL)
122 (void) free((char *)shells);
123 shells = NULL;
124 if (strings != NULL)
125 (void) free(strings);
126 strings = NULL;
127 if ((fp = fopen(SHELLS, "rF")) == (FILE *)0)
128 return ((char **)okshells);
130 * The +1 in the malloc() below is needed to handle the final
131 * fgets() NULL terminator. From fgets(3S):
133 * char *fgets(char *s, int n, FILE *stream);
135 * The fgets() function reads characters from the stream into
136 * the array pointed to by s, until n-1 characters are read, or
137 * a newline character is read and transferred to s, or an end-
138 * of-file condition is encountered. The string is then termi-
139 * nated with a null character.
141 if ((fstat(fileno(fp), &statb) == -1) || (statb.st_size > LONG_MAX) ||
142 ((strings = malloc((size_t)statb.st_size + 1)) == NULL)) {
143 (void) fclose(fp);
144 return ((char **)okshells);
146 shells = calloc((size_t)statb.st_size / 3, sizeof (char *));
147 if (shells == NULL) {
148 (void) fclose(fp);
149 (void) free(strings);
150 strings = NULL;
151 return ((char **)okshells);
153 sp = shells;
154 cp = strings;
155 while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
156 while (*cp != '#' && *cp != '/' && *cp != '\0')
157 cp++;
158 if (*cp == '#' || *cp == '\0')
159 continue;
160 *sp++ = cp;
161 while (!isspace(*cp) && *cp != '#' && *cp != '\0')
162 cp++;
163 *cp++ = '\0';
165 *sp = (char *)0;
166 (void) fclose(fp);
167 return (shells);