blob: 7ebc3fa9b10bed952243f7eeac230acf56e01df7 [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* general.c -- Stuff that is used by all files. */
2
Chet Ramey8868eda2020-12-06 15:51:17 -05003/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00004
5 This file is part of GNU Bash, the Bourne Again SHell.
6
Jari Aalto31859422009-01-12 13:36:28 +00007 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
Jari Aalto726f6381996-08-26 18:22:31 +000011
Jari Aalto31859422009-01-12 13:36:28 +000012 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
Jari Aalto726f6381996-08-26 18:22:31 +000016
Jari Aalto31859422009-01-12 13:36:28 +000017 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
Jari Aalto726f6381996-08-26 18:22:31 +000020
Jari Aaltoccc6cda1996-12-23 17:02:34 +000021#include "config.h"
22
23#include "bashtypes.h"
Chet Rameyac50fba2014-02-26 09:36:43 -050024#if defined (HAVE_SYS_PARAM_H)
Jari Aaltocce855b1998-04-17 19:52:44 +000025# include <sys/param.h>
26#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +000027#include "posixstat.h"
28
29#if defined (HAVE_UNISTD_H)
30# include <unistd.h>
31#endif
32
33#include "filecntl.h"
34#include "bashansi.h"
Jari Aalto726f6381996-08-26 18:22:31 +000035#include <stdio.h>
Jari Aaltof73dda02001-11-13 17:56:06 +000036#include "chartypes.h"
Jari Aalto726f6381996-08-26 18:22:31 +000037#include <errno.h>
Jari Aaltoccc6cda1996-12-23 17:02:34 +000038
Jari Aaltob80f6442004-07-27 13:29:18 +000039#include "bashintl.h"
40
Jari Aalto726f6381996-08-26 18:22:31 +000041#include "shell.h"
Chet Rameyd233b482019-01-07 09:27:52 -050042#include "parser.h"
43#include "flags.h"
44#include "findcmd.h"
Jari Aalto95732b42005-12-07 14:08:12 +000045#include "test.h"
Chet Rameyac50fba2014-02-26 09:36:43 -050046#include "trap.h"
Chet Ramey8868eda2020-12-06 15:51:17 -050047#include "pathexp.h"
Jari Aalto95732b42005-12-07 14:08:12 +000048
Chet Rameyd233b482019-01-07 09:27:52 -050049#include "builtins/common.h"
50
Chet Rameya0c0a002016-09-15 16:59:08 -040051#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
52# include <mbstr.h> /* mbschr */
53#endif
54
Jari Aalto726f6381996-08-26 18:22:31 +000055#include <tilde/tilde.h>
56
Jari Aalto726f6381996-08-26 18:22:31 +000057#if !defined (errno)
58extern int errno;
59#endif /* !errno */
60
Chet Rameyd233b482019-01-07 09:27:52 -050061#ifdef __CYGWIN__
62# include <sys/cygwin.h>
63#endif
Jari Aaltocce855b1998-04-17 19:52:44 +000064
Chet Ramey8868eda2020-12-06 15:51:17 -050065static char *bash_special_tilde_expansions PARAMS((char *));
66static int unquoted_tilde_word PARAMS((const char *));
67static void initialize_group_array PARAMS((void));
Jari Aalto7117c2d2002-07-17 14:10:11 +000068
Jari Aaltocce855b1998-04-17 19:52:44 +000069/* A standard error message to use when getcwd() returns NULL. */
Jari Aalto31859422009-01-12 13:36:28 +000070const char * const bash_getcwd_errstr = N_("getcwd: cannot access parent directories");
Jari Aalto726f6381996-08-26 18:22:31 +000071
Chet Rameyd233b482019-01-07 09:27:52 -050072/* Do whatever is necessary to initialize `Posix mode'. This currently
73 modifies the following variables which are controlled via shopt:
74 interactive_comments
75 source_uses_path
76 expand_aliases
77 inherit_errexit
78 print_shift_error
Chet Ramey8868eda2020-12-06 15:51:17 -050079 posixglob
Chet Rameyd233b482019-01-07 09:27:52 -050080
81 and the following variables which cannot be user-modified:
82
83 source_searches_cwd
84
85 If we add to the first list, we need to change the table and functions
86 below */
87
88static struct {
89 int *posix_mode_var;
90} posix_vars[] =
91{
Dan Pasanenf157ca82014-10-02 14:08:59 -050092 {&interactive_comments},
93 {&source_uses_path},
94 {&expand_aliases},
95 {&inherit_errexit},
96 {&print_shift_error},
97 {0}
Chet Rameyd233b482019-01-07 09:27:52 -050098};
99
Chet Ramey8868eda2020-12-06 15:51:17 -0500100static char *saved_posix_vars = 0;
101
Jari Aalto726f6381996-08-26 18:22:31 +0000102void
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000103posix_initialize (on)
104 int on;
Jari Aalto726f6381996-08-26 18:22:31 +0000105{
Jari Aalto28ef6c32001-04-06 19:14:31 +0000106 /* Things that should be turned on when posix mode is enabled. */
107 if (on != 0)
108 {
109 interactive_comments = source_uses_path = expand_aliases = 1;
Chet Rameya0c0a002016-09-15 16:59:08 -0400110 inherit_errexit = 1;
Jari Aalto31859422009-01-12 13:36:28 +0000111 source_searches_cwd = 0;
Chet Rameyd233b482019-01-07 09:27:52 -0500112 print_shift_error = 1;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000113 }
114
115 /* Things that should be turned on when posix mode is disabled. */
Chet Ramey8868eda2020-12-06 15:51:17 -0500116 else if (saved_posix_vars) /* on == 0, restore saved settings */
117 {
118 set_posix_options (saved_posix_vars);
119 free (saved_posix_vars);
120 saved_posix_vars = 0;
121 }
122 else /* on == 0, restore a default set of settings */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000123 {
124 source_searches_cwd = 1;
125 expand_aliases = interactive_shell;
Chet Rameyd233b482019-01-07 09:27:52 -0500126 print_shift_error = 0;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000127 }
Jari Aalto726f6381996-08-26 18:22:31 +0000128}
129
Chet Rameyd233b482019-01-07 09:27:52 -0500130int
131num_posix_options ()
132{
133 return ((sizeof (posix_vars) / sizeof (posix_vars[0])) - 1);
134}
135
136char *
137get_posix_options (bitmap)
138 char *bitmap;
139{
140 register int i;
141
142 if (bitmap == 0)
143 bitmap = (char *)xmalloc (num_posix_options ()); /* no trailing NULL */
144 for (i = 0; posix_vars[i].posix_mode_var; i++)
145 bitmap[i] = *(posix_vars[i].posix_mode_var);
146 return bitmap;
147}
148
Chet Ramey8868eda2020-12-06 15:51:17 -0500149#undef save_posix_options
150void
151save_posix_options ()
152{
153 saved_posix_vars = get_posix_options (saved_posix_vars);
154}
155
Chet Rameyd233b482019-01-07 09:27:52 -0500156void
157set_posix_options (bitmap)
158 const char *bitmap;
159{
160 register int i;
161
162 for (i = 0; posix_vars[i].posix_mode_var; i++)
163 *(posix_vars[i].posix_mode_var) = bitmap[i];
164}
165
Jari Aalto726f6381996-08-26 18:22:31 +0000166/* **************************************************************** */
167/* */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000168/* Functions to convert to and from and display non-standard types */
169/* */
170/* **************************************************************** */
171
Jari Aalto726f6381996-08-26 18:22:31 +0000172#if defined (RLIMTYPE)
173RLIMTYPE
174string_to_rlimtype (s)
175 char *s;
176{
Jari Aaltocce855b1998-04-17 19:52:44 +0000177 RLIMTYPE ret;
178 int neg;
Jari Aalto726f6381996-08-26 18:22:31 +0000179
Jari Aaltocce855b1998-04-17 19:52:44 +0000180 ret = 0;
181 neg = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000182 while (s && *s && whitespace (*s))
183 s++;
Chet Ramey00018032011-11-21 20:51:19 -0500184 if (s && (*s == '-' || *s == '+'))
Jari Aalto726f6381996-08-26 18:22:31 +0000185 {
186 neg = *s == '-';
187 s++;
188 }
Jari Aaltof73dda02001-11-13 17:56:06 +0000189 for ( ; s && *s && DIGIT (*s); s++)
190 ret = (ret * 10) + TODIGIT (*s);
Jari Aalto726f6381996-08-26 18:22:31 +0000191 return (neg ? -ret : ret);
192}
193
194void
195print_rlimtype (n, addnl)
196 RLIMTYPE n;
197 int addnl;
198{
Jari Aaltof73dda02001-11-13 17:56:06 +0000199 char s[INT_STRLEN_BOUND (RLIMTYPE) + 1], *p;
Jari Aalto726f6381996-08-26 18:22:31 +0000200
Jari Aaltof73dda02001-11-13 17:56:06 +0000201 p = s + sizeof(s);
202 *--p = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +0000203
204 if (n < 0)
205 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000206 do
207 *--p = '0' - n % 10;
208 while ((n /= 10) != 0);
209
210 *--p = '-';
211 }
212 else
213 {
214 do
215 *--p = '0' + n % 10;
216 while ((n /= 10) != 0);
Jari Aalto726f6381996-08-26 18:22:31 +0000217 }
218
Jari Aaltof73dda02001-11-13 17:56:06 +0000219 printf ("%s%s", p, addnl ? "\n" : "");
Jari Aalto726f6381996-08-26 18:22:31 +0000220}
221#endif /* RLIMTYPE */
222
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000223/* **************************************************************** */
224/* */
225/* Input Validation Functions */
226/* */
227/* **************************************************************** */
228
229/* Return non-zero if all of the characters in STRING are digits. */
230int
231all_digits (string)
Chet Rameya0c0a002016-09-15 16:59:08 -0400232 const char *string;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000233{
Chet Rameya0c0a002016-09-15 16:59:08 -0400234 register const char *s;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000235
236 for (s = string; *s; s++)
Jari Aaltof73dda02001-11-13 17:56:06 +0000237 if (DIGIT (*s) == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000238 return (0);
239
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000240 return (1);
241}
242
243/* Return non-zero if the characters pointed to by STRING constitute a
244 valid number. Stuff the converted number into RESULT if RESULT is
Jari Aaltof73dda02001-11-13 17:56:06 +0000245 not null. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000246int
247legal_number (string, result)
Jari Aalto31859422009-01-12 13:36:28 +0000248 const char *string;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000249 intmax_t *result;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000250{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000251 intmax_t value;
Jari Aaltocce855b1998-04-17 19:52:44 +0000252 char *ep;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000253
254 if (result)
255 *result = 0;
256
Chet Rameyac50fba2014-02-26 09:36:43 -0500257 if (string == 0)
258 return 0;
259
Jari Aaltof73dda02001-11-13 17:56:06 +0000260 errno = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000261 value = strtoimax (string, &ep, 10);
Jari Aalto31859422009-01-12 13:36:28 +0000262 if (errno || ep == string)
Jari Aaltof73dda02001-11-13 17:56:06 +0000263 return 0; /* errno is set on overflow or underflow */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000264
Jari Aalto7117c2d2002-07-17 14:10:11 +0000265 /* Skip any trailing whitespace, since strtoimax does not. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000266 while (whitespace (*ep))
267 ep++;
268
Jari Aaltocce855b1998-04-17 19:52:44 +0000269 /* If *string is not '\0' but *ep is '\0' on return, the entire string
270 is valid. */
Chet Rameyac50fba2014-02-26 09:36:43 -0500271 if (*string && *ep == '\0')
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000272 {
273 if (result)
Jari Aaltocce855b1998-04-17 19:52:44 +0000274 *result = value;
275 /* The SunOS4 implementation of strtol() will happily ignore
276 overflow conditions, so this cannot do overflow correctly
277 on those systems. */
278 return 1;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000279 }
Jari Aaltocce855b1998-04-17 19:52:44 +0000280
281 return (0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000282}
283
Jari Aalto726f6381996-08-26 18:22:31 +0000284/* Return 1 if this token is a legal shell `identifier'; that is, it consists
285 solely of letters, digits, and underscores, and does not begin with a
286 digit. */
287int
288legal_identifier (name)
Chet Rameya0c0a002016-09-15 16:59:08 -0400289 const char *name;
Jari Aalto726f6381996-08-26 18:22:31 +0000290{
Chet Rameya0c0a002016-09-15 16:59:08 -0400291 register const char *s;
Jari Aaltof73dda02001-11-13 17:56:06 +0000292 unsigned char c;
Jari Aalto726f6381996-08-26 18:22:31 +0000293
Jari Aaltof73dda02001-11-13 17:56:06 +0000294 if (!name || !(c = *name) || (legal_variable_starter (c) == 0))
Jari Aalto726f6381996-08-26 18:22:31 +0000295 return (0);
296
Jari Aaltof73dda02001-11-13 17:56:06 +0000297 for (s = name + 1; (c = *s) != 0; s++)
Jari Aalto726f6381996-08-26 18:22:31 +0000298 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000299 if (legal_variable_char (c) == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000300 return (0);
Jari Aalto726f6381996-08-26 18:22:31 +0000301 }
302 return (1);
303}
304
Chet Rameya0c0a002016-09-15 16:59:08 -0400305/* Return 1 if NAME is a valid value that can be assigned to a nameref
306 variable. FLAGS can be 2, in which case the name is going to be used
307 to create a variable. Other values are currently unused, but could
308 be used to allow values to be stored and indirectly referenced, but
309 not used in assignments. */
310int
311valid_nameref_value (name, flags)
312 const char *name;
313 int flags;
314{
315 if (name == 0 || *name == 0)
316 return 0;
317
318 /* valid identifier */
319#if defined (ARRAY_VARS)
320 if (legal_identifier (name) || (flags != 2 && valid_array_reference (name, 0)))
321#else
322 if (legal_identifier (name))
323#endif
324 return 1;
325
326 return 0;
327}
328
329int
330check_selfref (name, value, flags)
331 const char *name;
332 char *value;
333 int flags;
334{
335 char *t;
336
337 if (STREQ (name, value))
338 return 1;
339
340#if defined (ARRAY_VARS)
341 if (valid_array_reference (value, 0))
342 {
Chet Rameyd233b482019-01-07 09:27:52 -0500343 t = array_variable_name (value, 0, (char **)NULL, (int *)NULL);
Chet Rameya0c0a002016-09-15 16:59:08 -0400344 if (t && STREQ (name, t))
345 {
346 free (t);
347 return 1;
348 }
349 free (t);
350 }
351#endif
352
353 return 0; /* not a self reference */
354}
355
Jari Aalto726f6381996-08-26 18:22:31 +0000356/* Make sure that WORD is a valid shell identifier, i.e.
Chet Ramey8868eda2020-12-06 15:51:17 -0500357 does not contain a dollar sign, nor is quoted in any way.
358 If CHECK_WORD is non-zero,
Jari Aalto726f6381996-08-26 18:22:31 +0000359 the word is checked to ensure that it consists of only letters,
Chet Ramey8868eda2020-12-06 15:51:17 -0500360 digits, and underscores, and does not consist of all digits. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000361int
Jari Aalto726f6381996-08-26 18:22:31 +0000362check_identifier (word, check_word)
363 WORD_DESC *word;
364 int check_word;
365{
Chet Ramey8868eda2020-12-06 15:51:17 -0500366 if (word->flags & (W_HASDOLLAR|W_QUOTED)) /* XXX - HASDOLLAR? */
Jari Aalto726f6381996-08-26 18:22:31 +0000367 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000368 internal_error (_("`%s': not a valid identifier"), word->word);
Jari Aalto726f6381996-08-26 18:22:31 +0000369 return (0);
370 }
Chet Ramey8868eda2020-12-06 15:51:17 -0500371 else if (check_word && (all_digits (word->word) || legal_identifier (word->word) == 0))
Jari Aalto726f6381996-08-26 18:22:31 +0000372 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000373 internal_error (_("`%s': not a valid identifier"), word->word);
Jari Aalto726f6381996-08-26 18:22:31 +0000374 return (0);
375 }
376 else
377 return (1);
378}
379
Chet Rameya0c0a002016-09-15 16:59:08 -0400380/* Return 1 if STRING is a function name that the shell will import from
381 the environment. Currently we reject attempts to import shell functions
382 containing slashes, beginning with newlines or containing blanks. In
383 Posix mode, we require that STRING be a valid shell identifier. Not
384 used yet. */
385int
386importable_function_name (string, len)
387 const char *string;
388 size_t len;
389{
390 if (absolute_program (string)) /* don't allow slash */
391 return 0;
392 if (*string == '\n') /* can't start with a newline */
393 return 0;
394 if (shellblank (*string) || shellblank(string[len-1]))
395 return 0;
396 return (posixly_correct ? legal_identifier (string) : 1);
397}
398
399int
400exportable_function_name (string)
401 const char *string;
402{
403 if (absolute_program (string))
404 return 0;
405 if (mbschr (string, '=') != 0)
406 return 0;
407 return 1;
408}
409
Jari Aaltob80f6442004-07-27 13:29:18 +0000410/* Return 1 if STRING comprises a valid alias name. The shell accepts
411 essentially all characters except those which must be quoted to the
412 parser (which disqualifies them from alias expansion anyway) and `/'. */
413int
414legal_alias_name (string, flags)
Chet Rameya0c0a002016-09-15 16:59:08 -0400415 const char *string;
Jari Aaltob80f6442004-07-27 13:29:18 +0000416 int flags;
417{
Chet Rameya0c0a002016-09-15 16:59:08 -0400418 register const char *s;
Jari Aaltob80f6442004-07-27 13:29:18 +0000419
420 for (s = string; *s; s++)
421 if (shellbreak (*s) || shellxquote (*s) || shellexp (*s) || (*s == '/'))
422 return 0;
423 return 1;
424}
425
Jari Aalto7117c2d2002-07-17 14:10:11 +0000426/* Returns non-zero if STRING is an assignment statement. The returned value
Chet Rameyd233b482019-01-07 09:27:52 -0500427 is the index of the `=' sign. If FLAGS&1 we are expecting a compound assignment
Chet Ramey8868eda2020-12-06 15:51:17 -0500428 and require an array subscript before the `=' to denote an assignment
429 statement. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000430int
Jari Aaltob80f6442004-07-27 13:29:18 +0000431assignment (string, flags)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000432 const char *string;
Jari Aaltob80f6442004-07-27 13:29:18 +0000433 int flags;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000434{
435 register unsigned char c;
436 register int newi, indx;
437
438 c = string[indx = 0];
439
Jari Aaltob80f6442004-07-27 13:29:18 +0000440#if defined (ARRAY_VARS)
Chet Ramey8868eda2020-12-06 15:51:17 -0500441 /* If parser_state includes PST_COMPASSIGN, FLAGS will include 1, so we are
442 parsing the contents of a compound assignment. If parser_state includes
443 PST_REPARSE, we are in the middle of an assignment statement and breaking
444 the words between the parens into words and assignment statements, but
445 we don't need to check for that right now. Within a compound assignment,
446 the subscript is required to make the word an assignment statement. If
447 we don't have a subscript, even if the word is a valid assignment
448 statement otherwise, we don't want to treat it as one. */
449 if ((flags & 1) && c != '[') /* ] */
450 return (0);
451 else if ((flags & 1) == 0 && legal_variable_starter (c) == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000452#else
Jari Aalto7117c2d2002-07-17 14:10:11 +0000453 if (legal_variable_starter (c) == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000454#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +0000455 return (0);
456
457 while (c = string[indx])
458 {
459 /* The following is safe. Note that '=' at the start of a word
460 is not an assignment statement. */
461 if (c == '=')
462 return (indx);
463
464#if defined (ARRAY_VARS)
465 if (c == '[')
466 {
Chet Rameyd233b482019-01-07 09:27:52 -0500467 newi = skipsubscript (string, indx, (flags & 2) ? 1 : 0);
468 /* XXX - why not check for blank subscripts here, if we do in
469 valid_array_reference? */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000470 if (string[newi++] != ']')
471 return (0);
Jari Aalto95732b42005-12-07 14:08:12 +0000472 if (string[newi] == '+' && string[newi+1] == '=')
473 return (newi + 1);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000474 return ((string[newi] == '=') ? newi : 0);
475 }
476#endif /* ARRAY_VARS */
477
Jari Aalto95732b42005-12-07 14:08:12 +0000478 /* Check for `+=' */
479 if (c == '+' && string[indx+1] == '=')
480 return (indx + 1);
481
Jari Aalto7117c2d2002-07-17 14:10:11 +0000482 /* Variable names in assignment statements may contain only letters,
483 digits, and `_'. */
484 if (legal_variable_char (c) == 0)
485 return (0);
486
487 indx++;
488 }
489 return (0);
490}
491
Chet Rameyd233b482019-01-07 09:27:52 -0500492int
493line_isblank (line)
494 const char *line;
495{
496 register int i;
497
498 if (line == 0)
499 return 0; /* XXX */
500 for (i = 0; line[i]; i++)
501 if (isblank ((unsigned char)line[i]) == 0)
502 break;
503 return (line[i] == '\0');
504}
505
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000506/* **************************************************************** */
507/* */
508/* Functions to manage files and file descriptors */
509/* */
510/* **************************************************************** */
511
Jari Aalto726f6381996-08-26 18:22:31 +0000512/* A function to unset no-delay mode on a file descriptor. Used in shell.c
513 to unset it on the fd passed as stdin. Should be called on stdin if
514 readline gets an EAGAIN or EWOULDBLOCK when trying to read input. */
515
516#if !defined (O_NDELAY)
517# if defined (FNDELAY)
518# define O_NDELAY FNDELAY
519# endif
520#endif /* O_NDELAY */
521
522/* Make sure no-delay mode is not set on file descriptor FD. */
Jari Aaltobb706242000-03-17 21:46:59 +0000523int
Jari Aalto28ef6c32001-04-06 19:14:31 +0000524sh_unset_nodelay_mode (fd)
Jari Aalto726f6381996-08-26 18:22:31 +0000525 int fd;
526{
Jari Aaltobb706242000-03-17 21:46:59 +0000527 int flags, bflags;
Jari Aalto726f6381996-08-26 18:22:31 +0000528
529 if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
Jari Aaltobb706242000-03-17 21:46:59 +0000530 return -1;
Jari Aalto726f6381996-08-26 18:22:31 +0000531
Jari Aaltobb706242000-03-17 21:46:59 +0000532 bflags = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000533
534 /* This is defined to O_NDELAY in filecntl.h if O_NONBLOCK is not present
535 and O_NDELAY is defined. */
Jari Aaltobb706242000-03-17 21:46:59 +0000536#ifdef O_NONBLOCK
537 bflags |= O_NONBLOCK;
538#endif
539
540#ifdef O_NDELAY
541 bflags |= O_NDELAY;
542#endif
543
544 if (flags & bflags)
Jari Aalto726f6381996-08-26 18:22:31 +0000545 {
Jari Aaltobb706242000-03-17 21:46:59 +0000546 flags &= ~bflags;
547 return (fcntl (fd, F_SETFL, flags));
Jari Aalto726f6381996-08-26 18:22:31 +0000548 }
Jari Aalto726f6381996-08-26 18:22:31 +0000549
Jari Aaltobb706242000-03-17 21:46:59 +0000550 return 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000551}
552
Chet Rameyd233b482019-01-07 09:27:52 -0500553/* Just a wrapper for the define in include/filecntl.h */
554int
555sh_setclexec (fd)
556 int fd;
557{
558 return (SET_CLOSE_ON_EXEC (fd));
559}
560
Jari Aalto7117c2d2002-07-17 14:10:11 +0000561/* Return 1 if file descriptor FD is valid; 0 otherwise. */
562int
563sh_validfd (fd)
564 int fd;
565{
566 return (fcntl (fd, F_GETFD, 0) >= 0);
567}
568
Chet Ramey495aee42011-11-22 19:11:26 -0500569int
570fd_ispipe (fd)
571 int fd;
572{
573 errno = 0;
Chet Rameya0c0a002016-09-15 16:59:08 -0400574 return ((lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE));
Chet Ramey495aee42011-11-22 19:11:26 -0500575}
576
Jari Aaltob72432f1999-02-19 17:11:39 +0000577/* There is a bug in the NeXT 2.1 rlogind that causes opens
578 of /dev/tty to fail. */
579
580#if defined (__BEOS__)
581/* On BeOS, opening in non-blocking mode exposes a bug in BeOS, so turn it
582 into a no-op. This should probably go away in the future. */
583# undef O_NONBLOCK
584# define O_NONBLOCK 0
585#endif /* __BEOS__ */
586
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000587void
588check_dev_tty ()
589{
590 int tty_fd;
591 char *tty;
592
Jari Aaltod166f041997-06-05 14:59:13 +0000593 tty_fd = open ("/dev/tty", O_RDWR|O_NONBLOCK);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000594
595 if (tty_fd < 0)
596 {
597 tty = (char *)ttyname (fileno (stdin));
598 if (tty == 0)
599 return;
Jari Aaltod166f041997-06-05 14:59:13 +0000600 tty_fd = open (tty, O_RDWR|O_NONBLOCK);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000601 }
Chet Rameyac50fba2014-02-26 09:36:43 -0500602 if (tty_fd >= 0)
603 close (tty_fd);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000604}
605
606/* Return 1 if PATH1 and PATH2 are the same file. This is kind of
607 expensive. If non-NULL STP1 and STP2 point to stat structures
608 corresponding to PATH1 and PATH2, respectively. */
609int
610same_file (path1, path2, stp1, stp2)
Chet Rameya0c0a002016-09-15 16:59:08 -0400611 const char *path1, *path2;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000612 struct stat *stp1, *stp2;
613{
614 struct stat st1, st2;
615
616 if (stp1 == NULL)
617 {
618 if (stat (path1, &st1) != 0)
619 return (0);
620 stp1 = &st1;
621 }
622
623 if (stp2 == NULL)
624 {
625 if (stat (path2, &st2) != 0)
626 return (0);
627 stp2 = &st2;
628 }
629
630 return ((stp1->st_dev == stp2->st_dev) && (stp1->st_ino == stp2->st_ino));
631}
632
633/* Move FD to a number close to the maximum number of file descriptors
634 allowed in the shell process, to avoid the user stepping on it with
635 redirection and causing us extra work. If CHECK_NEW is non-zero,
636 we check whether or not the file descriptors are in use before
Jari Aaltod166f041997-06-05 14:59:13 +0000637 duplicating FD onto them. MAXFD says where to start checking the
638 file descriptors. If it's less than 20, we get the maximum value
639 available from getdtablesize(2). */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000640int
Jari Aaltod166f041997-06-05 14:59:13 +0000641move_to_high_fd (fd, check_new, maxfd)
642 int fd, check_new, maxfd;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000643{
644 int script_fd, nfds, ignore;
645
Jari Aaltod166f041997-06-05 14:59:13 +0000646 if (maxfd < 20)
647 {
648 nfds = getdtablesize ();
649 if (nfds <= 0)
650 nfds = 20;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000651 if (nfds > HIGH_FD_MAX)
652 nfds = HIGH_FD_MAX; /* reasonable maximum */
Jari Aaltod166f041997-06-05 14:59:13 +0000653 }
654 else
655 nfds = maxfd;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000656
657 for (nfds--; check_new && nfds > 3; nfds--)
658 if (fcntl (nfds, F_GETFD, &ignore) == -1)
659 break;
660
Jari Aalto7117c2d2002-07-17 14:10:11 +0000661 if (nfds > 3 && fd != nfds && (script_fd = dup2 (fd, nfds)) != -1)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000662 {
663 if (check_new == 0 || fd != fileno (stderr)) /* don't close stderr */
664 close (fd);
665 return (script_fd);
666 }
667
Jari Aalto7117c2d2002-07-17 14:10:11 +0000668 /* OK, we didn't find one less than our artificial maximum; return the
669 original file descriptor. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000670 return (fd);
671}
672
673/* Return non-zero if the characters from SAMPLE are not all valid
674 characters to be found in the first line of a shell script. We
675 check up to the first newline, or SAMPLE_LEN, whichever comes first.
676 All of the characters must be printable or whitespace. */
677
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000678int
679check_binary_file (sample, sample_len)
Chet Rameya0c0a002016-09-15 16:59:08 -0400680 const char *sample;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000681 int sample_len;
682{
683 register int i;
Jari Aaltof73dda02001-11-13 17:56:06 +0000684 unsigned char c;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000685
686 for (i = 0; i < sample_len; i++)
687 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000688 c = sample[i];
689 if (c == '\n')
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000690 return (0);
Jari Aalto06285672006-10-10 14:15:34 +0000691 if (c == '\0')
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000692 return (1);
693 }
694
695 return (0);
696}
Jari Aalto726f6381996-08-26 18:22:31 +0000697
698/* **************************************************************** */
699/* */
Jari Aalto31859422009-01-12 13:36:28 +0000700/* Functions to manipulate pipes */
701/* */
702/* **************************************************************** */
703
704int
705sh_openpipe (pv)
706 int *pv;
707{
708 int r;
709
710 if ((r = pipe (pv)) < 0)
711 return r;
712
713 pv[0] = move_to_high_fd (pv[0], 1, 64);
714 pv[1] = move_to_high_fd (pv[1], 1, 64);
715
716 return 0;
717}
718
719int
720sh_closepipe (pv)
721 int *pv;
722{
723 if (pv[0] >= 0)
724 close (pv[0]);
725
726 if (pv[1] >= 0)
727 close (pv[1]);
728
729 pv[0] = pv[1] = -1;
730 return 0;
731}
732
733/* **************************************************************** */
734/* */
Jari Aaltob80f6442004-07-27 13:29:18 +0000735/* Functions to inspect pathnames */
736/* */
737/* **************************************************************** */
738
739int
Jari Aalto31859422009-01-12 13:36:28 +0000740file_exists (fn)
Chet Rameya0c0a002016-09-15 16:59:08 -0400741 const char *fn;
Jari Aalto31859422009-01-12 13:36:28 +0000742{
743 struct stat sb;
744
745 return (stat (fn, &sb) == 0);
746}
747
748int
Jari Aaltob80f6442004-07-27 13:29:18 +0000749file_isdir (fn)
Chet Rameya0c0a002016-09-15 16:59:08 -0400750 const char *fn;
Jari Aaltob80f6442004-07-27 13:29:18 +0000751{
752 struct stat sb;
753
754 return ((stat (fn, &sb) == 0) && S_ISDIR (sb.st_mode));
755}
756
757int
758file_iswdir (fn)
Chet Rameya0c0a002016-09-15 16:59:08 -0400759 const char *fn;
Jari Aaltob80f6442004-07-27 13:29:18 +0000760{
Jari Aalto06285672006-10-10 14:15:34 +0000761 return (file_isdir (fn) && sh_eaccess (fn, W_OK) == 0);
Jari Aaltob80f6442004-07-27 13:29:18 +0000762}
763
Chet Ramey495aee42011-11-22 19:11:26 -0500764/* Return 1 if STRING is "." or "..", optionally followed by a directory
765 separator */
766int
Chet Rameyac50fba2014-02-26 09:36:43 -0500767path_dot_or_dotdot (string)
Chet Ramey495aee42011-11-22 19:11:26 -0500768 const char *string;
769{
770 if (string == 0 || *string == '\0' || *string != '.')
771 return (0);
772
773 /* string[0] == '.' */
774 if (PATHSEP(string[1]) || (string[1] == '.' && PATHSEP(string[2])))
775 return (1);
776
777 return (0);
778}
779
Jari Aalto95732b42005-12-07 14:08:12 +0000780/* Return 1 if STRING contains an absolute pathname, else 0. Used by `cd'
781 to decide whether or not to look up a directory name in $CDPATH. */
782int
783absolute_pathname (string)
784 const char *string;
785{
786 if (string == 0 || *string == '\0')
787 return (0);
788
789 if (ABSPATH(string))
790 return (1);
791
792 if (string[0] == '.' && PATHSEP(string[1])) /* . and ./ */
793 return (1);
794
795 if (string[0] == '.' && string[1] == '.' && PATHSEP(string[2])) /* .. and ../ */
796 return (1);
797
798 return (0);
799}
800
801/* Return 1 if STRING is an absolute program name; it is absolute if it
802 contains any slashes. This is used to decide whether or not to look
803 up through $PATH. */
804int
805absolute_program (string)
806 const char *string;
807{
Chet Ramey00018032011-11-21 20:51:19 -0500808 return ((char *)mbschr (string, '/') != (char *)NULL);
Jari Aalto95732b42005-12-07 14:08:12 +0000809}
Jari Aaltob80f6442004-07-27 13:29:18 +0000810
811/* **************************************************************** */
812/* */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000813/* Functions to manipulate pathnames */
Jari Aalto726f6381996-08-26 18:22:31 +0000814/* */
815/* **************************************************************** */
816
Jari Aalto726f6381996-08-26 18:22:31 +0000817/* Turn STRING (a pathname) into an absolute pathname, assuming that
818 DOT_PATH contains the symbolic location of `.'. This always
819 returns a new string, even if STRING was an absolute pathname to
820 begin with. */
821char *
822make_absolute (string, dot_path)
Chet Rameya0c0a002016-09-15 16:59:08 -0400823 const char *string, *dot_path;
Jari Aalto726f6381996-08-26 18:22:31 +0000824{
825 char *result;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000826
Jari Aalto28ef6c32001-04-06 19:14:31 +0000827 if (dot_path == 0 || ABSPATH(string))
Jari Aaltob80f6442004-07-27 13:29:18 +0000828#ifdef __CYGWIN__
829 {
830 char pathbuf[PATH_MAX + 1];
831
Chet Rameyd233b482019-01-07 09:27:52 -0500832 /* WAS cygwin_conv_to_full_posix_path (string, pathbuf); */
833 cygwin_conv_path (CCP_WIN_A_TO_POSIX, string, pathbuf, PATH_MAX);
Jari Aaltob80f6442004-07-27 13:29:18 +0000834 result = savestring (pathbuf);
835 }
836#else
Jari Aalto726f6381996-08-26 18:22:31 +0000837 result = savestring (string);
Jari Aaltob80f6442004-07-27 13:29:18 +0000838#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000839 else
Jari Aaltobb706242000-03-17 21:46:59 +0000840 result = sh_makepath (dot_path, string, 0);
Jari Aalto726f6381996-08-26 18:22:31 +0000841
842 return (result);
843}
844
Jari Aalto726f6381996-08-26 18:22:31 +0000845/* Return the `basename' of the pathname in STRING (the stuff after the
Jari Aalto95732b42005-12-07 14:08:12 +0000846 last '/'). If STRING is `/', just return it. */
Jari Aalto726f6381996-08-26 18:22:31 +0000847char *
848base_pathname (string)
849 char *string;
850{
851 char *p;
852
Jari Aalto95732b42005-12-07 14:08:12 +0000853#if 0
Jari Aalto28ef6c32001-04-06 19:14:31 +0000854 if (absolute_pathname (string) == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000855 return (string);
Jari Aalto95732b42005-12-07 14:08:12 +0000856#endif
857
858 if (string[0] == '/' && string[1] == 0)
859 return (string);
Jari Aalto726f6381996-08-26 18:22:31 +0000860
861 p = (char *)strrchr (string, '/');
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000862 return (p ? ++p : string);
Jari Aalto726f6381996-08-26 18:22:31 +0000863}
864
865/* Return the full pathname of FILE. Easy. Filenames that begin
866 with a '/' are returned as themselves. Other filenames have
867 the current working directory prepended. A new string is
868 returned in either case. */
869char *
870full_pathname (file)
871 char *file;
872{
Jari Aaltobb706242000-03-17 21:46:59 +0000873 char *ret;
Jari Aalto726f6381996-08-26 18:22:31 +0000874
Jari Aalto7117c2d2002-07-17 14:10:11 +0000875 file = (*file == '~') ? bash_tilde_expand (file, 0) : savestring (file);
Jari Aalto726f6381996-08-26 18:22:31 +0000876
Jari Aalto28ef6c32001-04-06 19:14:31 +0000877 if (ABSPATH(file))
Jari Aalto726f6381996-08-26 18:22:31 +0000878 return (file);
879
Jari Aaltobb706242000-03-17 21:46:59 +0000880 ret = sh_makepath ((char *)NULL, file, (MP_DOCWD|MP_RMDOT));
881 free (file);
Jari Aalto726f6381996-08-26 18:22:31 +0000882
Jari Aaltobb706242000-03-17 21:46:59 +0000883 return (ret);
Jari Aalto726f6381996-08-26 18:22:31 +0000884}
885
Jari Aalto726f6381996-08-26 18:22:31 +0000886/* A slightly related function. Get the prettiest name of this
887 directory possible. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000888static char tdir[PATH_MAX];
Jari Aalto726f6381996-08-26 18:22:31 +0000889
890/* Return a pretty pathname. If the first part of the pathname is
891 the same as $HOME, then replace that with `~'. */
892char *
893polite_directory_format (name)
894 char *name;
895{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000896 char *home;
897 int l;
Jari Aalto726f6381996-08-26 18:22:31 +0000898
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000899 home = get_string_value ("HOME");
900 l = home ? strlen (home) : 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000901 if (l > 1 && strncmp (home, name, l) == 0 && (!name[l] || name[l] == '/'))
902 {
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000903 strncpy (tdir + 1, name + l, sizeof(tdir) - 2);
Jari Aalto726f6381996-08-26 18:22:31 +0000904 tdir[0] = '~';
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000905 tdir[sizeof(tdir) - 1] = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +0000906 return (tdir);
907 }
908 else
909 return (name);
910}
911
Jari Aalto31859422009-01-12 13:36:28 +0000912/* Trim NAME. If NAME begins with `~/', skip over tilde prefix. Trim to
913 keep any tilde prefix and PROMPT_DIRTRIM trailing directory components
914 and replace the intervening characters with `...' */
915char *
916trim_pathname (name, maxlen)
917 char *name;
918 int maxlen;
919{
920 int nlen, ndirs;
921 intmax_t nskip;
922 char *nbeg, *nend, *ntail, *v;
923
924 if (name == 0 || (nlen = strlen (name)) == 0)
925 return name;
926 nend = name + nlen;
927
928 v = get_string_value ("PROMPT_DIRTRIM");
929 if (v == 0 || *v == 0)
930 return name;
931 if (legal_number (v, &nskip) == 0 || nskip <= 0)
932 return name;
933
934 /* Skip over tilde prefix */
935 nbeg = name;
936 if (name[0] == '~')
937 for (nbeg = name; *nbeg; nbeg++)
938 if (*nbeg == '/')
939 {
940 nbeg++;
941 break;
942 }
943 if (*nbeg == 0)
944 return name;
945
946 for (ndirs = 0, ntail = nbeg; *ntail; ntail++)
947 if (*ntail == '/')
948 ndirs++;
Chet Ramey00018032011-11-21 20:51:19 -0500949 if (ndirs < nskip)
Jari Aalto31859422009-01-12 13:36:28 +0000950 return name;
951
952 for (ntail = (*nend == '/') ? nend : nend - 1; ntail > nbeg; ntail--)
953 {
954 if (*ntail == '/')
955 nskip--;
956 if (nskip == 0)
957 break;
958 }
959 if (ntail == nbeg)
960 return name;
961
962 /* Now we want to return name[0..nbeg]+"..."+ntail, modifying name in place */
963 nlen = ntail - nbeg;
964 if (nlen <= 3)
965 return name;
966
967 *nbeg++ = '.';
968 *nbeg++ = '.';
969 *nbeg++ = '.';
970
971 nlen = nend - ntail;
Chet Rameyac50fba2014-02-26 09:36:43 -0500972 memmove (nbeg, ntail, nlen);
Jari Aalto31859422009-01-12 13:36:28 +0000973 nbeg[nlen] = '\0';
974
975 return name;
976}
977
Chet Rameya0c0a002016-09-15 16:59:08 -0400978/* Return a printable representation of FN without special characters. The
979 caller is responsible for freeing memory if this returns something other
980 than its argument. If FLAGS is non-zero, we are printing for portable
981 re-input and should single-quote filenames appropriately. */
982char *
983printable_filename (fn, flags)
984 char *fn;
985 int flags;
986{
987 char *newf;
988
989 if (ansic_shouldquote (fn))
990 newf = ansic_quote (fn, 0, NULL);
991 else if (flags && sh_contains_shell_metas (fn))
992 newf = sh_single_quote (fn);
993 else
994 newf = fn;
995
996 return newf;
997}
998
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000999/* Given a string containing units of information separated by colons,
1000 return the next one pointed to by (P_INDEX), or NULL if there are no more.
1001 Advance (P_INDEX) to the character after the colon. */
1002char *
1003extract_colon_unit (string, p_index)
1004 char *string;
1005 int *p_index;
Jari Aalto726f6381996-08-26 18:22:31 +00001006{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001007 int i, start, len;
1008 char *value;
1009
1010 if (string == 0)
1011 return (string);
1012
1013 len = strlen (string);
1014 if (*p_index >= len)
1015 return ((char *)NULL);
1016
1017 i = *p_index;
1018
1019 /* Each call to this routine leaves the index pointing at a colon if
1020 there is more to the path. If I is > 0, then increment past the
1021 `:'. If I is 0, then the path has a leading colon. Trailing colons
1022 are handled OK by the `else' part of the if statement; an empty
1023 string is returned in that case. */
1024 if (i && string[i] == ':')
1025 i++;
1026
1027 for (start = i; string[i] && string[i] != ':'; i++)
1028 ;
1029
1030 *p_index = i;
1031
1032 if (i == start)
Jari Aalto726f6381996-08-26 18:22:31 +00001033 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001034 if (string[i])
1035 (*p_index)++;
1036 /* Return "" in the case of a trailing `:'. */
Jari Aaltof73dda02001-11-13 17:56:06 +00001037 value = (char *)xmalloc (1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001038 value[0] = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +00001039 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001040 else
Jari Aaltobb706242000-03-17 21:46:59 +00001041 value = substring (string, start, i);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001042
1043 return (value);
Jari Aalto726f6381996-08-26 18:22:31 +00001044}
1045
Jari Aalto726f6381996-08-26 18:22:31 +00001046/* **************************************************************** */
1047/* */
1048/* Tilde Initialization and Expansion */
1049/* */
1050/* **************************************************************** */
1051
Jari Aaltocce855b1998-04-17 19:52:44 +00001052#if defined (PUSHD_AND_POPD)
Chet Ramey8868eda2020-12-06 15:51:17 -05001053extern char *get_dirstack_from_string PARAMS((char *));
Jari Aaltocce855b1998-04-17 19:52:44 +00001054#endif
1055
Jari Aaltof73dda02001-11-13 17:56:06 +00001056static char **bash_tilde_prefixes;
Jari Aalto95732b42005-12-07 14:08:12 +00001057static char **bash_tilde_prefixes2;
Jari Aaltof73dda02001-11-13 17:56:06 +00001058static char **bash_tilde_suffixes;
Jari Aalto95732b42005-12-07 14:08:12 +00001059static char **bash_tilde_suffixes2;
Jari Aaltof73dda02001-11-13 17:56:06 +00001060
Jari Aalto726f6381996-08-26 18:22:31 +00001061/* If tilde_expand hasn't been able to expand the text, perhaps it
1062 is a special shell expansion. This function is installed as the
Jari Aaltocce855b1998-04-17 19:52:44 +00001063 tilde_expansion_preexpansion_hook. It knows how to expand ~- and ~+.
1064 If PUSHD_AND_POPD is defined, ~[+-]N expands to directories from the
1065 directory stack. */
Jari Aalto726f6381996-08-26 18:22:31 +00001066static char *
Jari Aaltod166f041997-06-05 14:59:13 +00001067bash_special_tilde_expansions (text)
Jari Aalto726f6381996-08-26 18:22:31 +00001068 char *text;
1069{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001070 char *result;
Jari Aalto726f6381996-08-26 18:22:31 +00001071
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001072 result = (char *)NULL;
Jari Aaltocce855b1998-04-17 19:52:44 +00001073
1074 if (text[0] == '+' && text[1] == '\0')
1075 result = get_string_value ("PWD");
1076 else if (text[0] == '-' && text[1] == '\0')
1077 result = get_string_value ("OLDPWD");
1078#if defined (PUSHD_AND_POPD)
Jari Aaltof73dda02001-11-13 17:56:06 +00001079 else if (DIGIT (*text) || ((*text == '+' || *text == '-') && DIGIT (text[1])))
Jari Aaltocce855b1998-04-17 19:52:44 +00001080 result = get_dirstack_from_string (text);
1081#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001082
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001083 return (result ? savestring (result) : (char *)NULL);
Jari Aalto726f6381996-08-26 18:22:31 +00001084}
1085
1086/* Initialize the tilde expander. In Bash, we handle `~-' and `~+', as
1087 well as handling special tilde prefixes; `:~" and `=~' are indications
1088 that we should do tilde expansion. */
1089void
1090tilde_initialize ()
1091{
1092 static int times_called = 0;
1093
Jari Aaltod166f041997-06-05 14:59:13 +00001094 /* Tell the tilde expander that we want a crack first. */
Jari Aaltof73dda02001-11-13 17:56:06 +00001095 tilde_expansion_preexpansion_hook = bash_special_tilde_expansions;
Jari Aalto726f6381996-08-26 18:22:31 +00001096
1097 /* Tell the tilde expander about special strings which start a tilde
1098 expansion, and the special strings that end one. Only do this once.
1099 tilde_initialize () is called from within bashline_reinitialize (). */
Jari Aaltocce855b1998-04-17 19:52:44 +00001100 if (times_called++ == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00001101 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001102 bash_tilde_prefixes = strvec_create (3);
Jari Aaltof73dda02001-11-13 17:56:06 +00001103 bash_tilde_prefixes[0] = "=~";
1104 bash_tilde_prefixes[1] = ":~";
1105 bash_tilde_prefixes[2] = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00001106
Jari Aalto95732b42005-12-07 14:08:12 +00001107 bash_tilde_prefixes2 = strvec_create (2);
1108 bash_tilde_prefixes2[0] = ":~";
1109 bash_tilde_prefixes2[1] = (char *)NULL;
1110
Jari Aaltof73dda02001-11-13 17:56:06 +00001111 tilde_additional_prefixes = bash_tilde_prefixes;
1112
Jari Aalto7117c2d2002-07-17 14:10:11 +00001113 bash_tilde_suffixes = strvec_create (3);
Jari Aaltof73dda02001-11-13 17:56:06 +00001114 bash_tilde_suffixes[0] = ":";
1115 bash_tilde_suffixes[1] = "=~"; /* XXX - ?? */
1116 bash_tilde_suffixes[2] = (char *)NULL;
1117
1118 tilde_additional_suffixes = bash_tilde_suffixes;
Jari Aalto95732b42005-12-07 14:08:12 +00001119
1120 bash_tilde_suffixes2 = strvec_create (2);
1121 bash_tilde_suffixes2[0] = ":";
1122 bash_tilde_suffixes2[1] = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00001123 }
Jari Aalto726f6381996-08-26 18:22:31 +00001124}
1125
Jari Aaltof73dda02001-11-13 17:56:06 +00001126/* POSIX.2, 3.6.1: A tilde-prefix consists of an unquoted tilde character
1127 at the beginning of the word, followed by all of the characters preceding
1128 the first unquoted slash in the word, or all the characters in the word
1129 if there is no slash...If none of the characters in the tilde-prefix are
1130 quoted, the characters in the tilde-prefix following the tilde shell be
1131 treated as a possible login name. */
1132
1133#define TILDE_END(c) ((c) == '\0' || (c) == '/' || (c) == ':')
1134
1135static int
1136unquoted_tilde_word (s)
1137 const char *s;
1138{
1139 const char *r;
1140
1141 for (r = s; TILDE_END(*r) == 0; r++)
1142 {
1143 switch (*r)
1144 {
1145 case '\\':
1146 case '\'':
1147 case '"':
1148 return 0;
1149 }
1150 }
1151 return 1;
1152}
1153
Jari Aalto95732b42005-12-07 14:08:12 +00001154/* Find the end of the tilde-prefix starting at S, and return the tilde
1155 prefix in newly-allocated memory. Return the length of the string in
1156 *LENP. FLAGS tells whether or not we're in an assignment context --
1157 if so, `:' delimits the end of the tilde prefix as well. */
1158char *
1159bash_tilde_find_word (s, flags, lenp)
1160 const char *s;
1161 int flags, *lenp;
1162{
1163 const char *r;
1164 char *ret;
1165 int l;
1166
1167 for (r = s; *r && *r != '/'; r++)
1168 {
1169 /* Short-circuit immediately if we see a quote character. Even though
1170 POSIX says that `the first unquoted slash' (or `:') terminates the
1171 tilde-prefix, in practice, any quoted portion of the tilde prefix
1172 will cause it to not be expanded. */
1173 if (*r == '\\' || *r == '\'' || *r == '"')
1174 {
1175 ret = savestring (s);
1176 if (lenp)
1177 *lenp = 0;
1178 return ret;
1179 }
1180 else if (flags && *r == ':')
1181 break;
1182 }
1183 l = r - s;
1184 ret = xmalloc (l + 1);
1185 strncpy (ret, s, l);
1186 ret[l] = '\0';
1187 if (lenp)
1188 *lenp = l;
1189 return ret;
1190}
1191
Jari Aalto7117c2d2002-07-17 14:10:11 +00001192/* Tilde-expand S by running it through the tilde expansion library.
1193 ASSIGN_P is 1 if this is a variable assignment, so the alternate
Jari Aalto95732b42005-12-07 14:08:12 +00001194 tilde prefixes should be enabled (`=~' and `:~', see above). If
1195 ASSIGN_P is 2, we are expanding the rhs of an assignment statement,
1196 so `=~' is not valid. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001197char *
Jari Aalto7117c2d2002-07-17 14:10:11 +00001198bash_tilde_expand (s, assign_p)
Jari Aaltof73dda02001-11-13 17:56:06 +00001199 const char *s;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001200 int assign_p;
Jari Aalto726f6381996-08-26 18:22:31 +00001201{
Chet Ramey8868eda2020-12-06 15:51:17 -05001202 int r;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001203 char *ret;
Jari Aalto726f6381996-08-26 18:22:31 +00001204
Jari Aalto95732b42005-12-07 14:08:12 +00001205 tilde_additional_prefixes = assign_p == 0 ? (char **)0
1206 : (assign_p == 2 ? bash_tilde_prefixes2 : bash_tilde_prefixes);
1207 if (assign_p == 2)
1208 tilde_additional_suffixes = bash_tilde_suffixes2;
1209
Jari Aaltof73dda02001-11-13 17:56:06 +00001210 r = (*s == '~') ? unquoted_tilde_word (s) : 1;
1211 ret = r ? tilde_expand (s) : savestring (s);
Chet Rameyac50fba2014-02-26 09:36:43 -05001212
Chet Rameyac50fba2014-02-26 09:36:43 -05001213 QUIT;
1214
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001215 return (ret);
Jari Aalto726f6381996-08-26 18:22:31 +00001216}
Jari Aaltod166f041997-06-05 14:59:13 +00001217
1218/* **************************************************************** */
1219/* */
1220/* Functions to manipulate and search the group list */
1221/* */
1222/* **************************************************************** */
1223
1224static int ngroups, maxgroups;
1225
1226/* The set of groups that this user is a member of. */
1227static GETGROUPS_T *group_array = (GETGROUPS_T *)NULL;
1228
1229#if !defined (NOGROUP)
1230# define NOGROUP (gid_t) -1
1231#endif
1232
Jari Aaltod166f041997-06-05 14:59:13 +00001233static void
1234initialize_group_array ()
1235{
1236 register int i;
1237
1238 if (maxgroups == 0)
1239 maxgroups = getmaxgroups ();
1240
1241 ngroups = 0;
1242 group_array = (GETGROUPS_T *)xrealloc (group_array, maxgroups * sizeof (GETGROUPS_T));
1243
1244#if defined (HAVE_GETGROUPS)
1245 ngroups = getgroups (maxgroups, group_array);
1246#endif
1247
1248 /* If getgroups returns nothing, or the OS does not support getgroups(),
1249 make sure the groups array includes at least the current gid. */
1250 if (ngroups == 0)
1251 {
1252 group_array[0] = current_user.gid;
1253 ngroups = 1;
1254 }
1255
1256 /* If the primary group is not in the groups array, add it as group_array[0]
1257 and shuffle everything else up 1, if there's room. */
1258 for (i = 0; i < ngroups; i++)
1259 if (current_user.gid == (gid_t)group_array[i])
1260 break;
1261 if (i == ngroups && ngroups < maxgroups)
1262 {
1263 for (i = ngroups; i > 0; i--)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001264 group_array[i] = group_array[i - 1];
Jari Aaltod166f041997-06-05 14:59:13 +00001265 group_array[0] = current_user.gid;
1266 ngroups++;
1267 }
Jari Aaltocce855b1998-04-17 19:52:44 +00001268
1269 /* If the primary group is not group_array[0], swap group_array[0] and
1270 whatever the current group is. The vast majority of systems should
1271 not need this; a notable exception is Linux. */
1272 if (group_array[0] != current_user.gid)
1273 {
1274 for (i = 0; i < ngroups; i++)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001275 if (group_array[i] == current_user.gid)
1276 break;
Jari Aaltocce855b1998-04-17 19:52:44 +00001277 if (i < ngroups)
1278 {
1279 group_array[i] = group_array[0];
1280 group_array[0] = current_user.gid;
1281 }
1282 }
Jari Aaltod166f041997-06-05 14:59:13 +00001283}
1284
1285/* Return non-zero if GID is one that we have in our groups list. */
1286int
Jari Aaltocce855b1998-04-17 19:52:44 +00001287#if defined (__STDC__) || defined ( _MINIX)
1288group_member (gid_t gid)
1289#else
Jari Aaltod166f041997-06-05 14:59:13 +00001290group_member (gid)
1291 gid_t gid;
Jari Aaltocce855b1998-04-17 19:52:44 +00001292#endif /* !__STDC__ && !_MINIX */
Jari Aaltod166f041997-06-05 14:59:13 +00001293{
1294#if defined (HAVE_GETGROUPS)
1295 register int i;
1296#endif
1297
1298 /* Short-circuit if possible, maybe saving a call to getgroups(). */
1299 if (gid == current_user.gid || gid == current_user.egid)
1300 return (1);
1301
1302#if defined (HAVE_GETGROUPS)
1303 if (ngroups == 0)
1304 initialize_group_array ();
1305
1306 /* In case of error, the user loses. */
1307 if (ngroups <= 0)
1308 return (0);
1309
1310 /* Search through the list looking for GID. */
1311 for (i = 0; i < ngroups; i++)
1312 if (gid == (gid_t)group_array[i])
1313 return (1);
1314#endif
1315
1316 return (0);
1317}
1318
1319char **
1320get_group_list (ngp)
1321 int *ngp;
1322{
1323 static char **group_vector = (char **)NULL;
1324 register int i;
Jari Aaltod166f041997-06-05 14:59:13 +00001325
1326 if (group_vector)
1327 {
1328 if (ngp)
1329 *ngp = ngroups;
1330 return group_vector;
1331 }
1332
1333 if (ngroups == 0)
1334 initialize_group_array ();
1335
1336 if (ngroups <= 0)
1337 {
1338 if (ngp)
1339 *ngp = 0;
1340 return (char **)NULL;
1341 }
1342
Jari Aalto7117c2d2002-07-17 14:10:11 +00001343 group_vector = strvec_create (ngroups);
Jari Aaltod166f041997-06-05 14:59:13 +00001344 for (i = 0; i < ngroups; i++)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001345 group_vector[i] = itos (group_array[i]);
Jari Aaltob72432f1999-02-19 17:11:39 +00001346
Jari Aaltod166f041997-06-05 14:59:13 +00001347 if (ngp)
1348 *ngp = ngroups;
1349 return group_vector;
1350}
Jari Aaltob72432f1999-02-19 17:11:39 +00001351
1352int *
1353get_group_array (ngp)
1354 int *ngp;
1355{
1356 int i;
1357 static int *group_iarray = (int *)NULL;
1358
1359 if (group_iarray)
1360 {
1361 if (ngp)
1362 *ngp = ngroups;
1363 return (group_iarray);
1364 }
1365
1366 if (ngroups == 0)
1367 initialize_group_array ();
1368
1369 if (ngroups <= 0)
1370 {
1371 if (ngp)
1372 *ngp = 0;
1373 return (int *)NULL;
1374 }
1375
1376 group_iarray = (int *)xmalloc (ngroups * sizeof (int));
1377 for (i = 0; i < ngroups; i++)
1378 group_iarray[i] = (int)group_array[i];
1379
1380 if (ngp)
1381 *ngp = ngroups;
1382 return group_iarray;
1383}
Chet Rameya0c0a002016-09-15 16:59:08 -04001384
1385/* **************************************************************** */
1386/* */
1387/* Miscellaneous functions */
1388/* */
1389/* **************************************************************** */
1390
1391/* Return a value for PATH that is guaranteed to find all of the standard
1392 utilities. This uses Posix.2 configuration variables, if present. It
1393 uses a value defined in config.h as a last resort. */
1394char *
1395conf_standard_path ()
1396{
1397#if defined (_CS_PATH) && defined (HAVE_CONFSTR)
1398 char *p;
1399 size_t len;
1400
1401 len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0);
1402 if (len > 0)
1403 {
1404 p = (char *)xmalloc (len + 2);
1405 *p = '\0';
1406 confstr (_CS_PATH, p, len);
1407 return (p);
1408 }
1409 else
1410 return (savestring (STANDARD_UTILS_PATH));
1411#else /* !_CS_PATH || !HAVE_CONFSTR */
1412# if defined (CS_PATH)
1413 return (savestring (CS_PATH));
1414# else
1415 return (savestring (STANDARD_UTILS_PATH));
1416# endif /* !CS_PATH */
1417#endif /* !_CS_PATH || !HAVE_CONFSTR */
1418}
Chet Rameyd233b482019-01-07 09:27:52 -05001419
1420int
1421default_columns ()
1422{
1423 char *v;
1424 int c;
1425
1426 c = -1;
1427 v = get_string_value ("COLUMNS");
1428 if (v && *v)
1429 {
1430 c = atoi (v);
1431 if (c > 0)
1432 return c;
1433 }
1434
1435 if (check_window_size)
1436 get_new_window_size (0, (int *)0, &c);
1437
1438 return (c > 0 ? c : 80);
1439}
1440
1441