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