1 /* 2 * Copyright (c) 1985 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)getusershell.c 5.7 (Berkeley) 02/23/91"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/param.h> 13 #include <sys/file.h> 14 #include <sys/stat.h> 15 #include <ctype.h> 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <unistd.h> 19 20 #define SHELLS "/etc/shells" 21 22 /* 23 * Do not add local shells here. They should be added in /etc/shells 24 */ 25 static char *okshells[] = 26 { "/bin/sh", "/bin/csh", 0 }; 27 28 static char **shells, *strings; 29 static char **curshell = NULL; 30 extern char **initshells(); 31 32 /* 33 * Get a list of shells from SHELLS, if it exists. 34 */ 35 char * 36 getusershell() 37 { 38 char *ret; 39 40 if (curshell == NULL) 41 curshell = initshells(); 42 ret = *curshell; 43 if (ret != NULL) 44 curshell++; 45 return (ret); 46 } 47 48 void 49 endusershell() 50 { 51 52 if (shells != NULL) 53 free((char *)shells); 54 shells = NULL; 55 if (strings != NULL) 56 free(strings); 57 strings = NULL; 58 curshell = NULL; 59 } 60 61 void 62 setusershell() 63 { 64 65 curshell = initshells(); 66 } 67 68 static char ** 69 initshells() 70 { 71 register char **sp, *cp; 72 register FILE *fp; 73 struct stat statb; 74 75 if (shells != NULL) 76 free((char *)shells); 77 shells = NULL; 78 if (strings != NULL) 79 free(strings); 80 strings = NULL; 81 if ((fp = fopen(SHELLS, "r")) == (FILE *)0) 82 return(okshells); 83 if (fstat(fileno(fp), &statb) == -1) { 84 (void)fclose(fp); 85 return(okshells); 86 } 87 if ((strings = malloc((unsigned)statb.st_size)) == NULL) { 88 (void)fclose(fp); 89 return(okshells); 90 } 91 shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *)); 92 if (shells == NULL) { 93 (void)fclose(fp); 94 free(strings); 95 strings = NULL; 96 return(okshells); 97 } 98 sp = shells; 99 cp = strings; 100 while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) { 101 while (*cp != '#' && *cp != '/' && *cp != '\0') 102 cp++; 103 if (*cp == '#' || *cp == '\0') 104 continue; 105 *sp++ = cp; 106 while (!isspace(*cp) && *cp != '#' && *cp != '\0') 107 cp++; 108 *cp++ = '\0'; 109 } 110 *sp = (char *)0; 111 (void)fclose(fp); 112 return (shells); 113 } 114