xref: /original-bsd/lib/libc/gen/getusershell.c (revision 241757c4)
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 #if defined(LIBC_SCCS) && !defined(lint)
8 static char sccsid[] = "@(#)getusershell.c	5.4 (Berkeley) 07/25/86";
9 #endif LIBC_SCCS and not lint
10 
11 #include <sys/param.h>
12 #include <sys/file.h>
13 #include <sys/stat.h>
14 #include <ctype.h>
15 #include <stdio.h>
16 
17 #define SHELLS "/etc/shells"
18 
19 /*
20  * Do not add local shells here.  They should be added in /etc/shells
21  */
22 static char *okshells[] =
23     { "/bin/sh", "/bin/csh", 0 };
24 
25 static char **shells, *strings;
26 static char **curshell = NULL;
27 extern char **initshells();
28 
29 /*
30  * Get a list of shells from SHELLS, if it exists.
31  */
32 char *
33 getusershell()
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 endusershell()
46 {
47 
48 	if (shells != NULL)
49 		free((char *)shells);
50 	shells = NULL;
51 	if (strings != NULL)
52 		free(strings);
53 	strings = NULL;
54 	curshell = NULL;
55 }
56 
57 setusershell()
58 {
59 
60 	curshell = initshells();
61 }
62 
63 static char **
64 initshells()
65 {
66 	register char **sp, *cp;
67 	register FILE *fp;
68 	struct stat statb;
69 	extern char *malloc(), *calloc();
70 
71 	if (shells != NULL)
72 		free((char *)shells);
73 	shells = NULL;
74 	if (strings != NULL)
75 		free(strings);
76 	strings = NULL;
77 	if ((fp = fopen(SHELLS, "r")) == (FILE *)0)
78 		return(okshells);
79 	if (fstat(fileno(fp), &statb) == -1) {
80 		(void)fclose(fp);
81 		return(okshells);
82 	}
83 	if ((strings = malloc((unsigned)statb.st_size)) == NULL) {
84 		(void)fclose(fp);
85 		return(okshells);
86 	}
87 	shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *));
88 	if (shells == NULL) {
89 		(void)fclose(fp);
90 		free(strings);
91 		strings = NULL;
92 		return(okshells);
93 	}
94 	sp = shells;
95 	cp = strings;
96 	while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
97 		while (*cp != '#' && *cp != '/' && *cp != '\0')
98 			cp++;
99 		if (*cp == '#' || *cp == '\0')
100 			continue;
101 		*sp++ = cp;
102 		while (!isspace(*cp) && *cp != '#' && *cp != '\0')
103 			cp++;
104 		*cp++ = '\0';
105 	}
106 	*sp = (char *)0;
107 	(void)fclose(fp);
108 	return (shells);
109 }
110