Mercurial > hg > octave-kai > gnulib-hg
annotate lib/getusershell.c @ 7302:8a1a9361108c
* _fpending.c: Include <config.h> unconditionally, since we no
longer worry about uses that don't define HAVE_CONFIG_H.
* acl.c, alloca.c, argmatch.c, atexit.c, backupfile.c:
* basename.c, c-stack.c, c-strtod.c, calloc.c, canon-host.c:
* canonicalize.c, chdir-long.c, chdir-safer.c, chown.c:
* cloexec.c, close-stream.c, closeout.c, creat-safer.c:
* cycle-check.c, diacrit.c, dirchownmod.c, dirfd.c, dirname.c:
* dup-safer.c, dup2.c, error.c, euidaccess.c, exclude.c:
* exitfail.c, fchmodat.c, fchown-stub.c, fd-safer.c:
* file-type.c, fileblocks.c, filemode.c, filenamecat.c:
* fnmatch.c, fopen-safer.c, fprintftime.c, free.c, fsusage.c:
* ftruncate.c, fts-cycle.c, fts.c, full-write.c, gai_strerror.c:
* getcwd.c, getdate.y, getdomainname.c, getgroups.c:
* gethostname.c, gethrxtime.c, getloadavg.c, getlogin_r.c:
* getndelim2.c, getnline.c, getopt.c, getopt1.c, getpass.c:
* gettime.c, gettimeofday.c, getugroups.c, getusershell.c:
* glob.c, group-member.c, hard-locale.c, hash-pjw.c, hash.c:
* human.c, idcache.c, inet_ntop.c, inet_pton.c, inttostr.c:
* isdir.c, lchown.c, linebuffer.c, long-options.c, lstat.c:
* malloc.c, md5.c, memcasecmp.c, memchr.c, memcmp.c, memcoll.c:
* memcpy.c, memmove.c, memrchr.c, mkancesdirs.c, mkdir-p.c:
* mkdir.c, mkdirat.c, mkstemp-safer.c, mkstemp.c, modechange.c:
* mountlist.c, nanosleep.c, obstack.c, open-safer.c:
* openat-die.c, openat.c, pagealign_alloc.c, physmem.c:
* pipe-safer.c, posixtm.c, posixver.c, putenv.c, quote.c:
* quotearg.c, raise.c, readtokens.c, readtokens0.c, readutmp.c:
* realloc.c, regex.c, rename.c, rmdir.c, rpmatch.c, safe-read.c:
* same.c, save-cwd.c, savedir.c, setenv.c, settime.c, sha1.c:
* sig2str.c, snprintf.c, strdup.c, strerror.c, strftime.c:
* stripslash.c, strndup.c, strnlen.c, strpbrk.c, strtod.c:
* strtoimax.c, strtol.c, strverscmp.c, tempname.c, time_r.c:
* timegm.c, tmpfile-safer.c, unlinkdir.c, userspec.c, utime.c:
* utimecmp.c, utimens.c, version-etc-fsf.c, version-etc.c:
* xalloc-die.c, xgetcwd.c, xgethostname.c, xmalloc.c:
* xmemcoll.c, xnanosleep.c, xreadlink.c, xstrtod.c:
* xstrtoimax.c, xstrtol.c, xstrtoumax.c, yesno.c:
Likewise.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Wed, 13 Sep 2006 22:38:14 +0000 |
parents | fa896bb33133 |
children | bbbbbf4cd1c5 |
rev | line source |
---|---|
9 | 1 /* getusershell.c -- Return names of valid user shells. |
5318
7c24a825b51d
Remove dependencies on unlocked-io.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4827
diff
changeset
|
2 |
6927
fa896bb33133
* lib/memcasecmp.c: Include <limits.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6275
diff
changeset
|
3 Copyright (C) 1991, 1997, 2000, 2001, 2003, 2004, 2005, 2006 Free |
fa896bb33133
* lib/memcasecmp.c: Include <limits.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6275
diff
changeset
|
4 Software Foundation, Inc. |
9 | 5 |
6 This program is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 2, or (at your option) | |
9 any later version. | |
10 | |
11 This program is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
651
242f0fe39aa7
update FSF address in copyright
Jim Meyering <jim@meyering.net>
parents:
307
diff
changeset
|
17 along with this program; if not, write to the Free Software Foundation, |
5848
a48fb0e98c8c
*** empty log message ***
Paul Eggert <eggert@cs.ucla.edu>
parents:
5813
diff
changeset
|
18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
9 | 19 |
20 /* Written by David MacKenzie <djm@gnu.ai.mit.edu> */ | |
21 | |
7302
8a1a9361108c
* _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents:
6927
diff
changeset
|
22 #include <config.h> |
125 | 23 |
9 | 24 #ifndef SHELLS_FILE |
3052
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
25 # ifndef __DJGPP__ |
9 | 26 /* File containing a list of nonrestricted shells, one per line. */ |
3052
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
27 # define SHELLS_FILE "/etc/shells" |
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
28 # else |
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
29 /* This is a horrible kludge. Isn't there a better way? */ |
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
30 # define SHELLS_FILE "/dev/env/DJDIR/etc/shells" |
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
31 # endif |
9 | 32 #endif |
33 | |
4655 | 34 #include <stdlib.h> |
9 | 35 #include <ctype.h> |
5318
7c24a825b51d
Remove dependencies on unlocked-io.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4827
diff
changeset
|
36 |
6275 | 37 #include "stdio--.h" |
2654
c0220b12ea7d
(xmalloc, xrealloc): Remove functions.
Jim Meyering <jim@meyering.net>
parents:
1041
diff
changeset
|
38 #include "xalloc.h" |
9 | 39 |
5318
7c24a825b51d
Remove dependencies on unlocked-io.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4827
diff
changeset
|
40 #if USE_UNLOCKED_IO |
7c24a825b51d
Remove dependencies on unlocked-io.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4827
diff
changeset
|
41 # include "unlocked-io.h" |
7c24a825b51d
Remove dependencies on unlocked-io.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4827
diff
changeset
|
42 #endif |
7c24a825b51d
Remove dependencies on unlocked-io.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4827
diff
changeset
|
43 |
4656
4f4fb4d3874d
(readname, default_index, line_size, readname):
Paul Eggert <eggert@cs.ucla.edu>
parents:
4655
diff
changeset
|
44 static size_t readname (char **, size_t *, FILE *); |
9 | 45 |
3052
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
46 #if ! defined ADDITIONAL_DEFAULT_SHELLS && defined __MSDOS__ |
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
47 # define ADDITIONAL_DEFAULT_SHELLS \ |
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
48 "c:/dos/command.com", "c:/windows/command.com", "c:/command.com", |
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
49 #else |
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
50 # define ADDITIONAL_DEFAULT_SHELLS /* empty */ |
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
51 #endif |
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
52 |
9 | 53 /* 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
|
54 static char const* const default_shells[] = |
9 | 55 { |
3052
5d2b5bde7c6f
[!SHELLS_FILE && __DJGPP__]: Define
Jim Meyering <jim@meyering.net>
parents:
2966
diff
changeset
|
56 ADDITIONAL_DEFAULT_SHELLS |
9 | 57 "/bin/sh", "/bin/csh", "/usr/bin/sh", "/usr/bin/csh", NULL |
58 }; | |
59 | |
60 /* Index of the next shell in `default_shells' to return. | |
61 0 means we are not using `default_shells'. */ | |
4656
4f4fb4d3874d
(readname, default_index, line_size, readname):
Paul Eggert <eggert@cs.ucla.edu>
parents:
4655
diff
changeset
|
62 static size_t default_index = 0; |
9 | 63 |
64 /* Input stream from the shells file. */ | |
65 static FILE *shellstream = NULL; | |
66 | |
67 /* Line of input from the shells file. */ | |
68 static char *line = NULL; | |
69 | |
70 /* Number of bytes allocated for `line'. */ | |
4656
4f4fb4d3874d
(readname, default_index, line_size, readname):
Paul Eggert <eggert@cs.ucla.edu>
parents:
4655
diff
changeset
|
71 static size_t line_size = 0; |
9 | 72 |
73 /* Return an entry from the shells file, ignoring comment lines. | |
167 | 74 If the file doesn't exist, use the list in DEFAULT_SHELLS (above). |
75 In any case, the returned string is in memory allocated through malloc. | |
9 | 76 Return NULL if there are no more entries. */ |
77 | |
78 char * | |
4655 | 79 getusershell (void) |
9 | 80 { |
81 if (default_index > 0) | |
82 { | |
83 if (default_shells[default_index]) | |
84 /* Not at the end of the list yet. */ | |
167 | 85 return xstrdup (default_shells[default_index++]); |
9 | 86 return NULL; |
87 } | |
88 | |
89 if (shellstream == NULL) | |
90 { | |
6275 | 91 shellstream = fopen (SHELLS_FILE, "r"); |
9 | 92 if (shellstream == NULL) |
93 { | |
94 /* No shells file. Use the default list. */ | |
95 default_index = 1; | |
167 | 96 return xstrdup (default_shells[0]); |
9 | 97 } |
98 } | |
99 | |
100 while (readname (&line, &line_size, shellstream)) | |
101 { | |
102 if (*line != '#') | |
103 return line; | |
104 } | |
105 return NULL; /* End of file. */ | |
106 } | |
107 | |
108 /* Rewind the shells file. */ | |
109 | |
110 void | |
4655 | 111 setusershell (void) |
9 | 112 { |
113 default_index = 0; | |
2966
8d2c63fa3a16
(setusershell): Use rewind rather than
Jim Meyering <jim@meyering.net>
parents:
2928
diff
changeset
|
114 if (shellstream) |
8d2c63fa3a16
(setusershell): Use rewind rather than
Jim Meyering <jim@meyering.net>
parents:
2928
diff
changeset
|
115 rewind (shellstream); |
9 | 116 } |
117 | |
118 /* Close the shells file. */ | |
119 | |
120 void | |
4655 | 121 endusershell (void) |
9 | 122 { |
123 if (shellstream) | |
124 { | |
125 fclose (shellstream); | |
126 shellstream = NULL; | |
127 } | |
128 } | |
129 | |
130 /* Read a line from STREAM, removing any newline at the end. | |
131 Place the result in *NAME, which is malloc'd | |
132 and/or realloc'd as necessary and can start out NULL, | |
133 and whose size is passed and returned in *SIZE. | |
134 | |
4656
4f4fb4d3874d
(readname, default_index, line_size, readname):
Paul Eggert <eggert@cs.ucla.edu>
parents:
4655
diff
changeset
|
135 Return the number of bytes placed in *NAME |
9 | 136 if some nonempty sequence was found, otherwise 0. */ |
137 | |
4656
4f4fb4d3874d
(readname, default_index, line_size, readname):
Paul Eggert <eggert@cs.ucla.edu>
parents:
4655
diff
changeset
|
138 static size_t |
4f4fb4d3874d
(readname, default_index, line_size, readname):
Paul Eggert <eggert@cs.ucla.edu>
parents:
4655
diff
changeset
|
139 readname (char **name, size_t *size, FILE *stream) |
9 | 140 { |
141 int c; | |
4656
4f4fb4d3874d
(readname, default_index, line_size, readname):
Paul Eggert <eggert@cs.ucla.edu>
parents:
4655
diff
changeset
|
142 size_t name_index = 0; |
9 | 143 |
144 /* Skip blank space. */ | |
6927
fa896bb33133
* lib/memcasecmp.c: Include <limits.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6275
diff
changeset
|
145 while ((c = getc (stream)) != EOF && isspace (c)) |
9 | 146 /* Do nothing. */ ; |
790 | 147 |
4827
a6d03da0fa67
Simplify the code by using new xalloc.h features.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4656
diff
changeset
|
148 for (;;) |
9 | 149 { |
4827
a6d03da0fa67
Simplify the code by using new xalloc.h features.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4656
diff
changeset
|
150 if (*size <= name_index) |
a6d03da0fa67
Simplify the code by using new xalloc.h features.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4656
diff
changeset
|
151 *name = x2nrealloc (*name, size, sizeof **name); |
6927
fa896bb33133
* lib/memcasecmp.c: Include <limits.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6275
diff
changeset
|
152 if (c == EOF || isspace (c)) |
4827
a6d03da0fa67
Simplify the code by using new xalloc.h features.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4656
diff
changeset
|
153 break; |
9 | 154 (*name)[name_index++] = c; |
155 c = getc (stream); | |
156 } | |
157 (*name)[name_index] = '\0'; | |
158 return name_index; | |
159 } | |
160 | |
161 #ifdef TEST | |
4655 | 162 int |
163 main (void) | |
9 | 164 { |
165 char *s; | |
166 | |
167 while (s = getusershell ()) | |
168 puts (s); | |
169 exit (0); | |
170 } | |
171 #endif |