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