This source file includes following definitions.
- getusershell
- setusershell
- endusershell
- readname
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <config.h>
22
23
24 #include <unistd.h>
25
26 #ifndef SHELLS_FILE
27 # ifndef __DJGPP__
28
29 # define SHELLS_FILE "/etc/shells"
30 # else
31
32 # define SHELLS_FILE "/dev/env/DJDIR/etc/shells"
33 # endif
34 #endif
35
36 #include <stdlib.h>
37 #include <ctype.h>
38
39 #include "stdio--.h"
40 #include "xalloc.h"
41
42 #if GNULIB_GETUSERSHELL_SINGLE_THREAD
43 # include "unlocked-io.h"
44 #endif
45
46 static idx_t readname (char **, idx_t *, FILE *);
47
48 #if ! defined ADDITIONAL_DEFAULT_SHELLS && defined __MSDOS__
49 # define ADDITIONAL_DEFAULT_SHELLS \
50 "c:/dos/command.com", "c:/windows/command.com", "c:/command.com",
51 #else
52 # define ADDITIONAL_DEFAULT_SHELLS
53 #endif
54
55
56 static char const* const default_shells[] =
57 {
58 ADDITIONAL_DEFAULT_SHELLS
59 "/bin/sh", "/bin/csh", "/usr/bin/sh", "/usr/bin/csh", NULL
60 };
61
62
63
64 static size_t default_index = 0;
65
66
67 static FILE *shellstream = NULL;
68
69
70 static char *line = NULL;
71
72
73 static idx_t line_size = 0;
74
75
76
77
78
79
80 char *
81 getusershell (void)
82 {
83 if (default_index > 0)
84 {
85 if (default_shells[default_index])
86
87 return xstrdup (default_shells[default_index++]);
88 return NULL;
89 }
90
91 if (shellstream == NULL)
92 {
93 shellstream = fopen (SHELLS_FILE, "r");
94 if (shellstream == NULL)
95 {
96
97 default_index = 1;
98 return xstrdup (default_shells[0]);
99 }
100 }
101
102 while (readname (&line, &line_size, shellstream))
103 {
104 if (*line != '#')
105 return line;
106 }
107 return NULL;
108 }
109
110
111
112 void
113 setusershell (void)
114 {
115 default_index = 0;
116 if (shellstream)
117 rewind (shellstream);
118 }
119
120
121
122 void
123 endusershell (void)
124 {
125 if (shellstream)
126 {
127 fclose (shellstream);
128 shellstream = NULL;
129 }
130 }
131
132
133
134
135
136
137
138
139
140 static idx_t
141 readname (char **name, idx_t *size, FILE *stream)
142 {
143 int c;
144 size_t name_index = 0;
145
146
147 while ((c = getc (stream)) != EOF && isspace (c))
148 ;
149
150 for (;;)
151 {
152 if (*size <= name_index)
153 *name = xpalloc (*name, size, 1, -1, sizeof **name);
154 if (c == EOF || isspace (c))
155 break;
156 (*name)[name_index++] = c;
157 c = getc (stream);
158 }
159 (*name)[name_index] = '\0';
160 return name_index;
161 }
162
163 #ifdef TEST
164 int
165 main (void)
166 {
167 char *s;
168
169 while (s = getusershell ())
170 puts (s);
171 exit (0);
172 }
173 #endif