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