2 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
5 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
6 /* All Rights Reserved */
9 * Copyright (c) 1985 Regents of the University of California.
10 * All rights reserved. The Berkeley software License Agreement
11 * specifies the terms and conditions for redistribution.
15 #include <sys/types.h>
16 #include <sys/param.h>
26 #define SHELLS "/etc/shells"
29 * Do not add local shells here. They should be added in /etc/shells
31 * Do not add restricted shells:
32 * Shells returned by getusershell traditionally allow:
33 * - users to change away from (i.e., if you have an rksh in
34 * getusershell(), then users can change their shell to ksh)
35 * - by default, ftp in is allowed only for shells returned by
36 * getusershell(); since FTP has no restrictions on directory
37 * movement, adding rksh to getusershell() would defeat that
40 const char *okshells
[] = {
78 static char **shells
, *strings
;
79 static char **curshell
;
80 static char **initshells(void);
83 * Get a list of shells from SHELLS, if it exists.
91 curshell
= initshells();
103 (void) free((char *)shells
);
106 (void) free(strings
);
115 curshell
= initshells();
126 (void) free((char *)shells
);
129 (void) free(strings
);
131 if ((fp
= fopen(SHELLS
, "rF")) == (FILE *)0)
132 return ((char **)okshells
);
134 * The +1 in the malloc() below is needed to handle the final
135 * fgets() NULL terminator. From fgets(3S):
137 * char *fgets(char *s, int n, FILE *stream);
139 * The fgets() function reads characters from the stream into
140 * the array pointed to by s, until n-1 characters are read, or
141 * a newline character is read and transferred to s, or an end-
142 * of-file condition is encountered. The string is then termi-
143 * nated with a null character.
145 if ((fstat(fileno(fp
), &statb
) == -1) || (statb
.st_size
> LONG_MAX
) ||
146 ((strings
= malloc((size_t)statb
.st_size
+ 1)) == NULL
)) {
148 return ((char **)okshells
);
150 shells
= calloc((size_t)statb
.st_size
/ 3, sizeof (char *));
151 if (shells
== NULL
) {
153 (void) free(strings
);
155 return ((char **)okshells
);
159 while (fgets(cp
, MAXPATHLEN
+ 1, fp
) != NULL
) {
160 while (*cp
!= '#' && *cp
!= '/' && *cp
!= '\0')
162 if (*cp
== '#' || *cp
== '\0')
165 while (!isspace(*cp
) && *cp
!= '#' && *cp
!= '\0')