xref: /csrg-svn/lib/libc/gen/getusershell.c (revision 29662)
125429Smckusick /*
225429Smckusick  * Copyright (c) 1985 Regents of the University of California.
325429Smckusick  * All rights reserved.  The Berkeley software License Agreement
425429Smckusick  * specifies the terms and conditions for redistribution.
525429Smckusick  */
625429Smckusick 
726564Sdonn #if defined(LIBC_SCCS) && !defined(lint)
8*29662Sbloom static char sccsid[] = "@(#)getusershell.c	5.4 (Berkeley) 07/25/86";
926564Sdonn #endif LIBC_SCCS and not lint
1025429Smckusick 
1125429Smckusick #include <sys/param.h>
1225429Smckusick #include <sys/file.h>
1325429Smckusick #include <sys/stat.h>
1425429Smckusick #include <ctype.h>
1525429Smckusick #include <stdio.h>
1625429Smckusick 
1725429Smckusick #define SHELLS "/etc/shells"
1825429Smckusick 
1925429Smckusick /*
2025429Smckusick  * Do not add local shells here.  They should be added in /etc/shells
2125429Smckusick  */
2225429Smckusick static char *okshells[] =
2325429Smckusick     { "/bin/sh", "/bin/csh", 0 };
2425429Smckusick 
2525429Smckusick static char **shells, *strings;
26*29662Sbloom static char **curshell = NULL;
2725429Smckusick extern char **initshells();
2825429Smckusick 
2925429Smckusick /*
3025429Smckusick  * Get a list of shells from SHELLS, if it exists.
3125429Smckusick  */
3225429Smckusick char *
3325429Smckusick getusershell()
3425429Smckusick {
3525429Smckusick 	char *ret;
3625429Smckusick 
37*29662Sbloom 	if (curshell == NULL)
38*29662Sbloom 		curshell = initshells();
39*29662Sbloom 	ret = *curshell;
40*29662Sbloom 	if (ret != NULL)
41*29662Sbloom 		curshell++;
4225429Smckusick 	return (ret);
4325429Smckusick }
4425429Smckusick 
4525429Smckusick endusershell()
4625429Smckusick {
4725429Smckusick 
4825429Smckusick 	if (shells != NULL)
4925429Smckusick 		free((char *)shells);
5025429Smckusick 	shells = NULL;
5125429Smckusick 	if (strings != NULL)
5225429Smckusick 		free(strings);
5325429Smckusick 	strings = NULL;
54*29662Sbloom 	curshell = NULL;
5525429Smckusick }
5625429Smckusick 
5725429Smckusick setusershell()
5825429Smckusick {
5925429Smckusick 
60*29662Sbloom 	curshell = initshells();
6125429Smckusick }
6225429Smckusick 
6325429Smckusick static char **
6425429Smckusick initshells()
6525429Smckusick {
6625429Smckusick 	register char **sp, *cp;
6725429Smckusick 	register FILE *fp;
6825429Smckusick 	struct stat statb;
6925429Smckusick 	extern char *malloc(), *calloc();
7025429Smckusick 
7125429Smckusick 	if (shells != NULL)
7225429Smckusick 		free((char *)shells);
7325429Smckusick 	shells = NULL;
7425429Smckusick 	if (strings != NULL)
7525429Smckusick 		free(strings);
7625429Smckusick 	strings = NULL;
7725429Smckusick 	if ((fp = fopen(SHELLS, "r")) == (FILE *)0)
7825429Smckusick 		return(okshells);
7925429Smckusick 	if (fstat(fileno(fp), &statb) == -1) {
8025429Smckusick 		(void)fclose(fp);
8125429Smckusick 		return(okshells);
8225429Smckusick 	}
8325429Smckusick 	if ((strings = malloc((unsigned)statb.st_size)) == NULL) {
8425429Smckusick 		(void)fclose(fp);
8525429Smckusick 		return(okshells);
8625429Smckusick 	}
8725429Smckusick 	shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *));
8825429Smckusick 	if (shells == NULL) {
8925429Smckusick 		(void)fclose(fp);
9025429Smckusick 		free(strings);
9125429Smckusick 		strings = NULL;
9225429Smckusick 		return(okshells);
9325429Smckusick 	}
9425429Smckusick 	sp = shells;
9525429Smckusick 	cp = strings;
9625429Smckusick 	while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
97*29662Sbloom 		while (*cp != '#' && *cp != '/' && *cp != '\0')
9825429Smckusick 			cp++;
99*29662Sbloom 		if (*cp == '#' || *cp == '\0')
10025429Smckusick 			continue;
10125429Smckusick 		*sp++ = cp;
10225429Smckusick 		while (!isspace(*cp) && *cp != '#' && *cp != '\0')
10325429Smckusick 			cp++;
10425429Smckusick 		*cp++ = '\0';
10525429Smckusick 	}
10625429Smckusick 	*sp = (char *)0;
10725429Smckusick 	(void)fclose(fp);
10825429Smckusick 	return (shells);
10925429Smckusick }
110