xref: /csrg-svn/lib/libc/gen/getusershell.c (revision 35109)
125429Smckusick /*
225429Smckusick  * Copyright (c) 1985 Regents of the University of California.
3*35109Sbostic  * All rights reserved.
4*35109Sbostic  *
5*35109Sbostic  * Redistribution and use in source and binary forms are permitted
6*35109Sbostic  * provided that the above copyright notice and this paragraph are
7*35109Sbostic  * duplicated in all such forms and that any documentation,
8*35109Sbostic  * advertising materials, and other materials related to such
9*35109Sbostic  * distribution and use acknowledge that the software was developed
10*35109Sbostic  * by the University of California, Berkeley.  The name of the
11*35109Sbostic  * University may not be used to endorse or promote products derived
12*35109Sbostic  * from this software without specific prior written permission.
13*35109Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*35109Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*35109Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1625429Smckusick  */
1725429Smckusick 
1826564Sdonn #if defined(LIBC_SCCS) && !defined(lint)
19*35109Sbostic static char sccsid[] = "@(#)getusershell.c	5.5 (Berkeley) 07/21/88";
20*35109Sbostic #endif /* LIBC_SCCS and not lint */
2125429Smckusick 
2225429Smckusick #include <sys/param.h>
2325429Smckusick #include <sys/file.h>
2425429Smckusick #include <sys/stat.h>
2525429Smckusick #include <ctype.h>
2625429Smckusick #include <stdio.h>
2725429Smckusick 
2825429Smckusick #define SHELLS "/etc/shells"
2925429Smckusick 
3025429Smckusick /*
3125429Smckusick  * Do not add local shells here.  They should be added in /etc/shells
3225429Smckusick  */
3325429Smckusick static char *okshells[] =
3425429Smckusick     { "/bin/sh", "/bin/csh", 0 };
3525429Smckusick 
3625429Smckusick static char **shells, *strings;
3729662Sbloom static char **curshell = NULL;
3825429Smckusick extern char **initshells();
3925429Smckusick 
4025429Smckusick /*
4125429Smckusick  * Get a list of shells from SHELLS, if it exists.
4225429Smckusick  */
4325429Smckusick char *
4425429Smckusick getusershell()
4525429Smckusick {
4625429Smckusick 	char *ret;
4725429Smckusick 
4829662Sbloom 	if (curshell == NULL)
4929662Sbloom 		curshell = initshells();
5029662Sbloom 	ret = *curshell;
5129662Sbloom 	if (ret != NULL)
5229662Sbloom 		curshell++;
5325429Smckusick 	return (ret);
5425429Smckusick }
5525429Smckusick 
5625429Smckusick endusershell()
5725429Smckusick {
5825429Smckusick 
5925429Smckusick 	if (shells != NULL)
6025429Smckusick 		free((char *)shells);
6125429Smckusick 	shells = NULL;
6225429Smckusick 	if (strings != NULL)
6325429Smckusick 		free(strings);
6425429Smckusick 	strings = NULL;
6529662Sbloom 	curshell = NULL;
6625429Smckusick }
6725429Smckusick 
6825429Smckusick setusershell()
6925429Smckusick {
7025429Smckusick 
7129662Sbloom 	curshell = initshells();
7225429Smckusick }
7325429Smckusick 
7425429Smckusick static char **
7525429Smckusick initshells()
7625429Smckusick {
7725429Smckusick 	register char **sp, *cp;
7825429Smckusick 	register FILE *fp;
7925429Smckusick 	struct stat statb;
8025429Smckusick 	extern char *malloc(), *calloc();
8125429Smckusick 
8225429Smckusick 	if (shells != NULL)
8325429Smckusick 		free((char *)shells);
8425429Smckusick 	shells = NULL;
8525429Smckusick 	if (strings != NULL)
8625429Smckusick 		free(strings);
8725429Smckusick 	strings = NULL;
8825429Smckusick 	if ((fp = fopen(SHELLS, "r")) == (FILE *)0)
8925429Smckusick 		return(okshells);
9025429Smckusick 	if (fstat(fileno(fp), &statb) == -1) {
9125429Smckusick 		(void)fclose(fp);
9225429Smckusick 		return(okshells);
9325429Smckusick 	}
9425429Smckusick 	if ((strings = malloc((unsigned)statb.st_size)) == NULL) {
9525429Smckusick 		(void)fclose(fp);
9625429Smckusick 		return(okshells);
9725429Smckusick 	}
9825429Smckusick 	shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *));
9925429Smckusick 	if (shells == NULL) {
10025429Smckusick 		(void)fclose(fp);
10125429Smckusick 		free(strings);
10225429Smckusick 		strings = NULL;
10325429Smckusick 		return(okshells);
10425429Smckusick 	}
10525429Smckusick 	sp = shells;
10625429Smckusick 	cp = strings;
10725429Smckusick 	while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
10829662Sbloom 		while (*cp != '#' && *cp != '/' && *cp != '\0')
10925429Smckusick 			cp++;
11029662Sbloom 		if (*cp == '#' || *cp == '\0')
11125429Smckusick 			continue;
11225429Smckusick 		*sp++ = cp;
11325429Smckusick 		while (!isspace(*cp) && *cp != '#' && *cp != '\0')
11425429Smckusick 			cp++;
11525429Smckusick 		*cp++ = '\0';
11625429Smckusick 	}
11725429Smckusick 	*sp = (char *)0;
11825429Smckusick 	(void)fclose(fp);
11925429Smckusick 	return (shells);
12025429Smckusick }
121