xref: /titanic_52/usr/src/lib/libbc/libc/gen/common/getusershell.c (revision b02e9a2d4d2071d770e5aa9ae8f83f2bbe1f2ced)
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 *
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
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
59 setusershell(void)
60 {
61 
62 	curshell = initshells();
63 }
64 
65 static char **
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