xref: /csrg-svn/lib/libc/gen/getusershell.c (revision 42625)
125429Smckusick /*
225429Smckusick  * Copyright (c) 1985 Regents of the University of California.
335109Sbostic  * All rights reserved.
435109Sbostic  *
5*42625Sbostic  * %sccs.include.redist.c%
625429Smckusick  */
725429Smckusick 
826564Sdonn #if defined(LIBC_SCCS) && !defined(lint)
9*42625Sbostic static char sccsid[] = "@(#)getusershell.c	5.6 (Berkeley) 06/01/90";
1035109Sbostic #endif /* LIBC_SCCS and not lint */
1125429Smckusick 
1225429Smckusick #include <sys/param.h>
1325429Smckusick #include <sys/file.h>
1425429Smckusick #include <sys/stat.h>
1525429Smckusick #include <ctype.h>
1625429Smckusick #include <stdio.h>
1725429Smckusick 
1825429Smckusick #define SHELLS "/etc/shells"
1925429Smckusick 
2025429Smckusick /*
2125429Smckusick  * Do not add local shells here.  They should be added in /etc/shells
2225429Smckusick  */
2325429Smckusick static char *okshells[] =
2425429Smckusick     { "/bin/sh", "/bin/csh", 0 };
2525429Smckusick 
2625429Smckusick static char **shells, *strings;
2729662Sbloom static char **curshell = NULL;
2825429Smckusick extern char **initshells();
2925429Smckusick 
3025429Smckusick /*
3125429Smckusick  * Get a list of shells from SHELLS, if it exists.
3225429Smckusick  */
3325429Smckusick char *
3425429Smckusick getusershell()
3525429Smckusick {
3625429Smckusick 	char *ret;
3725429Smckusick 
3829662Sbloom 	if (curshell == NULL)
3929662Sbloom 		curshell = initshells();
4029662Sbloom 	ret = *curshell;
4129662Sbloom 	if (ret != NULL)
4229662Sbloom 		curshell++;
4325429Smckusick 	return (ret);
4425429Smckusick }
4525429Smckusick 
4625429Smckusick endusershell()
4725429Smckusick {
4825429Smckusick 
4925429Smckusick 	if (shells != NULL)
5025429Smckusick 		free((char *)shells);
5125429Smckusick 	shells = NULL;
5225429Smckusick 	if (strings != NULL)
5325429Smckusick 		free(strings);
5425429Smckusick 	strings = NULL;
5529662Sbloom 	curshell = NULL;
5625429Smckusick }
5725429Smckusick 
5825429Smckusick setusershell()
5925429Smckusick {
6025429Smckusick 
6129662Sbloom 	curshell = initshells();
6225429Smckusick }
6325429Smckusick 
6425429Smckusick static char **
6525429Smckusick initshells()
6625429Smckusick {
6725429Smckusick 	register char **sp, *cp;
6825429Smckusick 	register FILE *fp;
6925429Smckusick 	struct stat statb;
7025429Smckusick 	extern char *malloc(), *calloc();
7125429Smckusick 
7225429Smckusick 	if (shells != NULL)
7325429Smckusick 		free((char *)shells);
7425429Smckusick 	shells = NULL;
7525429Smckusick 	if (strings != NULL)
7625429Smckusick 		free(strings);
7725429Smckusick 	strings = NULL;
7825429Smckusick 	if ((fp = fopen(SHELLS, "r")) == (FILE *)0)
7925429Smckusick 		return(okshells);
8025429Smckusick 	if (fstat(fileno(fp), &statb) == -1) {
8125429Smckusick 		(void)fclose(fp);
8225429Smckusick 		return(okshells);
8325429Smckusick 	}
8425429Smckusick 	if ((strings = malloc((unsigned)statb.st_size)) == NULL) {
8525429Smckusick 		(void)fclose(fp);
8625429Smckusick 		return(okshells);
8725429Smckusick 	}
8825429Smckusick 	shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *));
8925429Smckusick 	if (shells == NULL) {
9025429Smckusick 		(void)fclose(fp);
9125429Smckusick 		free(strings);
9225429Smckusick 		strings = NULL;
9325429Smckusick 		return(okshells);
9425429Smckusick 	}
9525429Smckusick 	sp = shells;
9625429Smckusick 	cp = strings;
9725429Smckusick 	while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
9829662Sbloom 		while (*cp != '#' && *cp != '/' && *cp != '\0')
9925429Smckusick 			cp++;
10029662Sbloom 		if (*cp == '#' || *cp == '\0')
10125429Smckusick 			continue;
10225429Smckusick 		*sp++ = cp;
10325429Smckusick 		while (!isspace(*cp) && *cp != '#' && *cp != '\0')
10425429Smckusick 			cp++;
10525429Smckusick 		*cp++ = '\0';
10625429Smckusick 	}
10725429Smckusick 	*sp = (char *)0;
10825429Smckusick 	(void)fclose(fp);
10925429Smckusick 	return (shells);
11025429Smckusick }
111