1 /*
2 * Copyright (c) 1985 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7 #pragma ident "%Z%%M% %I% %E% SMI"
8
9 #include <sys/param.h>
10 #include <sys/file.h>
11 #include <sys/stat.h>
12 #include <ctype.h>
13 #include <stdio.h>
14 #include <malloc.h>
15
16 #define SHELLS "/etc/shells"
17
18 /*
19 * Do not add local shells here. They should be added in /etc/shells
20 */
21 static char *okshells[] =
22 { "/bin/sh", "/bin/csh", "/usr/bin/sh", "/usr/bin/csh", 0 };
23
24 static char **shells, *strings;
25 static char **curshell;
26
27 static char **initshells(void);
28
29 /*
30 * Get a list of shells from SHELLS, if it exists.
31 */
32 char *
getusershell(void)33 getusershell(void)
34 {
35 char *ret;
36
37 if (curshell == NULL)
38 curshell = initshells();
39 ret = *curshell;
40 if (ret != NULL)
41 curshell++;
42 return (ret);
43 }
44
45 void
endusershell(void)46 endusershell(void)
47 {
48
49 if (shells != NULL)
50 free((char *)shells);
51 shells = NULL;
52 if (strings != NULL)
53 free(strings);
54 strings = NULL;
55 curshell = NULL;
56 }
57
58 void
setusershell(void)59 setusershell(void)
60 {
61
62 curshell = initshells();
63 }
64
65 static char **
initshells(void)66 initshells(void)
67 {
68 char **sp, *cp;
69 FILE *fp;
70 struct stat statb;
71
72 if (shells != NULL)
73 free((char *)shells);
74 shells = NULL;
75 if (strings != NULL)
76 free(strings);
77 strings = NULL;
78 if ((fp = fopen(SHELLS, "r")) == (FILE *)0)
79 return (okshells);
80 if (fstat(fileno(fp), &statb) == -1) {
81 (void)fclose(fp);
82 return (okshells);
83 }
84 if ((strings = malloc((unsigned)statb.st_size + 1)) == NULL) {
85 (void)fclose(fp);
86 return (okshells);
87 }
88 shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *));
89 if (shells == NULL) {
90 (void)fclose(fp);
91 free(strings);
92 strings = NULL;
93 return (okshells);
94 }
95 sp = shells;
96 cp = strings;
97 while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
98 while (*cp != '#' && *cp != '/' && *cp != '\0')
99 cp++;
100 if (*cp == '#' || *cp == '\0')
101 continue;
102 *sp++ = cp;
103 while (!isspace(*cp) && *cp != '#' && *cp != '\0')
104 cp++;
105 *cp++ = '\0';
106 }
107 *sp = (char *)0;
108 (void)fclose(fp);
109 return (shells);
110 }
111