]> git.ipfire.org Git - thirdparty/bash.git/blame - general.c
fix for SIGINT in sourced script
[thirdparty/bash.git] / general.c
CommitLineData
726f6388
JA
1/* general.c -- Stuff that is used by all files. */
2
a0c0a00f 3/* Copyright (C) 1987-2016 Free Software Foundation, Inc.
726f6388
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
3185942a
JA
7 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.
726f6388 11
3185942a
JA
12 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.
726f6388 16
3185942a
JA
17 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*/
726f6388 20
ccc6cda3
JA
21#include "config.h"
22
726f6388 23#include "bashtypes.h"
ac50fbac 24#if defined (HAVE_SYS_PARAM_H)
cce855bc
JA
25# include <sys/param.h>
26#endif
ccc6cda3
JA
27#include "posixstat.h"
28
29#if defined (HAVE_UNISTD_H)
30# include <unistd.h>
31#endif
32
726f6388
JA
33#include "filecntl.h"
34#include "bashansi.h"
ccc6cda3 35#include <stdio.h>
f73dda09 36#include "chartypes.h"
ccc6cda3
JA
37#include <errno.h>
38
b80f6443
JA
39#include "bashintl.h"
40
726f6388 41#include "shell.h"
95732b49 42#include "test.h"
ac50fbac 43#include "trap.h"
95732b49 44
a0c0a00f
CR
45#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
46# include <mbstr.h> /* mbschr */
47#endif
48
726f6388
JA
49#include <tilde/tilde.h>
50
726f6388
JA
51#if !defined (errno)
52extern int errno;
53#endif /* !errno */
54
f73dda09 55extern int expand_aliases;
ccc6cda3 56extern int interactive_comments;
28ef6c31
JA
57extern int check_hashed_filenames;
58extern int source_uses_path;
59extern int source_searches_cwd;
a0c0a00f
CR
60extern int posixly_correct;
61extern int inherit_errexit;
cce855bc 62
7117c2d2
JA
63static char *bash_special_tilde_expansions __P((char *));
64static int unquoted_tilde_word __P((const char *));
65static void initialize_group_array __P((void));
66
cce855bc 67/* A standard error message to use when getcwd() returns NULL. */
3185942a 68const char * const bash_getcwd_errstr = N_("getcwd: cannot access parent directories");
726f6388 69
ccc6cda3 70/* Do whatever is necessary to initialize `Posix mode'. */
726f6388 71void
ccc6cda3
JA
72posix_initialize (on)
73 int on;
726f6388 74{
28ef6c31
JA
75 /* Things that should be turned on when posix mode is enabled. */
76 if (on != 0)
77 {
78 interactive_comments = source_uses_path = expand_aliases = 1;
a0c0a00f 79 inherit_errexit = 1;
3185942a 80 source_searches_cwd = 0;
28ef6c31
JA
81 }
82
83 /* Things that should be turned on when posix mode is disabled. */
84 if (on == 0)
85 {
86 source_searches_cwd = 1;
87 expand_aliases = interactive_shell;
88 }
726f6388
JA
89}
90
ccc6cda3
JA
91/* **************************************************************** */
92/* */
93/* Functions to convert to and from and display non-standard types */
94/* */
95/* **************************************************************** */
96
726f6388
JA
97#if defined (RLIMTYPE)
98RLIMTYPE
99string_to_rlimtype (s)
100 char *s;
101{
cce855bc
JA
102 RLIMTYPE ret;
103 int neg;
726f6388 104
cce855bc
JA
105 ret = 0;
106 neg = 0;
726f6388
JA
107 while (s && *s && whitespace (*s))
108 s++;
0001803f 109 if (s && (*s == '-' || *s == '+'))
726f6388
JA
110 {
111 neg = *s == '-';
112 s++;
113 }
f73dda09
JA
114 for ( ; s && *s && DIGIT (*s); s++)
115 ret = (ret * 10) + TODIGIT (*s);
726f6388
JA
116 return (neg ? -ret : ret);
117}
118
119void
120print_rlimtype (n, addnl)
121 RLIMTYPE n;
122 int addnl;
123{
f73dda09 124 char s[INT_STRLEN_BOUND (RLIMTYPE) + 1], *p;
726f6388 125
f73dda09
JA
126 p = s + sizeof(s);
127 *--p = '\0';
726f6388
JA
128
129 if (n < 0)
130 {
f73dda09
JA
131 do
132 *--p = '0' - n % 10;
133 while ((n /= 10) != 0);
134
135 *--p = '-';
136 }
137 else
138 {
139 do
140 *--p = '0' + n % 10;
141 while ((n /= 10) != 0);
726f6388
JA
142 }
143
f73dda09 144 printf ("%s%s", p, addnl ? "\n" : "");
726f6388
JA
145}
146#endif /* RLIMTYPE */
147
ccc6cda3
JA
148/* **************************************************************** */
149/* */
150/* Input Validation Functions */
151/* */
152/* **************************************************************** */
153
154/* Return non-zero if all of the characters in STRING are digits. */
155int
156all_digits (string)
a0c0a00f 157 const char *string;
ccc6cda3 158{
a0c0a00f 159 register const char *s;
28ef6c31
JA
160
161 for (s = string; *s; s++)
f73dda09 162 if (DIGIT (*s) == 0)
28ef6c31
JA
163 return (0);
164
ccc6cda3
JA
165 return (1);
166}
167
168/* Return non-zero if the characters pointed to by STRING constitute a
169 valid number. Stuff the converted number into RESULT if RESULT is
f73dda09 170 not null. */
ccc6cda3
JA
171int
172legal_number (string, result)
3185942a 173 const char *string;
7117c2d2 174 intmax_t *result;
ccc6cda3 175{
7117c2d2 176 intmax_t value;
cce855bc 177 char *ep;
ccc6cda3
JA
178
179 if (result)
180 *result = 0;
181
ac50fbac
CR
182 if (string == 0)
183 return 0;
184
f73dda09 185 errno = 0;
7117c2d2 186 value = strtoimax (string, &ep, 10);
3185942a 187 if (errno || ep == string)
f73dda09 188 return 0; /* errno is set on overflow or underflow */
ccc6cda3 189
7117c2d2 190 /* Skip any trailing whitespace, since strtoimax does not. */
28ef6c31
JA
191 while (whitespace (*ep))
192 ep++;
193
cce855bc
JA
194 /* If *string is not '\0' but *ep is '\0' on return, the entire string
195 is valid. */
ac50fbac 196 if (*string && *ep == '\0')
ccc6cda3
JA
197 {
198 if (result)
cce855bc
JA
199 *result = value;
200 /* The SunOS4 implementation of strtol() will happily ignore
201 overflow conditions, so this cannot do overflow correctly
202 on those systems. */
203 return 1;
ccc6cda3 204 }
cce855bc
JA
205
206 return (0);
ccc6cda3
JA
207}
208
726f6388
JA
209/* Return 1 if this token is a legal shell `identifier'; that is, it consists
210 solely of letters, digits, and underscores, and does not begin with a
211 digit. */
212int
213legal_identifier (name)
a0c0a00f 214 const char *name;
726f6388 215{
a0c0a00f 216 register const char *s;
f73dda09 217 unsigned char c;
726f6388 218
f73dda09 219 if (!name || !(c = *name) || (legal_variable_starter (c) == 0))
726f6388
JA
220 return (0);
221
f73dda09 222 for (s = name + 1; (c = *s) != 0; s++)
726f6388 223 {
f73dda09 224 if (legal_variable_char (c) == 0)
28ef6c31 225 return (0);
726f6388
JA
226 }
227 return (1);
228}
229
a0c0a00f
CR
230/* Return 1 if NAME is a valid value that can be assigned to a nameref
231 variable. FLAGS can be 2, in which case the name is going to be used
232 to create a variable. Other values are currently unused, but could
233 be used to allow values to be stored and indirectly referenced, but
234 not used in assignments. */
235int
236valid_nameref_value (name, flags)
237 const char *name;
238 int flags;
239{
240 if (name == 0 || *name == 0)
241 return 0;
242
243 /* valid identifier */
244#if defined (ARRAY_VARS)
245 if (legal_identifier (name) || (flags != 2 && valid_array_reference (name, 0)))
246#else
247 if (legal_identifier (name))
248#endif
249 return 1;
250
251 return 0;
252}
253
254int
255check_selfref (name, value, flags)
256 const char *name;
257 char *value;
258 int flags;
259{
260 char *t;
261
262 if (STREQ (name, value))
263 return 1;
264
265#if defined (ARRAY_VARS)
266 if (valid_array_reference (value, 0))
267 {
268 t = array_variable_name (value, (char **)NULL, (int *)NULL);
269 if (t && STREQ (name, t))
270 {
271 free (t);
272 return 1;
273 }
274 free (t);
275 }
276#endif
277
278 return 0; /* not a self reference */
279}
280
726f6388
JA
281/* Make sure that WORD is a valid shell identifier, i.e.
282 does not contain a dollar sign, nor is quoted in any way. Nor
283 does it consist of all digits. If CHECK_WORD is non-zero,
284 the word is checked to ensure that it consists of only letters,
285 digits, and underscores. */
ccc6cda3 286int
726f6388
JA
287check_identifier (word, check_word)
288 WORD_DESC *word;
289 int check_word;
290{
ccc6cda3 291 if ((word->flags & (W_HASDOLLAR|W_QUOTED)) || all_digits (word->word))
726f6388 292 {
b80f6443 293 internal_error (_("`%s': not a valid identifier"), word->word);
726f6388
JA
294 return (0);
295 }
296 else if (check_word && legal_identifier (word->word) == 0)
297 {
b80f6443 298 internal_error (_("`%s': not a valid identifier"), word->word);
726f6388
JA
299 return (0);
300 }
301 else
302 return (1);
303}
304
a0c0a00f
CR
305/* Return 1 if STRING is a function name that the shell will import from
306 the environment. Currently we reject attempts to import shell functions
307 containing slashes, beginning with newlines or containing blanks. In
308 Posix mode, we require that STRING be a valid shell identifier. Not
309 used yet. */
310int
311importable_function_name (string, len)
312 const char *string;
313 size_t len;
314{
315 if (absolute_program (string)) /* don't allow slash */
316 return 0;
317 if (*string == '\n') /* can't start with a newline */
318 return 0;
319 if (shellblank (*string) || shellblank(string[len-1]))
320 return 0;
321 return (posixly_correct ? legal_identifier (string) : 1);
322}
323
324int
325exportable_function_name (string)
326 const char *string;
327{
328 if (absolute_program (string))
329 return 0;
330 if (mbschr (string, '=') != 0)
331 return 0;
332 return 1;
333}
334
b80f6443
JA
335/* Return 1 if STRING comprises a valid alias name. The shell accepts
336 essentially all characters except those which must be quoted to the
337 parser (which disqualifies them from alias expansion anyway) and `/'. */
338int
339legal_alias_name (string, flags)
a0c0a00f 340 const char *string;
b80f6443
JA
341 int flags;
342{
a0c0a00f 343 register const char *s;
b80f6443
JA
344
345 for (s = string; *s; s++)
346 if (shellbreak (*s) || shellxquote (*s) || shellexp (*s) || (*s == '/'))
347 return 0;
348 return 1;
349}
350
7117c2d2
JA
351/* Returns non-zero if STRING is an assignment statement. The returned value
352 is the index of the `=' sign. */
353int
b80f6443 354assignment (string, flags)
7117c2d2 355 const char *string;
b80f6443 356 int flags;
7117c2d2
JA
357{
358 register unsigned char c;
359 register int newi, indx;
360
361 c = string[indx = 0];
362
b80f6443 363#if defined (ARRAY_VARS)
eb873671 364 if ((legal_variable_starter (c) == 0) && (flags == 0 || c != '[')) /* ] */
b80f6443 365#else
7117c2d2 366 if (legal_variable_starter (c) == 0)
b80f6443 367#endif
7117c2d2
JA
368 return (0);
369
370 while (c = string[indx])
371 {
372 /* The following is safe. Note that '=' at the start of a word
373 is not an assignment statement. */
374 if (c == '=')
375 return (indx);
376
377#if defined (ARRAY_VARS)
378 if (c == '[')
379 {
0001803f 380 newi = skipsubscript (string, indx, 0);
7117c2d2
JA
381 if (string[newi++] != ']')
382 return (0);
95732b49
JA
383 if (string[newi] == '+' && string[newi+1] == '=')
384 return (newi + 1);
7117c2d2
JA
385 return ((string[newi] == '=') ? newi : 0);
386 }
387#endif /* ARRAY_VARS */
388
95732b49
JA
389 /* Check for `+=' */
390 if (c == '+' && string[indx+1] == '=')
391 return (indx + 1);
392
7117c2d2
JA
393 /* Variable names in assignment statements may contain only letters,
394 digits, and `_'. */
395 if (legal_variable_char (c) == 0)
396 return (0);
397
398 indx++;
399 }
400 return (0);
401}
402
ccc6cda3
JA
403/* **************************************************************** */
404/* */
405/* Functions to manage files and file descriptors */
406/* */
407/* **************************************************************** */
408
726f6388
JA
409/* A function to unset no-delay mode on a file descriptor. Used in shell.c
410 to unset it on the fd passed as stdin. Should be called on stdin if
411 readline gets an EAGAIN or EWOULDBLOCK when trying to read input. */
412
413#if !defined (O_NDELAY)
414# if defined (FNDELAY)
415# define O_NDELAY FNDELAY
416# endif
417#endif /* O_NDELAY */
418
419/* Make sure no-delay mode is not set on file descriptor FD. */
bb70624e 420int
28ef6c31 421sh_unset_nodelay_mode (fd)
726f6388
JA
422 int fd;
423{
bb70624e 424 int flags, bflags;
726f6388
JA
425
426 if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
bb70624e 427 return -1;
726f6388 428
bb70624e 429 bflags = 0;
ccc6cda3
JA
430
431 /* This is defined to O_NDELAY in filecntl.h if O_NONBLOCK is not present
432 and O_NDELAY is defined. */
bb70624e
JA
433#ifdef O_NONBLOCK
434 bflags |= O_NONBLOCK;
435#endif
436
437#ifdef O_NDELAY
438 bflags |= O_NDELAY;
439#endif
440
441 if (flags & bflags)
726f6388 442 {
bb70624e
JA
443 flags &= ~bflags;
444 return (fcntl (fd, F_SETFL, flags));
726f6388 445 }
726f6388 446
bb70624e 447 return 0;
726f6388
JA
448}
449
7117c2d2
JA
450/* Return 1 if file descriptor FD is valid; 0 otherwise. */
451int
452sh_validfd (fd)
453 int fd;
454{
455 return (fcntl (fd, F_GETFD, 0) >= 0);
456}
457
495aee44
CR
458int
459fd_ispipe (fd)
460 int fd;
461{
462 errno = 0;
a0c0a00f 463 return ((lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE));
495aee44
CR
464}
465
b72432fd
JA
466/* There is a bug in the NeXT 2.1 rlogind that causes opens
467 of /dev/tty to fail. */
468
469#if defined (__BEOS__)
470/* On BeOS, opening in non-blocking mode exposes a bug in BeOS, so turn it
471 into a no-op. This should probably go away in the future. */
472# undef O_NONBLOCK
473# define O_NONBLOCK 0
474#endif /* __BEOS__ */
475
726f6388 476void
ccc6cda3 477check_dev_tty ()
726f6388 478{
ccc6cda3
JA
479 int tty_fd;
480 char *tty;
726f6388 481
d166f048 482 tty_fd = open ("/dev/tty", O_RDWR|O_NONBLOCK);
726f6388 483
ccc6cda3 484 if (tty_fd < 0)
726f6388 485 {
ccc6cda3
JA
486 tty = (char *)ttyname (fileno (stdin));
487 if (tty == 0)
488 return;
d166f048 489 tty_fd = open (tty, O_RDWR|O_NONBLOCK);
726f6388 490 }
ac50fbac
CR
491 if (tty_fd >= 0)
492 close (tty_fd);
726f6388
JA
493}
494
ccc6cda3
JA
495/* Return 1 if PATH1 and PATH2 are the same file. This is kind of
496 expensive. If non-NULL STP1 and STP2 point to stat structures
497 corresponding to PATH1 and PATH2, respectively. */
726f6388 498int
ccc6cda3 499same_file (path1, path2, stp1, stp2)
a0c0a00f 500 const char *path1, *path2;
ccc6cda3 501 struct stat *stp1, *stp2;
726f6388 502{
ccc6cda3 503 struct stat st1, st2;
726f6388 504
ccc6cda3 505 if (stp1 == NULL)
726f6388 506 {
ccc6cda3
JA
507 if (stat (path1, &st1) != 0)
508 return (0);
509 stp1 = &st1;
726f6388 510 }
726f6388 511
ccc6cda3
JA
512 if (stp2 == NULL)
513 {
514 if (stat (path2, &st2) != 0)
515 return (0);
516 stp2 = &st2;
517 }
726f6388 518
ccc6cda3 519 return ((stp1->st_dev == stp2->st_dev) && (stp1->st_ino == stp2->st_ino));
726f6388
JA
520}
521
ccc6cda3
JA
522/* Move FD to a number close to the maximum number of file descriptors
523 allowed in the shell process, to avoid the user stepping on it with
524 redirection and causing us extra work. If CHECK_NEW is non-zero,
525 we check whether or not the file descriptors are in use before
d166f048
JA
526 duplicating FD onto them. MAXFD says where to start checking the
527 file descriptors. If it's less than 20, we get the maximum value
528 available from getdtablesize(2). */
726f6388 529int
d166f048
JA
530move_to_high_fd (fd, check_new, maxfd)
531 int fd, check_new, maxfd;
726f6388 532{
ccc6cda3 533 int script_fd, nfds, ignore;
726f6388 534
d166f048
JA
535 if (maxfd < 20)
536 {
537 nfds = getdtablesize ();
538 if (nfds <= 0)
539 nfds = 20;
7117c2d2
JA
540 if (nfds > HIGH_FD_MAX)
541 nfds = HIGH_FD_MAX; /* reasonable maximum */
d166f048
JA
542 }
543 else
544 nfds = maxfd;
726f6388 545
ccc6cda3
JA
546 for (nfds--; check_new && nfds > 3; nfds--)
547 if (fcntl (nfds, F_GETFD, &ignore) == -1)
548 break;
726f6388 549
7117c2d2 550 if (nfds > 3 && fd != nfds && (script_fd = dup2 (fd, nfds)) != -1)
ccc6cda3
JA
551 {
552 if (check_new == 0 || fd != fileno (stderr)) /* don't close stderr */
553 close (fd);
554 return (script_fd);
555 }
726f6388 556
7117c2d2
JA
557 /* OK, we didn't find one less than our artificial maximum; return the
558 original file descriptor. */
ccc6cda3
JA
559 return (fd);
560}
561
562/* Return non-zero if the characters from SAMPLE are not all valid
563 characters to be found in the first line of a shell script. We
564 check up to the first newline, or SAMPLE_LEN, whichever comes first.
565 All of the characters must be printable or whitespace. */
726f6388 566
726f6388 567int
ccc6cda3 568check_binary_file (sample, sample_len)
a0c0a00f 569 const char *sample;
ccc6cda3 570 int sample_len;
726f6388 571{
ccc6cda3 572 register int i;
f73dda09 573 unsigned char c;
726f6388 574
ccc6cda3
JA
575 for (i = 0; i < sample_len; i++)
576 {
f73dda09
JA
577 c = sample[i];
578 if (c == '\n')
ccc6cda3 579 return (0);
0628567a 580 if (c == '\0')
ccc6cda3
JA
581 return (1);
582 }
726f6388 583
ccc6cda3 584 return (0);
726f6388
JA
585}
586
3185942a
JA
587/* **************************************************************** */
588/* */
589/* Functions to manipulate pipes */
590/* */
591/* **************************************************************** */
592
593int
594sh_openpipe (pv)
595 int *pv;
596{
597 int r;
598
599 if ((r = pipe (pv)) < 0)
600 return r;
601
602 pv[0] = move_to_high_fd (pv[0], 1, 64);
603 pv[1] = move_to_high_fd (pv[1], 1, 64);
604
605 return 0;
606}
607
608int
609sh_closepipe (pv)
610 int *pv;
611{
612 if (pv[0] >= 0)
613 close (pv[0]);
614
615 if (pv[1] >= 0)
616 close (pv[1]);
617
618 pv[0] = pv[1] = -1;
619 return 0;
620}
621
b80f6443
JA
622/* **************************************************************** */
623/* */
624/* Functions to inspect pathnames */
625/* */
626/* **************************************************************** */
627
3185942a
JA
628int
629file_exists (fn)
a0c0a00f 630 const char *fn;
3185942a
JA
631{
632 struct stat sb;
633
634 return (stat (fn, &sb) == 0);
635}
636
b80f6443
JA
637int
638file_isdir (fn)
a0c0a00f 639 const char *fn;
b80f6443
JA
640{
641 struct stat sb;
642
643 return ((stat (fn, &sb) == 0) && S_ISDIR (sb.st_mode));
644}
645
646int
647file_iswdir (fn)
a0c0a00f 648 const char *fn;
b80f6443 649{
0628567a 650 return (file_isdir (fn) && sh_eaccess (fn, W_OK) == 0);
b80f6443
JA
651}
652
495aee44
CR
653/* Return 1 if STRING is "." or "..", optionally followed by a directory
654 separator */
655int
ac50fbac 656path_dot_or_dotdot (string)
495aee44
CR
657 const char *string;
658{
659 if (string == 0 || *string == '\0' || *string != '.')
660 return (0);
661
662 /* string[0] == '.' */
663 if (PATHSEP(string[1]) || (string[1] == '.' && PATHSEP(string[2])))
664 return (1);
665
666 return (0);
667}
668
95732b49
JA
669/* Return 1 if STRING contains an absolute pathname, else 0. Used by `cd'
670 to decide whether or not to look up a directory name in $CDPATH. */
671int
672absolute_pathname (string)
673 const char *string;
674{
675 if (string == 0 || *string == '\0')
676 return (0);
677
678 if (ABSPATH(string))
679 return (1);
680
681 if (string[0] == '.' && PATHSEP(string[1])) /* . and ./ */
682 return (1);
683
684 if (string[0] == '.' && string[1] == '.' && PATHSEP(string[2])) /* .. and ../ */
685 return (1);
686
687 return (0);
688}
689
690/* Return 1 if STRING is an absolute program name; it is absolute if it
691 contains any slashes. This is used to decide whether or not to look
692 up through $PATH. */
693int
694absolute_program (string)
695 const char *string;
696{
0001803f 697 return ((char *)mbschr (string, '/') != (char *)NULL);
95732b49 698}
b80f6443 699
ccc6cda3
JA
700/* **************************************************************** */
701/* */
702/* Functions to manipulate pathnames */
703/* */
704/* **************************************************************** */
726f6388 705
726f6388
JA
706/* Turn STRING (a pathname) into an absolute pathname, assuming that
707 DOT_PATH contains the symbolic location of `.'. This always
708 returns a new string, even if STRING was an absolute pathname to
709 begin with. */
710char *
711make_absolute (string, dot_path)
a0c0a00f 712 const char *string, *dot_path;
726f6388
JA
713{
714 char *result;
ccc6cda3 715
28ef6c31 716 if (dot_path == 0 || ABSPATH(string))
b80f6443
JA
717#ifdef __CYGWIN__
718 {
719 char pathbuf[PATH_MAX + 1];
720
721 cygwin_conv_to_full_posix_path (string, pathbuf);
722 result = savestring (pathbuf);
723 }
724#else
726f6388 725 result = savestring (string);
b80f6443 726#endif
726f6388 727 else
bb70624e 728 result = sh_makepath (dot_path, string, 0);
726f6388
JA
729
730 return (result);
731}
732
726f6388 733/* Return the `basename' of the pathname in STRING (the stuff after the
95732b49 734 last '/'). If STRING is `/', just return it. */
726f6388
JA
735char *
736base_pathname (string)
737 char *string;
738{
739 char *p;
740
95732b49 741#if 0
28ef6c31 742 if (absolute_pathname (string) == 0)
726f6388 743 return (string);
95732b49
JA
744#endif
745
746 if (string[0] == '/' && string[1] == 0)
747 return (string);
726f6388
JA
748
749 p = (char *)strrchr (string, '/');
ccc6cda3 750 return (p ? ++p : string);
726f6388
JA
751}
752
753/* Return the full pathname of FILE. Easy. Filenames that begin
754 with a '/' are returned as themselves. Other filenames have
755 the current working directory prepended. A new string is
756 returned in either case. */
757char *
758full_pathname (file)
759 char *file;
760{
bb70624e 761 char *ret;
726f6388 762
7117c2d2 763 file = (*file == '~') ? bash_tilde_expand (file, 0) : savestring (file);
726f6388 764
28ef6c31 765 if (ABSPATH(file))
726f6388
JA
766 return (file);
767
bb70624e
JA
768 ret = sh_makepath ((char *)NULL, file, (MP_DOCWD|MP_RMDOT));
769 free (file);
726f6388 770
bb70624e 771 return (ret);
726f6388 772}
726f6388
JA
773
774/* A slightly related function. Get the prettiest name of this
775 directory possible. */
ccc6cda3 776static char tdir[PATH_MAX];
726f6388
JA
777
778/* Return a pretty pathname. If the first part of the pathname is
779 the same as $HOME, then replace that with `~'. */
780char *
781polite_directory_format (name)
782 char *name;
783{
ccc6cda3
JA
784 char *home;
785 int l;
726f6388 786
ccc6cda3
JA
787 home = get_string_value ("HOME");
788 l = home ? strlen (home) : 0;
726f6388
JA
789 if (l > 1 && strncmp (home, name, l) == 0 && (!name[l] || name[l] == '/'))
790 {
e8ce775d 791 strncpy (tdir + 1, name + l, sizeof(tdir) - 2);
726f6388 792 tdir[0] = '~';
e8ce775d 793 tdir[sizeof(tdir) - 1] = '\0';
726f6388
JA
794 return (tdir);
795 }
796 else
797 return (name);
798}
799
3185942a
JA
800/* Trim NAME. If NAME begins with `~/', skip over tilde prefix. Trim to
801 keep any tilde prefix and PROMPT_DIRTRIM trailing directory components
802 and replace the intervening characters with `...' */
803char *
804trim_pathname (name, maxlen)
805 char *name;
806 int maxlen;
807{
808 int nlen, ndirs;
809 intmax_t nskip;
810 char *nbeg, *nend, *ntail, *v;
811
812 if (name == 0 || (nlen = strlen (name)) == 0)
813 return name;
814 nend = name + nlen;
815
816 v = get_string_value ("PROMPT_DIRTRIM");
817 if (v == 0 || *v == 0)
818 return name;
819 if (legal_number (v, &nskip) == 0 || nskip <= 0)
820 return name;
821
822 /* Skip over tilde prefix */
823 nbeg = name;
824 if (name[0] == '~')
825 for (nbeg = name; *nbeg; nbeg++)
826 if (*nbeg == '/')
827 {
828 nbeg++;
829 break;
830 }
831 if (*nbeg == 0)
832 return name;
833
834 for (ndirs = 0, ntail = nbeg; *ntail; ntail++)
835 if (*ntail == '/')
836 ndirs++;
0001803f 837 if (ndirs < nskip)
3185942a
JA
838 return name;
839
840 for (ntail = (*nend == '/') ? nend : nend - 1; ntail > nbeg; ntail--)
841 {
842 if (*ntail == '/')
843 nskip--;
844 if (nskip == 0)
845 break;
846 }
847 if (ntail == nbeg)
848 return name;
849
850 /* Now we want to return name[0..nbeg]+"..."+ntail, modifying name in place */
851 nlen = ntail - nbeg;
852 if (nlen <= 3)
853 return name;
854
855 *nbeg++ = '.';
856 *nbeg++ = '.';
857 *nbeg++ = '.';
858
859 nlen = nend - ntail;
ac50fbac 860 memmove (nbeg, ntail, nlen);
3185942a
JA
861 nbeg[nlen] = '\0';
862
863 return name;
864}
865
a0c0a00f
CR
866/* Return a printable representation of FN without special characters. The
867 caller is responsible for freeing memory if this returns something other
868 than its argument. If FLAGS is non-zero, we are printing for portable
869 re-input and should single-quote filenames appropriately. */
870char *
871printable_filename (fn, flags)
872 char *fn;
873 int flags;
874{
875 char *newf;
876
877 if (ansic_shouldquote (fn))
878 newf = ansic_quote (fn, 0, NULL);
879 else if (flags && sh_contains_shell_metas (fn))
880 newf = sh_single_quote (fn);
881 else
882 newf = fn;
883
884 return newf;
885}
886
ccc6cda3
JA
887/* Given a string containing units of information separated by colons,
888 return the next one pointed to by (P_INDEX), or NULL if there are no more.
889 Advance (P_INDEX) to the character after the colon. */
890char *
891extract_colon_unit (string, p_index)
892 char *string;
893 int *p_index;
726f6388 894{
ccc6cda3
JA
895 int i, start, len;
896 char *value;
726f6388 897
ccc6cda3
JA
898 if (string == 0)
899 return (string);
726f6388 900
ccc6cda3
JA
901 len = strlen (string);
902 if (*p_index >= len)
903 return ((char *)NULL);
726f6388 904
ccc6cda3 905 i = *p_index;
726f6388 906
ccc6cda3
JA
907 /* Each call to this routine leaves the index pointing at a colon if
908 there is more to the path. If I is > 0, then increment past the
909 `:'. If I is 0, then the path has a leading colon. Trailing colons
910 are handled OK by the `else' part of the if statement; an empty
911 string is returned in that case. */
912 if (i && string[i] == ':')
913 i++;
914
915 for (start = i; string[i] && string[i] != ':'; i++)
916 ;
917
918 *p_index = i;
919
920 if (i == start)
921 {
922 if (string[i])
923 (*p_index)++;
924 /* Return "" in the case of a trailing `:'. */
f73dda09 925 value = (char *)xmalloc (1);
ccc6cda3
JA
926 value[0] = '\0';
927 }
928 else
bb70624e 929 value = substring (string, start, i);
ccc6cda3
JA
930
931 return (value);
726f6388 932}
726f6388
JA
933
934/* **************************************************************** */
935/* */
936/* Tilde Initialization and Expansion */
937/* */
938/* **************************************************************** */
939
cce855bc
JA
940#if defined (PUSHD_AND_POPD)
941extern char *get_dirstack_from_string __P((char *));
942#endif
943
f73dda09 944static char **bash_tilde_prefixes;
95732b49 945static char **bash_tilde_prefixes2;
f73dda09 946static char **bash_tilde_suffixes;
95732b49 947static char **bash_tilde_suffixes2;
f73dda09 948
726f6388
JA
949/* If tilde_expand hasn't been able to expand the text, perhaps it
950 is a special shell expansion. This function is installed as the
cce855bc
JA
951 tilde_expansion_preexpansion_hook. It knows how to expand ~- and ~+.
952 If PUSHD_AND_POPD is defined, ~[+-]N expands to directories from the
953 directory stack. */
726f6388 954static char *
d166f048 955bash_special_tilde_expansions (text)
726f6388
JA
956 char *text;
957{
ccc6cda3 958 char *result;
726f6388 959
ccc6cda3 960 result = (char *)NULL;
cce855bc
JA
961
962 if (text[0] == '+' && text[1] == '\0')
963 result = get_string_value ("PWD");
964 else if (text[0] == '-' && text[1] == '\0')
965 result = get_string_value ("OLDPWD");
966#if defined (PUSHD_AND_POPD)
f73dda09 967 else if (DIGIT (*text) || ((*text == '+' || *text == '-') && DIGIT (text[1])))
cce855bc
JA
968 result = get_dirstack_from_string (text);
969#endif
726f6388 970
ccc6cda3 971 return (result ? savestring (result) : (char *)NULL);
726f6388
JA
972}
973
974/* Initialize the tilde expander. In Bash, we handle `~-' and `~+', as
975 well as handling special tilde prefixes; `:~" and `=~' are indications
976 that we should do tilde expansion. */
977void
978tilde_initialize ()
979{
980 static int times_called = 0;
981
d166f048 982 /* Tell the tilde expander that we want a crack first. */
f73dda09 983 tilde_expansion_preexpansion_hook = bash_special_tilde_expansions;
726f6388
JA
984
985 /* Tell the tilde expander about special strings which start a tilde
986 expansion, and the special strings that end one. Only do this once.
987 tilde_initialize () is called from within bashline_reinitialize (). */
cce855bc 988 if (times_called++ == 0)
726f6388 989 {
7117c2d2 990 bash_tilde_prefixes = strvec_create (3);
f73dda09
JA
991 bash_tilde_prefixes[0] = "=~";
992 bash_tilde_prefixes[1] = ":~";
993 bash_tilde_prefixes[2] = (char *)NULL;
994
95732b49
JA
995 bash_tilde_prefixes2 = strvec_create (2);
996 bash_tilde_prefixes2[0] = ":~";
997 bash_tilde_prefixes2[1] = (char *)NULL;
998
f73dda09
JA
999 tilde_additional_prefixes = bash_tilde_prefixes;
1000
7117c2d2 1001 bash_tilde_suffixes = strvec_create (3);
f73dda09
JA
1002 bash_tilde_suffixes[0] = ":";
1003 bash_tilde_suffixes[1] = "=~"; /* XXX - ?? */
1004 bash_tilde_suffixes[2] = (char *)NULL;
1005
1006 tilde_additional_suffixes = bash_tilde_suffixes;
95732b49
JA
1007
1008 bash_tilde_suffixes2 = strvec_create (2);
1009 bash_tilde_suffixes2[0] = ":";
1010 bash_tilde_suffixes2[1] = (char *)NULL;
726f6388 1011 }
726f6388
JA
1012}
1013
f73dda09
JA
1014/* POSIX.2, 3.6.1: A tilde-prefix consists of an unquoted tilde character
1015 at the beginning of the word, followed by all of the characters preceding
1016 the first unquoted slash in the word, or all the characters in the word
1017 if there is no slash...If none of the characters in the tilde-prefix are
1018 quoted, the characters in the tilde-prefix following the tilde shell be
1019 treated as a possible login name. */
1020
1021#define TILDE_END(c) ((c) == '\0' || (c) == '/' || (c) == ':')
1022
1023static int
1024unquoted_tilde_word (s)
1025 const char *s;
1026{
1027 const char *r;
1028
1029 for (r = s; TILDE_END(*r) == 0; r++)
1030 {
1031 switch (*r)
1032 {
1033 case '\\':
1034 case '\'':
1035 case '"':
1036 return 0;
1037 }
1038 }
1039 return 1;
1040}
1041
95732b49
JA
1042/* Find the end of the tilde-prefix starting at S, and return the tilde
1043 prefix in newly-allocated memory. Return the length of the string in
1044 *LENP. FLAGS tells whether or not we're in an assignment context --
1045 if so, `:' delimits the end of the tilde prefix as well. */
1046char *
1047bash_tilde_find_word (s, flags, lenp)
1048 const char *s;
1049 int flags, *lenp;
1050{
1051 const char *r;
1052 char *ret;
1053 int l;
1054
1055 for (r = s; *r && *r != '/'; r++)
1056 {
1057 /* Short-circuit immediately if we see a quote character. Even though
1058 POSIX says that `the first unquoted slash' (or `:') terminates the
1059 tilde-prefix, in practice, any quoted portion of the tilde prefix
1060 will cause it to not be expanded. */
1061 if (*r == '\\' || *r == '\'' || *r == '"')
1062 {
1063 ret = savestring (s);
1064 if (lenp)
1065 *lenp = 0;
1066 return ret;
1067 }
1068 else if (flags && *r == ':')
1069 break;
1070 }
1071 l = r - s;
1072 ret = xmalloc (l + 1);
1073 strncpy (ret, s, l);
1074 ret[l] = '\0';
1075 if (lenp)
1076 *lenp = l;
1077 return ret;
1078}
1079
7117c2d2
JA
1080/* Tilde-expand S by running it through the tilde expansion library.
1081 ASSIGN_P is 1 if this is a variable assignment, so the alternate
95732b49
JA
1082 tilde prefixes should be enabled (`=~' and `:~', see above). If
1083 ASSIGN_P is 2, we are expanding the rhs of an assignment statement,
1084 so `=~' is not valid. */
ccc6cda3 1085char *
7117c2d2 1086bash_tilde_expand (s, assign_p)
f73dda09 1087 const char *s;
7117c2d2 1088 int assign_p;
726f6388 1089{
3185942a 1090 int old_immed, old_term, r;
ccc6cda3 1091 char *ret;
726f6388 1092
a0c0a00f 1093#if 0
ccc6cda3 1094 old_immed = interrupt_immediately;
3185942a 1095 old_term = terminate_immediately;
ac50fbac
CR
1096 /* We want to be able to interrupt tilde expansion. Ordinarily, we can just
1097 jump to top_level, but we don't want to run any trap commands in a signal
1098 handler context. We might be able to get away with just checking for
1099 things like SIGINT and SIGQUIT. */
1100 if (any_signals_trapped () < 0)
1101 interrupt_immediately = 1;
1102 terminate_immediately = 1;
a0c0a00f 1103#endif
95732b49
JA
1104
1105 tilde_additional_prefixes = assign_p == 0 ? (char **)0
1106 : (assign_p == 2 ? bash_tilde_prefixes2 : bash_tilde_prefixes);
1107 if (assign_p == 2)
1108 tilde_additional_suffixes = bash_tilde_suffixes2;
1109
f73dda09
JA
1110 r = (*s == '~') ? unquoted_tilde_word (s) : 1;
1111 ret = r ? tilde_expand (s) : savestring (s);
ac50fbac 1112
a0c0a00f 1113#if 0
ccc6cda3 1114 interrupt_immediately = old_immed;
3185942a 1115 terminate_immediately = old_term;
a0c0a00f 1116#endif
ac50fbac
CR
1117
1118 QUIT;
1119
ccc6cda3 1120 return (ret);
726f6388 1121}
d166f048
JA
1122
1123/* **************************************************************** */
1124/* */
1125/* Functions to manipulate and search the group list */
1126/* */
1127/* **************************************************************** */
1128
1129static int ngroups, maxgroups;
1130
1131/* The set of groups that this user is a member of. */
1132static GETGROUPS_T *group_array = (GETGROUPS_T *)NULL;
1133
1134#if !defined (NOGROUP)
1135# define NOGROUP (gid_t) -1
1136#endif
1137
d166f048
JA
1138static void
1139initialize_group_array ()
1140{
1141 register int i;
1142
1143 if (maxgroups == 0)
1144 maxgroups = getmaxgroups ();
1145
1146 ngroups = 0;
1147 group_array = (GETGROUPS_T *)xrealloc (group_array, maxgroups * sizeof (GETGROUPS_T));
1148
1149#if defined (HAVE_GETGROUPS)
1150 ngroups = getgroups (maxgroups, group_array);
1151#endif
1152
1153 /* If getgroups returns nothing, or the OS does not support getgroups(),
1154 make sure the groups array includes at least the current gid. */
1155 if (ngroups == 0)
1156 {
1157 group_array[0] = current_user.gid;
1158 ngroups = 1;
1159 }
1160
1161 /* If the primary group is not in the groups array, add it as group_array[0]
1162 and shuffle everything else up 1, if there's room. */
1163 for (i = 0; i < ngroups; i++)
1164 if (current_user.gid == (gid_t)group_array[i])
1165 break;
1166 if (i == ngroups && ngroups < maxgroups)
1167 {
1168 for (i = ngroups; i > 0; i--)
28ef6c31 1169 group_array[i] = group_array[i - 1];
d166f048
JA
1170 group_array[0] = current_user.gid;
1171 ngroups++;
1172 }
cce855bc
JA
1173
1174 /* If the primary group is not group_array[0], swap group_array[0] and
1175 whatever the current group is. The vast majority of systems should
1176 not need this; a notable exception is Linux. */
1177 if (group_array[0] != current_user.gid)
1178 {
1179 for (i = 0; i < ngroups; i++)
28ef6c31
JA
1180 if (group_array[i] == current_user.gid)
1181 break;
cce855bc
JA
1182 if (i < ngroups)
1183 {
1184 group_array[i] = group_array[0];
1185 group_array[0] = current_user.gid;
1186 }
1187 }
d166f048
JA
1188}
1189
1190/* Return non-zero if GID is one that we have in our groups list. */
1191int
cce855bc
JA
1192#if defined (__STDC__) || defined ( _MINIX)
1193group_member (gid_t gid)
1194#else
d166f048
JA
1195group_member (gid)
1196 gid_t gid;
cce855bc 1197#endif /* !__STDC__ && !_MINIX */
d166f048
JA
1198{
1199#if defined (HAVE_GETGROUPS)
1200 register int i;
1201#endif
1202
1203 /* Short-circuit if possible, maybe saving a call to getgroups(). */
1204 if (gid == current_user.gid || gid == current_user.egid)
1205 return (1);
1206
1207#if defined (HAVE_GETGROUPS)
1208 if (ngroups == 0)
1209 initialize_group_array ();
1210
1211 /* In case of error, the user loses. */
1212 if (ngroups <= 0)
1213 return (0);
1214
1215 /* Search through the list looking for GID. */
1216 for (i = 0; i < ngroups; i++)
1217 if (gid == (gid_t)group_array[i])
1218 return (1);
1219#endif
1220
1221 return (0);
1222}
1223
1224char **
1225get_group_list (ngp)
1226 int *ngp;
1227{
1228 static char **group_vector = (char **)NULL;
1229 register int i;
d166f048
JA
1230
1231 if (group_vector)
1232 {
1233 if (ngp)
1234 *ngp = ngroups;
1235 return group_vector;
1236 }
1237
1238 if (ngroups == 0)
1239 initialize_group_array ();
1240
1241 if (ngroups <= 0)
1242 {
1243 if (ngp)
1244 *ngp = 0;
1245 return (char **)NULL;
1246 }
1247
7117c2d2 1248 group_vector = strvec_create (ngroups);
d166f048 1249 for (i = 0; i < ngroups; i++)
7117c2d2 1250 group_vector[i] = itos (group_array[i]);
b72432fd 1251
d166f048
JA
1252 if (ngp)
1253 *ngp = ngroups;
1254 return group_vector;
1255}
b72432fd
JA
1256
1257int *
1258get_group_array (ngp)
1259 int *ngp;
1260{
1261 int i;
1262 static int *group_iarray = (int *)NULL;
1263
1264 if (group_iarray)
1265 {
1266 if (ngp)
1267 *ngp = ngroups;
1268 return (group_iarray);
1269 }
1270
1271 if (ngroups == 0)
1272 initialize_group_array ();
1273
1274 if (ngroups <= 0)
1275 {
1276 if (ngp)
1277 *ngp = 0;
1278 return (int *)NULL;
1279 }
1280
1281 group_iarray = (int *)xmalloc (ngroups * sizeof (int));
1282 for (i = 0; i < ngroups; i++)
1283 group_iarray[i] = (int)group_array[i];
1284
1285 if (ngp)
1286 *ngp = ngroups;
1287 return group_iarray;
1288}
a0c0a00f
CR
1289
1290/* **************************************************************** */
1291/* */
1292/* Miscellaneous functions */
1293/* */
1294/* **************************************************************** */
1295
1296/* Return a value for PATH that is guaranteed to find all of the standard
1297 utilities. This uses Posix.2 configuration variables, if present. It
1298 uses a value defined in config.h as a last resort. */
1299char *
1300conf_standard_path ()
1301{
1302#if defined (_CS_PATH) && defined (HAVE_CONFSTR)
1303 char *p;
1304 size_t len;
1305
1306 len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0);
1307 if (len > 0)
1308 {
1309 p = (char *)xmalloc (len + 2);
1310 *p = '\0';
1311 confstr (_CS_PATH, p, len);
1312 return (p);
1313 }
1314 else
1315 return (savestring (STANDARD_UTILS_PATH));
1316#else /* !_CS_PATH || !HAVE_CONFSTR */
1317# if defined (CS_PATH)
1318 return (savestring (CS_PATH));
1319# else
1320 return (savestring (STANDARD_UTILS_PATH));
1321# endif /* !CS_PATH */
1322#endif /* !_CS_PATH || !HAVE_CONFSTR */
1323}