xref: /csrg-svn/lib/libc/gen/getusershell.c (revision 26564)
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 
7*26564Sdonn #if defined(LIBC_SCCS) && !defined(lint)
8*26564Sdonn static char sccsid[] = "@(#)getusershell.c	5.2 (Berkeley) 03/09/86";
9*26564Sdonn #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 int inprogress;
2625429Smckusick static char **shells, *strings;
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 	static char **shells;
3725429Smckusick 
3825429Smckusick 	if (!inprogress)
3925429Smckusick 		shells = initshells();
4025429Smckusick 	ret = *shells;
4125429Smckusick 	if (*shells != NULL)
4225429Smckusick 		shells++;
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;
5525429Smckusick 	inprogress = 0;
5625429Smckusick }
5725429Smckusick 
5825429Smckusick setusershell()
5925429Smckusick {
6025429Smckusick 
6125429Smckusick 	shells = 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 	inprogress = 1;
7325429Smckusick 	if (shells != NULL)
7425429Smckusick 		free((char *)shells);
7525429Smckusick 	shells = NULL;
7625429Smckusick 	if (strings != NULL)
7725429Smckusick 		free(strings);
7825429Smckusick 	strings = NULL;
7925429Smckusick 	if ((fp = fopen(SHELLS, "r")) == (FILE *)0)
8025429Smckusick 		return(okshells);
8125429Smckusick 	if (fstat(fileno(fp), &statb) == -1) {
8225429Smckusick 		(void)fclose(fp);
8325429Smckusick 		return(okshells);
8425429Smckusick 	}
8525429Smckusick 	if ((strings = malloc((unsigned)statb.st_size)) == NULL) {
8625429Smckusick 		(void)fclose(fp);
8725429Smckusick 		return(okshells);
8825429Smckusick 	}
8925429Smckusick 	shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *));
9025429Smckusick 	if (shells == NULL) {
9125429Smckusick 		(void)fclose(fp);
9225429Smckusick 		free(strings);
9325429Smckusick 		strings = NULL;
9425429Smckusick 		return(okshells);
9525429Smckusick 	}
9625429Smckusick 	sp = shells;
9725429Smckusick 	cp = strings;
9825429Smckusick 	while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
9925429Smckusick 		while (*cp != '/' && *cp != '\0')
10025429Smckusick 			cp++;
10125429Smckusick 		if (*cp == '\0')
10225429Smckusick 			continue;
10325429Smckusick 		*sp++ = cp;
10425429Smckusick 		while (!isspace(*cp) && *cp != '#' && *cp != '\0')
10525429Smckusick 			cp++;
10625429Smckusick 		*cp++ = '\0';
10725429Smckusick 	}
10825429Smckusick 	*sp = (char *)0;
10925429Smckusick 	(void)fclose(fp);
11025429Smckusick 	return (shells);
11125429Smckusick }
112