| /* setusershell(), getusershell(), endusershell() for uClibc. | 
 |  * | 
 |  * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc@uclibc.org> | 
 |  * | 
 |  * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in | 
 |  * this tarball. | 
 |  */ | 
 | /* My manpage reads: | 
 |  * The  getusershell() function returns the next line from the file | 
 |  * /etc/shells, opening the file if necessary. The line should contain | 
 |  * the pathname of a valid user shell.  If /etc/shells does not exist | 
 |  * or is unreadable, getusershell() behaves as if /bin/sh and /bin/csh | 
 |  * were listed in the file. | 
 |  * The getusershell() function returns a NULL pointer on end-of-file. | 
 |  */ | 
 | #include <unistd.h> | 
 | #include <stdlib.h> | 
 | #include <paths.h> | 
 | #include <string.h> | 
 | #include "internal/parse_config.h" | 
 |  | 
 | #if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_UNIX98) | 
 |  | 
 | static const char * const defaultsh[] = { _PATH_BSHELL, _PATH_CSHELL, NULL}; | 
 | static char *shellb, **shells; | 
 | static parser_t *shellp; | 
 |  | 
 | void endusershell(void) | 
 | { | 
 | 	if (shellp) { | 
 | 		shells = (char**) shellb; | 
 | 		while (shells && *shells) { | 
 | 			char*xxx = *shells++; | 
 | 			free(xxx); | 
 | 		} | 
 | 		config_close(shellp); | 
 | 		shellp = NULL; | 
 | 	} | 
 | 	free(shellb); | 
 | 	shellb = NULL; | 
 | 	shells = NULL; | 
 | } | 
 | libc_hidden_def(endusershell) | 
 |  | 
 | void setusershell(void) | 
 | { | 
 | 	endusershell(); | 
 | 	shellp = config_open(_PATH_SHELLS); | 
 | 	if (shellp == NULL) | 
 | 		shells = (char **)defaultsh; | 
 | 	else { | 
 | 		char **shell = NULL; | 
 | 		int pos = 0; | 
 |  | 
 | 		while (config_read(shellp, &shell, 1, 1, "# \t", PARSE_NORMAL)) | 
 | 		{ | 
 | 			shellb = realloc(shellb, (pos + 2) * sizeof(char*)); | 
 | 			shells = (char**) shellb + pos++; | 
 | 			*shells++ = strdup(*shell); | 
 | 			*shells = NULL; | 
 |  | 
 | 		} | 
 | 		shells = (char **)shellb; | 
 | 	} | 
 | } | 
 | libc_hidden_def(setusershell) | 
 |  | 
 | char *getusershell(void) | 
 | { | 
 | 	char *sh; | 
 | 	if (shells == NULL) | 
 | 		setusershell(); | 
 | 	sh = *shells; | 
 | 	if (sh) | 
 | 		shells++; | 
 | 	return sh; | 
 | } | 
 | #endif |