1 /* 2 * Copyright (c) 1985 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #if defined(LIBC_SCCS) && !defined(lint) 8 static char sccsid[] = "@(#)getusershell.c 5.3 (Berkeley) 07/18/86"; 9 #endif LIBC_SCCS and not lint 10 11 #include <sys/param.h> 12 #include <sys/file.h> 13 #include <sys/stat.h> 14 #include <ctype.h> 15 #include <stdio.h> 16 17 #define SHELLS "/etc/shells" 18 19 /* 20 * Do not add local shells here. They should be added in /etc/shells 21 */ 22 static char *okshells[] = 23 { "/bin/sh", "/bin/csh", 0 }; 24 25 static int inprogress; 26 static char **shells, *strings; 27 extern char **initshells(); 28 29 /* 30 * Get a list of shells from SHELLS, if it exists. 31 */ 32 char * 33 getusershell() 34 { 35 char *ret; 36 static char **shells; 37 38 if (!inprogress) 39 shells = initshells(); 40 ret = *shells; 41 if (*shells != NULL) 42 shells++; 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 inprogress = 0; 56 } 57 58 setusershell() 59 { 60 61 shells = 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 inprogress = 1; 73 if (shells != NULL) 74 free((char *)shells); 75 shells = NULL; 76 if (strings != NULL) 77 free(strings); 78 strings = NULL; 79 if ((fp = fopen(SHELLS, "r")) == (FILE *)0) 80 return(okshells); 81 if (fstat(fileno(fp), &statb) == -1) { 82 (void)fclose(fp); 83 return(okshells); 84 } 85 if ((strings = malloc((unsigned)statb.st_size)) == NULL) { 86 (void)fclose(fp); 87 return(okshells); 88 } 89 shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *)); 90 if (shells == NULL) { 91 (void)fclose(fp); 92 free(strings); 93 strings = NULL; 94 return(okshells); 95 } 96 sp = shells; 97 cp = strings; 98 while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) { 99 if (*cp == '#') 100 continue; 101 while (*cp != '/' && *cp != '\0') 102 cp++; 103 if (*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