Mercurial > hg > octave-kai > gnulib-hg
annotate lib/getusershell.c @ 125:539738c0b6c2
merge with 1.8.1d
author | Jim Meyering <jim@meyering.net> |
---|---|
date | Tue, 12 Oct 1993 14:49:15 +0000 (1993-10-12) |
parents | 01c6d40adf9d |
children | 585326d9a995 |
rev | line source |
---|---|
9 | 1 /* getusershell.c -- Return names of valid user shells. |
2 Copyright (C) 1991 Free Software Foundation, Inc. | |
3 | |
4 This program is free software; you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 2, or (at your option) | |
7 any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
15 along with this program; if not, write to the Free Software | |
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
17 | |
18 /* Written by David MacKenzie <djm@gnu.ai.mit.edu> */ | |
19 | |
125 | 20 #ifdef HAVE_CONFIG_H |
21 #if defined (CONFIG_BROKETS) | |
22 /* We use <config.h> instead of "config.h" so that a compilation | |
23 using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h | |
24 (which it would do because it found this file in $srcdir). */ | |
25 #include <config.h> | |
26 #else | |
27 #include "config.h" | |
28 #endif | |
29 #endif | |
30 | |
9 | 31 #ifndef SHELLS_FILE |
32 /* File containing a list of nonrestricted shells, one per line. */ | |
33 #define SHELLS_FILE "/etc/shells" | |
34 #endif | |
35 | |
36 #include <stdio.h> | |
37 #include <ctype.h> | |
38 | |
39 #ifdef STDC_HEADERS | |
40 #include <stdlib.h> | |
41 #else | |
42 char *malloc (); | |
43 char *realloc (); | |
44 #endif | |
45 | |
46 static int readname (); | |
47 | |
48 /* List of shells to use if the shells file is missing. */ | |
16
01c6d40adf9d
Make tables static and const when possible.
Jim Meyering <jim@meyering.net>
parents:
9
diff
changeset
|
49 static char const* const default_shells[] = |
9 | 50 { |
51 "/bin/sh", "/bin/csh", "/usr/bin/sh", "/usr/bin/csh", NULL | |
52 }; | |
53 | |
54 /* Index of the next shell in `default_shells' to return. | |
55 0 means we are not using `default_shells'. */ | |
56 static int default_index = 0; | |
57 | |
58 /* Input stream from the shells file. */ | |
59 static FILE *shellstream = NULL; | |
60 | |
61 /* Line of input from the shells file. */ | |
62 static char *line = NULL; | |
63 | |
64 /* Number of bytes allocated for `line'. */ | |
65 static int line_size = 0; | |
66 | |
67 /* Return an entry from the shells file, ignoring comment lines. | |
68 Return NULL if there are no more entries. */ | |
69 | |
70 char * | |
71 getusershell () | |
72 { | |
73 if (default_index > 0) | |
74 { | |
75 if (default_shells[default_index]) | |
76 /* Not at the end of the list yet. */ | |
77 return default_shells[default_index++]; | |
78 return NULL; | |
79 } | |
80 | |
81 if (shellstream == NULL) | |
82 { | |
83 shellstream = fopen (SHELLS_FILE, "r"); | |
84 if (shellstream == NULL) | |
85 { | |
86 /* No shells file. Use the default list. */ | |
87 default_index = 1; | |
88 return default_shells[0]; | |
89 } | |
90 } | |
91 | |
92 while (readname (&line, &line_size, shellstream)) | |
93 { | |
94 if (*line != '#') | |
95 return line; | |
96 } | |
97 return NULL; /* End of file. */ | |
98 } | |
99 | |
100 /* Rewind the shells file. */ | |
101 | |
102 void | |
103 setusershell () | |
104 { | |
105 default_index = 0; | |
106 if (shellstream == NULL) | |
107 shellstream = fopen (SHELLS_FILE, "r"); | |
108 else | |
109 fseek (shellstream, 0L, 0); | |
110 } | |
111 | |
112 /* Close the shells file. */ | |
113 | |
114 void | |
115 endusershell () | |
116 { | |
117 if (shellstream) | |
118 { | |
119 fclose (shellstream); | |
120 shellstream = NULL; | |
121 } | |
122 } | |
123 | |
124 /* Allocate N bytes of memory dynamically, with error checking. */ | |
125 | |
126 static char * | |
127 xmalloc (n) | |
128 unsigned n; | |
129 { | |
130 char *p; | |
131 | |
132 p = malloc (n); | |
133 if (p == 0) | |
134 { | |
135 fprintf (stderr, "virtual memory exhausted\n"); | |
136 exit (1); | |
137 } | |
138 return p; | |
139 } | |
140 | |
141 /* Reallocate space P to size N, with error checking. */ | |
142 | |
143 static char * | |
144 xrealloc (p, n) | |
145 char *p; | |
146 unsigned n; | |
147 { | |
148 p = realloc (p, n); | |
149 if (p == 0) | |
150 { | |
151 fprintf (stderr, "virtual memory exhausted\n"); | |
152 exit (1); | |
153 } | |
154 return p; | |
155 } | |
156 | |
157 /* Read a line from STREAM, removing any newline at the end. | |
158 Place the result in *NAME, which is malloc'd | |
159 and/or realloc'd as necessary and can start out NULL, | |
160 and whose size is passed and returned in *SIZE. | |
161 | |
162 Return the number of characters placed in *NAME | |
163 if some nonempty sequence was found, otherwise 0. */ | |
164 | |
165 static int | |
166 readname (name, size, stream) | |
167 char **name; | |
168 int *size; | |
169 FILE *stream; | |
170 { | |
171 int c; | |
172 int name_index = 0; | |
173 | |
174 if (*name == NULL) | |
175 { | |
176 *size = 10; | |
177 *name = (char *) xmalloc (*size); | |
178 } | |
179 | |
180 /* Skip blank space. */ | |
181 while ((c = getc (stream)) != EOF && isspace (c)) | |
182 /* Do nothing. */ ; | |
183 | |
184 while (c != EOF && !isspace (c)) | |
185 { | |
186 (*name)[name_index++] = c; | |
187 while (name_index >= *size) | |
188 { | |
189 *size *= 2; | |
190 *name = (char *) xrealloc (*name, *size); | |
191 } | |
192 c = getc (stream); | |
193 } | |
194 (*name)[name_index] = '\0'; | |
195 return name_index; | |
196 } | |
197 | |
198 #ifdef TEST | |
199 main () | |
200 { | |
201 char *s; | |
202 | |
203 while (s = getusershell ()) | |
204 puts (s); | |
205 exit (0); | |
206 } | |
207 #endif |