1 /* setusershell(), getusershell(), endusershell() for uClibc.
2  *
3  * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc@uclibc.org>
4  *
5  * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in
6  * this tarball.
7  */
8 /* My manpage reads:
9  * The  getusershell() function returns the next line from the file
10  * /etc/shells, opening the file if necessary. The line should contain
11  * the pathname of a valid user shell.  If /etc/shells does not exist
12  * or is unreadable, getusershell() behaves as if /bin/sh and /bin/csh
13  * were listed in the file.
14  * The getusershell() function returns a NULL pointer on end-of-file.
15  */
16 #include <unistd.h>
17 #include <stdlib.h>
18 #include <paths.h>
19 #include <string.h>
20 #include "internal/parse_config.h"
21 
22 #if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_UNIX98)
23 
24 static const char * const defaultsh[] = { _PATH_BSHELL, _PATH_CSHELL, NULL};
25 static char *shellb, **shells;
26 static parser_t *shellp;
27 
endusershell(void)28 void endusershell(void)
29 {
30 	if (shellp) {
31 		shells = (char**) shellb;
32 		while (shells && *shells) {
33 			char*xxx = *shells++;
34 			free(xxx);
35 		}
36 		config_close(shellp);
37 		shellp = NULL;
38 	}
39 	free(shellb);
40 	shellb = NULL;
41 	shells = NULL;
42 }
libc_hidden_def(endusershell)43 libc_hidden_def(endusershell)
44 
45 void setusershell(void)
46 {
47 	endusershell();
48 	shellp = config_open(_PATH_SHELLS);
49 	if (shellp == NULL)
50 		shells = (char **)defaultsh;
51 	else {
52 		char **shell = NULL;
53 		int pos = 0;
54 
55 		while (config_read(shellp, &shell, 1, 1, "# \t", PARSE_NORMAL))
56 		{
57 			shellb = realloc(shellb, (pos + 2) * sizeof(char*));
58 			shells = (char**) shellb + pos++;
59 			*shells++ = strdup(*shell);
60 			*shells = NULL;
61 
62 		}
63 		shells = (char **)shellb;
64 	}
65 }
libc_hidden_def(setusershell)66 libc_hidden_def(setusershell)
67 
68 char *getusershell(void)
69 {
70 	char *sh;
71 	if (shells == NULL)
72 		setusershell();
73 	sh = *shells;
74 	if (sh)
75 		shells++;
76 	return sh;
77 }
78 #endif
79