1 /* 2 * Copyright (c) 1985, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifdef HAVE_CONFIG_H 35 #include <config.h> 36 #endif 37 38 RCSID("$Id: getusershell.c,v 1.8 1997/04/20 06:18:03 assar Exp $"); 39 40 #ifndef HAVE_GETUSERSHELL 41 42 #include <stdio.h> 43 #include <stdlib.h> 44 #ifdef HAVE_PATHS_H 45 #include <paths.h> 46 #endif 47 #ifdef HAVE_SYS_TYPES_H 48 #include <sys/types.h> 49 #endif 50 #ifdef HAVE_SYS_STAT_H 51 #include <sys/stat.h> 52 #endif 53 #ifdef HAVE_SYS_PARAM_H 54 #include <sys/param.h> 55 #endif 56 57 #ifndef _PATH_SHELLS 58 #define _PATH_SHELLS "/etc/shells" 59 #endif 60 61 #ifndef _PATH_BSHELL 62 #define _PATH_BSHELL "/bin/sh" 63 #endif 64 65 #ifndef _PATH_CSHELL 66 #define _PATH_CSHELL "/bin/csh" 67 #endif 68 69 /* 70 * Local shells should NOT be added here. They should be added in 71 * /etc/shells. 72 */ 73 74 static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; 75 static char **curshell, **shells, *strings; 76 static char **initshells (void); 77 78 /* 79 * Get a list of shells from _PATH_SHELLS, if it exists. 80 */ 81 char * 82 getusershell() 83 { 84 char *ret; 85 86 if (curshell == NULL) 87 curshell = initshells(); 88 ret = *curshell; 89 if (ret != NULL) 90 curshell++; 91 return (ret); 92 } 93 94 void 95 endusershell() 96 { 97 98 if (shells != NULL) 99 free(shells); 100 shells = NULL; 101 if (strings != NULL) 102 free(strings); 103 strings = NULL; 104 curshell = NULL; 105 } 106 107 void 108 setusershell() 109 { 110 111 curshell = initshells(); 112 } 113 114 static char ** 115 initshells() 116 { 117 char **sp, *cp; 118 FILE *fp; 119 struct stat statb; 120 121 if (shells != NULL) 122 free(shells); 123 shells = NULL; 124 if (strings != NULL) 125 free(strings); 126 strings = NULL; 127 if ((fp = fopen(_PATH_SHELLS, "r")) == NULL) 128 return (okshells); 129 if (fstat(fileno(fp), &statb) == -1) { 130 fclose(fp); 131 return (okshells); 132 } 133 if ((strings = malloc((u_int)statb.st_size)) == NULL) { 134 fclose(fp); 135 return (okshells); 136 } 137 shells = calloc((unsigned)statb.st_size / 3, sizeof (char *)); 138 if (shells == NULL) { 139 fclose(fp); 140 free(strings); 141 strings = NULL; 142 return (okshells); 143 } 144 sp = shells; 145 cp = strings; 146 while (fgets(cp, MaxPathLen + 1, fp) != NULL) { 147 while (*cp != '#' && *cp != '/' && *cp != '\0') 148 cp++; 149 if (*cp == '#' || *cp == '\0') 150 continue; 151 *sp++ = cp; 152 while (!isspace(*cp) && *cp != '#' && *cp != '\0') 153 cp++; 154 *cp++ = '\0'; 155 } 156 *sp = NULL; 157 fclose(fp); 158 return (shells); 159 } 160 #endif /* HAVE_GETUSERSHELL */ 161