xref: /csrg-svn/lib/libc/gen/getusershell.c (revision 46597)
125429Smckusick /*
225429Smckusick  * Copyright (c) 1985 Regents of the University of California.
335109Sbostic  * All rights reserved.
435109Sbostic  *
542625Sbostic  * %sccs.include.redist.c%
625429Smckusick  */
725429Smckusick 
826564Sdonn #if defined(LIBC_SCCS) && !defined(lint)
9*46597Sdonn static char sccsid[] = "@(#)getusershell.c	5.7 (Berkeley) 02/23/91";
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>
17*46597Sdonn #include <stdlib.h>
18*46597Sdonn #include <unistd.h>
1925429Smckusick 
2025429Smckusick #define SHELLS "/etc/shells"
2125429Smckusick 
2225429Smckusick /*
2325429Smckusick  * Do not add local shells here.  They should be added in /etc/shells
2425429Smckusick  */
2525429Smckusick static char *okshells[] =
2625429Smckusick     { "/bin/sh", "/bin/csh", 0 };
2725429Smckusick 
2825429Smckusick static char **shells, *strings;
2929662Sbloom static char **curshell = NULL;
3025429Smckusick extern char **initshells();
3125429Smckusick 
3225429Smckusick /*
3325429Smckusick  * Get a list of shells from SHELLS, if it exists.
3425429Smckusick  */
3525429Smckusick char *
3625429Smckusick getusershell()
3725429Smckusick {
3825429Smckusick 	char *ret;
3925429Smckusick 
4029662Sbloom 	if (curshell == NULL)
4129662Sbloom 		curshell = initshells();
4229662Sbloom 	ret = *curshell;
4329662Sbloom 	if (ret != NULL)
4429662Sbloom 		curshell++;
4525429Smckusick 	return (ret);
4625429Smckusick }
4725429Smckusick 
48*46597Sdonn void
4925429Smckusick endusershell()
5025429Smckusick {
5125429Smckusick 
5225429Smckusick 	if (shells != NULL)
5325429Smckusick 		free((char *)shells);
5425429Smckusick 	shells = NULL;
5525429Smckusick 	if (strings != NULL)
5625429Smckusick 		free(strings);
5725429Smckusick 	strings = NULL;
5829662Sbloom 	curshell = NULL;
5925429Smckusick }
6025429Smckusick 
61*46597Sdonn void
6225429Smckusick setusershell()
6325429Smckusick {
6425429Smckusick 
6529662Sbloom 	curshell = initshells();
6625429Smckusick }
6725429Smckusick 
6825429Smckusick static char **
6925429Smckusick initshells()
7025429Smckusick {
7125429Smckusick 	register char **sp, *cp;
7225429Smckusick 	register FILE *fp;
7325429Smckusick 	struct stat statb;
7425429Smckusick 
7525429Smckusick 	if (shells != NULL)
7625429Smckusick 		free((char *)shells);
7725429Smckusick 	shells = NULL;
7825429Smckusick 	if (strings != NULL)
7925429Smckusick 		free(strings);
8025429Smckusick 	strings = NULL;
8125429Smckusick 	if ((fp = fopen(SHELLS, "r")) == (FILE *)0)
8225429Smckusick 		return(okshells);
8325429Smckusick 	if (fstat(fileno(fp), &statb) == -1) {
8425429Smckusick 		(void)fclose(fp);
8525429Smckusick 		return(okshells);
8625429Smckusick 	}
8725429Smckusick 	if ((strings = malloc((unsigned)statb.st_size)) == NULL) {
8825429Smckusick 		(void)fclose(fp);
8925429Smckusick 		return(okshells);
9025429Smckusick 	}
9125429Smckusick 	shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *));
9225429Smckusick 	if (shells == NULL) {
9325429Smckusick 		(void)fclose(fp);
9425429Smckusick 		free(strings);
9525429Smckusick 		strings = NULL;
9625429Smckusick 		return(okshells);
9725429Smckusick 	}
9825429Smckusick 	sp = shells;
9925429Smckusick 	cp = strings;
10025429Smckusick 	while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
10129662Sbloom 		while (*cp != '#' && *cp != '/' && *cp != '\0')
10225429Smckusick 			cp++;
10329662Sbloom 		if (*cp == '#' || *cp == '\0')
10425429Smckusick 			continue;
10525429Smckusick 		*sp++ = cp;
10625429Smckusick 		while (!isspace(*cp) && *cp != '#' && *cp != '\0')
10725429Smckusick 			cp++;
10825429Smckusick 		*cp++ = '\0';
10925429Smckusick 	}
11025429Smckusick 	*sp = (char *)0;
11125429Smckusick 	(void)fclose(fp);
11225429Smckusick 	return (shells);
11325429Smckusick }
114