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