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.6 (Berkeley) 06/01/90"; 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 18 #define SHELLS "/etc/shells" 19 20 /* 21 * Do not add local shells here. They should be added in /etc/shells 22 */ 23 static char *okshells[] = 24 { "/bin/sh", "/bin/csh", 0 }; 25 26 static char **shells, *strings; 27 static char **curshell = NULL; 28 extern char **initshells(); 29 30 /* 31 * Get a list of shells from SHELLS, if it exists. 32 */ 33 char * 34 getusershell() 35 { 36 char *ret; 37 38 if (curshell == NULL) 39 curshell = initshells(); 40 ret = *curshell; 41 if (ret != NULL) 42 curshell++; 43 return (ret); 44 } 45 46 endusershell() 47 { 48 49 if (shells != NULL) 50 free((char *)shells); 51 shells = NULL; 52 if (strings != NULL) 53 free(strings); 54 strings = NULL; 55 curshell = NULL; 56 } 57 58 setusershell() 59 { 60 61 curshell = initshells(); 62 } 63 64 static char ** 65 initshells() 66 { 67 register char **sp, *cp; 68 register FILE *fp; 69 struct stat statb; 70 extern char *malloc(), *calloc(); 71 72 if (shells != NULL) 73 free((char *)shells); 74 shells = NULL; 75 if (strings != NULL) 76 free(strings); 77 strings = NULL; 78 if ((fp = fopen(SHELLS, "r")) == (FILE *)0) 79 return(okshells); 80 if (fstat(fileno(fp), &statb) == -1) { 81 (void)fclose(fp); 82 return(okshells); 83 } 84 if ((strings = malloc((unsigned)statb.st_size)) == NULL) { 85 (void)fclose(fp); 86 return(okshells); 87 } 88 shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *)); 89 if (shells == NULL) { 90 (void)fclose(fp); 91 free(strings); 92 strings = NULL; 93 return(okshells); 94 } 95 sp = shells; 96 cp = strings; 97 while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) { 98 while (*cp != '#' && *cp != '/' && *cp != '\0') 99 cp++; 100 if (*cp == '#' || *cp == '\0') 101 continue; 102 *sp++ = cp; 103 while (!isspace(*cp) && *cp != '#' && *cp != '\0') 104 cp++; 105 *cp++ = '\0'; 106 } 107 *sp = (char *)0; 108 (void)fclose(fp); 109 return (shells); 110 } 111