| /* 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 |