xref: /csrg-svn/lib/libc/gen/getusershell.c (revision 25429)
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 #ifndef lint
8 static char sccsid[] = "@(#)getusershell.c	5.1 (Berkeley) 11/08/85";
9 #endif 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 int inprogress;
26 static char **shells, *strings;
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 	static char **shells;
37 
38 	if (!inprogress)
39 		shells = initshells();
40 	ret = *shells;
41 	if (*shells != NULL)
42 		shells++;
43 	return (ret);
44 }
45 
46 endusershell()
47 {
48 
49 	if (shells != NULL)
50 		free((char *)shells);
51 	shells = NULL;
52 	if (strings != NULL)
53 		free(strings);
54 	strings = NULL;
55 	inprogress = 0;
56 }
57 
58 setusershell()
59 {
60 
61 	shells = initshells();
62 }
63 
64 static char **
65 initshells()
66 {
67 	register char **sp, *cp;
68 	register FILE *fp;
69 	struct stat statb;
70 	extern char *malloc(), *calloc();
71 
72 	inprogress = 1;
73 	if (shells != NULL)
74 		free((char *)shells);
75 	shells = NULL;
76 	if (strings != NULL)
77 		free(strings);
78 	strings = NULL;
79 	if ((fp = fopen(SHELLS, "r")) == (FILE *)0)
80 		return(okshells);
81 	if (fstat(fileno(fp), &statb) == -1) {
82 		(void)fclose(fp);
83 		return(okshells);
84 	}
85 	if ((strings = malloc((unsigned)statb.st_size)) == NULL) {
86 		(void)fclose(fp);
87 		return(okshells);
88 	}
89 	shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *));
90 	if (shells == NULL) {
91 		(void)fclose(fp);
92 		free(strings);
93 		strings = NULL;
94 		return(okshells);
95 	}
96 	sp = shells;
97 	cp = strings;
98 	while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
99 		while (*cp != '/' && *cp != '\0')
100 			cp++;
101 		if (*cp == '\0')
102 			continue;
103 		*sp++ = cp;
104 		while (!isspace(*cp) && *cp != '#' && *cp != '\0')
105 			cp++;
106 		*cp++ = '\0';
107 	}
108 	*sp = (char *)0;
109 	(void)fclose(fp);
110 	return (shells);
111 }
112