xref: /csrg-svn/lib/libc/gen/getusershell.c (revision 29571)
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.3 (Berkeley) 07/18/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 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 		if (*cp == '#')
100 			continue;
101 		while (*cp != '/' && *cp != '\0')
102 			cp++;
103 		if (*cp == '\0')
104 			continue;
105 		*sp++ = cp;
106 		while (!isspace(*cp) && *cp != '#' && *cp != '\0')
107 			cp++;
108 		*cp++ = '\0';
109 	}
110 	*sp = (char *)0;
111 	(void)fclose(fp);
112 	return (shells);
113 }
114