1 /* 2 * Copyright (c) 1985, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)getusershell.c 8.1 (Berkeley) 06/04/93"; 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 <stdio.h> 16 #include <ctype.h> 17 #include <stdlib.h> 18 #include <unistd.h> 19 #include <paths.h> 20 21 /* 22 * Local shells should NOT be added here. They should be added in 23 * /etc/shells. 24 */ 25 26 static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; 27 static char **curshell, **shells, *strings; 28 static char **initshells __P((void)); 29 30 /* 31 * Get a list of shells from _PATH_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 void 47 endusershell() 48 { 49 50 if (shells != NULL) 51 free(shells); 52 shells = NULL; 53 if (strings != NULL) 54 free(strings); 55 strings = NULL; 56 curshell = NULL; 57 } 58 59 void 60 setusershell() 61 { 62 63 curshell = initshells(); 64 } 65 66 static char ** 67 initshells() 68 { 69 register char **sp, *cp; 70 register FILE *fp; 71 struct stat statb; 72 73 if (shells != NULL) 74 free(shells); 75 shells = NULL; 76 if (strings != NULL) 77 free(strings); 78 strings = NULL; 79 if ((fp = fopen(_PATH_SHELLS, "r")) == NULL) 80 return (okshells); 81 if (fstat(fileno(fp), &statb) == -1) { 82 (void)fclose(fp); 83 return (okshells); 84 } 85 if ((strings = malloc((u_int)statb.st_size)) == NULL) { 86 (void)fclose(fp); 87 return (okshells); 88 } 89 shells = 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 while (*cp != '#' && *cp != '/' && *cp != '\0') 100 cp++; 101 if (*cp == '#' || *cp == '\0') 102 continue; 103 *sp++ = cp; 104 while (!isspace(*cp) && *cp != '#' && *cp != '\0') 105 cp++; 106 *cp++ = '\0'; 107 } 108 *sp = NULL; 109 (void)fclose(fp); 110 return (shells); 111 } 112